Home | History | Annotate | Download | only in net
      1 /*
      2  * Licensed to the Apache Software Foundation (ASF) under one or more
      3  * contributor license agreements.  See the NOTICE file distributed with
      4  * this work for additional information regarding copyright ownership.
      5  * The ASF licenses this file to You under the Apache License, Version 2.0
      6  * (the "License"); you may not use this file except in compliance with
      7  * the License.  You may obtain a copy of the License at
      8  *
      9  * http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
     13  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
     14  * License for the specific language governing permissions and limitations under
     15  * the License.
     16  */
     17 package org.apache.harmony.tests.java.net;
     18 
     19 import junit.framework.TestCase;
     20 
     21 import java.net.HttpCookie;
     22 import java.text.DateFormat;
     23 import java.text.SimpleDateFormat;
     24 import java.util.Date;
     25 import java.util.List;
     26 import java.util.Locale;
     27 import java.util.TimeZone;
     28 
     29 public class HttpCookieTest extends TestCase {
     30     private Locale locale;
     31 
     32     /**
     33      * java.net.HttpCookie(String, String).
     34      * @since 1.6
     35      */
     36     public void test_HttpCookie_LString_LString() {
     37         assertNotNull(new HttpCookie("harmony_6", "test,sem"));
     38         assertNotNull(new HttpCookie("harmony_6", null));
     39         assertNotNull(new HttpCookie("harmony    ", null));
     40         assertEquals("harmony", new HttpCookie("harmony ", null).getName());
     41 
     42         constructHttpCookie("", null);
     43 
     44         String value = "value";
     45         constructHttpCookie("", value);
     46 
     47         constructHttpCookie("harmony,", value);
     48         constructHttpCookie("harmony;", value);
     49         constructHttpCookie("$harmony", value);
     50         constructHttpCookie("n\tame", value);
     51         constructHttpCookie("n\rame", value);
     52         constructHttpCookie("n\r\name", value);
     53         constructHttpCookie("Comment", value);
     54         constructHttpCookie("CommentURL", value);
     55         constructHttpCookie("Domain", value);
     56         constructHttpCookie("Discard", value);
     57         constructHttpCookie("Max-Age", value);
     58         constructHttpCookie("  Path     ", value);
     59         constructHttpCookie("Port  ", value);
     60         constructHttpCookie("SeCure", value);
     61         constructHttpCookie("VErsion", value);
     62         constructHttpCookie("expires", value);
     63         constructHttpCookie("na\u0085me", value);
     64         constructHttpCookie("\u2028me", value);
     65         constructHttpCookie("na\u2029me", value);
     66 
     67         try {
     68             new HttpCookie(null, value);
     69             fail("Should throw NullPointerException");
     70         } catch (NullPointerException e) {
     71             // expected
     72         }
     73 
     74         try {
     75             new HttpCookie("\u007f", value);
     76             fail("Should throw IllegalArgumentException");
     77         } catch (IllegalArgumentException e) {
     78             // expected
     79         }
     80 
     81         HttpCookie cookie = new HttpCookie("harmony!", null);
     82         assertEquals("harmony!", cookie.getName());
     83 
     84         cookie = new HttpCookie("harmon$y", null);
     85         assertEquals("harmon$y", cookie.getName());
     86 
     87     }
     88 
     89     private static void constructHttpCookie(String name, String value) {
     90         try {
     91             new HttpCookie(name, value);
     92             fail("Should throw IllegalArgumentException");
     93         } catch (IllegalArgumentException e) {
     94             // expected
     95         }
     96     }
     97 
     98     /**
     99      * java.net.HttpCookie#domainMatches(String, String).
    100      * @since 1.6
    101      */
    102     public void test_DomainMatches() {
    103 
    104         /*
    105          * Rule 1: A host isn't in a domain (RFC 2965 sec. 3.3.2) if: The value
    106          * for the Domain attribute contains no embedded dots, and the value is
    107          * not .local.
    108          */
    109         boolean match = HttpCookie.domainMatches("hostname", "hostname");
    110         assertFalse(match);
    111 
    112         match = HttpCookie.domainMatches(".com", "test.com");
    113         assertFalse(match);
    114 
    115         match = HttpCookie.domainMatches(".com.", "test.com");
    116         assertFalse(match);
    117 
    118         // During comparison, host name is transformed to effective host name
    119         // first.
    120         match = HttpCookie.domainMatches(".local", "hostname");
    121         assertTrue(match);
    122 
    123         /*
    124          * Rule 3: The request-host is a HDN (not IP address) and has the form
    125          * HD, where D is the value of the Domain attribute, and H is a string
    126          * that contains one or more dots.
    127          */
    128         match = HttpCookie.domainMatches(".c.d", "a.b.c.d");
    129         assertTrue(match);
    130 
    131         match = HttpCookie.domainMatches("c.d", "a.b.c.d");
    132         assertFalse(match);
    133 
    134         match = HttpCookie.domainMatches(".foo.com", "y.x.foo.com");
    135         assertTrue(match);
    136 
    137         match = HttpCookie.domainMatches(".foo.com", "x.foo.com");
    138         assertTrue(match);
    139 
    140         match = HttpCookie.domainMatches(".local", "hostname.local");
    141         assertTrue(match);
    142 
    143         match = HttpCookie.domainMatches(".ajax.com", "a.ajax.com");
    144         assertTrue(match);
    145 
    146         match = HttpCookie.domainMatches(".ajax.com", "a.AJAX.com");
    147         assertTrue(match);
    148 
    149         match = HttpCookie.domainMatches("...", "test...");
    150         assertFalse(match);
    151 
    152         match = HttpCookie.domainMatches(".ajax.com", "b.a.AJAX.com");
    153         assertTrue(match);
    154 
    155         match = HttpCookie.domainMatches(".a", "b.a");
    156         assertFalse(match);
    157 
    158         // when either parameter is null
    159         match = HttpCookie.domainMatches(".ajax.com", null);
    160         assertFalse(match);
    161 
    162         match = HttpCookie.domainMatches(null, null);
    163         assertFalse(match);
    164 
    165         match = HttpCookie.domainMatches(null, "b.a.AJAX.com");
    166         assertFalse(match);
    167 
    168         // JDK-7023713
    169         match = HttpCookie.domainMatches("hostname.local", "hostname");
    170         assertTrue(match);
    171     }
    172 
    173     /**
    174      * java.net.HttpCookie#getVersion(), setVersion(int).
    175      * @since 1.6
    176      */
    177     public void test_Get_SetVersion() {
    178         HttpCookie cookie = new HttpCookie("name", "value");
    179         assertEquals(1, cookie.getVersion());
    180         cookie.setVersion(0);
    181         assertEquals(0, cookie.getVersion());
    182         cookie.setVersion(1);
    183         assertEquals(1, cookie.getVersion());
    184 
    185         try {
    186             cookie.setVersion(-1);
    187             fail("should throw IllegalArgumentException");
    188         } catch (IllegalArgumentException e) {
    189             // expected
    190         }
    191 
    192         try {
    193             cookie.setVersion(2);
    194             fail("should throw IllegalArgumentException");
    195         } catch (IllegalArgumentException e) {
    196             // expected
    197         }
    198     }
    199 
    200     /**
    201      * java.net.HttpCookie#getValue(), setValue(String)
    202      * @since 1.6
    203      */
    204     public void test_Get_SetValue() {
    205         HttpCookie cookie = new HttpCookie("name", "value");
    206         assertEquals("value", cookie.getValue());
    207         cookie.setValue("newValue");
    208         assertEquals("newValue", cookie.getValue());
    209 
    210         cookie.setValue(null);
    211         assertNull(cookie.getValue());
    212 
    213         cookie.setValue("na\u64DEme");
    214         assertEquals("na\u64DEme", cookie.getValue());
    215         cookie.setVersion(0);
    216         cookie.setValue("{(new value, 11)}");
    217         assertEquals("{(new value, 11)}", cookie.getValue());
    218     }
    219 
    220     /**
    221      * java.net.HttpCookie#getName()
    222      * @since 1.6
    223      */
    224     public void test_GetName() {
    225         HttpCookie cookie = new HttpCookie("testName", "value");
    226         assertEquals("testName", cookie.getName());
    227     }
    228 
    229     /**
    230      * java.net.HttpCookie#getSecure(), setSecure(boolean)
    231      * @since 1.6
    232      */
    233     public void test_Get_SetSecure() {
    234         HttpCookie cookie = new HttpCookie("testName", "value");
    235         assertFalse(cookie.getSecure());
    236         cookie.setVersion(0);
    237         assertFalse(cookie.getSecure());
    238 
    239         cookie.setSecure(true);
    240         assertTrue(cookie.getSecure());
    241         cookie.setSecure(false);
    242         cookie.setVersion(1);
    243         assertFalse(cookie.getSecure());
    244     }
    245 
    246     /**
    247      * java.net.HttpCookie#getPath(), setPath(String)
    248      * @since 1.6
    249      */
    250     public void test_Get_SetPath() {
    251         HttpCookie cookie = new HttpCookie("name", "test new value");
    252         assertNull(cookie.getPath());
    253 
    254         cookie.setPath("{}()  test,; 43!@");
    255         assertEquals("{}()  test,; 43!@", cookie.getPath());
    256 
    257         cookie.setPath(" test");
    258         assertEquals(" test", cookie.getPath());
    259 
    260         cookie.setPath("\u63DF\u64DE");
    261         cookie.setDomain("test");
    262         assertEquals("\u63DF\u64DE", cookie.getPath());
    263     }
    264 
    265     /**
    266      * java.net.HttpCookie#getMaxAge(), setMaxAge(long)
    267      * @since 1.6
    268      */
    269     public void test_Get_SetMaxAge() {
    270         HttpCookie cookie = new HttpCookie("name", "test new value");
    271         assertEquals(-1, cookie.getMaxAge());
    272 
    273         cookie.setMaxAge(Long.MAX_VALUE);
    274         assertEquals(Long.MAX_VALUE, cookie.getMaxAge());
    275 
    276         cookie.setMaxAge(Long.MIN_VALUE);
    277         cookie.setDiscard(false);
    278         assertEquals(Long.MIN_VALUE, cookie.getMaxAge());
    279     }
    280 
    281     /**
    282      * java.net.HttpCookie#getDomain(), setDomain(String)
    283      * @since 1.6
    284      */
    285     public void test_Get_SetDomain() {
    286         HttpCookie cookie = new HttpCookie("name", "test new value");
    287         assertNull(cookie.getDomain());
    288 
    289         cookie.setDomain("a.b.d.c.com.");
    290         assertEquals("a.b.d.c.com.", cookie.getDomain());
    291 
    292         cookie.setDomain("   a.b.d.c.com.  ");
    293         assertEquals("   a.b.d.c.com.  ", cookie.getDomain());
    294 
    295         cookie.setPath("temp/subTemp");
    296         cookie.setDomain("xy.foo.bar.de.edu");
    297         assertEquals("xy.foo.bar.de.edu", cookie.getDomain());
    298     }
    299 
    300     /**
    301      * java.net.HttpCookie#getPortlist(), setPortlist(String)
    302      * @since 1.6
    303      */
    304     public void test_Get_SetPortlist() {
    305         HttpCookie cookie = new HttpCookie("cookieName", "cookieName value");
    306         assertNull(cookie.getPortlist());
    307 
    308         cookie.setPortlist("80,23,20");
    309         assertEquals("80,23,20", cookie.getPortlist());
    310         cookie.setPortlist("abcdefg1234567");
    311         cookie.setValue("cookie value again");
    312         assertEquals("abcdefg1234567", cookie.getPortlist());
    313     }
    314 
    315     /**
    316      * java.net.HttpCookie#getDiscard(), setDiscard(boolean)
    317      * @since 1.6
    318      */
    319     public void test_Get_SetDiscard() {
    320         HttpCookie cookie = new HttpCookie("cookie'sName",
    321                 "cookie's Test value");
    322         assertFalse(cookie.getDiscard());
    323 
    324         cookie.setDiscard(true);
    325         assertTrue(cookie.getDiscard());
    326         cookie.setDiscard(false);
    327         cookie.setMaxAge(-1);
    328         assertFalse(cookie.getDiscard());
    329     }
    330 
    331     /**
    332      * java.net.HttpCookie#getCommentURL(), setCommentURL(String)
    333      * @since 1.6
    334      */
    335     public void test_Get_SetCommentURL() {
    336         HttpCookie cookie = new HttpCookie("cookie'\"sName",
    337                 "cookie's Test value");
    338         assertNull(cookie.getCommentURL());
    339 
    340         cookie.setCommentURL("http://www.test.com");
    341         assertEquals("http://www.test.com", cookie.getCommentURL());
    342 
    343         cookie.setCommentURL("schema://harmony.test.org");
    344         cookie.setComment("just a comment");
    345         assertEquals("schema://harmony.test.org", cookie.getCommentURL());
    346     }
    347 
    348     /**
    349      * java.net.HttpCookie#getComment(), setComment(String)
    350      * @since 1.6
    351      */
    352     public void test_Get_SetComment() {
    353         HttpCookie cookie = new HttpCookie("cookie'\"sName?",
    354                 "cookie's Test??!@# value");
    355         assertNull(cookie.getComment());
    356 
    357         cookie.setComment("");
    358         assertEquals("", cookie.getComment());
    359 
    360         cookie.setComment("cookie''s @#$!&*()");
    361         cookie.setVersion(0);
    362         assertEquals("cookie''s @#$!&*()", cookie.getComment());
    363     }
    364 
    365     /**
    366      * java.net.HttpCookie#hasExpired()
    367      * @since 1.6
    368      */
    369     public void test_HasExpired() {
    370         HttpCookie cookie = new HttpCookie("cookie'\"sName123456",
    371                 "cookie's Test?()!@# value");
    372         assertFalse(cookie.hasExpired());
    373 
    374         cookie.setMaxAge(0);
    375         assertTrue(cookie.hasExpired());
    376 
    377         cookie.setMaxAge(Long.MAX_VALUE);
    378         cookie.setVersion(0);
    379         assertFalse(cookie.hasExpired());
    380 
    381         cookie.setMaxAge(Long.MIN_VALUE);
    382         cookie.setDiscard(false);
    383         assertTrue(cookie.hasExpired());
    384 
    385         cookie.setDiscard(true);
    386         cookie.setMaxAge(-1);
    387         assertFalse(cookie.hasExpired());
    388     }
    389 
    390     /**
    391      * Regression test for http://b/25682357.
    392      */
    393     public void test_HasExpiredBug25682357() throws Exception {
    394         HttpCookie cookie1 = HttpCookie.parse("Set-Cookie:name=value;max-age=2;").get(0);
    395         HttpCookie cookie2 = HttpCookie.parse("Set-Cookie:name=value;max-age=100;").get(0);
    396         assertFalse(cookie1.hasExpired());
    397         assertFalse(cookie2.hasExpired());
    398 
    399         // Sleep for long enough to force expiry of the first cookie.
    400         Thread.sleep(3000);
    401         assertTrue(cookie1.hasExpired());
    402         assertFalse(cookie2.hasExpired());
    403 
    404         assertEquals(2, cookie1.getMaxAge());
    405         assertEquals(100, cookie2.getMaxAge());
    406 
    407         // Changing the max age should not reset the expiry status.
    408         cookie1.setMaxAge(2);
    409         assertTrue(cookie1.hasExpired());
    410     }
    411 
    412     /**
    413      * Regression test for http://b/25682357.
    414      */
    415     public void test_HasExpiredBug25682357_2() throws Exception {
    416         // The following tests do not pass on the RI: it may not handle "expires" at all.
    417         DateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
    418         dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
    419         String pastExpiryDate = dateFormat.format(new Date(System.currentTimeMillis() - 100_000));
    420         String pastExpiryCookieHeader =
    421             "Set-Cookie:name=value;expires=" + pastExpiryDate + ";";
    422         HttpCookie pastExpiryCookie = HttpCookie.parse(pastExpiryCookieHeader).get(0);
    423         assertTrue(pastExpiryCookie.hasExpired());
    424 
    425         String futureExpiryDate = dateFormat.format(new Date(System.currentTimeMillis() + 100_000));
    426         String futureExpiryCookieHeader =
    427             "Set-Cookie:name=value;expires=" + futureExpiryDate + ";";
    428         HttpCookie futureExpiryCookie = HttpCookie.parse(futureExpiryCookieHeader).get(0);
    429         assertFalse(futureExpiryCookie.hasExpired());
    430     }
    431 
    432     /**
    433      * java.net.HttpCookie#equals()
    434      * @since 1.6
    435      */
    436     public void test_Equals() {
    437         Object obj = new Object();
    438         HttpCookie cookie = new HttpCookie("test", "testValue");
    439         HttpCookie cookie2 = new HttpCookie("TesT", "TEstValue");
    440 
    441         assertFalse(cookie.equals(obj));
    442         assertFalse(cookie.equals(null));
    443         assertTrue(cookie2.equals(cookie));
    444         assertTrue(cookie.equals(cookie2));
    445         assertTrue(cookie.equals(cookie));
    446 
    447         cookie.setDomain("  test");
    448         cookie2.setDomain("test");
    449         assertFalse(cookie.equals(cookie2));
    450         cookie.setDomain("TEST");
    451         assertTrue(cookie.equals(cookie2));
    452 
    453         cookie.setPath("temp\\e");
    454         assertFalse(cookie.equals(cookie2));
    455         cookie2.setPath("temp\\E");
    456         assertFalse(cookie.equals(cookie2));
    457 
    458         cookie.setDiscard(true);
    459         cookie.setMaxAge(-1234);
    460         cookie2.setPath("temp\\e");
    461         assertTrue(cookie.equals(cookie2));
    462     }
    463 
    464     /**
    465      * java.net.HttpCookie#clone()
    466      * @since 1.6
    467      */
    468     public void test_Clone() {
    469         HttpCookie cookie = new HttpCookie("test", "testValue");
    470         cookie.setMaxAge(33l);
    471         cookie.setComment("test comment");
    472         HttpCookie cloneCookie = (HttpCookie) cookie.clone();
    473         assertNotSame(cloneCookie, cookie);
    474         assertEquals("test", cloneCookie.getName());
    475         assertEquals(33l, cloneCookie.getMaxAge());
    476         assertEquals("test comment", cloneCookie.getComment());
    477     }
    478 
    479     /**
    480      * java.net.HttpCookie#toString()
    481      * @since 1.6
    482      */
    483     public void test_ToString() {
    484         HttpCookie cookie = new HttpCookie("test", "testValue");
    485         cookie.setComment("ABCd");
    486         cookie.setCommentURL("\u63DF");
    487         cookie.setDomain(".B.com");
    488         cookie.setDiscard(true);
    489         cookie.setMaxAge(Integer.MAX_VALUE);
    490         cookie.setPath("temp/22RuTh");
    491         cookie.setPortlist("80.562Ab");
    492         cookie.setSecure(true);
    493         cookie.setVersion(1);
    494 
    495         assertEquals(
    496                 "test=\"testValue\";$Path=\"temp/22RuTh\";$Domain=\".b.com\";$Port=\"80.562Ab\"",
    497                 cookie.toString());
    498 
    499         cookie.setPath(null);
    500         assertEquals(
    501                 "test=\"testValue\";$Domain=\".b.com\";$Port=\"80.562Ab\"",
    502                 cookie.toString());
    503         cookie.setComment(null);
    504         assertEquals(
    505                 "test=\"testValue\";$Domain=\".b.com\";$Port=\"80.562Ab\"",
    506                 cookie.toString());
    507         cookie.setPortlist(null);
    508         assertEquals("test=\"testValue\";$Domain=\".b.com\"", cookie.toString());
    509         cookie.setDomain(null);
    510         assertEquals("test=\"testValue\"", cookie.toString());
    511 
    512         cookie.setVersion(0);
    513         cookie.setPortlist("80,8000");
    514         assertEquals("test=testValue", cookie.toString());
    515     }
    516 
    517     /**
    518      * java.net.HttpCookie#hashCode()
    519      * @since 1.6
    520      */
    521     public void test_HashCode() {
    522         HttpCookie cookie = new HttpCookie("nAmW_1", "value_1");
    523         assertEquals(-1052814577, cookie.hashCode());
    524 
    525         cookie.setDomain("a.b.c.de");
    526         assertEquals(1222695220, cookie.hashCode());
    527 
    528         cookie.setPath("3kmxiq;1");
    529         assertEquals(-675006347, cookie.hashCode());
    530         cookie.setPath("3KmxiQ;1");
    531         assertEquals(989616181, cookie.hashCode());
    532 
    533         cookie.setValue("Vw0,22_789");
    534         assertEquals(989616181, cookie.hashCode());
    535         cookie.setComment("comment");
    536         assertEquals(989616181, cookie.hashCode());
    537 
    538         cookie.setDomain("");
    539         assertEquals(-1285893616, cookie.hashCode());
    540     }
    541 
    542     /**
    543      * java.net.HttpCookie#parse(String) for exception cases
    544      * @since 1.6
    545      */
    546     public void test_Parse_exception() {
    547         try {
    548             HttpCookie.parse(null);
    549             fail("Should throw NullPointerException");
    550         } catch (NullPointerException e) {
    551             // expected
    552         }
    553         /*
    554          * Please note that Netscape draft specification does not fully conform
    555          * to the HTTP header format. Netscape draft does not specify whether
    556          * multiple cookies may be sent in one header. Hence, comma character
    557          * may be present in unquoted cookie value or unquoted parameter value.
    558          * Refer to <a
    559          * href="http://jakarta.apache.org/commons/httpclient/apidocs/org/apache/commons/httpclient/cookie/NetscapeDraftSpec.html#parse(java.lang.String,%20int,%20java.lang.String,%20boolean,%20java.lang.String)">
    560          * http://jakarta.apache.org/commons/httpclient/apidocs/org/apache/commons/httpclient/cookie/NetscapeDraftSpec.html#parse(java.lang.String,%20int,%20java.lang.String,%20boolean,%20java.lang.String)
    561          * </a>
    562          */
    563         // violates the cookie specification's syntax
    564         checkInvalidCookie("invalid cookie name");
    565         checkInvalidCookie("Set-Cookie2:");
    566         checkInvalidCookie("name");
    567         checkInvalidCookie("$name=");
    568         checkInvalidCookie("Set-Cookie2:$name=");
    569         checkInvalidCookie("Set-Cookie:$");
    570         checkInvalidCookie("Set-Cookie");
    571 
    572         // cookie name contains llegal characters
    573         checkInvalidCookie("Set-Cookie:n,ame=");
    574         checkInvalidCookie("Set-Cookie2:n\name=");
    575         checkInvalidCookie("Set-Cookie2:n,ame=");
    576         checkInvalidCookie("Set-Cookie2:n\tame=");
    577         checkInvalidCookie("Set-Cookie2:n\rame=");
    578         checkInvalidCookie("Set-Cookie2:n\r\name=");
    579         checkInvalidCookie("Set-Cookie2:na\u0085me=");
    580         checkInvalidCookie("Set-Cookie2:na\u2028me=");
    581         checkInvalidCookie("Set-Cookie2:na\u2029me=");
    582         checkInvalidCookie("Set-Cookie2:=");
    583         checkInvalidCookie("Set-Cookie2:name=tes,t");
    584 
    585         // 'CommentURL' is one of the tokens reserved, case-insensitive
    586         checkInvalidCookie("Set-Cookie2:COmmentURL=\"lala\"");
    587 
    588         // check value
    589         checkInvalidCookie("Set-Cookie2:val,ue");
    590         checkInvalidCookie("Set-Cookie2:name=test;comMent=sent,ence");
    591         checkInvalidCookie("Set-Cookie2:name=test;comMentUrL=u,rl");
    592         checkInvalidCookie("Set-Cookie2:name=test;Discard=fa,lse");
    593         checkInvalidCookie("Set-Cookie2:name=test;Disc,ard");
    594         checkInvalidCookie("Set-Cookie2:name=test;Domain=u,rl");
    595         checkInvalidCookie("Set-Cookie2:name=test;Path=pa,th");
    596         checkInvalidCookie("Set-Cookie2:name=test;Secure=se,cure");
    597         checkInvalidCookie("Set-Cookie2:name=test;se,cure");
    598         checkInvalidCookie("Set-Cookie2:name=test;Max-Age=se,cure");
    599         checkInvalidCookie("Set-Cookie2:name=test;Max-Age=");
    600         checkInvalidCookie("Set-Cookie2:name=test;Max-Age=max-age");
    601         checkInvalidCookie("Set-Cookie2:name=test;Max-Age=1000.0");
    602     }
    603 
    604     /**
    605      * java.net.HttpCookie#parse(String) for locales other than
    606      * Locale.ENGLISH.
    607      * @since 1.6
    608      */
    609     public void test_Parse_locale() {
    610         Locale.setDefault(Locale.FRENCH);
    611         List<HttpCookie> list = HttpCookie
    612                 .parse("Set-Cookie:name=test;expires=Thu, 30-Oct-2008 19:14:07 GMT;");
    613         HttpCookie cookie = list.get(0);
    614         assertTrue(cookie.hasExpired());
    615 
    616         Locale.setDefault(Locale.GERMAN);
    617         list = HttpCookie
    618                 .parse("Set-Cookie:name=test;expires=Sun, 30-Oct-2005 19:14:07 GMT;");
    619         cookie = list.get(0);
    620         assertTrue(cookie.hasExpired());
    621 
    622         Locale.setDefault(Locale.KOREA);
    623         list = HttpCookie
    624                 .parse("Set-Cookie:name=test;max-age=1234;expires=Sun, 30-Oct-2005 19:14:07 GMT;");
    625         cookie = list.get(0);
    626         assertEquals(0, cookie.getVersion());
    627         assertEquals(1234, cookie.getMaxAge());
    628         assertFalse(cookie.hasExpired());
    629 
    630         Locale.setDefault(Locale.TAIWAN);
    631         list = HttpCookie
    632                 .parse("Set-Cookie:name=test;max-age=-12345;");
    633         cookie = list.get(0);
    634         assertEquals(-12345, cookie.getMaxAge());
    635         assertTrue(cookie.hasExpired());
    636 
    637         // Locale does not affect version 1 cookie.
    638         Locale.setDefault(Locale.ITALIAN);
    639         list = HttpCookie.parse("Set-Cookie2:name=test;max-age=1000");
    640         cookie = list.get(0);
    641         assertEquals(1000, cookie.getMaxAge());
    642         assertFalse(cookie.hasExpired());
    643     }
    644 
    645     /**
    646      * java.net.HttpCookie#parse(String) for normal cases
    647      * @since 1.6
    648      */
    649     public void test_Parse() {
    650         List<HttpCookie> list = HttpCookie.parse("test=\"null\"");
    651         HttpCookie cookie = list.get(0);
    652         // when two '"' presents, the parser ignores it.
    653         assertEquals("null", cookie.getValue());
    654         assertNull(cookie.getComment());
    655         assertNull(cookie.getCommentURL());
    656         assertFalse(cookie.getDiscard());
    657         assertNull(cookie.getDomain());
    658         assertEquals(-1, cookie.getMaxAge());
    659         assertNull(cookie.getPath());
    660         assertNull(cookie.getPortlist());
    661         assertFalse(cookie.getSecure());
    662         // default version is 0
    663         assertEquals(0, cookie.getVersion());
    664 
    665         list = HttpCookie.parse("Set-cookie2:name=\"tes,t\"");
    666         cookie = list.get(0);
    667         // when two '"' presents, the parser ignores it.
    668         assertEquals("tes,t", cookie.getValue());
    669 
    670         // If cookie header = Set-Cookie2, version = 1
    671         list = HttpCookie
    672                 .parse("Set-cookie2:test=null\";;Port=abde,82;Path=/temp;;;Discard;commentURl=http://harmonytest.org;Max-age=-10;");
    673         cookie = list.get(0);
    674         assertEquals("null\"", cookie.getValue());
    675         assertEquals(1, cookie.getVersion());
    676         assertEquals("/temp", cookie.getPath());
    677         assertTrue(cookie.getDiscard());
    678         assertEquals("http://harmonytest.org", cookie.getCommentURL());
    679         assertEquals(-10l, cookie.getMaxAge());
    680         assertTrue(cookie.hasExpired());
    681         assertEquals("abde,82", cookie.getPortlist());
    682         // Version 0 cookie
    683         list = HttpCookie
    684                 .parse("Set-Cookie:name=tes,t;Comment=version1-cookie;Discard=false;commentURL=vers\nion1-cookie-url;Domain=x.y;");
    685         cookie = list.get(0);
    686         assertEquals(0, cookie.getVersion());
    687         assertEquals("tes,t", cookie.getValue());
    688         assertEquals("name", cookie.getName());
    689         assertEquals("version1-cookie", cookie.getComment());
    690         assertEquals("vers\nion1-cookie-url", cookie.getCommentURL());
    691         assertEquals("x.y", cookie.getDomain());
    692         assertTrue(cookie.getDiscard());
    693 
    694         // Check value
    695         checkValidValue("Set-Cookie:", "val,ue");
    696         checkValidValue("Set-Cookie:", "val\nue");
    697         checkValidValue("Set-Cookie:", "value=value");
    698         checkValidValue("Set-Cookie2:", "val\nue");
    699         checkValidValue("Set-Cookie2:", "val\u2029ue");
    700         checkValidValue("Set-Cookie2:", "value=value");
    701 
    702         // Check comment
    703         // In RFC 2965 '=' is mandatory, but this is not the case in RI.
    704         list = HttpCookie.parse("Set-Cookie:name=tes,t;Comment;");
    705         cookie = list.get(0);
    706         assertNull(cookie.getComment());
    707 
    708         list = HttpCookie
    709                 .parse("Set-Cookie:name=tes,t;Comment=sentence;Comment=anotherSentence");
    710         cookie = list.get(0);
    711         assertEquals("sentence", cookie.getComment());
    712 
    713         // Check CommentURL
    714         list = HttpCookie
    715                 .parse("Set-Cookie:name=tes,t;Commenturl;commentuRL=(la,la)");
    716         cookie = list.get(0);
    717         assertEquals("(la,la)", cookie.getCommentURL());
    718 
    719         // Check Domain
    720         list = HttpCookie.parse("Set-Cookie:name=test;Domain=a_domain");
    721         cookie = list.get(0);
    722         assertEquals("a_domain", cookie.getDomain());
    723 
    724         // Check Path
    725         list = HttpCookie.parse("Set-Cookie:name=test;PaTh=pa$th");
    726         cookie = list.get(0);
    727         assertEquals("pa$th", cookie.getPath());
    728 
    729         // Check Max-Age
    730         list = HttpCookie.parse("Set-Cookie:name=test;Max-Age=1000");
    731         cookie = list.get(0);
    732         assertEquals(1000, cookie.getMaxAge());
    733 
    734         list = HttpCookie.parse("Set-Cookie:name=test;Max-Age=-1000");
    735         cookie = list.get(0);
    736         assertEquals(-1000, cookie.getMaxAge());
    737 
    738         // TODO: Uncomment when Long.parseLong() accepts numbers with a leading +
    739         // list = HttpCookie.parse("Set-Cookie:name=test;max-age=+12345;");
    740         // cookie = list.get(0);
    741         // assertEquals(12345, cookie.getMaxAge());
    742 
    743         list = HttpCookie.parse("Set-Cookie:name=test;max-age=0;");
    744         cookie = list.get(0);
    745         assertEquals(0, cookie.getMaxAge());
    746 
    747         // Check portlist
    748         list = HttpCookie.parse("Set-Cookie:name=tes,t;port");
    749         cookie = list.get(0);
    750         assertEquals("", cookie.getPortlist());
    751 
    752         list = HttpCookie.parse("Set-Cookie:name=tes,t;port=");
    753         cookie = list.get(0);
    754         assertEquals("", cookie.getPortlist());
    755 
    756         list = HttpCookie.parse("Set-Cookie:name=tes,t;port=123 345");
    757         cookie = list.get(0);
    758         assertEquals("123 345", cookie.getPortlist());
    759 
    760         list = HttpCookie.parse("Set-Cookie:name=tes,t;port=123,345");
    761         cookie = list.get(0);
    762         assertEquals("123,345", cookie.getPortlist());
    763 
    764         // Check Secure
    765         list = HttpCookie.parse("Set-Cookie:name=test;secure");
    766         cookie = list.get(0);
    767         assertTrue(cookie.getSecure());
    768 
    769         list = HttpCookie.parse("Set-Cookie:name=test;secure=fa");
    770         cookie = list.get(0);
    771         assertTrue(cookie.getSecure());
    772         assertFalse(cookie.hasExpired());
    773 
    774         list = HttpCookie.parse("Set-Cookie2:name=test;secure=false");
    775         cookie = list.get(0);
    776         assertTrue(cookie.getSecure());
    777 
    778         // Check expire
    779         list = HttpCookie.parse("Set-Cookie:name=test;expires=2006-10-23");
    780         cookie = list.get(0);
    781         assertEquals(0, cookie.getMaxAge());
    782         assertTrue(cookie.hasExpired());
    783 
    784         // Also recognize invalid date
    785         list = HttpCookie
    786                 .parse("Set-Cookie:name=test;expires=Sun, 29-Feb-1999 19:14:07 GMT");
    787         cookie = list.get(0);
    788         assertTrue(cookie.getMaxAge() < 0);
    789         assertTrue(cookie.hasExpired());
    790 
    791         // Parse multiple cookies
    792         list = HttpCookie
    793                 .parse("Set-Cookie2:name=test;,Set-Cookie2:name2=test2;comment=c234;");
    794         cookie = list.get(0);
    795         assertEquals("name", cookie.getName());
    796         assertEquals(1, cookie.getVersion());
    797         assertEquals("test", cookie.getValue());
    798         cookie = list.get(1);
    799         assertEquals(1, cookie.getVersion());
    800         // From the second cookie, the "set-cookie2" header does not take effect
    801         assertEquals("Set-Cookie2:name2", cookie.getName());
    802         assertEquals("c234", cookie.getComment());
    803 
    804         list = HttpCookie.parse("Set-Cookie2:name=test,name2=test2");
    805         assertEquals(1, list.get(0).getVersion());
    806         assertEquals(1, list.get(1).getVersion());
    807 
    808         // Must begin with "set-cookie2" header
    809         list = HttpCookie.parse("name=test,Set-Cookie2:name2=test2");
    810         cookie = list.get(0);
    811         assertEquals(1, list.size());
    812 
    813         HttpCookie c = HttpCookie.parse(
    814                 "Set-cookie:NAME2=VALUE2;path=/t;domain=.b.c;version=1").get(0);
    815         assertEquals(1, c.getVersion());
    816 
    817         c = HttpCookie.parse(
    818                 "Set-cookie2:NAME2=VALUE2;path=/t;domain=.b.c;version=0")
    819                 .get(0);
    820         assertEquals(1, c.getVersion());
    821 
    822         list = HttpCookie.parse("Set-cookie:null=;Domain=null;Port=null");
    823         cookie = list.get(0);
    824 
    825         assertNotNull(cookie.getValue());
    826         assertNotNull(cookie.getName());
    827         assertNotNull(cookie.getDomain());
    828         assertNotNull(cookie.getPortlist());
    829 
    830         try {
    831             list = HttpCookie
    832                     .parse("Set-Cookie:a  name=tes,t;Commenturl;commentuRL=(la,la);path=hello");
    833             fail("IllegalArgumentException expected");
    834         } catch (IllegalArgumentException expected) {
    835         }
    836 
    837 
    838         list = HttpCookie
    839                 .parse("Set-Cookie:name=tes,t;Commenturl;commentuRL=(la,la);commentuRL=hello");
    840         cookie = list.get(0);
    841         assertEquals("(la,la)", cookie.getCommentURL());
    842 
    843         list = HttpCookie
    844                 .parse("Set-Cookie:name=tes,t;Commenturl;commentuRL=(la,la); path  =hello");
    845         cookie = list.get(0);
    846         assertEquals("(la,la)", cookie.getCommentURL());
    847         assertEquals("hello", cookie.getPath());
    848 
    849         try {
    850             list = HttpCookie
    851                     .parse("a  Set-Cookie:name=tes,t;Commenturl;commentuRL=(la,la);path=hello");
    852             fail("IllegalArgumentException expected");
    853         } catch (IllegalArgumentException expected) {
    854         }
    855     }
    856 
    857     public void test_Parse_httpOnly() {
    858         // Default is !httpOnly.
    859         List<HttpCookie> list = HttpCookie.parse("Set-Cookie: SID=31d4d96e407aad42");
    860         HttpCookie cookie = list.get(0);
    861 
    862         // Well formed, simple.
    863         list = HttpCookie.parse("Set-Cookie: SID=31d4d96e407aad42; HttpOnly");
    864         cookie = list.get(0);
    865 
    866         // Well formed, other attributes present.
    867         list = HttpCookie.parse("Set-Cookie: SID=31d4d96e407aad42; Path=/; Secure; HttpOnly");
    868         cookie = list.get(0);
    869         assertTrue(cookie.getSecure());
    870         assertEquals("/", cookie.getPath());
    871 
    872         // Mangled spacing, casing and attributes that have an (ignored) value.
    873         list = HttpCookie.parse("Set-Cookie:SID=31d4d96e407aad42;Path=/;secure=false;httponly=false");
    874         cookie = list.get(0);
    875         assertTrue(cookie.getSecure());
    876         assertEquals("/", cookie.getPath());
    877     }
    878 
    879     /**
    880      * java.net.HttpCookie#parse(String) for version conflict cases
    881      * @since 1.6
    882      */
    883     public void test_Parse_versionConflict() {
    884         // If attribute expires presents, cookie will be recognized as version
    885         // 0. No matter header is Set-cookie or Set-cookie2
    886         List<HttpCookie> list = HttpCookie
    887                 .parse("Set-Cookie2:name=;expires=;discard");
    888         HttpCookie cookie = list.get(0);
    889         assertEquals(0, cookie.getVersion());
    890         assertTrue(cookie.getDiscard());
    891 
    892         list = HttpCookie.parse("Set-Cookie: name=value;port=80");
    893         cookie = list.get(0);
    894         assertEquals(0, cookie.getVersion());
    895         assertEquals("80", cookie.getPortlist());
    896 
    897         // In Set-Cookie header, max-age does not take effect when expires
    898         // exists.
    899         list = HttpCookie
    900                 .parse("Set-Cookie:name=test;expires=Tue, 27-Jan-1998 19:14:07 GMT;Max-Age=1000");
    901         cookie = list.get(0);
    902         assertTrue(cookie.getMaxAge() < 0);
    903         assertTrue(cookie.hasExpired());
    904         assertFalse(cookie.getDiscard());
    905         // Reverse sequence. max-age takes effect and decides the result of
    906         // hasExpired() method.
    907         list = HttpCookie
    908                 .parse("Set-Cookie:name=value;max-age=1000;expires=Tue, 17-Jan-1998 19:14:07 GMT;version=1");
    909         cookie = list.get(0);
    910         assertEquals(0, cookie.getVersion());
    911         assertEquals(1000, cookie.getMaxAge());
    912         assertFalse(cookie.hasExpired());
    913 
    914         // expires decides the version. Not take Set-cookie header, version into
    915         // consideration if expires exists.
    916         list = HttpCookie
    917                 .parse("Set-Cookie2:name=value;max-age=1000;version=1;expires=Tue, 17-Jan-1998 19:07:14 GMT;");
    918         cookie = list.get(0);
    919         assertEquals(0, cookie.getVersion());
    920         assertEquals(1000, cookie.getMaxAge());
    921         assertFalse(cookie.hasExpired());
    922 
    923         // expires does not cover other version 1 attributes.
    924         list = HttpCookie
    925                 .parse("Set-Cookie2: name=value;expires=Sun, 27-Jan-2018 19:14:07 GMT;comment=mycomment;port=80,8080");
    926         cookie = list.get(0);
    927         assertEquals(0, cookie.getVersion());
    928         assertEquals("80,8080", cookie.getPortlist());
    929         assertEquals("mycomment", cookie.getComment());
    930 
    931         // When expires does not exist, version takes effect.
    932         list = HttpCookie.parse("Set-Cookie:name=test;Version=1");
    933         cookie = list.get(0);
    934         assertEquals(1, cookie.getVersion());
    935         assertEquals(-1, cookie.getMaxAge());
    936         list = HttpCookie.parse("Set-Cookie:name=test;vERsion=0;Version=1;versioN=0;vErsIon=1");
    937         cookie = list.get(0);
    938         assertEquals(1, cookie.getVersion());
    939 
    940         // When expires does not exist, max-age takes effect.
    941         list = HttpCookie.parse("Set-Cookie:name=test;Max-Age=11");
    942         cookie = list.get(0);
    943         assertEquals(1, cookie.getVersion());
    944         assertEquals(11, cookie.getMaxAge());
    945         // other version 1 attributes does not take effect
    946         list = HttpCookie
    947                 .parse("Set-Cookie:name=test;comment=mycomment;commentURL=url;discard;domain=a.b.com;path=temp;port=79;secure");
    948         cookie = list.get(0);
    949         assertEquals(0, cookie.getVersion());
    950     }
    951 
    952     // http://b/31039416. Android N+ checks current time in hasExpired.
    953     // Repeated invocations of cookie.hasExpired() may return different results
    954     // due to time passage.
    955     // This was not the case in earlier android versions, where hasExpired
    956     // was testing the value of max-age/expires at the time of cookie creation.
    957     public void test_hasExpired_checksTime() throws Exception {
    958         List<HttpCookie> list = HttpCookie.parse("Set-Cookie:name=test;Max-Age=1");
    959         HttpCookie cookie = list.get(0);
    960         assertFalse(cookie.hasExpired());
    961         Thread.sleep(2000);
    962         assertTrue(cookie.hasExpired());
    963     }
    964 
    965     /**
    966      * java.net.HttpCookie#parse(String) on multiple threads
    967      * Regression test for HARMONY-6307
    968      * @since 1.6
    969      */
    970     class ParseThread extends Thread {
    971         public AssertionError error = null;
    972 
    973         public void run() {
    974             try {
    975                 for (int i = 0; i < 200; i++) {
    976                     List<HttpCookie> list = HttpCookie.parse("Set-cookie:PREF=test;path=/;domain=.b.c;");
    977                     assertEquals(1, list.size());
    978                     HttpCookie cookie = list.get(0);
    979                     assertEquals(0, cookie.getVersion());
    980                     assertEquals(".b.c", cookie.getDomain());
    981                 }
    982             } catch (AssertionError e) {
    983                 error = e;
    984             }
    985         }
    986     }
    987 
    988     public void test_Parse_multipleThreads() throws InterruptedException {
    989         ParseThread[] threads = new ParseThread[10];
    990         // create threads
    991         for (int i = 0; i < threads.length; i++) {
    992             threads[i] = new ParseThread();
    993         }
    994 
    995         // start threads
    996         for (ParseThread thread : threads) {
    997             thread.start();
    998         }
    999 
   1000         // wait for threads to finish
   1001         for (ParseThread thread : threads) {
   1002             thread.join();
   1003         }
   1004 
   1005         for (ParseThread thread : threads) {
   1006             if (thread.error != null) {
   1007                 fail("Assertion thrown in thread " + thread + ": " + thread.error);
   1008             }
   1009         }
   1010     }
   1011 
   1012     private void checkValidValue(String header, String value) {
   1013         List<HttpCookie> list = HttpCookie
   1014                 .parse(header + "name=" + value + ";");
   1015         HttpCookie cookie = list.get(0);
   1016         assertEquals(value, cookie.getValue());
   1017     }
   1018 
   1019     private void checkInvalidCookie(String header) {
   1020         try {
   1021             HttpCookie.parse(header);
   1022             fail("Should throw IllegalArgumentException");
   1023         } catch (IllegalArgumentException e) {
   1024             // expected
   1025         }
   1026     }
   1027 
   1028     @Override
   1029     protected void setUp() throws Exception {
   1030         super.setUp();
   1031         // version 0 cookie only takes effect on Locale.ENGLISH
   1032         locale = Locale.getDefault();
   1033         Locale.setDefault(Locale.ENGLISH);
   1034     }
   1035 
   1036     @Override
   1037     protected void tearDown() throws Exception {
   1038         Locale.setDefault(locale);
   1039         super.tearDown();
   1040     }
   1041 
   1042 }
   1043