# HG changeset patch # User chegar # Date 1520108495 0 # Node ID 6218673d7fa0e89d3e65bc5a2ef4ac352d62ec4c # Parent fc391230cf7b4427a6073c8bb7d6e241d2406882 http-client-branch: 100-Continue 100-Continue diff -r fc391230cf7b -r 6218673d7fa0 src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java --- a/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java Sat Mar 03 09:57:25 2018 +0000 +++ b/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java Sat Mar 03 20:21:35 2018 +0000 @@ -436,7 +436,7 @@ acc = AccessController.getContext(); // Clone the, possibly untrusted, HttpRequest - HttpRequestImpl requestImpl = new HttpRequestImpl(userRequest, proxySelector, acc); + HttpRequestImpl requestImpl = new HttpRequestImpl(userRequest, proxySelector); if (requestImpl.method().equals("CONNECT")) throw new IllegalArgumentException("Unsupported method CONNECT"); diff -r fc391230cf7b -r 6218673d7fa0 src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestImpl.java --- a/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestImpl.java Sat Mar 03 09:57:25 2018 +0000 +++ b/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestImpl.java Sat Mar 03 20:21:35 2018 +0000 @@ -92,13 +92,18 @@ /** * Creates an HttpRequestImpl from the given request. */ - public HttpRequestImpl(HttpRequest request, ProxySelector ps, AccessControlContext acc) { + public HttpRequestImpl(HttpRequest request, ProxySelector ps) { String method = request.method(); this.method = method == null ? "GET" : method; this.userHeaders = request.headers(); if (request instanceof HttpRequestImpl) { - this.systemHeaders = ((HttpRequestImpl) request).systemHeaders; + // all cases exception WebSocket should have a new system headers this.isWebSocket = ((HttpRequestImpl) request).isWebSocket; + if (isWebSocket) { + this.systemHeaders = ((HttpRequestImpl) request).systemHeaders; + } else { + this.systemHeaders = new HttpHeadersImpl(); + } } else { this.systemHeaders = new HttpHeadersImpl(); } diff -r fc391230cf7b -r 6218673d7fa0 test/jdk/java/net/httpclient/ExpectContinue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/net/httpclient/ExpectContinue.java Sat Mar 03 20:21:35 2018 +0000 @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary Basic test for Expect 100-Continue ( HTTP/1.1 only ) + * @modules java.net.http + * jdk.httpserver + * @library /lib/testlibrary + * @build jdk.testlibrary.SimpleSSLContext + * @run testng/othervm ExpectContinue + */ + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; +import com.sun.net.httpserver.HttpsConfigurator; +import com.sun.net.httpserver.HttpsServer; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpRequest.BodyPublishers; +import java.net.http.HttpResponse; +import java.net.http.HttpResponse.BodyHandlers; +import java.util.List; +import javax.net.ssl.SSLContext; +import jdk.testlibrary.SimpleSSLContext; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import static java.lang.System.out; +import static org.testng.Assert.assertEquals; + +public class ExpectContinue { + + SSLContext sslContext; + HttpServer httpTestServer; // HTTP/1.1 [ 2 servers ] + HttpsServer httpsTestServer; // HTTPS/1.1 + String httpURI; + String httpsURI; + + @DataProvider(name = "positive") + public Object[][] positive() { + return new Object[][] { + { httpURI, false, "Billy" }, + { httpURI, false, "Bob" }, + { httpURI, true, "Jimmy" }, + { httpsURI, true, "Jack" }, + }; + } + + @Test(dataProvider = "positive") + void test(String uriString, boolean expectedContinue, String data) + throws Exception + { + out.printf("test(%s, %s, %s): starting%n", uriString, expectedContinue, data); + HttpClient client = HttpClient.newBuilder() + .sslContext(sslContext) + .build(); + + URI uri = URI.create(uriString); + HttpRequest request = HttpRequest.newBuilder(uri) + .expectContinue(expectedContinue) + .POST(BodyPublishers.ofString(data)) + .build(); + + HttpResponse response = client.send(request, + BodyHandlers.ofString()); + System.out.println("First response: " + response); + assertEquals(response.statusCode(), 200); + assertEquals(response.body(), data); + + // again with the same request, to ensure no Expect header duplication + response = client.send(request, BodyHandlers.ofString()); + System.out.println("Second response: " + response); + assertEquals(response.statusCode(), 200); + assertEquals(response.body(), data); + } + + @Test(dataProvider = "positive") + void testAsync(String uriString, boolean expectedContinue, String data) { + out.printf("test(%s, %s, %s): starting%n", uriString, expectedContinue, data); + HttpClient client = HttpClient.newBuilder() + .sslContext(sslContext) + .build(); + + URI uri = URI.create(uriString); + HttpRequest request = HttpRequest.newBuilder(uri) + .expectContinue(expectedContinue) + .POST(BodyPublishers.ofString(data)) + .build(); + + HttpResponse response = client.sendAsync(request, + BodyHandlers.ofString()).join(); + System.out.println("First response: " + response); + assertEquals(response.statusCode(), 200); + assertEquals(response.body(), data); + + // again with the same request, to ensure no Expect header duplication + response = client.sendAsync(request, BodyHandlers.ofString()).join(); + System.out.println("Second response: " + response); + assertEquals(response.statusCode(), 200); + assertEquals(response.body(), data); + } + + // -- Infrastructure + + @BeforeTest + public void setup() throws Exception { + sslContext = new SimpleSSLContext().get(); + if (sslContext == null) + throw new AssertionError("Unexpected null sslContext"); + + InetSocketAddress sa = new InetSocketAddress(0); + httpTestServer = HttpServer.create(sa, 0); + httpTestServer.createContext("/http1/ec", new Http1ExpectContinueHandler()); + httpURI = "http://127.0.0.1:" + httpTestServer.getAddress().getPort() + "/http1/ec"; + + httpsTestServer = HttpsServer.create(sa, 0); + httpsTestServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); + httpsTestServer.createContext("/https1/ec", new Http1ExpectContinueHandler()); + httpsURI = "https://127.0.0.1:" + httpsTestServer.getAddress().getPort() + "/https1/ec"; + + httpTestServer.start(); + httpsTestServer.start(); + } + + @AfterTest + public void teardown() throws Exception { + httpTestServer.stop(0); + httpsTestServer.stop(0); + } + + static class Http1ExpectContinueHandler implements HttpHandler { + @Override + public void handle(HttpExchange t) throws IOException { + try (InputStream is = t.getRequestBody(); + OutputStream os = t.getResponseBody()) { + byte[] bytes = is.readAllBytes(); + + List expect = t.getRequestHeaders().get("Expect"); + if (expect != null && expect.size() != 1) { + System.out.println("Server: Expect: " + expect); + Throwable ex = new AssertionError("Expect: " + expect); + ex.printStackTrace(); + t.sendResponseHeaders(500, 0); + } else { + t.sendResponseHeaders(200, bytes.length); + os.write(bytes); + } + } + } + } +} diff -r fc391230cf7b -r 6218673d7fa0 test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/AuthenticationFilterTest.java --- a/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/AuthenticationFilterTest.java Sat Mar 03 09:57:25 2018 +0000 +++ b/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/AuthenticationFilterTest.java Sat Mar 03 20:21:35 2018 +0000 @@ -190,7 +190,7 @@ HttpRequestBuilderImpl reqBuilder = new HttpRequestBuilderImpl(reqURI); HttpRequestImpl origReq = new HttpRequestImpl(reqBuilder); - HttpRequestImpl req = new HttpRequestImpl(origReq, ps, AccessController.getContext()); + HttpRequestImpl req = new HttpRequestImpl(origReq, ps); MultiExchange multi = new MultiExchange(origReq, req, client, BodyHandlers.replacing(null), null, AccessController.getContext()); @@ -256,7 +256,7 @@ HttpRequestBuilderImpl reqBuilder2 = new HttpRequestBuilderImpl(reqURI2); HttpRequestImpl origReq2 = new HttpRequestImpl(reqBuilder2); - HttpRequestImpl req2 = new HttpRequestImpl(origReq2, ps, AccessController.getContext()); + HttpRequestImpl req2 = new HttpRequestImpl(origReq2, ps); MultiExchange multi2 = new MultiExchange(origReq2, req2, client, HttpResponse.BodyHandlers.replacing(null), null, AccessController.getContext()); @@ -288,7 +288,7 @@ HttpRequestBuilderImpl reqBuilder3 = new HttpRequestBuilderImpl(reqURI3); HttpRequestImpl origReq3 = new HttpRequestImpl(reqBuilder3); - HttpRequestImpl req3 = new HttpRequestImpl(origReq3, ps, AccessController.getContext()); + HttpRequestImpl req3 = new HttpRequestImpl(origReq3, ps); MultiExchange multi3 = new MultiExchange(origReq3, req3, client, HttpResponse.BodyHandlers.replacing(null), null, AccessController.getContext()); @@ -331,8 +331,7 @@ req.proxy().getPort(), "/", null, null); HttpRequestBuilderImpl reqBuilder4 = new HttpRequestBuilderImpl(reqURI4); HttpRequestImpl origReq4 = new HttpRequestImpl(reqBuilder4); - HttpRequestImpl req4 = new HttpRequestImpl(origReq4, fakeProxy, - AccessController.getContext()); + HttpRequestImpl req4 = new HttpRequestImpl(origReq4, fakeProxy); MultiExchange multi4 = new MultiExchange(origReq4, req4, client, HttpResponse.BodyHandlers.replacing(null), null, AccessController.getContext()); @@ -372,8 +371,7 @@ // because the request has no proxy. HttpRequestBuilderImpl reqBuilder5 = new HttpRequestBuilderImpl(reqURI); HttpRequestImpl origReq5 = new HttpRequestImpl(reqBuilder5); - HttpRequestImpl req5 = new HttpRequestImpl(origReq5, NO_PROXY, - AccessController.getContext()); + HttpRequestImpl req5 = new HttpRequestImpl(origReq5, NO_PROXY); MultiExchange multi5 = new MultiExchange(origReq5, req5, client, HttpResponse.BodyHandlers.replacing(null), null, AccessController.getContext()); @@ -424,8 +422,7 @@ // server auth and proxy auth HttpRequestBuilderImpl reqBuilder6 = new HttpRequestBuilderImpl(reqURI); HttpRequestImpl origReq6 = new HttpRequestImpl(reqBuilder6); - HttpRequestImpl req6 = new HttpRequestImpl(origReq6, ps, - AccessController.getContext()); + HttpRequestImpl req6 = new HttpRequestImpl(origReq6, ps); MultiExchange multi6 = new MultiExchange(origReq6, req6, client, HttpResponse.BodyHandlers.replacing(null), null, AccessController.getContext()); @@ -448,8 +445,7 @@ assertTrue(reqURI7.getPath().contains("../../")); HttpRequestBuilderImpl reqBuilder7 = new HttpRequestBuilderImpl(reqURI7); HttpRequestImpl origReq7 = new HttpRequestImpl(reqBuilder7); - HttpRequestImpl req7 = new HttpRequestImpl(origReq7, ps, - AccessController.getContext()); + HttpRequestImpl req7 = new HttpRequestImpl(origReq7, ps); MultiExchange multi7 = new MultiExchange(origReq7, req7, client, HttpResponse.BodyHandlers.replacing(null), null, AccessController.getContext());