author | mbaesken |
Thu, 28 Nov 2019 13:02:39 +0100 | |
changeset 59323 | ae2eb76c486d |
parent 51364 | 31d9e82b2e64 |
child 56868 | 67c7659ecda5 |
permissions | -rw-r--r-- |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
1 |
/* |
49765 | 2 |
* Copyright (c) 2015, 2018, 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 |
|
49765 | 26 |
package jdk.internal.net.http; |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
27 |
|
50681 | 28 |
import java.io.IOException; |
29 |
import java.io.UncheckedIOException; |
|
30 |
import java.net.ConnectException; |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
31 |
import java.net.InetSocketAddress; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
32 |
import java.net.URI; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
33 |
import java.util.Base64; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
34 |
import java.util.Collections; |
48083 | 35 |
import java.util.HashSet; |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
36 |
import java.util.Map; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
37 |
import java.util.Set; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
38 |
import java.util.concurrent.ConcurrentHashMap; |
48083 | 39 |
import java.util.concurrent.CompletableFuture; |
49765 | 40 |
import jdk.internal.net.http.common.Log; |
41 |
import jdk.internal.net.http.common.Logger; |
|
42 |
import jdk.internal.net.http.common.MinimalFuture; |
|
43 |
import jdk.internal.net.http.common.Utils; |
|
44 |
import jdk.internal.net.http.frame.SettingsFrame; |
|
45 |
import static jdk.internal.net.http.frame.SettingsFrame.INITIAL_WINDOW_SIZE; |
|
46 |
import static jdk.internal.net.http.frame.SettingsFrame.ENABLE_PUSH; |
|
47 |
import static jdk.internal.net.http.frame.SettingsFrame.HEADER_TABLE_SIZE; |
|
48 |
import static jdk.internal.net.http.frame.SettingsFrame.MAX_CONCURRENT_STREAMS; |
|
49 |
import static jdk.internal.net.http.frame.SettingsFrame.MAX_FRAME_SIZE; |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
50 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
51 |
/** |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
52 |
* Http2 specific aspects of HttpClientImpl |
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 |
class Http2ClientImpl { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
55 |
|
49765 | 56 |
final static Logger debug = |
57 |
Utils.getDebugLogger("Http2ClientImpl"::toString, Utils.DEBUG); |
|
48083 | 58 |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
59 |
private final HttpClientImpl client; |
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 |
Http2ClientImpl(HttpClientImpl client) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
62 |
this.client = client; |
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 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
65 |
/* Map key is "scheme:host:port" */ |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
66 |
private final Map<String,Http2Connection> connections = new ConcurrentHashMap<>(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
67 |
|
48376
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
68 |
private final Set<String> failures = Collections.synchronizedSet(new HashSet<>()); |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
69 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
70 |
/** |
48376
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
71 |
* When HTTP/2 requested only. The following describes the aggregate behavior including the |
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
72 |
* calling code. In all cases, the HTTP2 connection cache |
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
73 |
* is checked first for a suitable connection and that is returned if available. |
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
74 |
* If not, a new connection is opened, except in https case when a previous negotiate failed. |
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
75 |
* In that case, we want to continue using http/1.1. When a connection is to be opened and |
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
76 |
* if multiple requests are sent in parallel then each will open a new connection. |
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
77 |
* |
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
78 |
* If negotiation/upgrade succeeds then |
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
79 |
* one connection will be put in the cache and the others will be closed |
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
80 |
* after the initial request completes (not strictly necessary for h2, only for h2c) |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
81 |
* |
48376
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
82 |
* If negotiate/upgrade fails, then any opened connections remain open (as http/1.1) |
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
83 |
* and will be used and cached in the http/1 cache. Note, this method handles the |
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
84 |
* https failure case only (by completing the CF with an ALPN exception, handled externally) |
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
85 |
* The h2c upgrade is handled externally also. |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
86 |
* |
48376
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
87 |
* Specific CF behavior of this method. |
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
88 |
* 1. completes with ALPN exception: h2 negotiate failed for first time. failure recorded. |
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
89 |
* 2. completes with other exception: failure not recorded. Caller must handle |
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
90 |
* 3. completes normally with null: no connection in cache for h2c or h2 failed previously |
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
91 |
* 4. completes normally with connection: h2 or h2c connection in cache. Use it. |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
92 |
*/ |
51364
31d9e82b2e64
8208391: Differentiate response and connect timeouts in HTTP Client API
chegar
parents:
50681
diff
changeset
|
93 |
CompletableFuture<Http2Connection> getConnectionFor(HttpRequestImpl req, |
31d9e82b2e64
8208391: Differentiate response and connect timeouts in HTTP Client API
chegar
parents:
50681
diff
changeset
|
94 |
Exchange<?> exchange) { |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
95 |
URI uri = req.uri(); |
48083 | 96 |
InetSocketAddress proxy = req.proxy(); |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
97 |
String key = Http2Connection.keyFor(uri, proxy); |
48083 | 98 |
|
48376
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
99 |
synchronized (this) { |
48083 | 100 |
Http2Connection connection = connections.get(key); |
49765 | 101 |
if (connection != null) { |
50681 | 102 |
try { |
103 |
if (connection.closed || !connection.reserveStream(true)) { |
|
104 |
if (debug.on()) |
|
105 |
debug.log("removing found closed or closing connection: %s", connection); |
|
106 |
deleteConnection(connection); |
|
107 |
} else { |
|
108 |
// fast path if connection already exists |
|
109 |
if (debug.on()) |
|
110 |
debug.log("found connection in the pool: %s", connection); |
|
111 |
return MinimalFuture.completedFuture(connection); |
|
112 |
} |
|
113 |
} catch (IOException e) { |
|
114 |
// thrown by connection.reserveStream() |
|
115 |
return MinimalFuture.failedFuture(e); |
|
49765 | 116 |
} |
48083 | 117 |
} |
118 |
||
48376
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
119 |
if (!req.secure() || failures.contains(key)) { |
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
120 |
// secure: negotiate failed before. Use http/1.1 |
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
121 |
// !secure: no connection available in cache. Attempt upgrade |
49765 | 122 |
if (debug.on()) debug.log("not found in connection pool"); |
48083 | 123 |
return MinimalFuture.completedFuture(null); |
124 |
} |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
125 |
} |
48083 | 126 |
return Http2Connection |
51364
31d9e82b2e64
8208391: Differentiate response and connect timeouts in HTTP Client API
chegar
parents:
50681
diff
changeset
|
127 |
.createAsync(req, this, exchange) |
48083 | 128 |
.whenComplete((conn, t) -> { |
48376
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
129 |
synchronized (Http2ClientImpl.this) { |
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
130 |
if (conn != null) { |
50681 | 131 |
try { |
132 |
conn.reserveStream(true); |
|
133 |
} catch (IOException e) { |
|
134 |
throw new UncheckedIOException(e); // shouldn't happen |
|
135 |
} |
|
48376
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
136 |
offerConnection(conn); |
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
137 |
} else { |
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
138 |
Throwable cause = Utils.getCompletionCause(t); |
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
139 |
if (cause instanceof Http2Connection.ALPNException) |
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
140 |
failures.add(key); |
48083 | 141 |
} |
142 |
} |
|
143 |
}); |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
144 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
145 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
146 |
/* |
48376
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
147 |
* Cache the given connection, if no connection to the same |
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
148 |
* destination exists. If one exists, then we let the initial stream |
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
149 |
* complete but allow it to close itself upon completion. |
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
150 |
* This situation should not arise with https because the request |
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
151 |
* has not been sent as part of the initial alpn negotiation |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
152 |
*/ |
48376
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
153 |
boolean offerConnection(Http2Connection c) { |
49765 | 154 |
if (debug.on()) debug.log("offering to the connection pool: %s", c); |
49944 | 155 |
if (c.closed || c.finalStream()) { |
49765 | 156 |
if (debug.on()) |
49944 | 157 |
debug.log("skipping offered closed or closing connection: %s", c); |
48376
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
158 |
return false; |
41ae5c69b09c
8192966: HttpClient should reuse TCP connection for h2c connections
michaelm
parents:
48263
diff
changeset
|
159 |
} |
49765 | 160 |
|
161 |
String key = c.key(); |
|
162 |
synchronized(this) { |
|
163 |
Http2Connection c1 = connections.putIfAbsent(key, c); |
|
164 |
if (c1 != null) { |
|
49944 | 165 |
c.setFinalStream(); |
49765 | 166 |
if (debug.on()) |
167 |
debug.log("existing entry in connection pool for %s", key); |
|
168 |
return false; |
|
169 |
} |
|
170 |
if (debug.on()) |
|
171 |
debug.log("put in the connection pool: %s", c); |
|
172 |
return true; |
|
173 |
} |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
174 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
175 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
176 |
void deleteConnection(Http2Connection c) { |
49765 | 177 |
if (debug.on()) |
178 |
debug.log("removing from the connection pool: %s", c); |
|
179 |
synchronized (this) { |
|
49944 | 180 |
Http2Connection c1 = connections.get(c.key()); |
181 |
if (c1 != null && c1.equals(c)) { |
|
182 |
connections.remove(c.key()); |
|
183 |
if (debug.on()) |
|
184 |
debug.log("removed from the connection pool: %s", c); |
|
185 |
} |
|
49765 | 186 |
} |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
187 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
188 |
|
48083 | 189 |
void stop() { |
49765 | 190 |
if (debug.on()) debug.log("stopping"); |
48083 | 191 |
connections.values().forEach(this::close); |
192 |
connections.clear(); |
|
193 |
} |
|
194 |
||
195 |
private void close(Http2Connection h2c) { |
|
196 |
try { h2c.close(); } catch (Throwable t) {} |
|
197 |
} |
|
198 |
||
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
199 |
HttpClientImpl client() { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
200 |
return client; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
201 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
202 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
203 |
/** Returns the client settings as a base64 (url) encoded string */ |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
204 |
String getSettingsString() { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
205 |
SettingsFrame sf = getClientSettings(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
206 |
byte[] settings = sf.toByteArray(); // without the header |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
207 |
Base64.Encoder encoder = Base64.getUrlEncoder() |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
208 |
.withoutPadding(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
209 |
return encoder.encodeToString(settings); |
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 |
private static final int K = 1024; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
213 |
|
48263
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
214 |
private static int getParameter(String property, int min, int max, int defaultValue) { |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
215 |
int value = Utils.getIntegerNetProperty(property, defaultValue); |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
216 |
// use default value if misconfigured |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
217 |
if (value < min || value > max) { |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
218 |
Log.logError("Property value for {0}={1} not in [{2}..{3}]: " + |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
219 |
"using default={4}", property, value, min, max, defaultValue); |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
220 |
value = defaultValue; |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
221 |
} |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
222 |
return value; |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
223 |
} |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
224 |
|
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
225 |
// used for the connection window, to have a connection window size |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
226 |
// bigger than the initial stream window size. |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
227 |
int getConnectionWindowSize(SettingsFrame clientSettings) { |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
228 |
// Maximum size is 2^31-1. Don't allow window size to be less |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
229 |
// than the stream window size. HTTP/2 specify a default of 64 * K -1, |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
230 |
// but we use 2^26 by default for better performance. |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
231 |
int streamWindow = clientSettings.getParameter(INITIAL_WINDOW_SIZE); |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
232 |
|
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
233 |
// The default is the max between the stream window size |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
234 |
// and the connection window size. |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
235 |
int defaultValue = Math.min(Integer.MAX_VALUE, |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
236 |
Math.max(streamWindow, K*K*32)); |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
237 |
|
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
238 |
return getParameter( |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
239 |
"jdk.httpclient.connectionWindowSize", |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
240 |
streamWindow, Integer.MAX_VALUE, defaultValue); |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
241 |
} |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
242 |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
243 |
SettingsFrame getClientSettings() { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
244 |
SettingsFrame frame = new SettingsFrame(); |
48263
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
245 |
// default defined for HTTP/2 is 4 K, we use 16 K. |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
246 |
frame.setParameter(HEADER_TABLE_SIZE, getParameter( |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
247 |
"jdk.httpclient.hpack.maxheadertablesize", |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
248 |
0, Integer.MAX_VALUE, 16 * K)); |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
249 |
// O: does not accept push streams. 1: accepts push streams. |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
250 |
frame.setParameter(ENABLE_PUSH, getParameter( |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
251 |
"jdk.httpclient.enablepush", |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
252 |
0, 1, 1)); |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
253 |
// HTTP/2 recommends to set the number of concurrent streams |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
254 |
// no lower than 100. We use 100. 0 means no stream would be |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
255 |
// accepted. That would render the client to be non functional, |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
256 |
// so we won't let 0 be configured for our Http2ClientImpl. |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
257 |
frame.setParameter(MAX_CONCURRENT_STREAMS, getParameter( |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
258 |
"jdk.httpclient.maxstreams", |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
259 |
1, Integer.MAX_VALUE, 100)); |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
260 |
// Maximum size is 2^31-1. Don't allow window size to be less |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
261 |
// than the minimum frame size as this is likely to be a |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
262 |
// configuration error. HTTP/2 specify a default of 64 * K -1, |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
263 |
// but we use 16 M for better performance. |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
264 |
frame.setParameter(INITIAL_WINDOW_SIZE, getParameter( |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
265 |
"jdk.httpclient.windowsize", |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
266 |
16 * K, Integer.MAX_VALUE, 16*K*K)); |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
267 |
// HTTP/2 specify a minimum size of 16 K, a maximum size of 2^24-1, |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
268 |
// and a default of 16 K. We use 16 K as default. |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
269 |
frame.setParameter(MAX_FRAME_SIZE, getParameter( |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
270 |
"jdk.httpclient.maxframesize", |
a559b7cd1dea
8193370: Provide more user friendly defaults for HTTP/2 client settings
dfuchs
parents:
48083
diff
changeset
|
271 |
16 * K, 16 * K * K -1, 16 * K)); |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
272 |
return frame; |
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 |
} |