author | smarks |
Mon, 04 Dec 2017 11:50:04 -0800 | |
changeset 48059 | 6ee80cd217e0 |
parent 47216 | 71c04702a3d5 |
child 48083 | b1c1b4ef4be2 |
child 55763 | 634d8e14c172 |
permissions | -rw-r--r-- |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
1 |
/* |
44639
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
2 |
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
4 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
5 |
* This code is free software; you can redistribute it and/or modify it |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
7 |
* published by the Free Software Foundation. Oracle designates this |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
8 |
* particular file as subject to the "Classpath" exception as provided |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
9 |
* by Oracle in the LICENSE file that accompanied this code. |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
10 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
15 |
* accompanied this code). |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
16 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
17 |
* You should have received a copy of the GNU General Public License version |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
20 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
22 |
* or visit www.oracle.com if you need additional information or have any |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
23 |
* questions. |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
24 |
*/ |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
25 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
26 |
package jdk.incubator.http; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
27 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
28 |
import java.io.IOException; |
44639
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
29 |
import java.io.UncheckedIOException; |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
30 |
import java.net.InetSocketAddress; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
31 |
import java.net.ProxySelector; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
32 |
import java.net.SocketPermission; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
33 |
import java.net.URI; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
34 |
import java.net.URISyntaxException; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
35 |
import java.net.URLPermission; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
36 |
import java.security.AccessControlContext; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
37 |
import java.security.AccessController; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
38 |
import java.security.PrivilegedAction; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
39 |
import java.security.PrivilegedActionException; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
40 |
import java.security.PrivilegedExceptionAction; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
41 |
import java.util.LinkedList; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
42 |
import java.util.List; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
43 |
import java.util.concurrent.CompletableFuture; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
44 |
import java.util.concurrent.Executor; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
45 |
import jdk.incubator.http.internal.common.MinimalFuture; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
46 |
import jdk.incubator.http.internal.common.Utils; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
47 |
import jdk.incubator.http.internal.common.Log; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
48 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
49 |
/** |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
50 |
* One request/response exchange (handles 100/101 intermediate response also). |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
51 |
* depth field used to track number of times a new request is being sent |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
52 |
* for a given API request. If limit exceeded exception is thrown. |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
53 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
54 |
* Security check is performed here: |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
55 |
* - uses AccessControlContext captured at API level |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
56 |
* - checks for appropriate URLPermission for request |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
57 |
* - if permission allowed, grants equivalent SocketPermission to call |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
58 |
* - in case of direct HTTP proxy, checks additionally for access to proxy |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
59 |
* (CONNECT proxying uses its own Exchange, so check done there) |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
60 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
61 |
*/ |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
62 |
final class Exchange<T> { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
63 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
64 |
final HttpRequestImpl request; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
65 |
final HttpClientImpl client; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
66 |
volatile ExchangeImpl<T> exchImpl; |
44639
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
67 |
// used to record possible cancellation raised before the exchImpl |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
68 |
// has been established. |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
69 |
private volatile IOException failed; |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
70 |
final List<SocketPermission> permissions = new LinkedList<>(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
71 |
final AccessControlContext acc; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
72 |
final MultiExchange<?,T> multi; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
73 |
final Executor parentExecutor; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
74 |
final HttpRequest.BodyProcessor requestProcessor; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
75 |
boolean upgrading; // to HTTP/2 |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
76 |
final PushGroup<?,T> pushGroup; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
77 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
78 |
Exchange(HttpRequestImpl request, MultiExchange<?,T> multi) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
79 |
this.request = request; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
80 |
this.upgrading = false; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
81 |
this.client = multi.client(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
82 |
this.multi = multi; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
83 |
this.acc = multi.acc; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
84 |
this.parentExecutor = multi.executor; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
85 |
this.requestProcessor = request.requestProcessor; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
86 |
this.pushGroup = multi.pushGroup; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
87 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
88 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
89 |
/* If different AccessControlContext to be used */ |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
90 |
Exchange(HttpRequestImpl request, |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
91 |
MultiExchange<?,T> multi, |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
92 |
AccessControlContext acc) |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
93 |
{ |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
94 |
this.request = request; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
95 |
this.acc = acc; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
96 |
this.upgrading = false; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
97 |
this.client = multi.client(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
98 |
this.multi = multi; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
99 |
this.parentExecutor = multi.executor; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
100 |
this.requestProcessor = request.requestProcessor; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
101 |
this.pushGroup = multi.pushGroup; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
102 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
103 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
104 |
PushGroup<?,T> getPushGroup() { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
105 |
return pushGroup; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
106 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
107 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
108 |
Executor executor() { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
109 |
return parentExecutor; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
110 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
111 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
112 |
public HttpRequestImpl request() { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
113 |
return request; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
114 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
115 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
116 |
HttpClientImpl client() { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
117 |
return client; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
118 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
119 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
120 |
public Response response() throws IOException, InterruptedException { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
121 |
return responseImpl(null); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
122 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
123 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
124 |
public T readBody(HttpResponse.BodyHandler<T> responseHandler) throws IOException { |
43999
4cc44dd9f14f
8164625: Pooled HttpConnection should be removed during close
prappo
parents:
43984
diff
changeset
|
125 |
// The connection will not be returned to the pool in the case of WebSocket |
4cc44dd9f14f
8164625: Pooled HttpConnection should be removed during close
prappo
parents:
43984
diff
changeset
|
126 |
return exchImpl.readBody(responseHandler, !request.isWebSocket()); |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
127 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
128 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
129 |
public CompletableFuture<T> readBodyAsync(HttpResponse.BodyHandler<T> handler) { |
43999
4cc44dd9f14f
8164625: Pooled HttpConnection should be removed during close
prappo
parents:
43984
diff
changeset
|
130 |
// The connection will not be returned to the pool in the case of WebSocket |
4cc44dd9f14f
8164625: Pooled HttpConnection should be removed during close
prappo
parents:
43984
diff
changeset
|
131 |
return exchImpl.readBodyAsync(handler, !request.isWebSocket(), parentExecutor); |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
132 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
133 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
134 |
public void cancel() { |
44639
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
135 |
// cancel can be called concurrently before or at the same time |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
136 |
// that the exchange impl is being established. |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
137 |
// In that case we won't be able to propagate the cancellation |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
138 |
// right away |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
139 |
if (exchImpl != null) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
140 |
exchImpl.cancel(); |
44639
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
141 |
} else { |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
142 |
// no impl - can't cancel impl yet. |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
143 |
// call cancel(IOException) instead which takes care |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
144 |
// of race conditions between impl/cancel. |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
145 |
cancel(new IOException("Request cancelled")); |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
146 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
147 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
148 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
149 |
public void cancel(IOException cause) { |
44639
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
150 |
// If the impl is non null, propagate the exception right away. |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
151 |
// Otherwise record it so that it can be propagated once the |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
152 |
// exchange impl has been established. |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
153 |
ExchangeImpl<?> impl = exchImpl; |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
154 |
if (impl != null) { |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
155 |
// propagate the exception to the impl |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
156 |
impl.cancel(cause); |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
157 |
} else { |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
158 |
try { |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
159 |
// no impl yet. record the exception |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
160 |
failed = cause; |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
161 |
// now call checkCancelled to recheck the impl. |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
162 |
// if the failed state is set and the impl is not null, reset |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
163 |
// the failed state and propagate the exception to the impl. |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
164 |
checkCancelled(false); |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
165 |
} catch (IOException x) { |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
166 |
// should not happen - we passed 'false' above |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
167 |
throw new UncheckedIOException(x); |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
168 |
} |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
169 |
} |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
170 |
} |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
171 |
|
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
172 |
// This method will raise an exception if one was reported and if |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
173 |
// it is possible to do so. If the exception can be raised, then |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
174 |
// the failed state will be reset. Otherwise, the failed state |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
175 |
// will persist until the exception can be raised and the failed state |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
176 |
// can be cleared. |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
177 |
// Takes care of possible race conditions. |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
178 |
private void checkCancelled(boolean throwIfNoImpl) throws IOException { |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
179 |
ExchangeImpl<?> impl = null; |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
180 |
IOException cause = null; |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
181 |
if (failed != null) { |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
182 |
synchronized(this) { |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
183 |
cause = failed; |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
184 |
impl = exchImpl; |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
185 |
if (throwIfNoImpl || impl != null) { |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
186 |
// The exception will be raised by one of the two methods |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
187 |
// below: reset the failed state. |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
188 |
failed = null; |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
189 |
} |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
190 |
} |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
191 |
} |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
192 |
if (cause == null) return; |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
193 |
if (impl != null) { |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
194 |
// The exception is raised by propagating it to the impl. |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
195 |
impl.cancel(cause); |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
196 |
} else if (throwIfNoImpl) { |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
197 |
// The exception is raised by throwing it immediately |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
198 |
throw cause; |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
199 |
} else { |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
200 |
Log.logTrace("Exchange: request [{0}/timeout={1}ms] no impl is set." |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
201 |
+ "\n\tCan''t cancel yet with {2}", |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
202 |
request.uri(), |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
203 |
request.duration() == null ? -1 : |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
204 |
// calling duration.toMillis() can throw an exception. |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
205 |
// this is just debugging, we don't care if it overflows. |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
206 |
(request.duration().getSeconds() * 1000 |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
207 |
+ request.duration().getNano() / 1000000), |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
208 |
cause); |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
209 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
210 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
211 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
212 |
public void h2Upgrade() { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
213 |
upgrading = true; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
214 |
request.setH2Upgrade(client.client2()); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
215 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
216 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
217 |
static final SocketPermission[] SOCKET_ARRAY = new SocketPermission[0]; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
218 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
219 |
Response responseImpl(HttpConnection connection) |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
220 |
throws IOException, InterruptedException |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
221 |
{ |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
222 |
SecurityException e = securityCheck(acc); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
223 |
if (e != null) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
224 |
throw e; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
225 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
226 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
227 |
if (permissions.size() > 0) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
228 |
try { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
229 |
return AccessController.doPrivileged( |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
230 |
(PrivilegedExceptionAction<Response>)() -> |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
231 |
responseImpl0(connection), |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
232 |
null, |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
233 |
permissions.toArray(SOCKET_ARRAY)); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
234 |
} catch (Throwable ee) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
235 |
if (ee instanceof PrivilegedActionException) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
236 |
ee = ee.getCause(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
237 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
238 |
if (ee instanceof IOException) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
239 |
throw (IOException) ee; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
240 |
} else { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
241 |
throw new RuntimeException(ee); // TODO: fix |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
242 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
243 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
244 |
} else { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
245 |
return responseImpl0(connection); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
246 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
247 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
248 |
|
44639
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
249 |
// get/set the exchange impl, solving race condition issues with |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
250 |
// potential concurrent calls to cancel() or cancel(IOException) |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
251 |
private void establishExchange(HttpConnection connection) |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
252 |
throws IOException, InterruptedException |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
253 |
{ |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
254 |
// check if we have been cancelled first. |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
255 |
checkCancelled(true); |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
256 |
// not yet cancelled: create/get a new impl |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
257 |
exchImpl = ExchangeImpl.get(this, connection); |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
258 |
// recheck for cancelled, in case of race conditions |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
259 |
checkCancelled(true); |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
260 |
// now we're good to go. because exchImpl is no longer null |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
261 |
// cancel() will be able to propagate directly to the impl |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
262 |
// after this point. |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
263 |
} |
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
264 |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
265 |
private Response responseImpl0(HttpConnection connection) |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
266 |
throws IOException, InterruptedException |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
267 |
{ |
44639
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
268 |
establishExchange(connection); |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
269 |
if (request.expectContinue()) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
270 |
Log.logTrace("Sending Expect: 100-Continue"); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
271 |
request.addSystemHeader("Expect", "100-Continue"); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
272 |
exchImpl.sendHeadersOnly(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
273 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
274 |
Log.logTrace("Waiting for 407-Expectation-Failed or 100-Continue"); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
275 |
Response resp = exchImpl.getResponse(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
276 |
HttpResponseImpl.logResponse(resp); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
277 |
int rcode = resp.statusCode(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
278 |
if (rcode != 100) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
279 |
Log.logTrace("Expectation failed: Received {0}", |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
280 |
rcode); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
281 |
if (upgrading && rcode == 101) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
282 |
throw new IOException( |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
283 |
"Unable to handle 101 while waiting for 100-Continue"); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
284 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
285 |
return resp; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
286 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
287 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
288 |
Log.logTrace("Received 100-Continue: sending body"); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
289 |
exchImpl.sendBody(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
290 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
291 |
Log.logTrace("Body sent: waiting for response"); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
292 |
resp = exchImpl.getResponse(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
293 |
HttpResponseImpl.logResponse(resp); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
294 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
295 |
return checkForUpgrade(resp, exchImpl); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
296 |
} else { |
43984 | 297 |
exchImpl.sendHeadersOnly(); |
298 |
exchImpl.sendBody(); |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
299 |
Response resp = exchImpl.getResponse(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
300 |
HttpResponseImpl.logResponse(resp); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
301 |
return checkForUpgrade(resp, exchImpl); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
302 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
303 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
304 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
305 |
// Completed HttpResponse will be null if response succeeded |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
306 |
// will be a non null responseAsync if expect continue returns an error |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
307 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
308 |
public CompletableFuture<Response> responseAsync() { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
309 |
return responseAsyncImpl(null); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
310 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
311 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
312 |
CompletableFuture<Response> responseAsyncImpl(HttpConnection connection) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
313 |
SecurityException e = securityCheck(acc); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
314 |
if (e != null) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
315 |
return MinimalFuture.failedFuture(e); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
316 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
317 |
if (permissions.size() > 0) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
318 |
return AccessController.doPrivileged( |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
319 |
(PrivilegedAction<CompletableFuture<Response>>)() -> |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
320 |
responseAsyncImpl0(connection), |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
321 |
null, |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
322 |
permissions.toArray(SOCKET_ARRAY)); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
323 |
} else { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
324 |
return responseAsyncImpl0(connection); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
325 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
326 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
327 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
328 |
CompletableFuture<Response> responseAsyncImpl0(HttpConnection connection) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
329 |
try { |
44639
5c2838d882a5
8178147: Race conditions in timeout handling code in http/2 incubator client
dfuchs
parents:
43999
diff
changeset
|
330 |
establishExchange(connection); |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
331 |
} catch (IOException | InterruptedException e) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
332 |
return MinimalFuture.failedFuture(e); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
333 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
334 |
if (request.expectContinue()) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
335 |
request.addSystemHeader("Expect", "100-Continue"); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
336 |
Log.logTrace("Sending Expect: 100-Continue"); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
337 |
return exchImpl |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
338 |
.sendHeadersAsync() |
43984 | 339 |
.thenCompose(v -> exchImpl.getResponseAsync(parentExecutor)) |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
340 |
.thenCompose((Response r1) -> { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
341 |
HttpResponseImpl.logResponse(r1); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
342 |
int rcode = r1.statusCode(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
343 |
if (rcode == 100) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
344 |
Log.logTrace("Received 100-Continue: sending body"); |
43984 | 345 |
CompletableFuture<Response> cf = |
346 |
exchImpl.sendBodyAsync() |
|
347 |
.thenCompose(exIm -> exIm.getResponseAsync(parentExecutor)); |
|
348 |
cf = wrapForUpgrade(cf); |
|
349 |
cf = wrapForLog(cf); |
|
350 |
return cf; |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
351 |
} else { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
352 |
Log.logTrace("Expectation failed: Received {0}", |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
353 |
rcode); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
354 |
if (upgrading && rcode == 101) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
355 |
IOException failed = new IOException( |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
356 |
"Unable to handle 101 while waiting for 100"); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
357 |
return MinimalFuture.failedFuture(failed); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
358 |
} |
43984 | 359 |
return exchImpl.readBodyAsync(this::ignoreBody, false, parentExecutor) |
360 |
.thenApply(v -> r1); |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
361 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
362 |
}); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
363 |
} else { |
43984 | 364 |
CompletableFuture<Response> cf = exchImpl |
365 |
.sendHeadersAsync() |
|
366 |
.thenCompose(ExchangeImpl::sendBodyAsync) |
|
367 |
.thenCompose(exIm -> exIm.getResponseAsync(parentExecutor)); |
|
368 |
cf = wrapForUpgrade(cf); |
|
369 |
cf = wrapForLog(cf); |
|
370 |
return cf; |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
371 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
372 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
373 |
|
43984 | 374 |
private CompletableFuture<Response> wrapForUpgrade(CompletableFuture<Response> cf) { |
375 |
if (upgrading) { |
|
376 |
return cf.thenCompose(r -> checkForUpgradeAsync(r, exchImpl)); |
|
377 |
} |
|
378 |
return cf; |
|
379 |
} |
|
380 |
||
381 |
private CompletableFuture<Response> wrapForLog(CompletableFuture<Response> cf) { |
|
382 |
if (Log.requests()) { |
|
383 |
return cf.thenApply(response -> { |
|
384 |
HttpResponseImpl.logResponse(response); |
|
385 |
return response; |
|
386 |
}); |
|
387 |
} |
|
388 |
return cf; |
|
389 |
} |
|
390 |
||
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
391 |
HttpResponse.BodyProcessor<T> ignoreBody(int status, HttpHeaders hdrs) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
392 |
return HttpResponse.BodyProcessor.discard((T)null); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
393 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
394 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
395 |
// if this response was received in reply to an upgrade |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
396 |
// then create the Http2Connection from the HttpConnection |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
397 |
// initialize it and wait for the real response on a newly created Stream |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
398 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
399 |
private CompletableFuture<Response> |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
400 |
checkForUpgradeAsync(Response resp, |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
401 |
ExchangeImpl<T> ex) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
402 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
403 |
int rcode = resp.statusCode(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
404 |
if (upgrading && (rcode == 101)) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
405 |
Http1Exchange<T> e = (Http1Exchange<T>)ex; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
406 |
// check for 101 switching protocols |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
407 |
// 101 responses are not supposed to contain a body. |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
408 |
// => should we fail if there is one? |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
409 |
return e.readBodyAsync(this::ignoreBody, false, parentExecutor) |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
410 |
.thenCompose((T v) -> // v is null |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
411 |
Http2Connection.createAsync(e.connection(), |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
412 |
client.client2(), |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
413 |
this, e.getBuffer()) |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
414 |
.thenCompose((Http2Connection c) -> { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
415 |
c.putConnection(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
416 |
Stream<T> s = c.getStream(1); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
417 |
exchImpl = s; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
418 |
return s.getResponseAsync(null); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
419 |
}) |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
420 |
); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
421 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
422 |
return MinimalFuture.completedFuture(resp); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
423 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
424 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
425 |
private Response checkForUpgrade(Response resp, |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
426 |
ExchangeImpl<T> ex) |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
427 |
throws IOException, InterruptedException |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
428 |
{ |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
429 |
int rcode = resp.statusCode(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
430 |
if (upgrading && (rcode == 101)) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
431 |
Http1Exchange<T> e = (Http1Exchange<T>) ex; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
432 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
433 |
// 101 responses are not supposed to contain a body. |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
434 |
// => should we fail if there is one? |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
435 |
// => readBody called here by analogy with |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
436 |
// checkForUpgradeAsync above |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
437 |
e.readBody(this::ignoreBody, false); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
438 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
439 |
// must get connection from Http1Exchange |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
440 |
Http2Connection h2con = new Http2Connection(e.connection(), |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
441 |
client.client2(), |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
442 |
this, e.getBuffer()); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
443 |
h2con.putConnection(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
444 |
Stream<T> s = h2con.getStream(1); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
445 |
exchImpl = s; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
446 |
Response xx = s.getResponse(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
447 |
HttpResponseImpl.logResponse(xx); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
448 |
return xx; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
449 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
450 |
return resp; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
451 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
452 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
453 |
private URI getURIForSecurityCheck() { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
454 |
URI u; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
455 |
String method = request.method(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
456 |
InetSocketAddress authority = request.authority(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
457 |
URI uri = request.uri(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
458 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
459 |
// CONNECT should be restricted at API level |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
460 |
if (method.equalsIgnoreCase("CONNECT")) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
461 |
try { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
462 |
u = new URI("socket", |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
463 |
null, |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
464 |
authority.getHostString(), |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
465 |
authority.getPort(), |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
466 |
null, |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
467 |
null, |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
468 |
null); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
469 |
} catch (URISyntaxException e) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
470 |
throw new InternalError(e); // shouldn't happen |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
471 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
472 |
} else { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
473 |
u = uri; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
474 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
475 |
return u; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
476 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
477 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
478 |
/** |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
479 |
* Do the security check and return any exception. |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
480 |
* Return null if no check needed or passes. |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
481 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
482 |
* Also adds any generated permissions to the "permissions" list. |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
483 |
*/ |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
484 |
private SecurityException securityCheck(AccessControlContext acc) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
485 |
SecurityManager sm = System.getSecurityManager(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
486 |
if (sm == null) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
487 |
return null; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
488 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
489 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
490 |
String method = request.method(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
491 |
HttpHeaders userHeaders = request.getUserHeaders(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
492 |
URI u = getURIForSecurityCheck(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
493 |
URLPermission p = Utils.getPermission(u, method, userHeaders.map()); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
494 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
495 |
try { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
496 |
assert acc != null; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
497 |
sm.checkPermission(p, acc); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
498 |
permissions.add(getSocketPermissionFor(u)); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
499 |
} catch (SecurityException e) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
500 |
return e; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
501 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
502 |
ProxySelector ps = client.proxy().orElse(null); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
503 |
if (ps != null) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
504 |
InetSocketAddress proxy = (InetSocketAddress) |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
505 |
ps.select(u).get(0).address(); // TODO: check this |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
506 |
// may need additional check |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
507 |
if (!method.equals("CONNECT")) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
508 |
// a direct http proxy. Need to check access to proxy |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
509 |
try { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
510 |
u = new URI("socket", null, proxy.getHostString(), |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
511 |
proxy.getPort(), null, null, null); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
512 |
} catch (URISyntaxException e) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
513 |
throw new InternalError(e); // shouldn't happen |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
514 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
515 |
p = new URLPermission(u.toString(), "CONNECT"); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
516 |
try { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
517 |
sm.checkPermission(p, acc); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
518 |
} catch (SecurityException e) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
519 |
permissions.clear(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
520 |
return e; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
521 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
522 |
String sockperm = proxy.getHostString() + |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
523 |
":" + Integer.toString(proxy.getPort()); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
524 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
525 |
permissions.add(new SocketPermission(sockperm, "connect,resolve")); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
526 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
527 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
528 |
return null; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
529 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
530 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
531 |
HttpClient.Redirect followRedirects() { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
532 |
return client.followRedirects(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
533 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
534 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
535 |
HttpClient.Version version() { |
44854
5a486e0acd29
8175814: Update default HttpClient protocol version and optional request version
michaelm
parents:
44639
diff
changeset
|
536 |
return multi.version(); |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
537 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
538 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
539 |
private static SocketPermission getSocketPermissionFor(URI url) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
540 |
if (System.getSecurityManager() == null) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
541 |
return null; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
542 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
543 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
544 |
StringBuilder sb = new StringBuilder(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
545 |
String host = url.getHost(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
546 |
sb.append(host); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
547 |
int port = url.getPort(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
548 |
if (port == -1) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
549 |
String scheme = url.getScheme(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
550 |
if ("http".equals(scheme)) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
551 |
sb.append(":80"); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
552 |
} else { // scheme must be https |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
553 |
sb.append(":443"); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
554 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
555 |
} else { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
556 |
sb.append(':') |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
557 |
.append(Integer.toString(port)); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
558 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
559 |
String target = sb.toString(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
560 |
return new SocketPermission(target, "connect"); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
561 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
562 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
563 |
AccessControlContext getAccessControlContext() { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
564 |
return acc; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
565 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
566 |
} |