Path: blob/master/test/jdk/sun/net/www/protocol/https/NewImpl/JavaxHTTPSConnection.java
41161 views
/*1* Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 447425526* @summary Can no longer obtain a com.sun.net.ssl.HttpsURLConnection27* @library /test/lib28* @run main/othervm JavaxHTTPSConnection29* @run main/othervm -Djava.net.preferIPv6Addresses=true JavaxHTTPSConnection30*31* SunJSSE does not support dynamic system properties, no way to re-use32* system properties in samevm/agentvm mode.33* @author Brad Wetmore34*/3536import java.io.*;37import java.net.*;38import java.security.cert.*;39import javax.net.ssl.*;40import jdk.test.lib.net.URIBuilder;4142/**43* See if we can obtain a javax.net.ssl.HttpsURLConnection,44* and then play with it a bit.45*/46public class JavaxHTTPSConnection {4748/*49* =============================================================50* Set the various variables needed for the tests, then51* specify what tests to run on each side.52*/5354/*55* Should we run the client or server in a separate thread?56* Both sides can throw exceptions, but do you have a preference57* as to which side should be the main thread.58*/59static boolean separateServerThread = true;6061/*62* Where do we find the keystores?63*/64static String pathToStores = "../../../../../../javax/net/ssl/etc";65static String keyStoreFile = "keystore";66static String trustStoreFile = "truststore";67static String passwd = "passphrase";6869/*70* Is the server ready to serve?71*/72volatile static boolean serverReady = false;7374/*75* Turn on SSL debugging?76*/77static boolean debug = false;7879/*80* If the client or server is doing some kind of object creation81* that the other side depends on, and that thread prematurely82* exits, you may experience a hang. The test harness will83* terminate all hung threads after its timeout has expired,84* currently 3 minutes by default, but you might try to be85* smart about it....86*/8788/**89* Returns the path to the file obtained from90* parsing the HTML header.91*/92private static String getPath(DataInputStream in)93throws IOException94{95String line = in.readLine();96String path = "";97// extract class from GET line98if (line.startsWith("GET /")) {99line = line.substring(5, line.length()-1).trim();100int index = line.indexOf(' ');101if (index != -1) {102path = line.substring(0, index);103}104}105106// eat the rest of header107do {108line = in.readLine();109} while ((line.length() != 0) &&110(line.charAt(0) != '\r') && (line.charAt(0) != '\n'));111112if (path.length() != 0) {113return path;114} else {115throw new IOException("Malformed Header");116}117}118119/**120* Returns an array of bytes containing the bytes for121* the file represented by the argument <b>path</b>.122*123* In our case, we just pretend to send something back.124*125* @return the bytes for the file126* @exception FileNotFoundException if the file corresponding127* to <b>path</b> could not be loaded.128*/129private byte[] getBytes(String path)130throws IOException131{132return "Hello world, I am here".getBytes();133}134135/*136* Define the server side of the test.137*138* If the server prematurely exits, serverReady will be set to true139* to avoid infinite hangs.140*/141void doServerSide() throws Exception {142143InetAddress loopback = InetAddress.getLoopbackAddress();144InetSocketAddress serverAddress = new InetSocketAddress(loopback, serverPort);145SSLServerSocketFactory sslssf =146(SSLServerSocketFactory) SSLServerSocketFactory.getDefault();147SSLServerSocket sslServerSocket =148(SSLServerSocket) sslssf.createServerSocket();149sslServerSocket.bind(serverAddress);150serverPort = sslServerSocket.getLocalPort();151152/*153* Signal Client, we're ready for his connect.154*/155serverReady = true;156157SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();158DataOutputStream out =159new DataOutputStream(sslSocket.getOutputStream());160161try {162// get path to class file from header163DataInputStream in =164new DataInputStream(sslSocket.getInputStream());165String path = getPath(in);166// retrieve bytecodes167byte[] bytecodes = getBytes(path);168// send bytecodes in response (assumes HTTP/1.0 or later)169try {170out.writeBytes("HTTP/1.0 200 OK\r\n");171out.writeBytes("Content-Length: " + bytecodes.length + "\r\n");172out.writeBytes("Content-Type: text/html\r\n\r\n");173out.write(bytecodes);174out.flush();175} catch (IOException ie) {176ie.printStackTrace();177return;178}179180} catch (Exception e) {181e.printStackTrace();182// write out error response183out.writeBytes("HTTP/1.0 400 " + e.getMessage() + "\r\n");184out.writeBytes("Content-Type: text/html\r\n\r\n");185out.flush();186} finally {187// close the socket188System.out.println("Server closing socket");189sslSocket.close();190serverReady = false;191}192}193194/*195* Define the client side of the test.196*197* If the server prematurely exits, serverReady will be set to true198* to avoid infinite hangs.199*/200void doClientSide() throws Exception {201HostnameVerifier reservedHV =202HttpsURLConnection.getDefaultHostnameVerifier();203try {204/*205* Wait for server to get started.206*/207while (!serverReady) {208Thread.sleep(50);209}210211HttpsURLConnection.setDefaultHostnameVerifier(new NameVerifier());212URL url = URIBuilder.newBuilder()213.scheme("https")214.loopback()215.port(serverPort)216.path("/etc/hosts")217.toURL();218System.out.println("Client opening: " + url);219URLConnection urlc = url.openConnection(Proxy.NO_PROXY);220221if (!(urlc instanceof javax.net.ssl.HttpsURLConnection)) {222throw new Exception("URLConnection ! instanceof " +223"javax.net.ssl.HttpsURLConnection");224}225226BufferedReader in = null;227try {228in = new BufferedReader(new InputStreamReader(229urlc.getInputStream()));230String inputLine;231System.out.print("Client reading... ");232while ((inputLine = in.readLine()) != null)233System.out.println(inputLine);234235System.out.println("Cipher Suite: " +236((HttpsURLConnection)urlc).getCipherSuite());237Certificate[] certs =238((HttpsURLConnection)urlc).getServerCertificates();239for (int i = 0; i < certs.length; i++) {240System.out.println(certs[0]);241}242243in.close();244} catch (SSLException e) {245if (in != null)246in.close();247throw e;248}249System.out.println("Client reports: SUCCESS");250} finally {251HttpsURLConnection.setDefaultHostnameVerifier(reservedHV);252}253}254255static class NameVerifier implements HostnameVerifier {256public boolean verify(String hostname, SSLSession session) {257System.out.println(258"HostnameVerifier: returning true");259return true;260}261}262263/*264* =============================================================265* The remainder is just support stuff266*/267268// use any free port by default269volatile int serverPort = 0;270271volatile Exception serverException = null;272volatile Exception clientException = null;273274public static void main(String[] args) throws Exception {275String keyFilename =276System.getProperty("test.src", "./") + "/" + pathToStores +277"/" + keyStoreFile;278String trustFilename =279System.getProperty("test.src", "./") + "/" + pathToStores +280"/" + trustStoreFile;281282System.setProperty("javax.net.ssl.keyStore", keyFilename);283System.setProperty("javax.net.ssl.keyStorePassword", passwd);284System.setProperty("javax.net.ssl.trustStore", trustFilename);285System.setProperty("javax.net.ssl.trustStorePassword", passwd);286287if (debug)288System.setProperty("javax.net.debug", "all");289290/*291* Start the tests.292*/293new JavaxHTTPSConnection();294}295296Thread clientThread = null;297Thread serverThread = null;298299/*300* Primary constructor, used to drive remainder of the test.301*302* Fork off the other side, then do your work.303*/304JavaxHTTPSConnection() throws Exception {305if (separateServerThread) {306startServer(true);307startClient(false);308} else {309startClient(true);310startServer(false);311}312313/*314* Wait for other side to close down.315*/316if (separateServerThread) {317serverThread.join();318} else {319clientThread.join();320}321322/*323* When we get here, the test is pretty much over.324*325* If the main thread excepted, that propagates back326* immediately. If the other thread threw an exception, we327* should report back.328*/329if (serverException != null) {330System.out.print("Server Exception:");331throw serverException;332}333if (clientException != null) {334System.out.print("Client Exception:");335throw clientException;336}337}338339void startServer(boolean newThread) throws Exception {340if (newThread) {341serverThread = new Thread() {342public void run() {343try {344doServerSide();345} catch (Exception e) {346/*347* Our server thread just died.348*349* Release the client, if not active already...350*/351System.err.println("Server died...");352serverReady = true;353serverException = e;354}355}356};357serverThread.start();358} else {359doServerSide();360}361}362363void startClient(boolean newThread) throws Exception {364if (newThread) {365clientThread = new Thread() {366public void run() {367try {368doClientSide();369} catch (Exception e) {370/*371* Our client thread just died.372*/373System.err.println("Client died...");374clientException = e;375}376}377};378clientThread.start();379} else {380doClientSide();381}382}383}384385386