# HG changeset patch # User dfuchs # Date 1519403132 0 # Node ID 56c52d6417d103fff0789054b0220f102dac65ca # Parent 8a6065d830b9818d62d3dfc7232451d969798721 http-client-branch: HTTP/2 200 response headers should not be appended to the 100-continue response headers diff -r 8a6065d830b9 -r 56c52d6417d1 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 Thu Feb 22 17:33:21 2018 +0000 +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java Fri Feb 23 16:25:32 2018 +0000 @@ -1191,6 +1191,12 @@ private static final Set PSEUDO_HEADERS = Set.of(":authority", ":method", ":path", ":scheme", ":status"); + /** + * Called when END_HEADERS was received. This consumer may be invoked + * again after reset() is called, but for a whole new set of headers. + */ + void reset() { } + @Override public void onDecoded(CharSequence name, CharSequence value) throws UncheckedIOException diff -r 8a6065d830b9 -r 56c52d6417d1 src/java.net.http/share/classes/jdk/internal/net/http/Response.java --- a/src/java.net.http/share/classes/jdk/internal/net/http/Response.java Thu Feb 22 17:33:21 2018 +0000 +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Response.java Fri Feb 23 16:25:32 2018 +0000 @@ -64,7 +64,7 @@ int statusCode, HttpClient.Version version, boolean isConnectResponse) { - this.headers = headers; + this.headers = ImmutableHeaders.of(headers); this.request = req; this.version = version; this.exchange = exchange; diff -r 8a6065d830b9 -r 56c52d6417d1 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 Thu Feb 22 17:33:21 2018 +0000 +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java Fri Feb 23 16:25:32 2018 +0000 @@ -113,8 +113,8 @@ final Http2Connection connection; final HttpRequestImpl request; - final DecodingCallback rspHeadersConsumer; - HttpHeadersImpl responseHeaders; + final HeadersConsumer rspHeadersConsumer; + final HttpHeadersImpl responseHeaders; final HttpHeadersImpl requestPseudoHeaders; volatile HttpResponse.BodySubscriber responseSubscriber; final HttpRequest.BodyPublisher requestPublisher; @@ -232,7 +232,7 @@ { try { Log.logTrace("Reading body on stream {0}", streamid); - BodySubscriber bodySubscriber = handler.apply(responseCode, responseHeaders); + BodySubscriber bodySubscriber = handler.apply(responseCode, response.headers); CompletableFuture cf = receiveData(bodySubscriber, executor); PushGroup pg = exchange.getPushGroup(); @@ -243,6 +243,7 @@ return cf; } catch (Throwable t) { // may be thrown by handler.apply + cancelImpl(t); return MinimalFuture.failedFuture(t); } } @@ -387,6 +388,9 @@ Log.logHeaders(sb.toString()); } + // this will clear the response headers + rspHeadersConsumer.reset(); + completeResponse(response); } @@ -1145,6 +1149,8 @@ Log.logHeaders(sb.toString()); } + rspHeadersConsumer.reset(); + // different implementations for normal streams and pushed streams completeResponse(response); } @@ -1184,6 +1190,10 @@ private class HeadersConsumer extends Http2Connection.ValidatingHeadersConsumer { + void reset() { + responseHeaders.clear(); + } + @Override public void onDecoded(CharSequence name, CharSequence value) throws UncheckedIOException diff -r 8a6065d830b9 -r 56c52d6417d1 src/java.net.http/share/classes/jdk/internal/net/http/common/HttpHeadersImpl.java --- a/src/java.net.http/share/classes/jdk/internal/net/http/common/HttpHeadersImpl.java Thu Feb 22 17:33:21 2018 +0000 +++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/HttpHeadersImpl.java Fri Feb 23 16:25:32 2018 +0000 @@ -70,4 +70,8 @@ values.add(value); headers.put(name, values); } + + public void clear() { + headers.clear(); + } } diff -r 8a6065d830b9 -r 56c52d6417d1 test/jdk/java/net/httpclient/AsFileDownloadTest.java --- a/test/jdk/java/net/httpclient/AsFileDownloadTest.java Thu Feb 22 17:33:21 2018 +0000 +++ b/test/jdk/java/net/httpclient/AsFileDownloadTest.java Fri Feb 23 16:25:32 2018 +0000 @@ -160,6 +160,7 @@ void test(String uriString, String contentDispositionValue, String expectedFilename) throws Exception { + out.printf("test(%s, %s, %s): starting", uriString, contentDispositionValue, expectedFilename); HttpClient client = HttpClient.newBuilder().sslContext(sslContext).build(); URI uri = URI.create(uriString); @@ -228,6 +229,7 @@ void negativeTest(String uriString, String contentDispositionValue) throws Exception { + out.printf("negativeTest(%s, %s): starting", uriString, contentDispositionValue); HttpClient client = HttpClient.newBuilder().sslContext(sslContext).build(); URI uri = URI.create(uriString); diff -r 8a6065d830b9 -r 56c52d6417d1 test/jdk/java/net/httpclient/FlowAdapterSubscriberTest.java --- a/test/jdk/java/net/httpclient/FlowAdapterSubscriberTest.java Thu Feb 22 17:33:21 2018 +0000 +++ b/test/jdk/java/net/httpclient/FlowAdapterSubscriberTest.java Fri Feb 23 16:25:32 2018 +0000 @@ -72,7 +72,7 @@ * @library /lib/testlibrary http2/server * @build Http2TestServer * @build jdk.testlibrary.SimpleSSLContext - * @run testng/othervm FlowAdapterSubscriberTest + * @run testng/othervm -Djdk.internal.httpclient.debug=true FlowAdapterSubscriberTest */ public class FlowAdapterSubscriberTest { @@ -86,6 +86,14 @@ String httpsURI; String http2URI; String https2URI; + static final long start = System.nanoTime(); + public static String now() { + long now = System.nanoTime() - start; + long secs = now / 1000_000_000; + long mill = (now % 1000_000_000) / 1000_000; + long nan = now % 1000_000; + return String.format("[%d s, %d ms, %d ns] ", secs, mill, nan); + } @DataProvider(name = "uris") public Object[][] variants() { @@ -101,6 +109,7 @@ @Test public void testNull() { + System.out.printf(now() + "testNull() starting%n"); assertThrows(NPE, () -> BodyHandler.fromSubscriber(null)); assertThrows(NPE, () -> BodyHandler.fromSubscriber(null, Function.identity())); assertThrows(NPE, () -> BodyHandler.fromSubscriber(new ListSubscriber(), null)); @@ -121,6 +130,7 @@ @Test(dataProvider = "uris") void testListWithFinisher(String url) { + System.out.printf(now() + "testListWithFinisher(%s) starting%n", url); HttpClient client = HttpClient.newBuilder().sslContext(sslContext).build(); HttpRequest request = HttpRequest.newBuilder(URI.create(url)) .POST(fromString("May the luck of the Irish be with you!")).build(); @@ -136,6 +146,7 @@ @Test(dataProvider = "uris") void testListWithoutFinisher(String url) { + System.out.printf(now() + "testListWithoutFinisher(%s) starting%n", url); HttpClient client = HttpClient.newBuilder().sslContext(sslContext).build(); HttpRequest request = HttpRequest.newBuilder(URI.create(url)) .POST(fromString("May the luck of the Irish be with you!")).build(); @@ -151,6 +162,7 @@ @Test(dataProvider = "uris") void testListWithFinisherBlocking(String url) throws Exception { + System.out.printf(now() + "testListWithFinisherBlocking(%s) starting%n", url); HttpClient client = HttpClient.newBuilder().sslContext(sslContext).build(); HttpRequest request = HttpRequest.newBuilder(URI.create(url)) .POST(fromString("May the luck of the Irish be with you!")).build(); @@ -166,6 +178,7 @@ @Test(dataProvider = "uris") void testListWithoutFinisherBlocking(String url) throws Exception { + System.out.printf(now() + "testListWithoutFinisherBlocking(%s) starting%n", url); HttpClient client = HttpClient.newBuilder().sslContext(sslContext).build(); HttpRequest request = HttpRequest.newBuilder(URI.create(url)) .POST(fromString("May the luck of the Irish be with you!")).build(); @@ -183,6 +196,7 @@ @Test(dataProvider = "uris") void testCollectionWithFinisher(String url) { + System.out.printf(now() + "testCollectionWithFinisher(%s) starting%n", url); HttpClient client = HttpClient.newBuilder().sslContext(sslContext).build(); HttpRequest request = HttpRequest.newBuilder(URI.create(url)) .POST(fromString("What's the craic?")).build(); @@ -198,6 +212,7 @@ @Test(dataProvider = "uris") void testCollectionWithoutFinisher(String url) { + System.out.printf(now() + "testCollectionWithoutFinisher(%s) starting%n", url); HttpClient client = HttpClient.newBuilder().sslContext(sslContext).build(); HttpRequest request = HttpRequest.newBuilder(URI.create(url)) .POST(fromString("What's the craic?")).build(); @@ -213,6 +228,7 @@ @Test(dataProvider = "uris") void testCollectionWithFinisherBlocking(String url) throws Exception { + System.out.printf(now() + "testCollectionWithFinisherBlocking(%s) starting%n", url); HttpClient client = HttpClient.newBuilder().sslContext(sslContext).build(); HttpRequest request = HttpRequest.newBuilder(URI.create(url)) .POST(fromString("What's the craic?")).build(); @@ -228,6 +244,7 @@ @Test(dataProvider = "uris") void testCollectionWithoutFinisheBlocking(String url) throws Exception { + System.out.printf(now() + "testCollectionWithoutFinisheBlocking(%s) starting%n", url); HttpClient client = HttpClient.newBuilder().sslContext(sslContext).build(); HttpRequest request = HttpRequest.newBuilder(URI.create(url)) .POST(fromString("What's the craic?")).build(); @@ -245,6 +262,7 @@ @Test(dataProvider = "uris") void testIterableWithFinisher(String url) { + System.out.printf(now() + "testIterableWithFinisher(%s) starting%n", url); HttpClient client = HttpClient.newBuilder().sslContext(sslContext).build(); HttpRequest request = HttpRequest.newBuilder(URI.create(url)) .POST(fromString("We're sucking diesel now!")).build(); @@ -260,6 +278,7 @@ @Test(dataProvider = "uris") void testIterableWithoutFinisher(String url) { + System.out.printf(now() + "testIterableWithoutFinisher(%s) starting%n", url); HttpClient client = HttpClient.newBuilder().sslContext(sslContext).build(); HttpRequest request = HttpRequest.newBuilder(URI.create(url)) .POST(fromString("We're sucking diesel now!")).build(); @@ -275,6 +294,7 @@ @Test(dataProvider = "uris") void testIterableWithFinisherBlocking(String url) throws Exception { + System.out.printf(now() + "testIterableWithFinisherBlocking(%s) starting%n", url); HttpClient client = HttpClient.newBuilder().sslContext(sslContext).build(); HttpRequest request = HttpRequest.newBuilder(URI.create(url)) .POST(fromString("We're sucking diesel now!")).build(); @@ -290,6 +310,7 @@ @Test(dataProvider = "uris") void testIterableWithoutFinisherBlocking(String url) throws Exception { + System.out.printf(now() + "testIterableWithoutFinisherBlocking(%s) starting%n", url); HttpClient client = HttpClient.newBuilder().sslContext(sslContext).build(); HttpRequest request = HttpRequest.newBuilder(URI.create(url)) .POST(fromString("We're sucking diesel now!")).build(); @@ -307,6 +328,7 @@ @Test(dataProvider = "uris") void testObjectWithFinisher(String url) { + System.out.printf(now() + "testObjectWithFinisher(%s) starting%n", url); HttpClient client = HttpClient.newBuilder().sslContext(sslContext).build(); HttpRequest request = HttpRequest.newBuilder(URI.create(url)) .POST(fromString("May the wind always be at your back.")).build(); @@ -322,6 +344,7 @@ @Test(dataProvider = "uris") void testObjectWithoutFinisher(String url) { + System.out.printf(now() + "testObjectWithoutFinisher(%s) starting%n", url); HttpClient client = HttpClient.newBuilder().sslContext(sslContext).build(); HttpRequest request = HttpRequest.newBuilder(URI.create(url)) .POST(fromString("May the wind always be at your back.")).build(); @@ -337,6 +360,7 @@ @Test(dataProvider = "uris") void testObjectWithFinisherBlocking(String url) throws Exception { + System.out.printf(now() + "testObjectWithFinisherBlocking(%s) starting%n", url); HttpClient client = HttpClient.newBuilder().sslContext(sslContext).build(); HttpRequest request = HttpRequest.newBuilder(URI.create(url)) .POST(fromString("May the wind always be at your back.")).build(); @@ -352,6 +376,7 @@ @Test(dataProvider = "uris") void testObjectWithoutFinisherBlocking(String url) throws Exception { + System.out.printf(now() + "testObjectWithoutFinisherBlocking(%s) starting%n", url); HttpClient client = HttpClient.newBuilder().sslContext(sslContext).build(); HttpRequest request = HttpRequest.newBuilder(URI.create(url)) .POST(fromString("May the wind always be at your back.")).build(); @@ -370,6 +395,7 @@ @Test(dataProvider = "uris") void mappingFromByteArray(String url) throws Exception { + System.out.printf(now() + "mappingFromByteArray(%s) starting%n", url); HttpClient client = HttpClient.newBuilder().sslContext(sslContext).build(); HttpRequest request = HttpRequest.newBuilder(URI.create(url)) .POST(fromString("We're sucking diesel now!")).build(); @@ -384,6 +410,7 @@ @Test(dataProvider = "uris") void mappingFromInputStream(String url) throws Exception { + System.out.printf(now() + "mappingFromInputStream(%s) starting%n", url); HttpClient client = HttpClient.newBuilder().sslContext(sslContext).build(); HttpRequest request = HttpRequest.newBuilder(URI.create(url)) .POST(fromString("May the wind always be at your back.")).build();