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