src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java
branchhttp-client-branch
changeset 56474 fe2bf7b369b8
parent 56463 b583caf69b39
child 56477 46c04919ee5c
equal deleted inserted replaced
56463:b583caf69b39 56474:fe2bf7b369b8
    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.
  1162         return Utils.getIntegerNetProperty(
  1170         return Utils.getIntegerNetProperty(
  1163                 "jdk.httpclient.receiveBufferSize",
  1171                 "jdk.httpclient.receiveBufferSize",
  1164                 0 // only set the size if > 0
  1172                 0 // only set the size if > 0
  1165         );
  1173         );
  1166     }
  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 socket. 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 manage a pool of
       
  1193     // maximum 3 direct byte buffers (SocketTube.MAX_BUFFERS) that
       
  1194     // are used for reading encrypted bytes off the socket before
       
  1195     // copying before unwrapping.
       
  1196     private static final class SSLDirectBufferSupplier implements BufferSupplier {
       
  1197         private final ConcurrentLinkedQueue<ByteBuffer> queue = new ConcurrentLinkedQueue<>();
       
  1198         private final HttpClientImpl client;
       
  1199         private final Logger debug;
       
  1200         public SSLDirectBufferSupplier(HttpClientImpl client) {
       
  1201             this.client = Objects.requireNonNull(client);
       
  1202             this.debug = client.debug;
       
  1203         }
       
  1204 
       
  1205         // get a buffer from the pool, or allocate a new one if needed.
       
  1206         @Override
       
  1207         public ByteBuffer get() {
       
  1208             assert client.isSelectorThread();
       
  1209             ByteBuffer buf = queue.poll();
       
  1210             if (buf == null) {
       
  1211                 if (debug.on()) {
       
  1212                     // should not appear more than SocketTube.MAX_BUFFERS
       
  1213                     debug.log("ByteBuffer.allocateDirect(%d)", Utils.BUFSIZE);
       
  1214                 }
       
  1215                 buf = ByteBuffer.allocateDirect(Utils.BUFSIZE);
       
  1216             } else {
       
  1217                 // if (debug.on()) { // this trace is mostly noise.
       
  1218                 //    debug.log("ByteBuffer.recycle(%d)", buf.remaining());
       
  1219                 // }
       
  1220             }
       
  1221             assert buf.isDirect();
       
  1222             assert buf.position() == 0;
       
  1223             assert buf.hasRemaining();
       
  1224             assert buf.limit() == Utils.BUFSIZE;
       
  1225             return buf;
       
  1226         }
       
  1227 
       
  1228         // return the buffer to the pool
       
  1229         @Override
       
  1230         public void recycle(ByteBuffer buffer) {
       
  1231             assert client.isSelectorThread();
       
  1232             assert buffer.isDirect();
       
  1233             assert !buffer.hasRemaining();
       
  1234             buffer.position(0);
       
  1235             buffer.limit(buffer.capacity());
       
  1236             queue.offer(buffer);
       
  1237             assert queue.size() <= SocketTube.MAX_BUFFERS;
       
  1238         }
       
  1239     }
       
  1240 
  1167 }
  1241 }