18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package jdk.internal.net.http;
27
28 import javax.net.ssl.SSLContext;
29 import javax.net.ssl.SSLParameters;
30 import java.io.IOException;
31 import java.io.UncheckedIOException;
32 import java.lang.ref.Reference;
33 import java.lang.ref.WeakReference;
34 import java.net.Authenticator;
35 import java.net.ConnectException;
36 import java.net.CookieHandler;
37 import java.net.ProxySelector;
38 import java.net.http.HttpTimeoutException;
39 import java.nio.ByteBuffer;
40 import java.nio.channels.CancelledKeyException;
41 import java.nio.channels.ClosedChannelException;
42 import java.nio.channels.SelectableChannel;
43 import java.nio.channels.SelectionKey;
44 import java.nio.channels.Selector;
45 import java.nio.channels.SocketChannel;
46 import java.security.AccessControlContext;
47 import java.security.AccessController;
48 import java.security.NoSuchAlgorithmException;
49 import java.security.PrivilegedAction;
50 import java.time.Instant;
51 import java.time.temporal.ChronoUnit;
52 import java.util.ArrayList;
53 import java.util.HashSet;
54 import java.util.Iterator;
55 import java.util.LinkedList;
56 import java.util.List;
57 import java.util.Objects;
58 import java.util.Optional;
59 import java.util.Set;
60 import java.util.TreeSet;
61 import java.util.concurrent.CompletableFuture;
62 import java.util.concurrent.CompletionException;
63 import java.util.concurrent.ExecutionException;
64 import java.util.concurrent.Executor;
65 import java.util.concurrent.Executors;
66 import java.util.concurrent.ThreadFactory;
67 import java.util.concurrent.atomic.AtomicInteger;
68 import java.util.concurrent.atomic.AtomicLong;
69 import java.util.function.BooleanSupplier;
137 DelegatingExecutor(BooleanSupplier isInSelectorThread, Executor delegate) {
138 this.isInSelectorThread = isInSelectorThread;
139 this.delegate = delegate;
140 }
141
142 Executor delegate() {
143 return delegate;
144 }
145
146 @Override
147 public void execute(Runnable command) {
148 if (isInSelectorThread.getAsBoolean()) {
149 delegate.execute(command);
150 } else {
151 command.run();
152 }
153 }
154 }
155
156 private final CookieHandler cookieHandler;
157 private final Redirect followRedirects;
158 private final Optional<ProxySelector> userProxySelector;
159 private final ProxySelector proxySelector;
160 private final Authenticator authenticator;
161 private final Version version;
162 private final ConnectionPool connections;
163 private final DelegatingExecutor delegatingExecutor;
164 private final boolean isDefaultExecutor;
165 // Security parameters
166 private final SSLContext sslContext;
167 private final SSLParameters sslParams;
168 private final SelectorManager selmgr;
169 private final FilterFactory filters;
170 private final Http2ClientImpl client2;
171 private final long id;
172 private final String dbgTag;
173
174 // The SSL DirectBuffer Supplier provides the ability to recycle
175 // buffers used between the socket reader and the SSLEngine, or
176 // more precisely between the SocketTube publisher and the
261 if (builder.sslContext == null) {
262 try {
263 sslContext = SSLContext.getDefault();
264 } catch (NoSuchAlgorithmException ex) {
265 throw new InternalError(ex);
266 }
267 } else {
268 sslContext = builder.sslContext;
269 }
270 Executor ex = builder.executor;
271 if (ex == null) {
272 ex = Executors.newCachedThreadPool(new DefaultThreadFactory(id));
273 isDefaultExecutor = true;
274 } else {
275 isDefaultExecutor = false;
276 }
277 delegatingExecutor = new DelegatingExecutor(this::isSelectorThread, ex);
278 facadeRef = new WeakReference<>(facadeFactory.createFacade(this));
279 client2 = new Http2ClientImpl(this);
280 cookieHandler = builder.cookieHandler;
281 followRedirects = builder.followRedirects == null ?
282 Redirect.NEVER : builder.followRedirects;
283 this.userProxySelector = Optional.ofNullable(builder.proxy);
284 this.proxySelector = userProxySelector
285 .orElseGet(HttpClientImpl::getDefaultProxySelector);
286 if (debug.on())
287 debug.log("proxySelector is %s (user-supplied=%s)",
288 this.proxySelector, userProxySelector.isPresent());
289 authenticator = builder.authenticator;
290 if (builder.version == null) {
291 version = HttpClient.Version.HTTP_2;
292 } else {
293 version = builder.version;
294 }
295 if (builder.sslParams == null) {
296 sslParams = getDefaultParams(sslContext);
297 } else {
298 sslParams = builder.sslParams;
299 }
300 connections = new ConnectionPool(id);
530 public <T> HttpResponse<T>
531 send(HttpRequest req, BodyHandler<T> responseHandler)
532 throws IOException, InterruptedException
533 {
534 CompletableFuture<HttpResponse<T>> cf = null;
535 try {
536 cf = sendAsync(req, responseHandler, null, null);
537 return cf.get();
538 } catch (InterruptedException ie) {
539 if (cf != null )
540 cf.cancel(true);
541 throw ie;
542 } catch (ExecutionException e) {
543 final Throwable throwable = e.getCause();
544 final String msg = throwable.getMessage();
545
546 if (throwable instanceof IllegalArgumentException) {
547 throw new IllegalArgumentException(msg, throwable);
548 } else if (throwable instanceof SecurityException) {
549 throw new SecurityException(msg, throwable);
550 } else if (throwable instanceof HttpTimeoutException) {
551 throw new HttpTimeoutException(msg);
552 } else if (throwable instanceof ConnectException) {
553 ConnectException ce = new ConnectException(msg);
554 ce.initCause(throwable);
555 throw ce;
556 } else if (throwable instanceof IOException) {
557 throw new IOException(msg, throwable);
558 } else {
559 throw new IOException(msg, throwable);
560 }
561 }
562 }
563
564 private static final Executor ASYNC_POOL = new CompletableFuture<Void>().defaultExecutor();
565
566 @Override
567 public <T> CompletableFuture<HttpResponse<T>>
568 sendAsync(HttpRequest userRequest, BodyHandler<T> responseHandler)
569 {
1107 ? Optional.empty()
1108 : Optional.of(delegatingExecutor.delegate());
1109 }
1110
1111 ConnectionPool connectionPool() {
1112 return connections;
1113 }
1114
1115 @Override
1116 public Redirect followRedirects() {
1117 return followRedirects;
1118 }
1119
1120
1121 @Override
1122 public Optional<CookieHandler> cookieHandler() {
1123 return Optional.ofNullable(cookieHandler);
1124 }
1125
1126 @Override
1127 public Optional<ProxySelector> proxy() {
1128 return this.userProxySelector;
1129 }
1130
1131 // Return the effective proxy that this client uses.
1132 ProxySelector proxySelector() {
1133 return proxySelector;
1134 }
1135
1136 @Override
1137 public WebSocket.Builder newWebSocketBuilder() {
1138 // Make sure to pass the HttpClientFacade to the WebSocket builder.
1139 // This will ensure that the facade is not released before the
1140 // WebSocket has been created, at which point the pendingOperationCount
1141 // will have been incremented by the RawChannelTube.
1142 // See RawChannelTube.
1143 return new BuilderImpl(this.facade(), proxySelector);
1144 }
1145
1146 @Override
|
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package jdk.internal.net.http;
27
28 import javax.net.ssl.SSLContext;
29 import javax.net.ssl.SSLParameters;
30 import java.io.IOException;
31 import java.io.UncheckedIOException;
32 import java.lang.ref.Reference;
33 import java.lang.ref.WeakReference;
34 import java.net.Authenticator;
35 import java.net.ConnectException;
36 import java.net.CookieHandler;
37 import java.net.ProxySelector;
38 import java.net.http.HttpConnectTimeoutException;
39 import java.net.http.HttpTimeoutException;
40 import java.nio.ByteBuffer;
41 import java.nio.channels.CancelledKeyException;
42 import java.nio.channels.ClosedChannelException;
43 import java.nio.channels.SelectableChannel;
44 import java.nio.channels.SelectionKey;
45 import java.nio.channels.Selector;
46 import java.nio.channels.SocketChannel;
47 import java.security.AccessControlContext;
48 import java.security.AccessController;
49 import java.security.NoSuchAlgorithmException;
50 import java.security.PrivilegedAction;
51 import java.time.Duration;
52 import java.time.Instant;
53 import java.time.temporal.ChronoUnit;
54 import java.util.ArrayList;
55 import java.util.HashSet;
56 import java.util.Iterator;
57 import java.util.LinkedList;
58 import java.util.List;
59 import java.util.Objects;
60 import java.util.Optional;
61 import java.util.Set;
62 import java.util.TreeSet;
63 import java.util.concurrent.CompletableFuture;
64 import java.util.concurrent.CompletionException;
65 import java.util.concurrent.ExecutionException;
66 import java.util.concurrent.Executor;
67 import java.util.concurrent.Executors;
68 import java.util.concurrent.ThreadFactory;
69 import java.util.concurrent.atomic.AtomicInteger;
70 import java.util.concurrent.atomic.AtomicLong;
71 import java.util.function.BooleanSupplier;
139 DelegatingExecutor(BooleanSupplier isInSelectorThread, Executor delegate) {
140 this.isInSelectorThread = isInSelectorThread;
141 this.delegate = delegate;
142 }
143
144 Executor delegate() {
145 return delegate;
146 }
147
148 @Override
149 public void execute(Runnable command) {
150 if (isInSelectorThread.getAsBoolean()) {
151 delegate.execute(command);
152 } else {
153 command.run();
154 }
155 }
156 }
157
158 private final CookieHandler cookieHandler;
159 private final Duration connectTimeout;
160 private final Redirect followRedirects;
161 private final Optional<ProxySelector> userProxySelector;
162 private final ProxySelector proxySelector;
163 private final Authenticator authenticator;
164 private final Version version;
165 private final ConnectionPool connections;
166 private final DelegatingExecutor delegatingExecutor;
167 private final boolean isDefaultExecutor;
168 // Security parameters
169 private final SSLContext sslContext;
170 private final SSLParameters sslParams;
171 private final SelectorManager selmgr;
172 private final FilterFactory filters;
173 private final Http2ClientImpl client2;
174 private final long id;
175 private final String dbgTag;
176
177 // The SSL DirectBuffer Supplier provides the ability to recycle
178 // buffers used between the socket reader and the SSLEngine, or
179 // more precisely between the SocketTube publisher and the
264 if (builder.sslContext == null) {
265 try {
266 sslContext = SSLContext.getDefault();
267 } catch (NoSuchAlgorithmException ex) {
268 throw new InternalError(ex);
269 }
270 } else {
271 sslContext = builder.sslContext;
272 }
273 Executor ex = builder.executor;
274 if (ex == null) {
275 ex = Executors.newCachedThreadPool(new DefaultThreadFactory(id));
276 isDefaultExecutor = true;
277 } else {
278 isDefaultExecutor = false;
279 }
280 delegatingExecutor = new DelegatingExecutor(this::isSelectorThread, ex);
281 facadeRef = new WeakReference<>(facadeFactory.createFacade(this));
282 client2 = new Http2ClientImpl(this);
283 cookieHandler = builder.cookieHandler;
284 connectTimeout = builder.connectTimeout;
285 followRedirects = builder.followRedirects == null ?
286 Redirect.NEVER : builder.followRedirects;
287 this.userProxySelector = Optional.ofNullable(builder.proxy);
288 this.proxySelector = userProxySelector
289 .orElseGet(HttpClientImpl::getDefaultProxySelector);
290 if (debug.on())
291 debug.log("proxySelector is %s (user-supplied=%s)",
292 this.proxySelector, userProxySelector.isPresent());
293 authenticator = builder.authenticator;
294 if (builder.version == null) {
295 version = HttpClient.Version.HTTP_2;
296 } else {
297 version = builder.version;
298 }
299 if (builder.sslParams == null) {
300 sslParams = getDefaultParams(sslContext);
301 } else {
302 sslParams = builder.sslParams;
303 }
304 connections = new ConnectionPool(id);
534 public <T> HttpResponse<T>
535 send(HttpRequest req, BodyHandler<T> responseHandler)
536 throws IOException, InterruptedException
537 {
538 CompletableFuture<HttpResponse<T>> cf = null;
539 try {
540 cf = sendAsync(req, responseHandler, null, null);
541 return cf.get();
542 } catch (InterruptedException ie) {
543 if (cf != null )
544 cf.cancel(true);
545 throw ie;
546 } catch (ExecutionException e) {
547 final Throwable throwable = e.getCause();
548 final String msg = throwable.getMessage();
549
550 if (throwable instanceof IllegalArgumentException) {
551 throw new IllegalArgumentException(msg, throwable);
552 } else if (throwable instanceof SecurityException) {
553 throw new SecurityException(msg, throwable);
554 } else if (throwable instanceof HttpConnectTimeoutException) {
555 HttpConnectTimeoutException hcte = new HttpConnectTimeoutException(msg);
556 hcte.initCause(throwable);
557 throw hcte;
558 } else if (throwable instanceof HttpTimeoutException) {
559 throw new HttpTimeoutException(msg);
560 } else if (throwable instanceof ConnectException) {
561 ConnectException ce = new ConnectException(msg);
562 ce.initCause(throwable);
563 throw ce;
564 } else if (throwable instanceof IOException) {
565 throw new IOException(msg, throwable);
566 } else {
567 throw new IOException(msg, throwable);
568 }
569 }
570 }
571
572 private static final Executor ASYNC_POOL = new CompletableFuture<Void>().defaultExecutor();
573
574 @Override
575 public <T> CompletableFuture<HttpResponse<T>>
576 sendAsync(HttpRequest userRequest, BodyHandler<T> responseHandler)
577 {
1115 ? Optional.empty()
1116 : Optional.of(delegatingExecutor.delegate());
1117 }
1118
1119 ConnectionPool connectionPool() {
1120 return connections;
1121 }
1122
1123 @Override
1124 public Redirect followRedirects() {
1125 return followRedirects;
1126 }
1127
1128
1129 @Override
1130 public Optional<CookieHandler> cookieHandler() {
1131 return Optional.ofNullable(cookieHandler);
1132 }
1133
1134 @Override
1135 public Optional<Duration> connectTimeout() {
1136 return Optional.ofNullable(connectTimeout);
1137 }
1138
1139 @Override
1140 public Optional<ProxySelector> proxy() {
1141 return this.userProxySelector;
1142 }
1143
1144 // Return the effective proxy that this client uses.
1145 ProxySelector proxySelector() {
1146 return proxySelector;
1147 }
1148
1149 @Override
1150 public WebSocket.Builder newWebSocketBuilder() {
1151 // Make sure to pass the HttpClientFacade to the WebSocket builder.
1152 // This will ensure that the facade is not released before the
1153 // WebSocket has been created, at which point the pendingOperationCount
1154 // will have been incremented by the RawChannelTube.
1155 // See RawChannelTube.
1156 return new BuilderImpl(this.facade(), proxySelector);
1157 }
1158
1159 @Override
|