1 /*
   2  * Copyright (c) 2003, 2011, 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 /* @test
  25  * @summary Unit test for java.net.CookieHandler
  26  * @bug 4696506 4942650
  27  * @author Yingxian Wang
  28  */
  29 
  30 import java.net.*;
  31 import java.util.*;
  32 import java.io.*;
  33 import javax.net.ssl.*;
  34 
  35 public class CookieHandlerTest {
  36     static Map<String,String> cookies;
  37     ServerSocket ss;
  38 
  39     /*
  40      * =============================================================
  41      * Set the various variables needed for the tests, then
  42      * specify what tests to run on each side.
  43      */
  44 
  45     /*
  46      * Should we run the client or server in a separate thread?
  47      * Both sides can throw exceptions, but do you have a preference
  48      * as to which side should be the main thread.
  49      */
  50     static boolean separateServerThread = true;
  51 
  52     /*
  53      * Where do we find the keystores?
  54      */
  55     static String pathToStores = "../../../../../../etc";
  56     static String keyStoreFile = "keystore";
  57     static String trustStoreFile = "truststore";
  58     static String passwd = "passphrase";
  59 
  60     /*
  61      * Is the server ready to serve?
  62      */
  63     volatile static boolean serverReady = false;
  64 
  65     /*
  66      * Turn on SSL debugging?
  67      */
  68     static boolean debug = false;
  69 
  70     /*
  71      * Define the server side of the test.
  72      *
  73      * If the server prematurely exits, serverReady will be set to true
  74      * to avoid infinite hangs.
  75      */
  76     void doServerSide() throws Exception {
  77         SSLServerSocketFactory sslssf =
  78             (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
  79         SSLServerSocket sslServerSocket =
  80             (SSLServerSocket) sslssf.createServerSocket(serverPort);
  81         serverPort = sslServerSocket.getLocalPort();
  82 
  83         /*
  84          * Signal Client, we're ready for his connect.
  85          */
  86         serverReady = true;
  87         SSLSocket sslSocket = null;
  88         try {
  89             sslSocket = (SSLSocket) sslServerSocket.accept();
  90 
  91             // check request contains "Cookie"
  92             InputStream is = sslSocket.getInputStream ();
  93             BufferedReader r = new BufferedReader(new InputStreamReader(is));
  94             boolean flag = false;
  95             String x;
  96             while ((x=r.readLine()) != null) {
  97                 if (x.length() ==0) {
  98                     break;
  99                 }
 100                 String header = "Cookie: ";
 101                 if (x.startsWith(header)) {
 102                     if (x.equals("Cookie: "+((String)cookies.get("Cookie")))) {
 103                         flag = true;
 104                     }
 105                 }
 106             }
 107             if (!flag) {
 108                 throw new RuntimeException("server should see cookie in request");
 109             }
 110 
 111             PrintStream out = new PrintStream(
 112                                  new BufferedOutputStream(
 113                                     sslSocket.getOutputStream() ));
 114 
 115             /* send the header */
 116             out.print("HTTP/1.1 200 OK\r\n");
 117             out.print("Set-Cookie2: "+((String)cookies.get("Set-Cookie2")+"\r\n"));
 118             out.print("Content-Type: text/html; charset=iso-8859-1\r\n");
 119             out.print("Connection: close\r\n");
 120             out.print("\r\n");
 121             out.print("<HTML>");
 122             out.print("<HEAD><TITLE>Testing cookie</TITLE></HEAD>");
 123             out.print("<BODY>OK.</BODY>");
 124             out.print("</HTML>");
 125             out.flush();
 126 
 127             sslSocket.close();
 128             sslServerSocket.close();
 129         } catch (Exception e) {
 130             e.printStackTrace();
 131         }
 132     }
 133 
 134     /*
 135      * Define the client side of the test.
 136      *
 137      * If the server prematurely exits, serverReady will be set to true
 138      * to avoid infinite hangs.
 139      */
 140     void doClientSide() throws Exception {
 141 
 142         /*
 143          * Wait for server to get started.
 144          */
 145         while (!serverReady) {
 146             Thread.sleep(50);
 147         }
 148         HttpsURLConnection http = null;
 149         /* establish http connection to server */
 150         String uri = "https://localhost:" + +serverPort ;
 151         URL url = new URL(uri);
 152         HttpsURLConnection.setDefaultHostnameVerifier(new NameVerifier());
 153         http = (HttpsURLConnection)url.openConnection();
 154 
 155         int respCode = http.getResponseCode();
 156         http.disconnect();
 157 
 158     }
 159 
 160     static class NameVerifier implements HostnameVerifier {
 161         public boolean verify(String hostname, SSLSession session) {
 162             return true;
 163         }
 164     }
 165 
 166     /*
 167      * =============================================================
 168      * The remainder is just support stuff
 169      */
 170 
 171     // use any free port by default
 172     volatile int serverPort = 0;
 173 
 174     volatile Exception serverException = null;
 175     volatile Exception clientException = null;
 176 
 177     public static void main(String args[]) throws Exception {
 178         String keyFilename =
 179             System.getProperty("test.src", "./") + "/" + pathToStores +
 180                 "/" + keyStoreFile;
 181         String trustFilename =
 182             System.getProperty("test.src", "./") + "/" + pathToStores +
 183                 "/" + trustStoreFile;
 184 
 185         System.setProperty("javax.net.ssl.keyStore", keyFilename);
 186         System.setProperty("javax.net.ssl.keyStorePassword", passwd);
 187         System.setProperty("javax.net.ssl.trustStore", trustFilename);
 188         System.setProperty("javax.net.ssl.trustStorePassword", passwd);
 189 
 190         if (debug)
 191             System.setProperty("javax.net.debug", "all");
 192 
 193         /*
 194          * Start the tests.
 195          */
 196         cookies = new HashMap<String, String>();
 197         cookies.put("Cookie",
 198               "$Version=\"1\"; Customer=\"WILE_E_COYOTE\"; $Path=\"/acme\"");
 199         cookies.put("Set-Cookie2",
 200           "$Version=\"1\"; Part_Number=\"Riding_Rocket_0023\"; " +
 201           "$Path=\"/acme/ammo\"; Part_Number=\"Rocket_Launcher_0001\"; "+
 202           "$Path=\"/acme\"");
 203         CookieHandler.setDefault(new MyCookieHandler());
 204         new CookieHandlerTest();
 205     }
 206 
 207     Thread clientThread = null;
 208     Thread serverThread = null;
 209     /*
 210      * Primary constructor, used to drive remainder of the test.
 211      *
 212      * Fork off the other side, then do your work.
 213      */
 214     CookieHandlerTest() throws Exception {
 215         if (separateServerThread) {
 216             startServer(true);
 217             startClient(false);
 218         } else {
 219             startClient(true);
 220             startServer(false);
 221         }
 222 
 223         /*
 224          * Wait for other side to close down.
 225          */
 226         if (separateServerThread) {
 227             serverThread.join();
 228         } else {
 229             clientThread.join();
 230         }
 231 
 232         /*
 233          * When we get here, the test is pretty much over.
 234          *
 235          * If the main thread excepted, that propagates back
 236          * immediately.  If the other thread threw an exception, we
 237          * should report back.
 238          */
 239         if (serverException != null)
 240             throw serverException;
 241         if (clientException != null)
 242             throw clientException;
 243 
 244         if (!getCalled || !putCalled) {
 245             throw new RuntimeException ("Either get or put method is not called");
 246         }
 247     }
 248 
 249     void startServer(boolean newThread) throws Exception {
 250         if (newThread) {
 251             serverThread = new Thread() {
 252                 public void run() {
 253                     try {
 254                         doServerSide();
 255                     } catch (Exception e) {
 256                         /*
 257                          * Our server thread just died.
 258                          *
 259                          * Release the client, if not active already...
 260                          */
 261                         System.err.println("Server died...");
 262                         serverReady = true;
 263                         serverException = e;
 264                     }
 265                 }
 266             };
 267             serverThread.start();
 268         } else {
 269             doServerSide();
 270         }
 271     }
 272 
 273     void startClient(boolean newThread) throws Exception {
 274         if (newThread) {
 275             clientThread = new Thread() {
 276                 public void run() {
 277                     try {
 278                         doClientSide();
 279                     } catch (Exception e) {
 280                         /*
 281                          * Our client thread just died.
 282                          */
 283                         System.err.println("Client died...");
 284                         clientException = e;
 285                     }
 286                 }
 287             };
 288             clientThread.start();
 289         } else {
 290             doClientSide();
 291         }
 292     }
 293 
 294     static boolean getCalled = false, putCalled = false;
 295 
 296     static class MyCookieHandler extends CookieHandler {
 297         public Map<String,List<String>>
 298             get(URI uri, Map<String,List<String>> requestHeaders)
 299             throws IOException {
 300             getCalled = true;
 301             // returns cookies[0]
 302             // they will be include in request
 303             Map<String,List<String>> map = new HashMap<>();
 304             List<String> l = new ArrayList<>();
 305             l.add(cookies.get("Cookie"));
 306             map.put("Cookie",l);
 307             return Collections.unmodifiableMap(map);
 308         }
 309 
 310         public void
 311             put(URI uri, Map<String,List<String>> responseHeaders)
 312             throws IOException {
 313             putCalled = true;
 314             // check response has cookies[1]
 315             List<String> l = responseHeaders.get("Set-Cookie2");
 316             String value = l.get(0);
 317             if (!value.equals((String)cookies.get("Set-Cookie2"))) {
 318                 throw new RuntimeException("cookie should be available for handle to put into cache");
 319                }
 320         }
 321     }
 322 
 323 }