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 }