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 } |