1/* 2 * Copyright (c) 2005, 2013, 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 * @summary Unit test for java.net.CookieManager 27 * @bug 6244040 7150552 7051862 28 * @modules jdk.httpserver 29 * @run main/othervm -ea CookieManagerTest 30 * @author Edward Wang 31 */ 32 33import com.sun.net.httpserver.*; 34import java.io.IOException; 35import java.net.*; 36import static java.net.Proxy.NO_PROXY; 37 38public class CookieManagerTest { 39 40 static CookieTransactionHandler httpTrans; 41 static HttpServer server; 42 43 static final String hostAddress = getAddr(); 44 45 /** Returns an IP literal suitable for use by the test. */ 46 static String getAddr() { 47 try { 48 InetAddress lh = InetAddress.getLocalHost(); 49 System.out.println("Trying: " + lh); 50 if (lh.isReachable(5_000)) { 51 System.out.println("Using: " + lh); 52 return lh.getHostAddress(); 53 } 54 } catch (IOException x) { 55 System.out.println("Debug: caught:" + x); 56 } 57 System.out.println("Using: \"127.0.0.1\""); 58 return "127.0.0.1"; 59 } 60 61 public static void main(String[] args) throws Exception { 62 startHttpServer(); 63 makeHttpCall(); 64 65 if (httpTrans.badRequest) { 66 throw new RuntimeException("Test failed : bad cookie header"); 67 } 68 checkCookiePolicy(); 69 } 70 71 public static void startHttpServer() throws IOException { 72 httpTrans = new CookieTransactionHandler(); 73 server = HttpServer.create(new InetSocketAddress(0), 0); 74 server.createContext("/", httpTrans); 75 server.start(); 76 } 77 78 /* 79 * Checks if CookiePolicy.ACCEPT_ORIGINAL_SERVER#shouldAccept() 80 * returns false for null arguments 81 */ 82 private static void checkCookiePolicy() throws Exception { 83 CookiePolicy cp = CookiePolicy.ACCEPT_ORIGINAL_SERVER; 84 boolean retVal; 85 retVal = cp.shouldAccept(null, null); 86 checkValue(retVal); 87 retVal = cp.shouldAccept(null, new HttpCookie("CookieName", "CookieVal")); 88 checkValue(retVal); 89 retVal = cp.shouldAccept((new URL("http", "localhost", 2345, "/")).toURI(), 90 null); 91 checkValue(retVal); 92 } 93 94 private static void checkValue(boolean val) { 95 if (val) 96 throw new RuntimeException("Return value is not false!"); 97 } 98 99 public static void makeHttpCall() throws IOException { 100 try { 101 int port = server.getAddress().getPort(); 102 System.out.println("http server listenining on: " + port); 103 104 // install CookieManager to use 105 CookieHandler.setDefault(new CookieManager()); 106 107 for (int i = 0; i < CookieTransactionHandler.testCount; i++) { 108 System.out.println("====== CookieManager test " + (i+1) 109 + " ======"); 110 ((CookieManager)CookieHandler.getDefault()) 111 .setCookiePolicy(CookieTransactionHandler.testPolicies[i]); 112 ((CookieManager)CookieHandler.getDefault()) 113 .getCookieStore().removeAll(); 114 URL url = new URL("http" , 115 hostAddress, 116 server.getAddress().getPort(), 117 CookieTransactionHandler.testCases[i][0] 118 .serverPath); 119 System.out.println("Requesting " + url); 120 HttpURLConnection uc = (HttpURLConnection)url.openConnection(NO_PROXY); 121 uc.getResponseCode(); 122 uc.disconnect(); 123 } 124 } finally { 125 server.stop(0); 126 } 127 } 128} 129 130class CookieTransactionHandler implements HttpHandler { 131 132 private int testcaseDone = 0; 133 private int testDone = 0; 134 135 public static boolean badRequest = false; 136 // the main test control logic will also loop exactly this number 137 // to send http request 138 public static final int testCount = 6; 139 140 @Override 141 public void handle(HttpExchange exchange) throws IOException { 142 if (testDone < testCases[testcaseDone].length) { 143 // still have other tests to run, 144 // check the Cookie header and then redirect it 145 if (testDone > 0) checkRequest(exchange.getRequestHeaders()); 146 exchange.getResponseHeaders().add("Location", 147 testCases[testcaseDone][testDone].serverPath); 148 exchange.getResponseHeaders() 149 .add(testCases[testcaseDone][testDone].headerToken, 150 testCases[testcaseDone][testDone].cookieToSend); 151 exchange.sendResponseHeaders(302, -1); 152 testDone++; 153 } else { 154 // the last test of this test case 155 if (testDone > 0) checkRequest(exchange.getRequestHeaders()); 156 testcaseDone++; 157 testDone = 0; 158 exchange.sendResponseHeaders(200, -1); 159 } 160 exchange.close(); 161 } 162 163 private void checkRequest(Headers hdrs) { 164 165 assert testDone > 0; 166 String cookieHeader = hdrs.getFirst("Cookie"); 167 if (cookieHeader != null && 168 cookieHeader 169 .equalsIgnoreCase(testCases[testcaseDone][testDone-1] 170 .cookieToRecv)) 171 { 172 System.out.printf("%15s %s\n", "PASSED:", cookieHeader); 173 } else { 174 System.out.printf("%15s %s\n", "FAILED:", cookieHeader); 175 System.out.printf("%15s %s\n\n", "should be:", 176 testCases[testcaseDone][testDone-1].cookieToRecv); 177 badRequest = true; 178 } 179 } 180 181 // test cases 182 public static class CookieTestCase { 183 public String headerToken; 184 public String cookieToSend; 185 public String cookieToRecv; 186 public String serverPath; 187 188 public CookieTestCase(String h, String cts, String ctr, String sp) { 189 headerToken = h; 190 cookieToSend = cts; 191 cookieToRecv = ctr; 192 serverPath = sp; 193 } 194 }; 195 196 /* 197 * these two must match each other, 198 * i.e. testCases.length == testPolicies.length 199 */ 200 201 // the test cases to run; each test case may contain multiple roundtrips 202 public static CookieTestCase[][] testCases = null; 203 // indicates what CookiePolicy to use with each test cases 204 public static CookiePolicy[] testPolicies = null; 205 206 CookieTransactionHandler() { 207 testCases = new CookieTestCase[testCount][]; 208 testPolicies = new CookiePolicy[testCount]; 209 210 String localHostAddr = CookieManagerTest.hostAddress; 211 212 int count = 0; 213 214 // an http session with Netscape cookies exchanged 215 testPolicies[count] = CookiePolicy.ACCEPT_ORIGINAL_SERVER; 216 testCases[count++] = new CookieTestCase[]{ 217 new CookieTestCase("Set-Cookie", 218 "CUSTOMER=WILE:BOB; " + 219 "path=/; expires=Sat, 09-Nov-2030 23:12:40 GMT;" + "domain=." + 220 localHostAddr, 221 "CUSTOMER=WILE:BOB", 222 "/" 223 ), 224 new CookieTestCase("Set-Cookie", 225 "PART_NUMBER=ROCKET_LAUNCHER_0001; path=/;" + "domain=." + localHostAddr, 226 "CUSTOMER=WILE:BOB; PART_NUMBER=ROCKET_LAUNCHER_0001", 227 "/" 228 ), 229 new CookieTestCase("Set-Cookie", 230 "SHIPPING=FEDEX; path=/foo;" + "domain=." + localHostAddr, 231 "CUSTOMER=WILE:BOB; PART_NUMBER=ROCKET_LAUNCHER_0001", 232 "/" 233 ), 234 new CookieTestCase("Set-Cookie", 235 "SHIPPING=FEDEX; path=/foo;" + "domain=." + localHostAddr, 236 "CUSTOMER=WILE:BOB; PART_NUMBER=ROCKET_LAUNCHER_0001; SHIPPING=FEDEX", 237 "/foo" 238 ) 239 }; 240 241 // check whether or not path rule is applied 242 testPolicies[count] = CookiePolicy.ACCEPT_ORIGINAL_SERVER; 243 testCases[count++] = new CookieTestCase[]{ 244 new CookieTestCase("Set-Cookie", 245 "PART_NUMBER=ROCKET_LAUNCHER_0001; path=/;" + "domain=." + localHostAddr, 246 "PART_NUMBER=ROCKET_LAUNCHER_0001", 247 "/" 248 ), 249 new CookieTestCase("Set-Cookie", 250 "PART_NUMBER=RIDING_ROCKET_0023; path=/ammo;" + "domain=." + localHostAddr, 251 "PART_NUMBER=RIDING_ROCKET_0023; PART_NUMBER=ROCKET_LAUNCHER_0001", 252 "/ammo" 253 ) 254 }; 255 256 // an http session with rfc2965 cookies exchanged 257 testPolicies[count] = CookiePolicy.ACCEPT_ORIGINAL_SERVER; 258 testCases[count++] = new CookieTestCase[]{ 259 new CookieTestCase("Set-Cookie2", 260 "Customer=\"WILE_E_COYOTE\"; Version=\"1\"; Path=\"/acme\";" + "domain=." + localHostAddr, 261 "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";$Domain=\"." + localHostAddr + "\"", 262 "/acme/login" 263 ), 264 new CookieTestCase("Set-Cookie2", 265 "Part_Number=\"Rocket_Launcher_0001\"; Version=\"1\";Path=\"/acme\";" + "domain=." + localHostAddr, 266 "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";" + "$Domain=\"." + 267 localHostAddr + "\"" + "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" 268 + "$Domain=\"." + localHostAddr + "\"", 269 "/acme/pickitem" 270 ), 271 new CookieTestCase("Set-Cookie2", 272 "Shipping=\"FedEx\"; Version=\"1\"; Path=\"/acme\";" + "domain=." + localHostAddr, 273 "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + 274 "\"" + "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" + "$Domain=\"." 275 + localHostAddr + "\"" + "; Shipping=\"FedEx\";$Path=\"/acme\";" + 276 "$Domain=\"." + localHostAddr + "\"", 277 "/acme/shipping" 278 ) 279 }; 280 281 // check whether or not the path rule is applied 282 testPolicies[count] = CookiePolicy.ACCEPT_ORIGINAL_SERVER; 283 testCases[count++] = new CookieTestCase[]{ 284 new CookieTestCase("Set-Cookie2", 285 "Part_Number=\"Rocket_Launcher_0001\"; Version=\"1\"; Path=\"/acme\";" + "domain=." + localHostAddr, 286 "$Version=\"1\"; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";$Domain=\"." + localHostAddr + "\"", 287 "/acme/ammo" 288 ), 289 new CookieTestCase("Set-Cookie2", 290 "Part_Number=\"Riding_Rocket_0023\"; Version=\"1\"; Path=\"/acme/ammo\";" + "domain=." 291 + localHostAddr, 292 "$Version=\"1\"; Part_Number=\"Riding_Rocket_0023\";$Path=\"/acme/ammo\";$Domain=\"." 293 + localHostAddr + "\"" + "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" 294 + "$Domain=\"." + localHostAddr + "\"", 295 "/acme/ammo" 296 ), 297 new CookieTestCase("", 298 "", 299 "$Version=\"1\"; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"", 300 "/acme/parts" 301 ) 302 }; 303 304 // new cookie should overwrite old cookie 305 testPolicies[count] = CookiePolicy.ACCEPT_ORIGINAL_SERVER; 306 testCases[count++] = new CookieTestCase[]{ 307 new CookieTestCase("Set-Cookie2", 308 "Part_Number=\"Rocket_Launcher_0001\"; Version=\"1\"; Path=\"/acme\";" + "domain=." + localHostAddr, 309 "$Version=\"1\"; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";$Domain=\"." + localHostAddr + "\"", 310 "/acme" 311 ), 312 new CookieTestCase("Set-Cookie2", 313 "Part_Number=\"Rocket_Launcher_2000\"; Version=\"1\"; Path=\"/acme\";" + "domain=." + localHostAddr, 314 "$Version=\"1\"; Part_Number=\"Rocket_Launcher_2000\";$Path=\"/acme\";$Domain=\"." + localHostAddr + "\"", 315 "/acme" 316 ) 317 }; 318 319 // cookies without domain attributes 320 // RFC 2965 states that domain should default to host 321 testPolicies[count] = CookiePolicy.ACCEPT_ALL; 322 testCases[count++] = new CookieTestCase[]{ 323 new CookieTestCase("Set-Cookie2", 324 "Customer=\"WILE_E_COYOTE\"; Version=\"1\"; Path=\"/acme\"", 325 "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";$Domain=\""+localHostAddr+"\"", 326 "/acme/login" 327 ), 328 new CookieTestCase("Set-Cookie2", 329 "Part_Number=\"Rocket_Launcher_0001\"; Version=\"1\";Path=\"/acme\"", 330 "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";$Domain=\""+localHostAddr+"\"" + 331 "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";$Domain=\""+localHostAddr+"\"", 332 "/acme/pickitem" 333 ), 334 new CookieTestCase("Set-Cookie2", 335 "Shipping=\"FedEx\"; Version=\"1\"; Path=\"/acme\"", 336 "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";$Domain=\""+localHostAddr+"\"" + 337 "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";$Domain=\""+localHostAddr+"\"" + 338 "; Shipping=\"FedEx\";$Path=\"/acme\";$Domain=\""+localHostAddr+"\"", 339 "/acme/shipping" 340 ) 341 }; 342 343 assert count == testCount; 344 } 345} 346