src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java
changeset 49944 4690a2871b44
parent 49765 ee6f7a61f3a5
child 50681 4254bed3c09d
child 56507 2294c51eae30
child 56656 2a396fdb3afb
equal deleted inserted replaced
49943:8e1ed2a15845 49944:4690a2871b44
    26 package jdk.internal.net.http;
    26 package jdk.internal.net.http;
    27 
    27 
    28 import javax.net.ssl.SSLContext;
    28 import javax.net.ssl.SSLContext;
    29 import javax.net.ssl.SSLParameters;
    29 import javax.net.ssl.SSLParameters;
    30 import java.io.IOException;
    30 import java.io.IOException;
    31 import java.lang.System.Logger.Level;
       
    32 import java.lang.ref.Reference;
    31 import java.lang.ref.Reference;
    33 import java.lang.ref.WeakReference;
    32 import java.lang.ref.WeakReference;
    34 import java.net.Authenticator;
    33 import java.net.Authenticator;
    35 import java.net.CookieHandler;
    34 import java.net.CookieHandler;
    36 import java.net.ProxySelector;
    35 import java.net.ProxySelector;
       
    36 import java.nio.ByteBuffer;
    37 import java.nio.channels.CancelledKeyException;
    37 import java.nio.channels.CancelledKeyException;
    38 import java.nio.channels.ClosedChannelException;
    38 import java.nio.channels.ClosedChannelException;
    39 import java.nio.channels.SelectableChannel;
    39 import java.nio.channels.SelectableChannel;
    40 import java.nio.channels.SelectionKey;
    40 import java.nio.channels.SelectionKey;
    41 import java.nio.channels.Selector;
    41 import java.nio.channels.Selector;
    45 import java.security.NoSuchAlgorithmException;
    45 import java.security.NoSuchAlgorithmException;
    46 import java.security.PrivilegedAction;
    46 import java.security.PrivilegedAction;
    47 import java.time.Instant;
    47 import java.time.Instant;
    48 import java.time.temporal.ChronoUnit;
    48 import java.time.temporal.ChronoUnit;
    49 import java.util.ArrayList;
    49 import java.util.ArrayList;
    50 import java.util.Arrays;
       
    51 import java.util.HashSet;
    50 import java.util.HashSet;
    52 import java.util.Iterator;
    51 import java.util.Iterator;
    53 import java.util.LinkedList;
    52 import java.util.LinkedList;
    54 import java.util.List;
    53 import java.util.List;
    55 import java.util.Objects;
    54 import java.util.Objects;
    56 import java.util.Optional;
    55 import java.util.Optional;
    57 import java.util.Set;
    56 import java.util.Set;
    58 import java.util.TreeSet;
    57 import java.util.TreeSet;
    59 import java.util.concurrent.CompletableFuture;
    58 import java.util.concurrent.CompletableFuture;
       
    59 import java.util.concurrent.ConcurrentLinkedQueue;
    60 import java.util.concurrent.ExecutionException;
    60 import java.util.concurrent.ExecutionException;
    61 import java.util.concurrent.Executor;
    61 import java.util.concurrent.Executor;
    62 import java.util.concurrent.Executors;
    62 import java.util.concurrent.Executors;
    63 import java.util.concurrent.ThreadFactory;
    63 import java.util.concurrent.ThreadFactory;
    64 import java.util.concurrent.atomic.AtomicInteger;
    64 import java.util.concurrent.atomic.AtomicInteger;
    68 import java.net.http.HttpRequest;
    68 import java.net.http.HttpRequest;
    69 import java.net.http.HttpResponse;
    69 import java.net.http.HttpResponse;
    70 import java.net.http.HttpResponse.BodyHandler;
    70 import java.net.http.HttpResponse.BodyHandler;
    71 import java.net.http.HttpResponse.PushPromiseHandler;
    71 import java.net.http.HttpResponse.PushPromiseHandler;
    72 import java.net.http.WebSocket;
    72 import java.net.http.WebSocket;
       
    73 import jdk.internal.net.http.common.BufferSupplier;
    73 import jdk.internal.net.http.common.Log;
    74 import jdk.internal.net.http.common.Log;
    74 import jdk.internal.net.http.common.Logger;
    75 import jdk.internal.net.http.common.Logger;
    75 import jdk.internal.net.http.common.Pair;
    76 import jdk.internal.net.http.common.Pair;
    76 import jdk.internal.net.http.common.Utils;
    77 import jdk.internal.net.http.common.Utils;
    77 import jdk.internal.net.http.common.OperationTrackers.Trackable;
    78 import jdk.internal.net.http.common.OperationTrackers.Trackable;
   135     private final SelectorManager selmgr;
   136     private final SelectorManager selmgr;
   136     private final FilterFactory filters;
   137     private final FilterFactory filters;
   137     private final Http2ClientImpl client2;
   138     private final Http2ClientImpl client2;
   138     private final long id;
   139     private final long id;
   139     private final String dbgTag;
   140     private final String dbgTag;
       
   141 
       
   142     // The SSL DirectBuffer Supplier provides the ability to recycle
       
   143     // buffers used between the socket reader and the SSLEngine, or
       
   144     // more precisely between the SocketTube publisher and the
       
   145     // SSLFlowDelegate reader.
       
   146     private final SSLDirectBufferSupplier sslBufferSupplier
       
   147             = new SSLDirectBufferSupplier(this);
   140 
   148 
   141     // This reference is used to keep track of the facade HttpClient
   149     // This reference is used to keep track of the facade HttpClient
   142     // that was returned to the application code.
   150     // that was returned to the application code.
   143     // It makes it possible to know when the application no longer
   151     // It makes it possible to know when the application no longer
   144     // holds any reference to the HttpClient.
   152     // holds any reference to the HttpClient.
  1158     }
  1166     }
  1159 
  1167 
  1160     // used for the connection window
  1168     // used for the connection window
  1161     int getReceiveBufferSize() {
  1169     int getReceiveBufferSize() {
  1162         return Utils.getIntegerNetProperty(
  1170         return Utils.getIntegerNetProperty(
  1163                 "jdk.httpclient.receiveBufferSize", 2 * 1024 * 1024
  1171                 "jdk.httpclient.receiveBufferSize",
       
  1172                 0 // only set the size if > 0
  1164         );
  1173         );
  1165     }
  1174     }
       
  1175 
       
  1176     // Optimization for reading SSL encrypted data
       
  1177     // --------------------------------------------
       
  1178 
       
  1179     // Returns a BufferSupplier that can be used for reading
       
  1180     // encrypted bytes of the channel. These buffers can then
       
  1181     // be recycled by the SSLFlowDelegate::Reader after their
       
  1182     // content has been copied in the SSLFlowDelegate::Reader
       
  1183     // readBuf.
       
  1184     // Because allocating, reading, copying, and recycling
       
  1185     // all happen in the SelectorManager thread,
       
  1186     // then this BufferSupplier can be shared between all
       
  1187     // the SSL connections managed by this client.
       
  1188     BufferSupplier getSSLBufferSupplier() {
       
  1189         return sslBufferSupplier;
       
  1190     }
       
  1191 
       
  1192     // An implementation of BufferSupplier that manages a pool of
       
  1193     // maximum 3 direct byte buffers (SocketTube.MAX_BUFFERS) that
       
  1194     // are used for reading encrypted bytes off the channel before
       
  1195     // copying and subsequent unwrapping.
       
  1196     private static final class SSLDirectBufferSupplier implements BufferSupplier {
       
  1197         private static final int POOL_SIZE = SocketTube.MAX_BUFFERS;
       
  1198         private final ByteBuffer[] pool = new ByteBuffer[POOL_SIZE];
       
  1199         private final HttpClientImpl client;
       
  1200         private final Logger debug;
       
  1201         private int tail, count; // no need for volatile: only accessed in SM thread.
       
  1202 
       
  1203         SSLDirectBufferSupplier(HttpClientImpl client) {
       
  1204             this.client = Objects.requireNonNull(client);
       
  1205             this.debug = client.debug;
       
  1206         }
       
  1207 
       
  1208         // Gets a buffer from the pool, or allocates a new one if needed.
       
  1209         @Override
       
  1210         public ByteBuffer get() {
       
  1211             assert client.isSelectorThread();
       
  1212             assert tail <= POOL_SIZE : "allocate tail is " + tail;
       
  1213             ByteBuffer buf;
       
  1214             if (tail == 0) {
       
  1215                 if (debug.on()) {
       
  1216                     // should not appear more than SocketTube.MAX_BUFFERS
       
  1217                     debug.log("ByteBuffer.allocateDirect(%d)", Utils.BUFSIZE);
       
  1218                 }
       
  1219                 assert count++ < POOL_SIZE : "trying to allocate more than "
       
  1220                             + POOL_SIZE + " buffers";
       
  1221                 buf = ByteBuffer.allocateDirect(Utils.BUFSIZE);
       
  1222             } else {
       
  1223                 assert tail > 0 : "non positive tail value: " + tail;
       
  1224                 tail--;
       
  1225                 buf = pool[tail];
       
  1226                 pool[tail] = null;
       
  1227             }
       
  1228             assert buf.isDirect();
       
  1229             assert buf.position() == 0;
       
  1230             assert buf.hasRemaining();
       
  1231             assert buf.limit() == Utils.BUFSIZE;
       
  1232             assert tail < POOL_SIZE;
       
  1233             assert tail >= 0;
       
  1234             return buf;
       
  1235         }
       
  1236 
       
  1237         // Returns the given buffer to the pool.
       
  1238         @Override
       
  1239         public void recycle(ByteBuffer buffer) {
       
  1240             assert client.isSelectorThread();
       
  1241             assert buffer.isDirect();
       
  1242             assert !buffer.hasRemaining();
       
  1243             assert tail < POOL_SIZE : "recycle tail is " + tail;
       
  1244             assert tail >= 0;
       
  1245             buffer.position(0);
       
  1246             buffer.limit(buffer.capacity());
       
  1247             // don't fail if assertions are off. we have asserted above.
       
  1248             if (tail < POOL_SIZE) {
       
  1249                 pool[tail] = buffer;
       
  1250                 tail++;
       
  1251             }
       
  1252             assert tail <= POOL_SIZE;
       
  1253             assert tail > 0;
       
  1254         }
       
  1255     }
       
  1256 
  1166 }
  1257 }