test/jdk/sun/net/www/protocol/https/NewImpl/ComHTTPSConnection.java
branchstuefe-statistical-history
changeset 57244 a535e674d50d
parent 57221 9653470b7294
parent 54010 17fb726e6d8e
child 57245 0ed37e453a39
equal deleted inserted replaced
57221:9653470b7294 57244:a535e674d50d
     1 /*
       
     2  * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 
       
    24 /*
       
    25  * @test
       
    26  * @bug 4474255
       
    27  * @summary Can no longer obtain a com.sun.net.ssl.HttpsURLConnection
       
    28  * @modules java.base/com.sun.net.ssl
       
    29  *          java.base/com.sun.net.ssl.internal.www.protocol.https
       
    30  * @run main/othervm ComHTTPSConnection
       
    31  *
       
    32  *     SunJSSE does not support dynamic system properties, no way to re-use
       
    33  *     system properties in samevm/agentvm mode.
       
    34  * @author Brad Wetmore
       
    35  */
       
    36 
       
    37 import java.io.*;
       
    38 import java.net.*;
       
    39 import java.security.cert.Certificate;
       
    40 import javax.net.ssl.*;
       
    41 import com.sun.net.ssl.HostnameVerifier;
       
    42 import com.sun.net.ssl.HttpsURLConnection;
       
    43 
       
    44 /**
       
    45  * See if we can obtain a com.sun.net.ssl.HttpsURLConnection,
       
    46  * and then play with it a bit.
       
    47  */
       
    48 public class ComHTTPSConnection {
       
    49 
       
    50     /*
       
    51      * =============================================================
       
    52      * Set the various variables needed for the tests, then
       
    53      * specify what tests to run on each side.
       
    54      */
       
    55 
       
    56     /*
       
    57      * Should we run the client or server in a separate thread?
       
    58      * Both sides can throw exceptions, but do you have a preference
       
    59      * as to which side should be the main thread.
       
    60      */
       
    61     static boolean separateServerThread = true;
       
    62 
       
    63     /*
       
    64      * Where do we find the keystores?
       
    65      */
       
    66     static String pathToStores = "../../../../../../javax/net/ssl/etc";
       
    67     static String keyStoreFile = "keystore";
       
    68     static String trustStoreFile = "truststore";
       
    69     static String passwd = "passphrase";
       
    70 
       
    71     /*
       
    72      * Is the server ready to serve?
       
    73      */
       
    74     volatile static boolean serverReady = false;
       
    75 
       
    76     /*
       
    77      * Turn on SSL debugging?
       
    78      */
       
    79     static boolean debug = false;
       
    80 
       
    81     /*
       
    82      * If the client or server is doing some kind of object creation
       
    83      * that the other side depends on, and that thread prematurely
       
    84      * exits, you may experience a hang.  The test harness will
       
    85      * terminate all hung threads after its timeout has expired,
       
    86      * currently 3 minutes by default, but you might try to be
       
    87      * smart about it....
       
    88      */
       
    89 
       
    90     /**
       
    91      * Returns the path to the file obtained from
       
    92      * parsing the HTML header.
       
    93      */
       
    94     private static String getPath(DataInputStream in)
       
    95         throws IOException
       
    96     {
       
    97         String line = in.readLine();
       
    98         String path = "";
       
    99         // extract class from GET line
       
   100         if (line.startsWith("GET /")) {
       
   101             line = line.substring(5, line.length()-1).trim();
       
   102             int index = line.indexOf(' ');
       
   103             if (index != -1) {
       
   104                 path = line.substring(0, index);
       
   105             }
       
   106         }
       
   107 
       
   108         // eat the rest of header
       
   109         do {
       
   110             line = in.readLine();
       
   111         } while ((line.length() != 0) &&
       
   112                  (line.charAt(0) != '\r') && (line.charAt(0) != '\n'));
       
   113 
       
   114         if (path.length() != 0) {
       
   115             return path;
       
   116         } else {
       
   117             throw new IOException("Malformed Header");
       
   118         }
       
   119     }
       
   120 
       
   121     /**
       
   122      * Returns an array of bytes containing the bytes for
       
   123      * the file represented by the argument <b>path</b>.
       
   124      *
       
   125      * In our case, we just pretend to send something back.
       
   126      *
       
   127      * @return the bytes for the file
       
   128      * @exception FileNotFoundException if the file corresponding
       
   129      * to <b>path</b> could not be loaded.
       
   130      */
       
   131     private byte[] getBytes(String path)
       
   132         throws IOException
       
   133     {
       
   134         return "Hello world, I am here".getBytes();
       
   135     }
       
   136 
       
   137     /*
       
   138      * Define the server side of the test.
       
   139      *
       
   140      * If the server prematurely exits, serverReady will be set to true
       
   141      * to avoid infinite hangs.
       
   142      */
       
   143     void doServerSide() throws Exception {
       
   144 
       
   145         SSLServerSocketFactory sslssf =
       
   146           (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
       
   147         SSLServerSocket sslServerSocket =
       
   148             (SSLServerSocket) sslssf.createServerSocket(serverPort);
       
   149         serverPort = sslServerSocket.getLocalPort();
       
   150 
       
   151         /*
       
   152          * Signal Client, we're ready for his connect.
       
   153          */
       
   154         serverReady = true;
       
   155 
       
   156         SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
       
   157         DataOutputStream out =
       
   158                 new DataOutputStream(sslSocket.getOutputStream());
       
   159 
       
   160         try {
       
   161              // get path to class file from header
       
   162              DataInputStream in =
       
   163                         new DataInputStream(sslSocket.getInputStream());
       
   164              String path = getPath(in);
       
   165              // retrieve bytecodes
       
   166              byte[] bytecodes = getBytes(path);
       
   167              // send bytecodes in response (assumes HTTP/1.0 or later)
       
   168              try {
       
   169                 out.writeBytes("HTTP/1.0 200 OK\r\n");
       
   170                 out.writeBytes("Content-Length: " + bytecodes.length + "\r\n");
       
   171                 out.writeBytes("Content-Type: text/html\r\n\r\n");
       
   172                 out.write(bytecodes);
       
   173                 out.flush();
       
   174              } catch (IOException ie) {
       
   175                 ie.printStackTrace();
       
   176                 return;
       
   177              }
       
   178 
       
   179         } catch (Exception e) {
       
   180              e.printStackTrace();
       
   181              // write out error response
       
   182              out.writeBytes("HTTP/1.0 400 " + e.getMessage() + "\r\n");
       
   183              out.writeBytes("Content-Type: text/html\r\n\r\n");
       
   184              out.flush();
       
   185         } finally {
       
   186              // close the socket
       
   187              System.out.println("Server closing socket");
       
   188              sslSocket.close();
       
   189              serverReady = false;
       
   190         }
       
   191     }
       
   192 
       
   193     private static class ComSunHTTPSHandlerFactory implements URLStreamHandlerFactory {
       
   194         private static String SUPPORTED_PROTOCOL = "https";
       
   195 
       
   196         public URLStreamHandler createURLStreamHandler(String protocol) {
       
   197             if (!protocol.equalsIgnoreCase(SUPPORTED_PROTOCOL))
       
   198                 return null;
       
   199 
       
   200             return new com.sun.net.ssl.internal.www.protocol.https.Handler();
       
   201         }
       
   202     }
       
   203 
       
   204     /*
       
   205      * Define the client side of the test.
       
   206      *
       
   207      * If the server prematurely exits, serverReady will be set to true
       
   208      * to avoid infinite hangs.
       
   209      */
       
   210     void doClientSide() throws Exception {
       
   211         /*
       
   212          * Wait for server to get started.
       
   213          */
       
   214         while (!serverReady) {
       
   215             Thread.sleep(50);
       
   216         }
       
   217 
       
   218         HostnameVerifier reservedHV =
       
   219             HttpsURLConnection.getDefaultHostnameVerifier();
       
   220         try {
       
   221             URL.setURLStreamHandlerFactory(new ComSunHTTPSHandlerFactory());
       
   222             HttpsURLConnection.setDefaultHostnameVerifier(new NameVerifier());
       
   223 
       
   224             URL url = new URL("https://" + "localhost:" + serverPort +
       
   225                                     "/etc/hosts");
       
   226             URLConnection urlc = url.openConnection();
       
   227 
       
   228             if (!(urlc instanceof com.sun.net.ssl.HttpsURLConnection)) {
       
   229                 throw new Exception(
       
   230                     "URLConnection ! instanceof " +
       
   231                     "com.sun.net.ssl.HttpsURLConnection");
       
   232             }
       
   233 
       
   234             BufferedReader in = null;
       
   235             try {
       
   236                 in = new BufferedReader(new InputStreamReader(
       
   237                                    urlc.getInputStream()));
       
   238                 String inputLine;
       
   239                 System.out.print("Client reading... ");
       
   240                 while ((inputLine = in.readLine()) != null)
       
   241                     System.out.println(inputLine);
       
   242 
       
   243                 System.out.println("Cipher Suite: " +
       
   244                     ((HttpsURLConnection)urlc).getCipherSuite());
       
   245                 Certificate[] certs =
       
   246                     ((HttpsURLConnection)urlc).getServerCertificates();
       
   247                 for (int i = 0; i < certs.length; i++) {
       
   248                     System.out.println(certs[0]);
       
   249                 }
       
   250 
       
   251                 in.close();
       
   252             } catch (SSLException e) {
       
   253                 if (in != null)
       
   254                     in.close();
       
   255                 throw e;
       
   256             }
       
   257             System.out.println("Client reports:  SUCCESS");
       
   258         } finally {
       
   259             HttpsURLConnection.setDefaultHostnameVerifier(reservedHV);
       
   260         }
       
   261     }
       
   262 
       
   263     static class NameVerifier implements HostnameVerifier {
       
   264         public boolean verify(String urlHostname,
       
   265                         String certHostname) {
       
   266             System.out.println(
       
   267                 "CertificateHostnameVerifier: " + urlHostname + " == "
       
   268                 + certHostname + " returning true");
       
   269             return true;
       
   270         }
       
   271     }
       
   272 
       
   273     /*
       
   274      * =============================================================
       
   275      * The remainder is just support stuff
       
   276      */
       
   277 
       
   278     // use any free port by default
       
   279     volatile int serverPort = 0;
       
   280 
       
   281     volatile Exception serverException = null;
       
   282     volatile Exception clientException = null;
       
   283 
       
   284     public static void main(String[] args) throws Exception {
       
   285         String keyFilename =
       
   286             System.getProperty("test.src", "./") + "/" + pathToStores +
       
   287                 "/" + keyStoreFile;
       
   288         String trustFilename =
       
   289             System.getProperty("test.src", "./") + "/" + pathToStores +
       
   290                 "/" + trustStoreFile;
       
   291 
       
   292         System.setProperty("javax.net.ssl.keyStore", keyFilename);
       
   293         System.setProperty("javax.net.ssl.keyStorePassword", passwd);
       
   294         System.setProperty("javax.net.ssl.trustStore", trustFilename);
       
   295         System.setProperty("javax.net.ssl.trustStorePassword", passwd);
       
   296 
       
   297         if (debug)
       
   298             System.setProperty("javax.net.debug", "all");
       
   299 
       
   300         /*
       
   301          * Start the tests.
       
   302          */
       
   303         new ComHTTPSConnection();
       
   304     }
       
   305 
       
   306     Thread clientThread = null;
       
   307     Thread serverThread = null;
       
   308 
       
   309     /*
       
   310      * Primary constructor, used to drive remainder of the test.
       
   311      *
       
   312      * Fork off the other side, then do your work.
       
   313      */
       
   314     ComHTTPSConnection() throws Exception {
       
   315         if (separateServerThread) {
       
   316             startServer(true);
       
   317             startClient(false);
       
   318         } else {
       
   319             startClient(true);
       
   320             startServer(false);
       
   321         }
       
   322 
       
   323         /*
       
   324          * Wait for other side to close down.
       
   325          */
       
   326         if (separateServerThread) {
       
   327             serverThread.join();
       
   328         } else {
       
   329             clientThread.join();
       
   330         }
       
   331 
       
   332         /*
       
   333          * When we get here, the test is pretty much over.
       
   334          *
       
   335          * If the main thread excepted, that propagates back
       
   336          * immediately.  If the other thread threw an exception, we
       
   337          * should report back.
       
   338          */
       
   339         if (serverException != null) {
       
   340             System.out.print("Server Exception:");
       
   341             throw serverException;
       
   342         }
       
   343         if (clientException != null) {
       
   344             System.out.print("Client Exception:");
       
   345             throw clientException;
       
   346         }
       
   347     }
       
   348 
       
   349     void startServer(boolean newThread) throws Exception {
       
   350         if (newThread) {
       
   351             serverThread = new Thread() {
       
   352                 public void run() {
       
   353                     try {
       
   354                         doServerSide();
       
   355                     } catch (Exception e) {
       
   356                         /*
       
   357                          * Our server thread just died.
       
   358                          *
       
   359                          * Release the client, if not active already...
       
   360                          */
       
   361                         System.err.println("Server died...");
       
   362                         serverReady = true;
       
   363                         serverException = e;
       
   364                     }
       
   365                 }
       
   366             };
       
   367             serverThread.start();
       
   368         } else {
       
   369             doServerSide();
       
   370         }
       
   371     }
       
   372 
       
   373     void startClient(boolean newThread) throws Exception {
       
   374         if (newThread) {
       
   375             clientThread = new Thread() {
       
   376                 public void run() {
       
   377                     try {
       
   378                         doClientSide();
       
   379                     } catch (Exception e) {
       
   380                         /*
       
   381                          * Our client thread just died.
       
   382                          */
       
   383                         System.err.println("Client died...");
       
   384                         clientException = e;
       
   385                     }
       
   386                 }
       
   387             };
       
   388             clientThread.start();
       
   389         } else {
       
   390             doClientSide();
       
   391         }
       
   392     }
       
   393 }