diff -r 4ebc2e2fb97c -r 71c04702a3d5 test/jdk/java/net/httpclient/http2/TLSConnection.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/net/httpclient/http2/TLSConnection.java Tue Sep 12 19:03:39 2017 +0200 @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2016, 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. + */ + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URI; +import java.net.URISyntaxException; +import jdk.incubator.http.HttpClient; +import jdk.incubator.http.HttpRequest; +import jdk.incubator.http.HttpResponse; +import javax.net.ssl.SSLParameters; +import javax.net.ssl.SSLSession; +import static jdk.incubator.http.HttpRequest.BodyProcessor.fromString; +import static jdk.incubator.http.HttpResponse.BodyHandler.asString; + +/* + * @test + * @bug 8150769 8157107 + * @key intermittent + * @library server + * @summary Checks that SSL parameters can be set for HTTP/2 connection + * @modules jdk.incubator.httpclient/jdk.incubator.http.internal.common + * jdk.incubator.httpclient/jdk.incubator.http.internal.frame + * jdk.incubator.httpclient/jdk.incubator.http.internal.hpack + * @run main/othervm TLSConnection + */ +public class TLSConnection { + + private static final String KEYSTORE = System.getProperty("test.src") + + File.separator + "keystore.p12"; + private static final String PASSWORD = "password"; + + public static void main(String[] args) throws Exception { + + // enable all logging + System.setProperty("jdk.httpclient.HttpClient.log", "all,frames:all"); + + // initialize JSSE + System.setProperty("javax.net.ssl.keyStore", KEYSTORE); + System.setProperty("javax.net.ssl.keyStorePassword", PASSWORD); + System.setProperty("javax.net.ssl.trustStore", KEYSTORE); + System.setProperty("javax.net.ssl.trustStorePassword", PASSWORD); + + Handler handler = new Handler(); + + try (Http2TestServer server = new Http2TestServer("127.0.0.1", true, 0)) { + server.addHandler(handler, "/"); + server.start(); + + int port = server.getAddress().getPort(); + String uriString = "https://127.0.0.1:" + Integer.toString(port); + + // run test cases + boolean success = true; + + SSLParameters parameters = null; + success &= expectFailure( + "Test #1: SSL parameters is null, expect NPE", + () -> connect(uriString, parameters), + NullPointerException.class); + + success &= expectSuccess( + "Test #2: default SSL parameters, " + + "expect successful connection", + () -> connect(uriString, new SSLParameters())); + success &= checkProtocol(handler.getSSLSession(), "TLSv1.2"); + + // set SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA cipher suite + // which has less priority in default cipher suite list + success &= expectSuccess( + "Test #3: SSL parameters with " + + "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA cipher suite, " + + "expect successful connection", + () -> connect(uriString, new SSLParameters( + new String[] { "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA" }))); + success &= checkProtocol(handler.getSSLSession(), "TLSv1.2"); + success &= checkCipherSuite(handler.getSSLSession(), + "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA"); + + // set TLS_RSA_WITH_AES_128_CBC_SHA cipher suite + // which has less priority in default cipher suite list + // also set TLSv11 protocol + success &= expectSuccess( + "Test #4: SSL parameters with " + + "TLS_RSA_WITH_AES_128_CBC_SHA cipher suite," + + " expect successful connection", + () -> connect(uriString, new SSLParameters( + new String[] { "TLS_RSA_WITH_AES_128_CBC_SHA" }, + new String[] { "TLSv1.1" }))); + success &= checkProtocol(handler.getSSLSession(), "TLSv1.1"); + success &= checkCipherSuite(handler.getSSLSession(), + "TLS_RSA_WITH_AES_128_CBC_SHA"); + + if (success) { + System.out.println("Test passed"); + } else { + throw new RuntimeException("At least one test case failed"); + } + } + } + + private static interface Test { + + public void run() throws Exception; + } + + private static class Handler implements Http2Handler { + + private static final byte[] BODY = "Test response".getBytes(); + + private volatile SSLSession sslSession; + + @Override + public void handle(Http2TestExchange t) throws IOException { + System.out.println("Handler: received request to " + + t.getRequestURI()); + + try (InputStream is = t.getRequestBody()) { + byte[] body = is.readAllBytes(); + System.out.println("Handler: read " + body.length + + " bytes of body: "); + System.out.println(new String(body)); + } + + try (OutputStream os = t.getResponseBody()) { + t.sendResponseHeaders(200, BODY.length); + os.write(BODY); + } + + sslSession = t.getSSLSession(); + } + + SSLSession getSSLSession() { + return sslSession; + } + } + + private static void connect(String uriString, SSLParameters sslParameters) + throws URISyntaxException, IOException, InterruptedException + { + HttpClient client = HttpClient.newBuilder() + .sslParameters(sslParameters) + .version(HttpClient.Version.HTTP_2) + .build(); + HttpRequest request = HttpRequest.newBuilder(new URI(uriString)) + .POST(fromString("body")) + .build(); + String body = client.send(request, asString()).body(); + + System.out.println("Response: " + body); + } + + private static boolean checkProtocol(SSLSession session, String protocol) { + if (session == null) { + System.out.println("Check protocol: no session provided"); + return false; + } + + System.out.println("Check protocol: negotiated protocol: " + + session.getProtocol()); + System.out.println("Check protocol: expected protocol: " + + protocol); + if (!protocol.equals(session.getProtocol())) { + System.out.println("Check protocol: unexpected negotiated protocol"); + return false; + } + + return true; + } + + private static boolean checkCipherSuite(SSLSession session, String ciphersuite) { + if (session == null) { + System.out.println("Check protocol: no session provided"); + return false; + } + + System.out.println("Check protocol: negotiated ciphersuite: " + + session.getCipherSuite()); + System.out.println("Check protocol: expected ciphersuite: " + + ciphersuite); + if (!ciphersuite.equals(session.getCipherSuite())) { + System.out.println("Check protocol: unexpected negotiated ciphersuite"); + return false; + } + + return true; + } + + private static boolean expectSuccess(String message, Test test) { + System.out.println(message); + try { + test.run(); + System.out.println("Passed"); + return true; + } catch (Exception e) { + System.out.println("Failed: unexpected exception:"); + e.printStackTrace(System.out); + return false; + } + } + + private static boolean expectFailure(String message, Test test, + Class expectedException) { + + System.out.println(message); + try { + test.run(); + System.out.println("Failed: unexpected successful connection"); + return false; + } catch (Exception e) { + System.out.println("Got an exception:"); + e.printStackTrace(System.out); + if (expectedException != null + && !expectedException.isAssignableFrom(e.getClass())) { + System.out.printf("Failed: expected %s, but got %s%n", + expectedException.getName(), + e.getClass().getName()); + return false; + } + System.out.println("Passed: expected exception"); + return true; + } + } + +}