< prev index next >

src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java

Print this page




  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


< prev index next >