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