# HG changeset patch # User dfuchs # Date 1525451283 -3600 # Node ID a594484f54dbe6afe5f922ba19ae7e2994b6e138 # Parent 15ff86a732eae7da483adaf8dfafdcb9839c5472# Parent e4b3cc56e2b2be37c8bdaa029b8b0ad01e2d79c5 Merge diff -r e4b3cc56e2b2 -r a594484f54db make/common/Modules.gmk diff -r e4b3cc56e2b2 -r a594484f54db src/hotspot/share/gc/shared/jvmFlagConstraintsGC.cpp diff -r e4b3cc56e2b2 -r a594484f54db src/hotspot/share/gc/shared/jvmFlagConstraintsGC.hpp diff -r e4b3cc56e2b2 -r a594484f54db src/hotspot/share/runtime/flags/jvmFlagConstraintList.cpp diff -r e4b3cc56e2b2 -r a594484f54db src/hotspot/share/runtime/flags/jvmFlagConstraintList.hpp diff -r e4b3cc56e2b2 -r a594484f54db src/hotspot/share/runtime/flags/jvmFlagConstraintsCompiler.cpp diff -r e4b3cc56e2b2 -r a594484f54db src/hotspot/share/runtime/flags/jvmFlagConstraintsCompiler.hpp diff -r e4b3cc56e2b2 -r a594484f54db src/hotspot/share/runtime/flags/jvmFlagConstraintsRuntime.cpp diff -r e4b3cc56e2b2 -r a594484f54db src/hotspot/share/runtime/flags/jvmFlagConstraintsRuntime.hpp diff -r e4b3cc56e2b2 -r a594484f54db src/hotspot/share/runtime/flags/jvmFlagRangeList.cpp diff -r e4b3cc56e2b2 -r a594484f54db src/hotspot/share/runtime/flags/jvmFlagRangeList.hpp diff -r e4b3cc56e2b2 -r a594484f54db src/hotspot/share/runtime/flags/jvmFlagWriteableList.cpp diff -r e4b3cc56e2b2 -r a594484f54db src/hotspot/share/runtime/flags/jvmFlagWriteableList.hpp diff -r e4b3cc56e2b2 -r a594484f54db src/java.base/share/classes/java/net/doc-files/net-properties.html diff -r e4b3cc56e2b2 -r a594484f54db src/java.base/share/classes/module-info.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.base/share/lib/security/default.policy diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/java/net/http/HttpClient.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/java/net/http/HttpHeaders.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/java/net/http/HttpRequest.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/java/net/http/HttpResponse.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/java/net/http/HttpTimeoutException.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/java/net/http/WebSocket.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/java/net/http/WebSocketHandshakeException.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/java/net/http/package-info.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/AbstractAsyncSSLConnection.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/AbstractSubscription.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/AsyncEvent.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/AsyncSSLConnection.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/AsyncSSLTunnelConnection.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/AsyncTriggerEvent.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/AuthenticationFilter.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/BufferingSubscriber.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/ConnectionPool.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/CookieFilter.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/Exchange.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/ExchangeImpl.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/FilterFactory.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/HeaderFilter.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/HeaderParser.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/Http1AsyncReceiver.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/Http1Exchange.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/Http1HeaderParser.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/Http1Request.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/Http1Response.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java --- a/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java Fri May 04 12:14:09 2018 -0400 +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java Fri May 04 17:28:03 2018 +0100 @@ -273,7 +273,7 @@ */ private final WindowController windowController = new WindowController(); private final FramesController framesController = new FramesController(); - private final Http2TubeSubscriber subscriber = new Http2TubeSubscriber(); + private final Http2TubeSubscriber subscriber; final ConnectionWindowUpdateSender windowUpdater; private volatile Throwable cause; private volatile Supplier initial; @@ -290,6 +290,7 @@ String key) { this.connection = connection; this.client2 = client2; + this.subscriber = new Http2TubeSubscriber(client2.client()); this.nextstreamid = nextstreamid; this.key = key; this.clientSettings = this.client2.getClientSettings(); @@ -643,7 +644,7 @@ client2.deleteConnection(this); List> c = new LinkedList<>(streams.values()); for (Stream s : c) { - s.cancelImpl(t); + s.connectionClosing(t); } connection.close(); } @@ -797,12 +798,22 @@ } void resetStream(int streamid, int code) throws IOException { - Log.logError( - "Resetting stream {0,number,integer} with error code {1,number,integer}", - streamid, code); - ResetFrame frame = new ResetFrame(streamid, code); - sendFrame(frame); - closeStream(streamid); + try { + if (connection.channel().isOpen()) { + // no need to try & send a reset frame if the + // connection channel is already closed. + Log.logError( + "Resetting stream {0,number,integer} with error code {1,number,integer}", + streamid, code); + ResetFrame frame = new ResetFrame(streamid, code); + sendFrame(frame); + } else if (debug.on()) { + debug.log("Channel already closed, no need to reset stream %d", + streamid); + } + } finally { + closeStream(streamid); + } } void closeStream(int streamid) { @@ -1148,14 +1159,19 @@ * A simple tube subscriber for reading from the connection flow. */ final class Http2TubeSubscriber implements TubeSubscriber { - volatile Flow.Subscription subscription; - volatile boolean completed; - volatile boolean dropped; - volatile Throwable error; - final ConcurrentLinkedQueue queue + private volatile Flow.Subscription subscription; + private volatile boolean completed; + private volatile boolean dropped; + private volatile Throwable error; + private final ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue<>(); - final SequentialScheduler scheduler = + private final SequentialScheduler scheduler = SequentialScheduler.synchronizedScheduler(this::processQueue); + private final HttpClientImpl client; + + Http2TubeSubscriber(HttpClientImpl client) { + this.client = Objects.requireNonNull(client); + } final void processQueue() { try { @@ -1179,6 +1195,12 @@ } } + private final void runOrSchedule() { + if (client.isSelectorThread()) { + scheduler.runOrSchedule(client.theExecutor()); + } else scheduler.runOrSchedule(); + } + @Override public void onSubscribe(Flow.Subscription subscription) { // supports being called multiple time. @@ -1202,7 +1224,7 @@ if (debug.on()) debug.log(() -> "onNext: got " + Utils.remaining(item) + " bytes in " + item.size() + " buffers"); queue.addAll(item); - scheduler.runOrSchedule(client().theExecutor()); + runOrSchedule(); } @Override @@ -1210,7 +1232,7 @@ if (debug.on()) debug.log(() -> "onError: " + throwable); error = throwable; completed = true; - scheduler.runOrSchedule(client().theExecutor()); + runOrSchedule(); } @Override @@ -1218,7 +1240,7 @@ if (debug.on()) debug.log("EOF"); error = new EOFException("EOF reached while reading"); completed = true; - scheduler.runOrSchedule(client().theExecutor()); + runOrSchedule(); } @Override diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/HttpClientBuilderImpl.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/HttpClientFacade.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/HttpConnection.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestBuilderImpl.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestImpl.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/HttpResponseImpl.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/ImmutableHeaders.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/LineSubscriberAdapter.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/MultiExchange.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/PlainHttpConnection.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/PlainProxyConnection.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/PlainTunnelingConnection.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/PrivilegedExecutor.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/ProxyAuthenticationRequired.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/PullPublisher.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/PushGroup.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/RawChannelTube.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/RedirectFilter.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/RequestPublishers.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/Response.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/ResponseBodyHandlers.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/ResponseContent.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/SocketTube.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/Stream.java --- a/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java Fri May 04 12:14:09 2018 -0400 +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java Fri May 04 17:28:03 2018 +0100 @@ -25,9 +25,9 @@ package jdk.internal.net.http; +import java.io.EOFException; import java.io.IOException; import java.io.UncheckedIOException; -import java.lang.System.Logger.Level; import java.net.URI; import java.nio.ByteBuffer; import java.util.ArrayList; @@ -171,7 +171,7 @@ Http2Frame frame = inputQ.peek(); if (frame instanceof ResetFrame) { inputQ.remove(); - handleReset((ResetFrame)frame); + handleReset((ResetFrame)frame, subscriber); return; } DataFrame df = (DataFrame)frame; @@ -424,25 +424,56 @@ } else if (closed) { Log.logTrace("Ignoring RST_STREAM frame received on closed stream {0}", streamid); } else { - // put it in the input queue in order to read all - // pending data frames first. Indeed, a server may send - // RST_STREAM after sending END_STREAM, in which case we should - // ignore it. However, we won't know if we have received END_STREAM - // or not until all pending data frames are read. - receiveResetFrame(frame); - // RST_STREAM was pushed to the queue. It will be handled by - // asyncReceive after all pending data frames have been - // processed. - Log.logTrace("RST_STREAM pushed in queue for stream {0}", streamid); + Flow.Subscriber subscriber = + responseSubscriber == null ? pendingResponseSubscriber : responseSubscriber; + if (response == null && subscriber == null) { + // we haven't receive the headers yet, and won't receive any! + // handle reset now. + handleReset(frame, subscriber); + } else { + // put it in the input queue in order to read all + // pending data frames first. Indeed, a server may send + // RST_STREAM after sending END_STREAM, in which case we should + // ignore it. However, we won't know if we have received END_STREAM + // or not until all pending data frames are read. + receiveResetFrame(frame); + // RST_STREAM was pushed to the queue. It will be handled by + // asyncReceive after all pending data frames have been + // processed. + Log.logTrace("RST_STREAM pushed in queue for stream {0}", streamid); + } } } - void handleReset(ResetFrame frame) { + void handleReset(ResetFrame frame, Flow.Subscriber subscriber) { Log.logTrace("Handling RST_STREAM on stream {0}", streamid); if (!closed) { - close(); - int error = frame.getErrorCode(); - completeResponseExceptionally(new IOException(ErrorFrame.stringForCode(error))); + synchronized (this) { + if (closed) { + if (debug.on()) debug.log("Stream already closed: ignoring RESET"); + return; + } + closed = true; + } + try { + int error = frame.getErrorCode(); + IOException e = new IOException("Received RST_STREAM: " + + ErrorFrame.stringForCode(error)); + if (errorRef.compareAndSet(null, e)) { + if (subscriber != null) { + subscriber.onError(e); + } + } + completeResponseExceptionally(e); + if (!requestBodyCF.isDone()) { + requestBodyCF.completeExceptionally(errorRef.get()); // we may be sending the body.. + } + if (responseBodyCF != null) { + responseBodyCF.completeExceptionally(errorRef.get()); + } + } finally { + connection.closeStream(streamid); + } } else { Log.logTrace("Ignoring RST_STREAM frame received on closed stream {0}", streamid); } @@ -1033,6 +1064,15 @@ cancelImpl(cause); } + void connectionClosing(Throwable cause) { + Flow.Subscriber subscriber = + responseSubscriber == null ? pendingResponseSubscriber : responseSubscriber; + errorRef.compareAndSet(null, cause); + if (subscriber != null && !sched.isStopped() && !inputQ.isEmpty()) { + sched.runOrSchedule(); + } else cancelImpl(cause); + } + // This method sends a RST_STREAM frame void cancelImpl(Throwable e) { errorRef.compareAndSet(null, e); @@ -1062,7 +1102,13 @@ try { // will send a RST_STREAM frame if (streamid != 0) { - connection.resetStream(streamid, ResetFrame.CANCEL); + e = Utils.getCompletionCause(e); + if (e instanceof EOFException) { + // read EOF: no need to try & send reset + connection.closeStream(streamid); + } else { + connection.resetStream(streamid, ResetFrame.CANCEL); + } } } catch (IOException ex) { Log.logError(ex); diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/TimeoutEvent.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/WindowController.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/WindowUpdateSender.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/common/ConnectionExpiredException.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/common/DebugLogger.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/common/Demand.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/common/FlowTube.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/common/HttpHeadersImpl.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/common/Log.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/common/Logger.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/common/MinimalFuture.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/common/Pair.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/common/SSLFlowDelegate.java --- a/src/java.net.http/share/classes/jdk/internal/net/http/common/SSLFlowDelegate.java Fri May 04 12:14:09 2018 -0400 +++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/SSLFlowDelegate.java Fri May 04 17:28:03 2018 +0100 @@ -87,13 +87,17 @@ final Logger debug = Utils.getDebugLogger(this::dbgString, Utils.DEBUG); + private static final ByteBuffer SENTINEL = Utils.EMPTY_BYTEBUFFER; + private static final ByteBuffer HS_TRIGGER = ByteBuffer.allocate(0); + // When handshake is in progress trying to wrap may produce no bytes. + private static final ByteBuffer NOTHING = ByteBuffer.allocate(0); + final Executor exec; final Reader reader; final Writer writer; final SSLEngine engine; final String tubeName; // hack final CompletableFuture alpnCF; // completes on initial handshake - final static ByteBuffer SENTINEL = Utils.EMPTY_BYTEBUFFER; volatile boolean close_notify_received; final CompletableFuture readerCF; final CompletableFuture writerCF; @@ -245,13 +249,16 @@ final Logger debugr = Utils.getDebugLogger(this::dbgString, Utils.DEBUG); private final class ReaderDownstreamPusher implements Runnable { - @Override public void run() { processData(); } + @Override + public void run() { + processData(); + } } Reader() { super(); scheduler = SequentialScheduler.synchronizedScheduler( - new ReaderDownstreamPusher()); + new ReaderDownstreamPusher()); this.readBuf = ByteBuffer.allocate(1024); readBuf.limit(0); // keep in read mode } @@ -276,7 +283,7 @@ public void incoming(List buffers, boolean complete) { if (debugr.on()) debugr.log("Adding %d bytes to read buffer", - Utils.remaining(buffers)); + Utils.remaining(buffers)); addToReadBuf(buffers, complete); scheduler.runOrSchedule(exec); } @@ -289,7 +296,7 @@ private void reallocReadBuf() { int sz = readBuf.capacity(); - ByteBuffer newb = ByteBuffer.allocate(sz*2); + ByteBuffer newb = ByteBuffer.allocate(sz * 2); readBuf.flip(); Utils.copy(readBuf, newb); readBuf = newb; @@ -300,7 +307,7 @@ if (readBuf.remaining() > TARGET_BUFSIZE) { if (debugr.on()) debugr.log("readBuf has more than TARGET_BUFSIZE: %d", - readBuf.remaining()); + readBuf.remaining()); return 0; } else { return super.upstreamWindowUpdate(currentWindow, downstreamQsize); @@ -309,6 +316,7 @@ // readBuf is kept ready for reading outside of this method private void addToReadBuf(List buffers, boolean complete) { + assert Utils.remaining(buffers) > 0 || buffers.isEmpty(); synchronized (readBufferLock) { for (ByteBuffer buf : buffers) { readBuf.compact(); @@ -344,14 +352,15 @@ // In this case we need to wait for more bytes than what // we had before calling unwrap() again. volatile int minBytesRequired; + // work function where it all happens final void processData() { try { if (debugr.on()) debugr.log("processData:" - + " readBuf remaining:" + readBuf.remaining() - + ", state:" + states(handshakeState) - + ", engine handshake status:" + engine.getHandshakeStatus()); + + " readBuf remaining:" + readBuf.remaining() + + ", state:" + states(handshakeState) + + ", engine handshake status:" + engine.getHandshakeStatus()); int len; boolean complete = false; while (readBuf.remaining() > (len = minBytesRequired)) { @@ -400,14 +409,13 @@ outgoing(Utils.EMPTY_BB_LIST, true); return; } - if (result.handshaking() && !complete) { + if (result.handshaking()) { + handshaking = true; if (debugr.on()) debugr.log("handshaking"); - if (doHandshake(result, READER)) { - resumeActivity(); - } - handshaking = true; + if (doHandshake(result, READER)) continue; // need unwrap + else break; // doHandshake will have triggered the write scheduler if necessary } else { - if ((handshakeState.getAndSet(NOT_HANDSHAKING)& ~DOING_TASKS) == HANDSHAKING) { + if ((handshakeState.getAndSet(NOT_HANDSHAKING) & ~DOING_TASKS) == HANDSHAKING) { handshaking = false; applicationBufferSize = engine.getSession().getApplicationBufferSize(); packetBufferSize = engine.getSession().getPacketBufferSize(); @@ -443,12 +451,19 @@ EngineResult unwrapBuffer(ByteBuffer src) throws IOException { ByteBuffer dst = getAppBuffer(); + int len = src.remaining(); while (true) { SSLEngineResult sslResult = engine.unwrap(src, dst); switch (sslResult.getStatus()) { case BUFFER_OVERFLOW: - // may happen only if app size buffer was changed. - // get it again if app buffer size changed + // may happen if app size buffer was changed, or if + // our 'adaptiveBufferSize' guess was too small for + // the current payload. In that case, update the + // value of applicationBufferSize, and allocate a + // buffer of that size, which we are sure will be + // big enough to decode whatever needs to be + // decoded. We will later update adaptiveBufferSize + // in OK: below. int appSize = applicationBufferSize = engine.getSession().getApplicationBufferSize(); ByteBuffer b = ByteBuffer.allocate(appSize + dst.position()); @@ -457,11 +472,26 @@ dst = b; break; case CLOSED: + assert dst.position() == 0; return doClosure(new EngineResult(sslResult)); case BUFFER_UNDERFLOW: // handled implicitly by compaction/reallocation of readBuf + assert dst.position() == 0; return new EngineResult(sslResult); case OK: + int size = dst.position(); + if (debug.on()) { + debugr.log("Decoded " + size + " bytes out of " + len + + " into buffer of " + dst.capacity() + + " remaining to decode: " + src.remaining()); + } + // if the record payload was bigger than what was originally + // allocated, then sets the adaptiveAppBufferSize to size + // and we will use that new size as a guess for the next app + // buffer. + if (size > adaptiveAppBufferSize) { + adaptiveAppBufferSize = ((size + 7) >>> 3) << 3; + } dst.flip(); return new EngineResult(sslResult, dst); } @@ -662,8 +692,8 @@ } cleanList(writeList); // tidy up the source list sendResultBytes(result); - if (handshaking && !completing) { - if (needWrap()) { + if (handshaking) { + if (!completing && needWrap()) { continue; } else { return; @@ -687,11 +717,30 @@ } } + // The SSLEngine insists on being given a buffer that is at least + // SSLSession.getPacketBufferSize() long (usually 16K). If given + // a smaller buffer it will go in BUFFER_OVERFLOW, even if it only + // has 6 bytes to wrap. Typical usage shows that for GET we + // usually produce an average of ~ 100 bytes. + // To avoid wasting space, and because allocating and zeroing + // 16K buffers for encoding 6 bytes is costly, we are reusing the + // same writeBuffer to interact with SSLEngine.wrap(). + // If the SSLEngine produces less than writeBuffer.capacity() / 2, + // then we copy off the bytes to a smaller buffer that we send + // downstream. Otherwise, we send the writeBuffer downstream + // and will allocate a new one next time. + volatile ByteBuffer writeBuffer; @SuppressWarnings("fallthrough") EngineResult wrapBuffers(ByteBuffer[] src) throws SSLException { + long len = Utils.remaining(src); if (debugw.on()) - debugw.log("wrapping " + Utils.remaining(src) + " bytes"); - ByteBuffer dst = getNetBuffer(); + debugw.log("wrapping " + len + " bytes"); + + ByteBuffer dst = writeBuffer; + if (dst == null) dst = writeBuffer = getNetBuffer(); + assert dst.position() == 0 : "buffer position is " + dst.position(); + assert dst.hasRemaining() : "buffer has no remaining space: capacity=" + dst.capacity(); + while (true) { SSLEngineResult sslResult = engine.wrap(src, dst); if (debugw.on()) debugw.log("SSLResult: " + sslResult); @@ -702,7 +751,7 @@ if (debugw.on()) debugw.log("BUFFER_OVERFLOW"); int netSize = packetBufferSize = engine.getSession().getPacketBufferSize(); - ByteBuffer b = ByteBuffer.allocate(netSize + dst.position()); + ByteBuffer b = writeBuffer = ByteBuffer.allocate(netSize + dst.position()); dst.flip(); b.put(dst); dst = b; @@ -712,11 +761,27 @@ // fallthrough. There could be some remaining data in dst. // CLOSED will be handled by the caller. case OK: - dst.flip(); - final ByteBuffer dest = dst; + final ByteBuffer dest; + if (dst.position() == 0) { + dest = NOTHING; // can happen if handshake is in progress + } else if (dst.position() < dst.capacity() / 2) { + // less than half the buffer was used. + // copy off the bytes to a smaller buffer, and keep + // the writeBuffer for next time. + dst.flip(); + dest = Utils.copyAligned(dst); + dst.clear(); + } else { + // more than half the buffer was used. + // just send that buffer downstream, and we will + // get a new writeBuffer next time it is needed. + dst.flip(); + dest = dst; + writeBuffer = null; + } if (debugw.on()) - debugw.log("OK => produced: %d, not wrapped: %d", - dest.remaining(), Utils.remaining(src)); + debugw.log("OK => produced: %d bytes into %d, not wrapped: %d", + dest.remaining(), dest.capacity(), Utils.remaining(src)); return new EngineResult(sslResult, dest); case BUFFER_UNDERFLOW: // Shouldn't happen. Doesn't returns when wrap() @@ -800,7 +865,6 @@ private static final int HANDSHAKING = 1; private static final int DOING_TASKS = 4; // bit added to above state - private static final ByteBuffer HS_TRIGGER = ByteBuffer.allocate(0); private static final int READER = 1; private static final int WRITER = 2; @@ -997,6 +1061,8 @@ } } + // The maximum network buffer size negotiated during + // the handshake. Usually 16K. volatile int packetBufferSize; final ByteBuffer getNetBuffer() { int netSize = packetBufferSize; @@ -1006,13 +1072,32 @@ return ByteBuffer.allocate(netSize); } + // The maximum application buffer size negotiated during + // the handshake. Usually close to 16K. volatile int applicationBufferSize; + // Despite of the maximum applicationBufferSize negotiated + // above, TLS records usually have a much smaller payload. + // The adaptativeAppBufferSize records the max payload + // ever decoded, and we use that as a guess for how big + // a buffer we will need for the next payload. + // This avoids allocating and zeroing a 16K buffer for + // nothing... + volatile int adaptiveAppBufferSize; final ByteBuffer getAppBuffer() { int appSize = applicationBufferSize; if (appSize <= 0) { - applicationBufferSize = appSize = engine.getSession().getApplicationBufferSize(); + applicationBufferSize = appSize + = engine.getSession().getApplicationBufferSize(); } - return ByteBuffer.allocate(appSize); + int size = adaptiveAppBufferSize; + if (size <= 0) { + size = 512; // start with 512 this is usually enough for handshaking / headers + } else if (size > appSize) { + size = appSize; + } + // will cause a BUFFER_OVERFLOW if not big enough, but + // that's OK. + return ByteBuffer.allocate(size); } final String dbgString() { diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/common/SSLTube.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/common/SequentialScheduler.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/common/SubscriberWrapper.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/common/SubscriptionBase.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java --- a/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java Fri May 04 12:14:09 2018 -0400 +++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java Fri May 04 17:28:03 2018 +0100 @@ -534,6 +534,16 @@ return dst; } + public static ByteBuffer copyAligned(ByteBuffer src) { + int len = src.remaining(); + int size = ((len + 7) >> 3) << 3; + assert size >= len; + ByteBuffer dst = ByteBuffer.allocate(size); + dst.put(src); + dst.flip(); + return dst; + } + public static String dump(Object... objects) { return Arrays.toString(objects); } diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/frame/ContinuationFrame.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/frame/DataFrame.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/frame/ErrorFrame.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/frame/FramesDecoder.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/frame/FramesEncoder.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/frame/GoAwayFrame.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/frame/HeaderFrame.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/frame/HeadersFrame.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/frame/Http2Frame.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/frame/MalformedFrame.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/frame/OutgoingHeaders.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/frame/PingFrame.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/frame/PriorityFrame.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/frame/PushPromiseFrame.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/frame/ResetFrame.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/frame/SettingsFrame.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/frame/WindowUpdateFrame.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/hpack/BinaryRepresentationWriter.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/hpack/BulkSizeUpdateWriter.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/hpack/Decoder.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/hpack/DecodingCallback.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/hpack/Encoder.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/hpack/HPACK.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/hpack/HeaderTable.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/hpack/Huffman.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/hpack/ISO_8859_1.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/hpack/IndexNameValueWriter.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/hpack/IndexedWriter.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/hpack/IntegerReader.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/hpack/IntegerWriter.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/hpack/LiteralNeverIndexedWriter.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/hpack/LiteralWithIndexingWriter.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/hpack/LiteralWriter.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/hpack/SimpleHeaderTable.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/hpack/SizeUpdateWriter.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/hpack/StringReader.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/hpack/StringWriter.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/hpack/package-info.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/websocket/BuilderImpl.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/websocket/CheckFailedException.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/websocket/FailWebSocketException.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/websocket/Frame.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/websocket/MessageDecoder.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/websocket/MessageEncoder.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/websocket/MessageQueue.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/websocket/MessageStreamConsumer.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/websocket/RawChannel.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/websocket/StatusCodes.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/websocket/Transport.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/websocket/TransportFactory.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/websocket/TransportFactoryImpl.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/websocket/TransportImpl.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/websocket/UTF8AccumulatingDecoder.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/websocket/WebSocketImpl.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/jdk/internal/net/http/websocket/WebSocketRequest.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.net.http/share/classes/module-info.java diff -r e4b3cc56e2b2 -r a594484f54db src/java.se/share/classes/module-info.java diff -r e4b3cc56e2b2 -r a594484f54db src/jdk.httpserver/share/classes/sun/net/httpserver/ChunkedInputStream.java diff -r e4b3cc56e2b2 -r a594484f54db src/jdk.httpserver/share/classes/sun/net/httpserver/FixedLengthInputStream.java diff -r e4b3cc56e2b2 -r a594484f54db src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/ProblemList.txt diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/AbstractNoBody.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/AsFileDownloadTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/AsFileDownloadTest.policy diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/BasicAuthTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/BasicRedirectTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/BodyProcessorInputStreamTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/BufferingSubscriberCancelTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/BufferingSubscriberErrorCompleteTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/BufferingSubscriberTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/CancelledResponse.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/ConcurrentResponses.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/CookieHeaderTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/CustomRequestPublisher.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/CustomResponseSubscriber.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/DependentActionsTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/DependentPromiseActionsTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/DigestEchoClient.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/DigestEchoClientSSL.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/DigestEchoServer.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/EchoHandler.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/EncodedCharsInURI.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/EscapedOctetsInURI.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/ExpectContinue.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/FlowAdapterPublisherTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/FlowAdapterSubscriberTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/FlowAdaptersCompileOnly.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/HandshakeFailureTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/HeadersTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/HeadersTest1.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/HeadersTest2.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/HttpClientBuilderTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/HttpEchoHandler.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/HttpInputStreamTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/HttpRequestBuilderTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/HttpResponseInputStreamTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/HttpServerAdapters.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/HttpsTunnelTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/ImmutableFlowItems.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/ImmutableHeaders.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/InterruptedBlockingSend.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/InvalidInputStreamSubscriptionRequest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/InvalidSSLContextTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/InvalidSubscriptionRequest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/LightWeightHttpServer.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/LineAdaptersCompileOnly.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/LineBodyHandlerTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/LineStreamsAndSurrogatesTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/LineSubscribersAndSurrogatesTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/ManyRequests.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/ManyRequestsLegacy.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/MappingResponseSubscriber.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/MessageHeadersTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/MethodsTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/MockServer.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/MultiAuthTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/NoBodyPartOne.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/NoBodyPartTwo.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/ProxyAuthDisabledSchemes.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/ProxyAuthDisabledSchemesSSL.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/ProxyAuthTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/ProxyServer.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/ProxyTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/RedirectMethodChange.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/RedirectWithCookie.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/RequestBodyTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/RequestBodyTest.policy diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/RequestBuilderTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/ResponsePublisher.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/RetryWithCookie.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/ServerCloseTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/ShortRequestBody.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/SmallTimeout.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/SmokeTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/SplitResponse.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/StreamingBody.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/SubscriberPublisherAPIExceptions.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/ThrowingPublishers.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/ThrowingPushPromises.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/ThrowingSubscribers.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/TimeoutBasic.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/TimeoutOrdering.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/VersionTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/ZeroRedirects.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/examples/JavadocExamples.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/examples/WebSocketExample.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/BadHeadersTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/BasicTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/ContinuationFrameTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/ErrorTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/FixedThreadPoolTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/HpackBinaryTestDriver.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/HpackCircularBufferDriver.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/HpackDecoderDriver.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/HpackEncoderDriver.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/HpackHeaderTableDriver.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/HpackHuffmanDriver.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/HpackTestHelper.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/ImplicitPushCancel.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/ProxyTest2.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/RedirectTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/ServerPush.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/ServerPushWithDiffTypes.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/TLSConnection.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/Timeout.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/java.net.http/jdk/internal/net/http/hpack/BinaryPrimitivesTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/java.net.http/jdk/internal/net/http/hpack/BuffersTestingKit.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/java.net.http/jdk/internal/net/http/hpack/CircularBufferTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/java.net.http/jdk/internal/net/http/hpack/DecoderTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/java.net.http/jdk/internal/net/http/hpack/EncoderTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/java.net.http/jdk/internal/net/http/hpack/HeaderTableTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/java.net.http/jdk/internal/net/http/hpack/HuffmanTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/java.net.http/jdk/internal/net/http/hpack/SpecHelper.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/java.net.http/jdk/internal/net/http/hpack/TestHelper.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/server/BodyInputStream.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/server/BodyOutputStream.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/server/EchoHandler.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/server/ExceptionallyCloseable.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/server/Http2EchoHandler.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/server/Http2RedirectHandler.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/server/Http2TestExchange.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/server/Http2TestExchangeImpl.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/server/Http2TestExchangeSupplier.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/server/Http2TestServer.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/server/Http2TestServerConnection.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/server/OutgoingPushPromise.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/server/PushHandler.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/server/Queue.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/http2/server/TestUtil.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/offline/DelegatingHttpClient.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/offline/FixedHttpHeaders.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/offline/FixedHttpResponse.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/offline/FixedResponseHttpClient.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/offline/OfflineTesting.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/security/0.policy diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/security/1.policy diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/security/10.policy diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/security/11.policy diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/security/12.policy diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/security/14.policy diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/security/15.policy diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/security/2.policy diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/security/3.policy diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/security/4.policy diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/security/5.policy diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/security/6.policy diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/security/7.policy diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/security/8.policy diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/security/9.policy diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/security/Driver.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/security/Security.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/security/filePerms/FileProcessorPermissionTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/security/filePerms/allpermissions.policy diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/ssltest/CertificateTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/ssltest/Server.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/websocket/AutomaticPong.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/websocket/ConnectionHandoverTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/websocket/DummyWebSocketServer.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/websocket/Frame.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/websocket/HeaderWriterDriver.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/websocket/MaskerDriver.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/websocket/MockListener.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/websocket/PendingBinaryPingClose.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/websocket/PendingBinaryPongClose.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/websocket/PendingOperations.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/websocket/PendingPingBinaryClose.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/websocket/PendingPingTextClose.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/websocket/PendingPongBinaryClose.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/websocket/PendingPongTextClose.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/websocket/PendingTextPingClose.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/websocket/PendingTextPongClose.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/websocket/ReaderDriver.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/websocket/SendTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/websocket/Support.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/websocket/WSHandshakeExceptionTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/websocket/WebSocketBuilderTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/websocket/WebSocketExtendedTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/websocket/WebSocketTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/websocket/java.net.http/jdk/internal/net/http/websocket/HeaderWriterTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/websocket/java.net.http/jdk/internal/net/http/websocket/MaskerTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/websocket/java.net.http/jdk/internal/net/http/websocket/MessageQueueTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/websocket/java.net.http/jdk/internal/net/http/websocket/ReaderTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/websocket/java.net.http/jdk/internal/net/http/websocket/TestSupport.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/websocket/security/WSURLPermissionTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/websocket/security/httpclient.policy diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/whitebox/ConnectionPoolTestDriver.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/whitebox/DemandTestDriver.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/whitebox/FlowTestDriver.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/whitebox/FramesDecoderTestDriver.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/whitebox/Http1HeaderParserTestDriver.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/whitebox/MinimalFutureTestDriver.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/whitebox/RawChannelTestDriver.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/whitebox/SSLEchoTubeTestDriver.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/whitebox/SSLTubeTestDriver.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/whitebox/SelectorTestDriver.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/whitebox/WrapperTestDriver.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/AbstractRandomTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/AbstractSSLTubeTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/AuthenticationFilterTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/ConnectionPoolTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/FlowTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/Http1HeaderParserTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/RawChannelTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/SSLEchoTubeTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/SSLTubeTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/SelectorTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/WrapperTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/common/DemandTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/common/MinimalFutureTest.java diff -r e4b3cc56e2b2 -r a594484f54db test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/frame/FramesDecoderTest.java