http-client-branch: HTTP/2 200 response headers should not be appended to the 100-continue response headers
--- 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<String> 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
--- 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;
--- 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<T> responseSubscriber;
final HttpRequest.BodyPublisher requestPublisher;
@@ -232,7 +232,7 @@
{
try {
Log.logTrace("Reading body on stream {0}", streamid);
- BodySubscriber<T> bodySubscriber = handler.apply(responseCode, responseHeaders);
+ BodySubscriber<T> bodySubscriber = handler.apply(responseCode, response.headers);
CompletableFuture<T> 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
--- 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();
+ }
}
--- 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);
--- 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();