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