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