Home | History | Annotate | Download | only in net
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 /* Licensed to the Apache Software Foundation (ASF) under one or more
     18  * contributor license agreements.  See the NOTICE file distributed with
     19  * this work for additional information regarding copyright ownership.
     20  * The ASF licenses this file to You under the Apache License, Version 2.0
     21  * (the "License"); you may not use this file except in compliance with
     22  * the License.  You may obtain a copy of the License at
     23  *
     24  *     http://www.apache.org/licenses/LICENSE-2.0
     25  *
     26  * Unless required by applicable law or agreed to in writing, software
     27  * distributed under the License is distributed on an "AS IS" BASIS,
     28  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     29  * See the License for the specific language governing permissions and
     30  * limitations under the License.
     31  */
     32 
     33 package libcore.java.net;
     34 
     35 import com.google.mockwebserver.MockResponse;
     36 import com.google.mockwebserver.MockWebServer;
     37 import com.google.mockwebserver.RecordedRequest;
     38 import java.io.IOException;
     39 import java.net.CookieHandler;
     40 import java.net.CookieManager;
     41 import static java.net.CookiePolicy.ACCEPT_ORIGINAL_SERVER;
     42 
     43 import java.net.CookiePolicy;
     44 import java.net.CookieStore;
     45 import java.net.HttpCookie;
     46 import java.net.HttpURLConnection;
     47 import java.net.URI;
     48 import java.net.URISyntaxException;
     49 import java.net.URLConnection;
     50 import java.util.ArrayList;
     51 import java.util.Arrays;
     52 import java.util.Collection;
     53 import java.util.Collections;
     54 import java.util.Comparator;
     55 import java.util.HashMap;
     56 import java.util.LinkedHashMap;
     57 import java.util.List;
     58 import java.util.Locale;
     59 import java.util.Map;
     60 import java.util.RandomAccess;
     61 import java.util.TreeMap;
     62 
     63 import junit.framework.TestCase;
     64 
     65 public abstract class AbstractCookiesTest extends TestCase {
     66 
     67     private static final Map<String, List<String>> EMPTY_COOKIES_MAP = Collections.emptyMap();
     68 
     69     private CookieHandler defaultHandler;
     70     private CookieManager cookieManager;
     71     private CookieStore cookieStore;
     72     private MockWebServer server;
     73 
     74 
     75     @Override public void setUp() throws Exception {
     76         super.setUp();
     77         server = new MockWebServer();
     78         defaultHandler = CookieHandler.getDefault();
     79         cookieManager = new CookieManager(createCookieStore(), null);
     80         cookieStore = cookieManager.getCookieStore();
     81     }
     82 
     83     @Override public void tearDown() throws Exception {
     84         CookieHandler.setDefault(defaultHandler);
     85         server.shutdown();
     86         super.tearDown();
     87     }
     88 
     89     protected abstract CookieStore createCookieStore();
     90 
     91     public void testNetscapeResponse() throws Exception {
     92         CookieManager cookieManager = new CookieManager(createCookieStore(),
     93                 ACCEPT_ORIGINAL_SERVER);
     94         CookieHandler.setDefault(cookieManager);
     95         server.play();
     96 
     97         server.enqueue(new MockResponse().addHeader("Set-Cookie: a=android; "
     98                 + "expires=Fri, 31-Dec-9999 23:59:59 GMT; "
     99                 + "path=/path; "
    100                 + "domain=" + server.getCookieDomain() + "; "
    101                 + "secure"));
    102         get(server, "/path/foo");
    103 
    104         List<HttpCookie> cookies = cookieManager.getCookieStore().getCookies();
    105         assertEquals(1, cookies.size());
    106         HttpCookie cookie = cookies.get(0);
    107         assertEquals("a", cookie.getName());
    108         assertEquals("android", cookie.getValue());
    109         assertEquals(null, cookie.getComment());
    110         assertEquals(null, cookie.getCommentURL());
    111         assertEquals(false, cookie.getDiscard());
    112         assertEquals(server.getCookieDomain(), cookie.getDomain());
    113         assertTrue(cookie.getMaxAge() > 100000000000L);
    114         assertEquals("/path", cookie.getPath());
    115         assertEquals(true, cookie.getSecure());
    116         assertEquals(0, cookie.getVersion());
    117     }
    118 
    119     public void testRfc2109Response() throws Exception {
    120         CookieManager cookieManager = new CookieManager(createCookieStore(),
    121                 ACCEPT_ORIGINAL_SERVER);
    122         CookieHandler.setDefault(cookieManager);
    123         server.play();
    124 
    125         server.enqueue(new MockResponse().addHeader("Set-Cookie: a=android; "
    126                 + "Comment=this cookie is delicious; "
    127                 + "Domain=" + server.getCookieDomain() + "; "
    128                 + "Max-Age=60; "
    129                 + "Path=/path; "
    130                 + "Secure; "
    131                 + "Version=1"));
    132         get(server, "/path/foo");
    133 
    134         List<HttpCookie> cookies = cookieManager.getCookieStore().getCookies();
    135         assertEquals(1, cookies.size());
    136         HttpCookie cookie = cookies.get(0);
    137         assertEquals("a", cookie.getName());
    138         assertEquals("android", cookie.getValue());
    139         assertEquals("this cookie is delicious", cookie.getComment());
    140         assertEquals(null, cookie.getCommentURL());
    141         assertEquals(false, cookie.getDiscard());
    142         assertEquals(server.getCookieDomain(), cookie.getDomain());
    143         assertEquals(60, cookie.getMaxAge());
    144         assertEquals("/path", cookie.getPath());
    145         assertEquals(true, cookie.getSecure());
    146         assertEquals(1, cookie.getVersion());
    147     }
    148 
    149     public void testRfc2965Response() throws Exception {
    150         CookieManager cookieManager = new CookieManager(createCookieStore(),
    151                 ACCEPT_ORIGINAL_SERVER);
    152         CookieHandler.setDefault(cookieManager);
    153         server.play();
    154 
    155         server.enqueue(new MockResponse().addHeader("Set-Cookie2: a=android; "
    156                 + "Comment=this cookie is delicious; "
    157                 + "CommentURL=http://google.com/; "
    158                 + "Discard; "
    159                 + "Domain=" + server.getCookieDomain() + "; "
    160                 + "Max-Age=60; "
    161                 + "Path=/path; "
    162                 + "Port=\"80,443," + server.getPort() + "\"; "
    163                 + "Secure; "
    164                 + "Version=1"));
    165         get(server, "/path/foo");
    166 
    167         List<HttpCookie> cookies = cookieManager.getCookieStore().getCookies();
    168         assertEquals(1, cookies.size());
    169         HttpCookie cookie = cookies.get(0);
    170         assertEquals("a", cookie.getName());
    171         assertEquals("android", cookie.getValue());
    172         assertEquals("this cookie is delicious", cookie.getComment());
    173         assertEquals("http://google.com/", cookie.getCommentURL());
    174         assertEquals(true, cookie.getDiscard());
    175         assertEquals(server.getCookieDomain(), cookie.getDomain());
    176         assertEquals(60, cookie.getMaxAge());
    177         assertEquals("/path", cookie.getPath());
    178         assertEquals("80,443," + server.getPort(), cookie.getPortlist());
    179         assertEquals(true, cookie.getSecure());
    180         assertEquals(1, cookie.getVersion());
    181     }
    182 
    183     public void testQuotedAttributeValues() throws Exception {
    184         CookieManager cookieManager = new CookieManager(createCookieStore(),
    185                 ACCEPT_ORIGINAL_SERVER);
    186 
    187         CookieHandler.setDefault(cookieManager);
    188         server.play();
    189 
    190         server.enqueue(new MockResponse().addHeader("Set-Cookie2: a=\"android\"; "
    191                 + "Comment=\"this cookie is delicious\"; "
    192                 + "CommentURL=\"http://google.com/\"; "
    193                 + "Discard; "
    194                 + "Domain=\"" + server.getCookieDomain() + "\"; "
    195                 + "Max-Age=\"60\"; "
    196                 + "Path=\"/path\"; "
    197                 + "Port=\"80,443," + server.getPort() + "\"; "
    198                 + "Secure; "
    199                 + "Version=\"1\""));
    200         get(server, "/path/foo");
    201 
    202         List<HttpCookie> cookies = cookieManager.getCookieStore().getCookies();
    203         assertEquals(1, cookies.size());
    204         HttpCookie cookie = cookies.get(0);
    205         assertEquals("a", cookie.getName());
    206         assertEquals("android", cookie.getValue());
    207         assertEquals("this cookie is delicious", cookie.getComment());
    208         assertEquals("http://google.com/", cookie.getCommentURL());
    209         assertEquals(true, cookie.getDiscard());
    210         assertEquals(server.getCookieDomain(), cookie.getDomain());
    211         assertEquals(60, cookie.getMaxAge());
    212         assertEquals("/path", cookie.getPath());
    213         assertEquals("80,443," + server.getPort(), cookie.getPortlist());
    214         assertEquals(true, cookie.getSecure());
    215         assertEquals(1, cookie.getVersion());
    216     }
    217 
    218     public void testResponseWithMultipleCookieHeaderLines() throws Exception {
    219         TestCookieStore cookieStore = new TestCookieStore();
    220         CookieManager cookieManager = new CookieManager(cookieStore, ACCEPT_ORIGINAL_SERVER);
    221         cookieManager.put(new URI("http://android.com"), cookieHeaders("a=android", "b=banana"));
    222         List<HttpCookie> cookies = sortedCopy(cookieStore.cookies);
    223         assertEquals(2, cookies.size());
    224         HttpCookie cookieA = cookies.get(0);
    225         assertEquals("a", cookieA.getName());
    226         assertEquals("android", cookieA.getValue());
    227         HttpCookie cookieB = cookies.get(1);
    228         assertEquals("b", cookieB.getName());
    229         assertEquals("banana", cookieB.getValue());
    230     }
    231 
    232     public void testDomainDefaulting() throws Exception {
    233         TestCookieStore cookieStore = new TestCookieStore();
    234         CookieManager cookieManager = new CookieManager(cookieStore, ACCEPT_ORIGINAL_SERVER);
    235         cookieManager.put(new URI("http://android.com/"), cookieHeaders("a=android"));
    236         assertEquals("android.com", cookieStore.getCookie("a").getDomain());
    237     }
    238 
    239     public void testNonMatchingDomainsRejected() throws Exception {
    240         TestCookieStore cookieStore = new TestCookieStore();
    241         CookieManager cookieManager = new CookieManager(cookieStore, ACCEPT_ORIGINAL_SERVER);
    242         cookieManager.put(new URI("http://android.com/"),
    243                 cookieHeaders("a=android;domain=google.com"));
    244         assertEquals(Collections.<HttpCookie>emptyList(), cookieStore.cookies);
    245     }
    246 
    247     public void testMatchingDomainsAccepted() throws Exception {
    248         TestCookieStore cookieStore = new TestCookieStore();
    249         CookieManager cookieManager = new CookieManager(cookieStore, ACCEPT_ORIGINAL_SERVER);
    250         cookieManager.put(new URI("http://www.android.com/"),
    251                 cookieHeaders("a=android;domain=.android.com"));
    252         assertEquals(".android.com", cookieStore.getCookie("a").getDomain());
    253     }
    254 
    255     public void testPathDefaulting() throws Exception {
    256         TestCookieStore cookieStore = new TestCookieStore();
    257         CookieManager cookieManager = new CookieManager(cookieStore, ACCEPT_ORIGINAL_SERVER);
    258         cookieManager.put(new URI("http://android.com/foo/bar"), cookieHeaders("a=android"));
    259         assertEquals("/foo/", cookieStore.getCookie("a").getPath());
    260         cookieManager.put(new URI("http://android.com/"), cookieHeaders("b=banana"));
    261         assertEquals("/", cookieStore.getCookie("b").getPath());
    262         cookieManager.put(new URI("http://android.com/foo/"), cookieHeaders("c=carrot"));
    263         assertEquals("/foo/", cookieStore.getCookie("c").getPath());
    264     }
    265 
    266     public void testNonMatchingPathsRejected() throws Exception {
    267         TestCookieStore cookieStore = new TestCookieStore();
    268         CookieManager cookieManager = new CookieManager(cookieStore, ACCEPT_ORIGINAL_SERVER);
    269         cookieManager.put(new URI("http://android.com/foo/bar"),
    270                 cookieHeaders("a=android;path=/baz/bar"));
    271         assertEquals("Expected to reject cookies whose path is not a prefix of the request path",
    272                 Collections.<HttpCookie>emptyList(), cookieStore.cookies); // RI6 fails this
    273     }
    274 
    275     public void testMatchingPathsAccepted() throws Exception {
    276         TestCookieStore cookieStore = new TestCookieStore();
    277         CookieManager cookieManager = new CookieManager(cookieStore, ACCEPT_ORIGINAL_SERVER);
    278         cookieManager.put(new URI("http://android.com/foo/bar/"),
    279                 cookieHeaders("a=android;path=/foo"));
    280         assertEquals("/foo", cookieStore.getCookie("a").getPath());
    281     }
    282 
    283     public void testNoCookieHeaderSentIfNoCookiesMatch() throws IOException, URISyntaxException {
    284         CookieManager cookieManager = new CookieManager(null, ACCEPT_ORIGINAL_SERVER);
    285         Map<String, List<String>> cookieHeaders = cookieManager.get(
    286                 new URI("http://android.com/foo/bar/"), EMPTY_COOKIES_MAP);
    287         assertTrue(cookieHeaders.toString(), cookieHeaders.isEmpty()
    288                 || (cookieHeaders.size() == 1 && cookieHeaders.get("Cookie").isEmpty()));
    289     }
    290 
    291     public void testCookieManagerGet_schemeChecks() throws Exception {
    292         CookieManager cookieManager = new CookieManager(createCookieStore(), null);
    293 
    294         cookieManager.put(new URI("http://a.com/"), cookieHeaders("a1=android"));
    295         cookieManager.put(new URI("https://a.com/"), cookieHeaders("a2=android"));
    296         cookieManager.put(new URI("https://a.com/"), cookieHeaders("a3=android; Secure"));
    297 
    298         assertManagerCookiesMatch(cookieManager, "http://a.com/", "a1=android; a2=android");
    299         assertManagerCookiesMatch(cookieManager, "https://a.com/",
    300                 "a1=android; a2=android; a3=android");
    301     }
    302 
    303     public void testCookieManagerGet_hostChecks() throws Exception {
    304         CookieManager cookieManager = new CookieManager(createCookieStore(), null);
    305 
    306         cookieManager.put(new URI("http://a.com/"), cookieHeaders("a1=android"));
    307         cookieManager.put(new URI("http://b.com/"), cookieHeaders("b1=android"));
    308 
    309         assertManagerCookiesMatch(cookieManager, "http://a.com/", "a1=android");
    310         assertManagerCookiesMatch(cookieManager, "http://b.com/", "b1=android");
    311     }
    312 
    313     public void testCookieManagerGet_portChecks() throws Exception {
    314         CookieManager cookieManager = new CookieManager(createCookieStore(), null);
    315 
    316         cookieManager.put(new URI("http://a.com:443/"), cookieHeaders("a1=android"));
    317         cookieManager.put(new URI("http://a.com:8080/"), cookieHeaders("a2=android"));
    318         cookieManager.put(new URI("http://a.com:8080/"), cookieHeaders("a3=android; Port=8080"));
    319 
    320         assertManagerCookiesMatch(cookieManager, "http://a.com/", "a1=android; a2=android");
    321         assertManagerCookiesMatch(cookieManager, "http://a.com:8080/",
    322                 "a1=android; a2=android; a3=android");
    323     }
    324 
    325     public void testCookieManagerGet_pathChecks() throws Exception {
    326         CookieManager cookieManager = new CookieManager(createCookieStore(), null);
    327 
    328         cookieManager.put(new URI("http://a.com/"), cookieHeaders("a1=android"));
    329         cookieManager.put(new URI("http://a.com/path1"),
    330                 cookieHeaders("a2=android; Path=\"/path1\""));
    331         cookieManager.put(new URI("http://a.com/path2"),
    332                 cookieHeaders("a3=android; Path=\"/path2\""));
    333 
    334         assertManagerCookiesMatch(cookieManager, "http://a.com/notpath", "a1=android");
    335         assertManagerCookiesMatch(cookieManager, "http://a.com/path1", "a1=android; a2=android");
    336     }
    337 
    338     public void testSendingCookiesFromStore() throws Exception {
    339         server.enqueue(new MockResponse());
    340         server.play();
    341 
    342         CookieManager cookieManager = new CookieManager(createCookieStore(),
    343                 ACCEPT_ORIGINAL_SERVER);
    344         HttpCookie cookieA = createCookie("a", "android", server.getCookieDomain(), "/");
    345         cookieManager.getCookieStore().add(server.getUrl("/").toURI(), cookieA);
    346         HttpCookie cookieB = createCookie("b", "banana", server.getCookieDomain(), "/");
    347         cookieManager.getCookieStore().add(server.getUrl("/").toURI(), cookieB);
    348         CookieHandler.setDefault(cookieManager);
    349 
    350         get(server, "/");
    351         RecordedRequest request = server.takeRequest();
    352 
    353         List<String> receivedHeaders = request.getHeaders();
    354         assertContains(receivedHeaders, "Cookie: $Version=\"1\"; "
    355                 + "a=\"android\";$Path=\"/\";$Domain=\"" + server.getCookieDomain() + "\"; "
    356                 + "b=\"banana\";$Path=\"/\";$Domain=\"" + server.getCookieDomain() + "\"");
    357     }
    358 
    359     public void testRedirectsDoNotIncludeTooManyCookies() throws Exception {
    360         MockWebServer redirectTarget = new MockWebServer();
    361         redirectTarget.enqueue(new MockResponse().setBody("A"));
    362         redirectTarget.play();
    363 
    364         MockWebServer redirectSource = new MockWebServer();
    365         redirectSource.enqueue(new MockResponse()
    366                 .setResponseCode(HttpURLConnection.HTTP_MOVED_TEMP)
    367                 .addHeader("Location: " + redirectTarget.getUrl("/")));
    368         redirectSource.play();
    369 
    370         CookieManager cookieManager = new CookieManager(createCookieStore(),
    371                 ACCEPT_ORIGINAL_SERVER);
    372         HttpCookie cookie = createCookie("c", "cookie", redirectSource.getCookieDomain(), "/");
    373         String portList = Integer.toString(redirectSource.getPort());
    374         cookie.setPortlist(portList);
    375         cookieManager.getCookieStore().add(redirectSource.getUrl("/").toURI(), cookie);
    376         CookieHandler.setDefault(cookieManager);
    377 
    378         get(redirectSource, "/");
    379         RecordedRequest request = redirectSource.takeRequest();
    380 
    381         assertContains(request.getHeaders(), "Cookie: $Version=\"1\"; "
    382                 + "c=\"cookie\";$Path=\"/\";$Domain=\"" + redirectSource.getCookieDomain()
    383                 + "\";$Port=\"" + portList + "\"");
    384 
    385         for (String header : redirectTarget.takeRequest().getHeaders()) {
    386             if (header.startsWith("Cookie")) {
    387                 fail(header);
    388             }
    389         }
    390         redirectSource.shutdown();
    391         redirectTarget.shutdown();
    392     }
    393 
    394     /**
    395      * Test which headers show up where. The cookie manager should be notified
    396      * of both user-specified and derived headers like {@code Host}. Headers
    397      * named {@code Cookie} or {@code Cookie2} that are returned by the cookie
    398      * manager should show up in the request and in {@code
    399      * getRequestProperties}.
    400      */
    401     public void testHeadersSentToCookieHandler() throws IOException, InterruptedException {
    402         final Map<String, List<String>> cookieHandlerHeaders = new HashMap<String, List<String>>();
    403         CookieHandler.setDefault(new CookieManager(createCookieStore(), null) {
    404             @Override
    405             public Map<String, List<String>> get(URI uri,
    406                     Map<String, List<String>> requestHeaders) throws IOException {
    407                 cookieHandlerHeaders.putAll(requestHeaders);
    408                 Map<String, List<String>> result = new HashMap<String, List<String>>();
    409                 result.put("Cookie", Collections.singletonList("Bar=bar"));
    410                 result.put("Cookie2", Collections.singletonList("Baz=baz"));
    411                 result.put("Quux", Collections.singletonList("quux"));
    412                 return result;
    413             }
    414         });
    415         server.enqueue(new MockResponse());
    416         server.play();
    417 
    418         HttpURLConnection connection = (HttpURLConnection) server.getUrl("/").openConnection();
    419         assertEquals(Collections.<String, List<String>>emptyMap(),
    420                 connection.getRequestProperties());
    421 
    422         connection.setRequestProperty("Foo", "foo");
    423         connection.setDoOutput(true);
    424         connection.getOutputStream().write(5);
    425         connection.getOutputStream().close();
    426         connection.getInputStream().close();
    427 
    428         RecordedRequest request = server.takeRequest();
    429 
    430         assertContainsAll(cookieHandlerHeaders.keySet(), "Foo");
    431         assertContainsAll(cookieHandlerHeaders.keySet(),
    432                 "Content-Type", "User-Agent", "Connection", "Host");
    433         assertFalse(cookieHandlerHeaders.containsKey("Cookie"));
    434 
    435         /*
    436          * The API specifies that calling getRequestProperties() on a connected instance should fail
    437          * with an IllegalStateException, but the RI violates the spec and returns a valid map.
    438          * http://www.mail-archive.com/net-dev@openjdk.java.net/msg01768.html
    439          */
    440         try {
    441             assertContainsAll(connection.getRequestProperties().keySet(), "Foo");
    442             assertContainsAll(connection.getRequestProperties().keySet(),
    443                     "Content-Type", "Content-Length", "User-Agent", "Connection", "Host");
    444             assertContainsAll(connection.getRequestProperties().keySet(), "Cookie", "Cookie2");
    445             assertFalse(connection.getRequestProperties().containsKey("Quux"));
    446         } catch (IllegalStateException expected) {
    447         }
    448 
    449         assertContainsAll(request.getHeaders(), "Foo: foo", "Cookie: Bar=bar", "Cookie2: Baz=baz");
    450         assertFalse(request.getHeaders().contains("Quux: quux"));
    451     }
    452 
    453     public void testCookiesSentIgnoresCase() throws Exception {
    454         CookieHandler.setDefault(new CookieManager(createCookieStore(), null) {
    455             @Override public Map<String, List<String>> get(URI uri,
    456                     Map<String, List<String>> requestHeaders) throws IOException {
    457                 Map<String, List<String>> result = new HashMap<String, List<String>>();
    458                 result.put("COOKIE", Collections.singletonList("Bar=bar"));
    459                 result.put("cooKIE2", Collections.singletonList("Baz=baz"));
    460                 return result;
    461             }
    462         });
    463         server. enqueue(new MockResponse());
    464         server.play();
    465 
    466         get(server, "/");
    467 
    468         RecordedRequest request = server.takeRequest();
    469         assertContainsAll(request.getHeaders(), "COOKIE: Bar=bar", "cooKIE2: Baz=baz");
    470         assertFalse(request.getHeaders().contains("Quux: quux"));
    471     }
    472 
    473     /**
    474      * RFC 2109 and RFC 2965 disagree here. 2109 says two equals strings match only if they are
    475      * fully-qualified domain names. 2965 says two equal strings always match. We're testing for
    476      * 2109 behavior because it's more widely used, it's more conservative, and it's what the RI
    477      * does.
    478      */
    479     public void testDomainMatchesOnLocalAddresses() {
    480         assertFalse(HttpCookie.domainMatches("localhost", "localhost"));
    481         assertFalse(HttpCookie.domainMatches("b", "b"));
    482     }
    483 
    484     public void testDomainMatchesOnIpAddress() {
    485         assertTrue(HttpCookie.domainMatches("127.0.0.1", "127.0.0.1"));
    486         assertFalse(HttpCookie.domainMatches("127.0.0.1", "127.0.0.0"));
    487         assertFalse(HttpCookie.domainMatches("127.0.0.1", "localhost"));
    488     }
    489 
    490     public void testDomainMatchesCaseMapping() {
    491         testDomainMatchesCaseMapping(Locale.US);
    492     }
    493 
    494     public void testDomainMatchesCaseMappingExoticLocale() {
    495         testDomainMatchesCaseMapping(new Locale("tr", "TR"));
    496     }
    497 
    498     private void testDomainMatchesCaseMapping(Locale locale) {
    499         Locale defaultLocale = Locale.getDefault();
    500         Locale.setDefault(locale);
    501         try {
    502             assertTrue(HttpCookie.domainMatches(".android.com", "WWW.ANDROID.COM"));
    503             assertFalse(HttpCookie.domainMatches("android.com", "WWW.ANDROID.COM"));
    504         } finally {
    505             Locale.setDefault(defaultLocale);
    506         }
    507     }
    508 
    509     /**
    510      * From the spec, "If an explicitly specified value does not start with a dot, the user agent
    511      * supplies a leading dot.". This prepending doesn't happen in setDomain.
    512      */
    513     public void testDomainNotAutomaticallyPrefixedWithDot() {
    514         HttpCookie cookie = new HttpCookie("Foo", "foo");
    515         cookie.setDomain("localhost");
    516         assertEquals("localhost", cookie.getDomain());
    517     }
    518 
    519     public void testCookieStoreNullUris() {
    520         CookieStore cookieStore = new CookieManager(createCookieStore(), null).getCookieStore();
    521         HttpCookie cookieA = createCookie("a", "android", ".android.com", "/source");
    522         HttpCookie cookieB = createCookie("b", "banana", "code.google.com", "/p/android");
    523 
    524         try {
    525             cookieStore.add(null, cookieA);
    526         } catch (NullPointerException expected) {
    527             // the RI crashes even though the cookie does get added to the store; sigh
    528             expected.printStackTrace();
    529         }
    530         assertEquals(Arrays.asList(cookieA), cookieStore.getCookies());
    531         try {
    532             cookieStore.add(null, cookieB);
    533         } catch (NullPointerException expected) {
    534         }
    535         assertEquals(Arrays.asList(cookieA, cookieB), cookieStore.getCookies());
    536 
    537         try {
    538             cookieStore.get(null);
    539             fail();
    540         } catch (NullPointerException expected) {
    541         }
    542 
    543         assertEquals(Collections.<URI>emptyList(), cookieStore.getURIs());
    544         assertTrue(cookieStore.remove(null, cookieA));
    545         assertEquals(Arrays.asList(cookieB), cookieStore.getCookies());
    546 
    547         assertTrue(cookieStore.removeAll());
    548         assertEquals(Collections.<URI>emptyList(), cookieStore.getURIs());
    549         assertEquals(Collections.<HttpCookie>emptyList(), cookieStore.getCookies());
    550     }
    551 
    552     public void testCookieStoreRemoveAll() throws URISyntaxException {
    553         CookieStore cookieStore = new CookieManager(createCookieStore(), null).getCookieStore();
    554         cookieStore.add(new URI("http://code.google.com/"), new HttpCookie("a", "android"));
    555         assertTrue(cookieStore.removeAll());
    556         assertEquals(Collections.<URI>emptyList(), cookieStore.getURIs());
    557         assertEquals(Collections.<HttpCookie>emptyList(), cookieStore.getCookies());
    558         assertFalse("Expected removeAll() to return false when the call doesn't mutate the store",
    559                 cookieStore.removeAll());  // RI6 fails this
    560     }
    561 
    562     public void testCookieStoreAddAcceptsConflictingUri() throws URISyntaxException {
    563         CookieStore cookieStore = new CookieManager().getCookieStore();
    564         HttpCookie cookieA = createCookie("a", "android", ".android.com", "/source/");
    565         cookieStore.add(new URI("http://google.com/source/"), cookieA);
    566         assertEquals(Arrays.asList(cookieA), cookieStore.getCookies());
    567     }
    568 
    569     public void testCookieStoreRemoveRequiresUri() throws URISyntaxException {
    570         CookieStore cookieStore = new CookieManager(createCookieStore(), null).getCookieStore();
    571         HttpCookie cookieA = new HttpCookie("a", "android");
    572         cookieStore.add(new URI("http://android.com/source/"), cookieA);
    573         assertFalse("Expected remove() to take the cookie URI into account.", // RI6 fails this
    574                 cookieStore.remove(new URI("http://code.google.com/"), cookieA));
    575         assertEquals(Arrays.asList(cookieA), cookieStore.getCookies());
    576     }
    577 
    578     public void testCookieStoreUriUsesHttpSchemeAlways() throws URISyntaxException {
    579         CookieStore cookieStore = new CookieManager(createCookieStore(), null).getCookieStore();
    580         cookieStore.add(new URI("https://a.com/"), new HttpCookie("a", "android"));
    581         assertEquals(Arrays.asList(new URI("http://a.com")), cookieStore.getURIs());
    582     }
    583 
    584     public void testCookieStoreUriDropsUserInfo() throws URISyntaxException {
    585         CookieStore cookieStore = new CookieManager(createCookieStore(), null).getCookieStore();
    586         cookieStore.add(new URI("http://jesse:secret@a.com/"), new HttpCookie("a", "android"));
    587         assertEquals(Arrays.asList(new URI("http://a.com")), cookieStore.getURIs());
    588     }
    589 
    590     public void testCookieStoreUriKeepsHost() throws URISyntaxException {
    591         CookieStore cookieStore = new CookieManager(createCookieStore(), null).getCookieStore();
    592         cookieStore.add(new URI("http://b.com/"), new HttpCookie("a", "android"));
    593         assertEquals(Arrays.asList(new URI("http://b.com")), cookieStore.getURIs());
    594     }
    595 
    596     public void testCookieStoreUriDropsPort() throws URISyntaxException {
    597         CookieStore cookieStore = new CookieManager(createCookieStore(), null).getCookieStore();
    598         cookieStore.add(new URI("http://a.com:443/"), new HttpCookie("a", "android"));
    599         assertEquals(Arrays.asList(new URI("http://a.com")), cookieStore.getURIs());
    600     }
    601 
    602     public void testCookieStoreUriDropsPath() throws URISyntaxException {
    603         CookieStore cookieStore = new CookieManager(createCookieStore(), null).getCookieStore();
    604         cookieStore.add(new URI("http://a.com/a/"), new HttpCookie("a", "android"));
    605         assertEquals(Arrays.asList(new URI("http://a.com")), cookieStore.getURIs());
    606     }
    607 
    608     public void testCookieStoreUriDropsFragment() throws URISyntaxException {
    609         CookieStore cookieStore = new CookieManager(createCookieStore(), null).getCookieStore();
    610         cookieStore.add(new URI("http://a.com/a/foo#fragment"), new HttpCookie("a", "android"));
    611         assertEquals(Arrays.asList(new URI("http://a.com")), cookieStore.getURIs());
    612     }
    613 
    614     public void testCookieStoreUriDropsQuery() throws URISyntaxException {
    615         CookieStore cookieStore = new CookieManager(createCookieStore(), null).getCookieStore();
    616         cookieStore.add(new URI("http://a.com/a/foo?query=value"), new HttpCookie("a", "android"));
    617         assertEquals(Arrays.asList(new URI("http://a.com")), cookieStore.getURIs());
    618     }
    619 
    620     public void testCookieStoreGet() throws Exception {
    621         CookieStore cookieStore = new CookieManager(createCookieStore(), null).getCookieStore();
    622         HttpCookie cookiePort1 = createCookie("a1", "android", "a.com", "/path1");
    623         HttpCookie cookiePort2 = createCookie("a2", "android", "a.com", "/path2");
    624         HttpCookie secureCookie = createCookie("a3", "android", "a.com", "/path3");
    625         secureCookie.setSecure(true);
    626         HttpCookie notSecureCookie = createCookie("a4", "android", "a.com", "/path4");
    627 
    628         HttpCookie bCookie = createCookie("b1", "android", "b.com", "/path5");
    629 
    630         cookieStore.add(new URI("http://a.com:443/path1"), cookiePort1);
    631         cookieStore.add(new URI("http://a.com:8080/path2"), cookiePort2);
    632         cookieStore.add(new URI("https://a.com:443/path3"), secureCookie);
    633         cookieStore.add(new URI("https://a.com:443/path4"), notSecureCookie);
    634         cookieStore.add(new URI("https://b.com:8080/path5"), bCookie);
    635 
    636         List<HttpCookie> expectedStoreCookies = new ArrayList<>();
    637         expectedStoreCookies.add(cookiePort1);
    638         expectedStoreCookies.add(cookiePort2);
    639         expectedStoreCookies.add(secureCookie);
    640         expectedStoreCookies.add(notSecureCookie);
    641 
    642         // The default CookieStore implementation on Android is currently responsible for matching
    643         // the host/domain but not handling other cookie rules: it ignores the scheme (e.g. "secure"
    644         // checks), port and path.
    645         // The tests below fail on the RI. It looks like in the RI it is CookieStoreImpl that is
    646         // enforcing "secure" checks.
    647         assertEquals(expectedStoreCookies, cookieStore.get(new URI("http://a.com:443/anypath")));
    648         assertEquals(expectedStoreCookies, cookieStore.get(new URI("http://a.com:8080/anypath")));
    649         assertEquals(expectedStoreCookies, cookieStore.get(new URI("https://a.com/anypath")));
    650         assertEquals(expectedStoreCookies, cookieStore.get(new URI("http://a.com/anypath")));
    651     }
    652 
    653     /**
    654      * Regression test for http://b/25682357 /
    655      * https://code.google.com/p/android/issues/detail?id=193475
    656      * CookieStoreImpl.get(URI) not handling ports properly in the absence of an explicit cookie
    657      * Domain.
    658      */
    659     public void testCookieStoreGetWithPort() throws Exception {
    660         CookieStore cookieStore = new CookieManager(createCookieStore(), null).getCookieStore();
    661         HttpCookie cookie = new HttpCookie("theme", "light");
    662         // Deliberately not setting the cookie domain or path.
    663         cookieStore.add(new URI("http://a.com:12345"), cookie);
    664 
    665         // CookieStoreImpl must ignore the port during retrieval when domain is not set.
    666         assertEquals(1, cookieStore.get(new URI("http://a.com:12345/path1")).size());
    667         assertEquals(1, cookieStore.get(new URI("http://a.com/path1")).size());
    668     }
    669 
    670     public void testCookieStoreGetWithSecure() throws Exception {
    671         CookieStore cookieStore = new CookieManager(createCookieStore(), null).getCookieStore();
    672         HttpCookie cookie = createCookie("theme", "light", "a.com", "/path");
    673         cookie.setSecure(true);
    674         cookieStore.add(new URI("https://a.com/path"), cookie);
    675 
    676         // CookieStoreImpl on Android ignores the "Secure" attribute. The RI implements the secure
    677         // check in CookieStoreImpl. For safety / app compatibility, if this is changed Android
    678         // should probably implement it in both places.
    679         assertEquals(1, cookieStore.get(new URI("http://a.com/path")).size());
    680         assertEquals(1, cookieStore.get(new URI("https://a.com/path")).size());
    681     }
    682 
    683     public void testCookieStoreEviction() throws Exception {
    684         CookieStore cookieStore = new CookieManager(createCookieStore(), null).getCookieStore();
    685         HttpCookie themeCookie = createCookie("theme", "light", "a.com", "/");
    686         cookieStore.add(new URI("http://a.com/"), themeCookie);
    687 
    688         HttpCookie sidCookie = createCookie("sid", "mysid", "a.com", "/");
    689         cookieStore.add(new URI("http://a.com/"), sidCookie);
    690 
    691         HttpCookie replacementThemeCookie = createCookie("theme", "dark", "a.com", "/");
    692         cookieStore.add(new URI("http://a.com/"), replacementThemeCookie);
    693 
    694         // toString() is used below to avoid confusion with assertEquals():
    695         // HttpCookie.equals() is implemented so that it only checks name, path and domain
    696         // attributes but we also want to check the value.
    697         assertEquals(
    698                 "[sid=\"mysid\";$Path=\"/\";$Domain=\"a.com\", "
    699                         + "theme=\"dark\";$Path=\"/\";$Domain=\"a.com\"]",
    700                 cookieStore.get(new URI("http://a.com/")).toString());
    701 
    702         HttpCookie replacementSidCookie = createCookie("sid", "mynewsid", "A.cOm", "/");
    703         cookieStore.add(new URI("http://a.com/"), replacementSidCookie);
    704 
    705         assertEquals(
    706                 "[theme=\"dark\";$Path=\"/\";$Domain=\"a.com\", "
    707                         + "sid=\"mynewsid\";$Path=\"/\";$Domain=\"a.com\"]",
    708                 cookieStore.get(new URI("http://a.com/")).toString());
    709     }
    710 
    711     /**
    712      * CookieStoreImpl has a strict requirement on HttpCookie.equals() to enable replacement of
    713      * cookies with the same name.
    714      */
    715     public void testCookieEquality() throws Exception {
    716         HttpCookie baseCookie = createCookie("theme", "light", "a.com", "/");
    717 
    718         // None of the attributes immediately below should affect equality otherwise CookieStoreImpl
    719         // eviction will not work as intended.
    720         HttpCookie valueCookie = createCookie("theme", "light", "a.com", "/");
    721         valueCookie.setValue("dark");
    722         valueCookie.setPortlist("1234");
    723         valueCookie.setSecure(true);
    724         valueCookie.setComment("comment");
    725         valueCookie.setCommentURL("commentURL");
    726         valueCookie.setDiscard(true);
    727         valueCookie.setMaxAge(12345L);
    728         valueCookie.setVersion(1);
    729         assertEquals(baseCookie, valueCookie);
    730 
    731         // Changing any of the 3 main identity attributes should render cookies unequal.
    732         assertNotEquals(createCookie("theme2", "light", "a.com", "/"), baseCookie);
    733         assertNotEquals(createCookie("theme", "light", "b.com", "/"), baseCookie);
    734         assertNotEquals(createCookie("theme", "light", "a.com", "/path"), baseCookie);
    735     }
    736 
    737     private static void assertNotEquals(HttpCookie one, HttpCookie two) {
    738         assertFalse(one.equals(two));
    739         assertFalse(two.equals(one));
    740     }
    741 
    742     private void assertContains(Collection<String> collection, String element) {
    743         for (String c : collection) {
    744             if (c != null && c.equalsIgnoreCase(element)) {
    745                 return;
    746             }
    747         }
    748         fail("No " + element + " in " + collection);
    749     }
    750 
    751     private void assertContainsAll(Collection<String> collection, String... toFind) {
    752         for (String s : toFind) {
    753             assertContains(collection, s);
    754         }
    755     }
    756 
    757     private List<HttpCookie> sortedCopy(List<HttpCookie> cookies) {
    758         List<HttpCookie> result = new ArrayList<HttpCookie>(cookies);
    759         Collections.sort(result, new Comparator<HttpCookie>() {
    760             public int compare(HttpCookie a, HttpCookie b) {
    761                 return a.getName().compareTo(b.getName());
    762             }
    763         });
    764         return result;
    765     }
    766 
    767     private Map<String,List<String>> get(MockWebServer server, String path) throws Exception {
    768         URLConnection connection = server.getUrl(path).openConnection();
    769         Map<String, List<String>> headers = connection.getHeaderFields();
    770         connection.getInputStream().close();
    771         return headers;
    772     }
    773 
    774     private static Map<String, List<String>> cookieHeaders(String... headers) {
    775         return Collections.singletonMap("Set-Cookie", Arrays.asList(headers));
    776     }
    777 
    778     static class TestCookieStore implements CookieStore {
    779         private final List<HttpCookie> cookies = new ArrayList<HttpCookie>();
    780 
    781         public void add(URI uri, HttpCookie cookie) {
    782             cookies.add(cookie);
    783         }
    784 
    785         public HttpCookie getCookie(String name) {
    786             for (HttpCookie cookie : cookies) {
    787                 if (cookie.getName().equals(name)) {
    788                     return cookie;
    789                 }
    790             }
    791             throw new IllegalArgumentException("No cookie " + name + " in " + cookies);
    792         }
    793 
    794         public List<HttpCookie> get(URI uri) {
    795             throw new UnsupportedOperationException();
    796         }
    797 
    798         public List<HttpCookie> getCookies() {
    799             throw new UnsupportedOperationException();
    800         }
    801 
    802         public List<URI> getURIs() {
    803             throw new UnsupportedOperationException();
    804         }
    805 
    806         public boolean remove(URI uri, HttpCookie cookie) {
    807             throw new UnsupportedOperationException();
    808         }
    809 
    810         public boolean removeAll() {
    811             throw new UnsupportedOperationException();
    812         }
    813     }
    814 
    815     private static void assertManagerCookiesMatch(CookieManager cookieManager, String url,
    816         String expectedCookieRequestHeader) throws Exception {
    817 
    818         Map<String, List<String>> cookieHeaders =
    819                 cookieManager.get(new URI(url), EMPTY_COOKIES_MAP);
    820         if (expectedCookieRequestHeader == null) {
    821             assertTrue(cookieHeaders.isEmpty());
    822             return;
    823         }
    824 
    825         assertEquals(1, cookieHeaders.size());
    826         List<String> actualCookieHeaderStrings = cookieHeaders.get("Cookie");
    827 
    828         // For simplicity, we concatenate the cookie header strings if there are multiple ones.
    829         String actualCookieRequestHeader = actualCookieHeaderStrings.get(0);
    830         for (int i = 1; i < actualCookieHeaderStrings.size(); i++) {
    831             actualCookieRequestHeader += "; " + actualCookieHeaderStrings.get(i);
    832         }
    833         assertEquals(expectedCookieRequestHeader, actualCookieRequestHeader);
    834     }
    835 
    836     /**
    837      * Creates a well-formed cookie. The behavior when domain is unset varies between
    838      * RFC 2965 and RFC 6265. CookieStoreImpl assumes these values are set "correctly" by the time
    839      * it receives the HttpCookie instance.
    840      */
    841     private static HttpCookie createCookie(String name, String value, String domain, String path) {
    842         HttpCookie cookie = new HttpCookie(name, value);
    843         cookie.setDomain(domain);
    844         cookie.setPath(path);
    845         return cookie;
    846     }
    847 
    848     //
    849     // Start of org.apache.harmony.tests.java.net.CookieManagerTest.
    850     //
    851 
    852     /**
    853      * java.net.CookieStore#add(URI, HttpCookie)
    854      * @since 1.6
    855      */
    856     public void test_add_LURI_LHttpCookie() throws URISyntaxException {
    857         URI uri = new URI("http://harmony.test.unit.org");
    858         HttpCookie cookie = new HttpCookie("name1", "value1");
    859         cookie.setDiscard(true);
    860 
    861         // This needn't throw. We should use the cookie's domain, if set.
    862         // If no domain is set, this cookie will languish in the store until
    863         // it expires.
    864         cookieStore.add(null, cookie);
    865 
    866         try {
    867             cookieStore.add(uri, null);
    868             fail("should throw NullPointerException");
    869         } catch (NullPointerException e) {
    870             // expected
    871         }
    872 
    873         try {
    874             cookieStore.add(null, null);
    875             fail("should throw NullPointerException");
    876         } catch (NullPointerException e) {
    877             // expected
    878         }
    879 
    880         cookieStore.add(uri, cookie);
    881         List<HttpCookie> list = cookieStore.get(uri);
    882         assertEquals(1, list.size());
    883         assertTrue(list.contains(cookie));
    884 
    885         HttpCookie cookie2 = new HttpCookie("  NaME1   ", "  TESTVALUE1   ");
    886         cookieStore.add(uri, cookie2);
    887         list = cookieStore.get(uri);
    888         assertEquals(1, list.size());
    889         assertEquals("  TESTVALUE1   ", list.get(0).getValue());
    890         assertTrue(list.contains(cookie2));
    891 
    892         // domain and path attributes works
    893         HttpCookie anotherCookie = new HttpCookie("name1", "value1");
    894         anotherCookie.setDomain("domain");
    895         anotherCookie.setPath("Path");
    896         cookieStore.add(uri, anotherCookie);
    897         list = cookieStore.get(uri);
    898         assertEquals(2, list.size());
    899         assertNull(list.get(0).getDomain());
    900         assertEquals("domain", list.get(1).getDomain());
    901         assertEquals("Path", list.get(1).getPath());
    902 
    903         URI uri2 = new URI("http://.test.unit.org");
    904         HttpCookie cookie3 = new HttpCookie("NaME2", "VALUE2");
    905         cookieStore.add(uri2, cookie3);
    906         list = cookieStore.get(uri2);
    907         assertEquals(1, list.size());
    908         assertEquals("VALUE2", list.get(0).getValue());
    909         list = cookieStore.getCookies();
    910         assertEquals(3, list.size());
    911 
    912         // expired cookie won't be selected.
    913         HttpCookie cookie4 = new HttpCookie("cookie4", "value4");
    914         cookie4.setMaxAge(-2);
    915         assertTrue(cookie4.hasExpired());
    916         cookieStore.add(uri2, cookie4);
    917         list = cookieStore.getCookies();
    918         assertEquals(3, list.size());
    919         assertFalse(cookieStore.remove(uri2, cookie4));
    920 
    921         cookie4.setMaxAge(3000);
    922         cookie4.setDomain("domain");
    923         cookie4.setPath("path");
    924         cookieStore.add(uri2, cookie4);
    925         list = cookieStore.get(uri2);
    926         assertEquals(2, list.size());
    927 
    928         cookieStore.add(uri, cookie4);
    929         list = cookieStore.get(uri);
    930         assertEquals(3, list.size());
    931         list = cookieStore.get(uri2);
    932         assertEquals(2, list.size());
    933         list = cookieStore.getCookies();
    934         assertEquals(4, list.size());
    935 
    936         URI baduri = new URI("bad_url");
    937         HttpCookie cookie6 = new HttpCookie("cookie5", "value5");
    938         cookieStore.add(baduri, cookie6);
    939         list = cookieStore.get(baduri);
    940         assertTrue(list.contains(cookie6));
    941     }
    942 
    943     /**
    944      * java.net.CookieStore#get(URI)
    945      * @since 1.6
    946      */
    947     public void test_get_LURI() throws URISyntaxException {
    948         try {
    949             cookieStore.get(null);
    950             fail("should throw NullPointerException");
    951         } catch (NullPointerException e) {
    952             // expected
    953         }
    954 
    955         URI uri1 = new URI("http://get.uri1.test.org");
    956         List<HttpCookie> list = cookieStore.get(uri1);
    957         assertTrue(list.isEmpty());
    958 
    959         HttpCookie cookie1 = new HttpCookie("cookie_name1", "cookie_value1");
    960         HttpCookie cookie2 = new HttpCookie("cookie_name2", "cookie_value2");
    961         cookieStore.add(uri1, cookie1);
    962         cookieStore.add(uri1, cookie2);
    963         URI uri2 = new URI("http://get.uri2.test.org");
    964         HttpCookie cookie3 = new HttpCookie("cookie_name3", "cookie_value3");
    965         cookieStore.add(uri2, cookie3);
    966         list = cookieStore.get(uri1);
    967         assertEquals(2, list.size());
    968         list = cookieStore.get(uri2);
    969         assertEquals(1, list.size());
    970 
    971         // domain-match cookies also be selected.
    972         HttpCookie cookie4 = new HttpCookie("cookie_name4", "cookie_value4");
    973         cookie4.setDomain(".uri1.test.org");
    974         cookieStore.add(uri2, cookie4);
    975         list = cookieStore.get(uri1);
    976         assertEquals(3, list.size());
    977 
    978         cookieStore.add(uri1, cookie4);
    979         list = cookieStore.get(uri1);
    980         assertEquals(3, list.size());
    981         list = cookieStore.get(uri2);
    982         assertEquals(2, list.size());
    983 
    984         // expired cookie won't be selected.
    985         HttpCookie cookie5 = new HttpCookie("cookie_name5", "cookie_value5");
    986         cookie5.setMaxAge(-333);
    987         assertTrue(cookie5.hasExpired());
    988         cookieStore.add(uri1, cookie5);
    989         list = cookieStore.get(uri1);
    990         assertEquals(3, list.size());
    991         assertFalse(cookieStore.remove(uri1, cookie5));
    992         list = cookieStore.getCookies();
    993         assertEquals(4, list.size());
    994 
    995         cookie4.setMaxAge(-123);
    996         list = cookieStore.get(uri1);
    997         assertEquals(2, list.size());
    998         list = cookieStore.getCookies();
    999         assertEquals(3, list.size());
   1000         // expired cookies are also deleted even if it domain-matches the URI
   1001         HttpCookie cookie6 = new HttpCookie("cookie_name6", "cookie_value6");
   1002         cookie6.setMaxAge(-2);
   1003         cookie6.setDomain(".uri1.test.org");
   1004         cookieStore.add(uri2, cookie6);
   1005         list = cookieStore.get(uri1);
   1006         assertEquals(2, list.size());
   1007         assertFalse(cookieStore.remove(null, cookie6));
   1008 
   1009         URI uri3 = new URI("http://get.uri3.test.org");
   1010         assertTrue(cookieStore.get(uri3).isEmpty());
   1011         URI baduri = new URI("invalid_uri");
   1012         assertTrue(cookieStore.get(baduri).isEmpty());
   1013     }
   1014 
   1015     /**
   1016      * java.net.CookieStore#getCookies()
   1017      * @since 1.6
   1018      */
   1019     public void test_getCookies() throws URISyntaxException {
   1020         List<HttpCookie> list = cookieStore.getCookies();
   1021         assertTrue(list.isEmpty());
   1022         assertTrue(list instanceof RandomAccess);
   1023 
   1024         HttpCookie cookie1 = new HttpCookie("cookie_name", "cookie_value");
   1025         URI uri1 = new URI("http://getcookies1.test.org");
   1026         cookieStore.add(uri1, cookie1);
   1027         list = cookieStore.getCookies();
   1028         assertTrue(list.contains(cookie1));
   1029 
   1030         HttpCookie cookie2 = new HttpCookie("cookie_name2", "cookie_value2");
   1031         URI uri2 = new URI("http://getcookies2.test.org");
   1032         cookieStore.add(uri2, cookie2);
   1033         list = cookieStore.getCookies();
   1034         assertEquals(2, list.size());
   1035         assertTrue(list.contains(cookie1));
   1036         assertTrue(list.contains(cookie2));
   1037 
   1038         // duplicated cookie won't be selected.
   1039         cookieStore.add(uri2, cookie1);
   1040         list = cookieStore.getCookies();
   1041         assertEquals(2, list.size());
   1042         // expired cookie won't be selected.
   1043         HttpCookie cookie3 = new HttpCookie("cookie_name3", "cookie_value3");
   1044         cookie3.setMaxAge(-1357);
   1045         cookieStore.add(uri1, cookie3);
   1046         list = cookieStore.getCookies();
   1047         assertEquals(2, list.size());
   1048 
   1049         try {
   1050             list.add(new HttpCookie("readOnlyName", "readOnlyValue"));
   1051             fail("should throw UnsupportedOperationException");
   1052         } catch (UnsupportedOperationException e) {
   1053             // expected
   1054         }
   1055 
   1056         try {
   1057             list.remove(new HttpCookie("readOnlyName", "readOnlyValue"));
   1058             fail("should throw UnsupportedOperationException");
   1059         } catch (UnsupportedOperationException e) {
   1060             // expected
   1061         }
   1062     }
   1063 
   1064     /**
   1065      * java.net.CookieStore#getURIs()
   1066      * @since 1.6
   1067      */
   1068     public void test_getURIs() throws URISyntaxException {
   1069         List<URI> list = cookieStore.getURIs();
   1070         assertTrue(list.isEmpty());
   1071 
   1072         URI uri1 = new URI("http://geturis1.test.com");
   1073         HttpCookie cookie1 = new HttpCookie("cookie_name1", "cookie_value1");
   1074         cookieStore.add(uri1, cookie1);
   1075         list = cookieStore.getURIs();
   1076         assertEquals("geturis1.test.com", list.get(0).getHost());
   1077 
   1078         HttpCookie cookie2 = new HttpCookie("cookie_name2", "cookie_value2");
   1079         cookieStore.add(uri1, cookie2);
   1080         list = cookieStore.getURIs();
   1081         assertEquals(1, list.size());
   1082 
   1083         URI uri2 = new URI("http://geturis2.test.com");
   1084         cookieStore.add(uri2, cookie2);
   1085         list = cookieStore.getURIs();
   1086         assertEquals(2, list.size());
   1087         assertTrue(list.contains(uri1));
   1088         assertTrue(list.contains(uri2));
   1089     }
   1090 
   1091     /**
   1092      * java.net.CookieStore#remove(URI, HttpCookie)
   1093      * @since 1.6
   1094      */
   1095     public void test_remove_LURI_LHttpCookie() throws URISyntaxException {
   1096         URI uri1 = new URI("http://remove1.test.com");
   1097         HttpCookie cookie1 = new HttpCookie("cookie_name1", "cookie_value1");
   1098         try {
   1099             cookieStore.remove(uri1, null);
   1100             fail("should throw NullPointerException");
   1101         } catch (NullPointerException e) {
   1102             // expected
   1103         }
   1104         assertFalse(cookieStore.remove(uri1, cookie1));
   1105         assertFalse(cookieStore.remove(null, cookie1));
   1106 
   1107         cookieStore.add(uri1, cookie1);
   1108         URI uri2 = new URI("http://remove2.test.com");
   1109         HttpCookie cookie2 = new HttpCookie("cookie_name2", "cookie_value2");
   1110         cookieStore.add(uri2, cookie2);
   1111         assertTrue(cookieStore.remove(uri1, cookie1));
   1112         assertFalse(cookieStore.remove(uri1, cookie1));
   1113         assertEquals(2, cookieStore.getURIs().size());
   1114         assertEquals(1, cookieStore.getCookies().size());
   1115         assertTrue(cookieStore.remove(uri2, cookie2));
   1116         assertFalse(cookieStore.remove(uri2, cookie2));
   1117         assertEquals(2, cookieStore.getURIs().size());
   1118         assertEquals(0, cookieStore.getCookies().size());
   1119 
   1120         assertTrue(cookieStore.removeAll());
   1121         cookieStore.add(uri1, cookie1);
   1122         cookieStore.add(uri2, cookie2);
   1123         HttpCookie cookie3 = new HttpCookie("cookie_name3", "cookie_value3");
   1124         assertFalse(cookieStore.remove(null, cookie3));
   1125         // No guarantees on behavior if we call remove with a different
   1126         // uri from the one originally associated with the cookie.
   1127         assertFalse(cookieStore.remove(null, cookie1));
   1128         assertTrue(cookieStore.remove(uri1, cookie1));
   1129         assertFalse(cookieStore.remove(uri1, cookie1));
   1130 
   1131         assertEquals(2, cookieStore.getURIs().size());
   1132         assertEquals(1, cookieStore.getCookies().size());
   1133         assertTrue(cookieStore.remove(uri2, cookie2));
   1134         assertFalse(cookieStore.remove(uri2, cookie2));
   1135         assertEquals(2, cookieStore.getURIs().size());
   1136         assertEquals(0, cookieStore.getCookies().size());
   1137 
   1138         cookieStore.removeAll();
   1139         // expired cookies can also be deleted.
   1140         cookie2.setMaxAge(-34857);
   1141         cookieStore.add(uri2, cookie2);
   1142         assertTrue(cookieStore.remove(uri2, cookie2));
   1143         assertFalse(cookieStore.remove(uri2, cookie2));
   1144         assertEquals(0, cookieStore.getCookies().size());
   1145 
   1146         cookie2.setMaxAge(34857);
   1147         cookieStore.add(uri1, cookie1);
   1148         cookieStore.add(uri2, cookie1);
   1149         cookieStore.add(uri2, cookie2);
   1150         assertTrue(cookieStore.remove(uri1, cookie1));
   1151         assertFalse(cookieStore.remove(uri1, cookie1));
   1152         assertTrue(cookieStore.get(uri2).contains(cookie1));
   1153         assertTrue(cookieStore.get(uri2).contains(cookie2));
   1154         assertEquals(0, cookieStore.get(uri1).size());
   1155         cookieStore.remove(uri2, cookie2);
   1156 
   1157         cookieStore.removeAll();
   1158         cookieStore.add(uri2, cookie2);
   1159         cookieStore.add(uri1, cookie1);
   1160         assertEquals(2, cookieStore.getCookies().size());
   1161         assertFalse(cookieStore.remove(uri2, cookie1));
   1162         assertTrue(cookieStore.remove(uri1, cookie1));
   1163         assertEquals(2, cookieStore.getURIs().size());
   1164         assertEquals(1, cookieStore.getCookies().size());
   1165         assertTrue(cookieStore.getCookies().contains(cookie2));
   1166 
   1167         cookieStore.removeAll();
   1168         URI uri3 = new URI("http://remove3.test.com");
   1169         URI uri4 = new URI("http://test.com");
   1170         HttpCookie cookie4 = new HttpCookie("cookie_name4", "cookie_value4");
   1171         cookie4.setDomain(".test.com");
   1172         cookie2.setMaxAge(-34857);
   1173         cookie3.setMaxAge(-22);
   1174         cookie4.setMaxAge(-45);
   1175         cookieStore.add(uri1, cookie1);
   1176         cookieStore.add(uri2, cookie2);
   1177         cookieStore.add(uri3, cookie3);
   1178         cookieStore.add(uri4, cookie4);
   1179         assertEquals(0, cookieStore.get(uri2).size());
   1180         assertFalse(cookieStore.remove(uri2, cookie2));
   1181         assertTrue(cookieStore.remove(uri3, cookie3));
   1182         assertFalse(cookieStore.remove(uri4, cookie4));
   1183     }
   1184 
   1185     /**
   1186      * java.net.CookieStore#test_removeAll()
   1187      * @since 1.6
   1188      */
   1189     public void test_removeAll() throws URISyntaxException {
   1190         assertFalse(cookieStore.removeAll());
   1191 
   1192         URI uri1 = new URI("http://removeAll1.test.com");
   1193         HttpCookie cookie1 = new HttpCookie("cookie_name1", "cookie_value1");
   1194         cookieStore.add(uri1, cookie1);
   1195         URI uri2 = new URI("http://removeAll2.test.com");
   1196         HttpCookie cookie2 = new HttpCookie("cookie_name2", "cookie_value2");
   1197         cookieStore.add(uri2, cookie2);
   1198 
   1199         assertTrue(cookieStore.removeAll());
   1200         assertTrue(cookieStore.getURIs().isEmpty());
   1201         assertTrue(cookieStore.getCookies().isEmpty());
   1202 
   1203         assertFalse(cookieStore.removeAll());
   1204     }
   1205 
   1206     //
   1207     // Start of org.apache.harmony.tests.java.net.CookieStoreTest.
   1208     //
   1209 
   1210     private void checkValidParams4Get(URI uri,
   1211                                              Map<String, List<String>> map) throws IOException {
   1212         CookieManager manager = new CookieManager(createCookieStore(), null);
   1213         try {
   1214             manager.get(uri, map);
   1215             fail("Should throw IllegalArgumentException");
   1216         } catch (IllegalArgumentException e) {
   1217             // expected
   1218         }
   1219 
   1220     }
   1221 
   1222     private void checkValidParams4Put(URI uri,
   1223                                              Map<String, List<String>> map) throws IOException {
   1224         CookieManager manager = new CookieManager(createCookieStore(), null);
   1225         try {
   1226             manager.put(uri, map);
   1227             fail("Should throw IllegalArgumentException");
   1228         } catch (IllegalArgumentException e) {
   1229             // expected
   1230         }
   1231 
   1232     }
   1233 
   1234     /**
   1235      * {@link java.net.CookieManager#get(java.net.URI, java.util.Map)} &
   1236      * {@link java.net.CookieManager#put(java.net.URI, java.util.Map)}
   1237      * IllegalArgumentException
   1238      * @since 1.6
   1239      */
   1240     public void test_Put_Get_LURI_LMap_exception() throws IOException,
   1241             URISyntaxException {
   1242         // get
   1243         checkValidParams4Get(new URI(""), null);
   1244         checkValidParams4Get(new URI("http://www.test.com"), null);
   1245         checkValidParams4Get(null, null);
   1246         checkValidParams4Get(null, new HashMap<String, List<String>>());
   1247 
   1248         // put
   1249         checkValidParams4Put(new URI(""), null);
   1250         checkValidParams4Put(new URI("http://www.test.com"), null);
   1251         checkValidParams4Put(null, null);
   1252         checkValidParams4Put(null, new HashMap<String, List<String>>());
   1253     }
   1254 
   1255     private static Map<String, List<String>> addCookie(String[][] cookies) {
   1256         Map<String, List<String>> responseHeaders = new LinkedHashMap<String, List<String>>();
   1257         for (int i = 0; i < cookies.length; i++) {
   1258             List<String> fields = new ArrayList<String>();
   1259             for (int j = 1; j < cookies[i].length; j += 2) {
   1260                 fields.add(cookies[i][j]);
   1261             }
   1262             responseHeaders.put(cookies[i][0], fields);
   1263         }
   1264         return responseHeaders;
   1265     }
   1266 
   1267     private CookieManager store(String[][] cookies,
   1268                                        Map<String, List<String>> responseHeaders, CookiePolicy policy)
   1269             throws IOException, URISyntaxException {
   1270         CookieManager manager = new CookieManager(createCookieStore(), policy);
   1271         // Put all cookies into manager
   1272         for (int i = 0; i < cookies.length; i++) {
   1273             for (int j = 2; j < cookies[i].length; j += 2) {
   1274                 URI uri = new URI(cookies[i][j]);
   1275                 manager.put(uri, responseHeaders);
   1276             }
   1277         }
   1278         return manager;
   1279     }
   1280 
   1281     /**
   1282      * Unlike the RI, we flatten all matching cookies into a single Cookie header
   1283      * instead of sending down multiple cookie headers. Also, when no cookies match
   1284      * a given URI, we leave the requestHeaders unmodified.
   1285      *
   1286      * @since 1.6
   1287      */
   1288     public void test_Put_Get_LURI_LMap() throws IOException, URISyntaxException {
   1289         // cookie-key | (content, URI)...
   1290         String[][] cookies = {
   1291                 { "Set-cookie",
   1292                         "Set-cookie:PREF=test;path=/;domain=.b.c;", "http://a.b.c/",
   1293                         "Set-cookie:PREF1=test2;path=/;domain=.beg.com;", "http://a.b.c/" },
   1294 
   1295                 { "Set-cookie2",
   1296                         "Set-cookie2:NAME1=VALUE1;path=/te;domain=.b.c;", "http://a.b.c/test" },
   1297 
   1298                 { "Set-cookie",
   1299                         "Set-cookie2:NAME=VALUE;path=/;domain=.beg.com;", "http://a.beg.com/test",
   1300                         "Set-cookie2:NAME1=VALUE1;path=/;domain=.beg.com;", "http://a.beg.com/test" },
   1301 
   1302                 { "Set-cookie2",
   1303                         "Set-cookie3:NAME=VALUE;path=/;domain=.test.org;", "http://a.test.org/test" },
   1304 
   1305                 { null,
   1306                         "Set-cookie3:NAME=VALUE;path=/te;domain=.test.org;", "http://a.test.org/test" },
   1307 
   1308                 { "Set-cookie2",
   1309                         "lala", "http://a.test.org/test" }
   1310 
   1311         };
   1312 
   1313         // requires path of cookie is the prefix of uri
   1314         // domain of cookie must match that of uri
   1315         Map<String, List<String>> responseHeaders = addCookie(new String[][] {
   1316                 cookies[0], cookies[1] });
   1317         CookieManager manager = store(
   1318                 new String[][] { cookies[0], cookies[1] }, responseHeaders,
   1319                 null);
   1320 
   1321         HashMap<String, List<String>> dummyMap = new HashMap<String, List<String>>();
   1322         Map<String, List<String>> map = manager.get(new URI("http://a.b.c/"),
   1323                 dummyMap);
   1324 
   1325         assertEquals(1, map.size());
   1326         List<String> list = map.get("Cookie");
   1327         assertEquals(1, list.size());
   1328 
   1329         // requires path of cookie is the prefix of uri
   1330         map = manager.get(new URI("http://a.b.c/te"), dummyMap);
   1331         list = map.get("Cookie");
   1332         assertEquals(1, list.size());
   1333         assertTrue(list.get(0).contains("PREF=test"));
   1334         // Cookies from "/test" should *not* match the URI "/te".
   1335         assertFalse(list.get(0).contains("NAME=VALUE"));
   1336 
   1337         // If all cookies are of version 1, then $version=1 will be added
   1338         // ,no matter the value cookie-key
   1339         responseHeaders = addCookie(new String[][] { cookies[2] });
   1340         manager = store(new String[][] { cookies[2] }, responseHeaders, null);
   1341         map = manager.get(new URI("http://a.beg.com/test"), dummyMap);
   1342         list = map.get("Cookie");
   1343         assertEquals(1, list.size());
   1344         assertTrue(list.get(0).startsWith("$Version=\"1\""));
   1345 
   1346         // cookie-key will not have effect on determining cookie version
   1347         responseHeaders = addCookie(new String[][] { cookies[3] });
   1348         manager = store(new String[][] { cookies[3] }, responseHeaders, null);
   1349         map = manager.get(new URI("http://a.test.org/"), responseHeaders);
   1350         list = map.get("Cookie");
   1351         assertEquals(1, list.size());
   1352         assertEquals("Set-cookie3:NAME=VALUE", list.get(0));
   1353 
   1354         // When key is null, no cookie can be stored/retrieved, even if policy =
   1355         // ACCEPT_ALL
   1356         responseHeaders = addCookie(new String[][] { cookies[4] });
   1357         manager = store(new String[][] { cookies[4] }, responseHeaders,
   1358                 CookiePolicy.ACCEPT_ALL);
   1359         map = manager.get(new URI("http://a.test.org/"), responseHeaders);
   1360         list = map.get("Cookie");
   1361         assertNull(list);
   1362 
   1363         // All cookies will be rejected if policy == ACCEPT_NONE
   1364         responseHeaders = addCookie(new String[][] { cookies[3] });
   1365         manager = store(new String[][] { cookies[3] }, responseHeaders,
   1366                 CookiePolicy.ACCEPT_NONE);
   1367         map = manager.get(new URI("http://a.test.org/"), responseHeaders);
   1368         list = map.get("Cookie");
   1369         assertNull(list);
   1370 
   1371         responseHeaders = addCookie(new String[][] { cookies[5] });
   1372         manager = store(new String[][] { cookies[5] }, responseHeaders,
   1373                 CookiePolicy.ACCEPT_ALL);
   1374         list = map.get("Cookie");
   1375         assertNull(list);
   1376 
   1377         try {
   1378             map.put(null, null);
   1379             fail("Should throw UnsupportedOperationException");
   1380         } catch (UnsupportedOperationException e) {
   1381             // expected
   1382         }
   1383 
   1384     }
   1385 
   1386     /**
   1387      * {@link java.net.CookieManager#CookieManager()}
   1388      * @since 1.6
   1389      */
   1390     public void test_CookieManager() {
   1391         CookieManager cookieManager = new CookieManager();
   1392         assertNotNull(cookieManager);
   1393         assertNotNull(cookieManager.getCookieStore());
   1394     }
   1395 
   1396     /**
   1397      * {@link java.net.CookieManager#CookieManager(java.net.CookieStore, java.net.CookiePolicy)}
   1398      * @since 1.6
   1399      */
   1400     public void testCookieManager_LCookieStore_LCookiePolicy() {
   1401         class DummyStore implements CookieStore {
   1402             public String getName() {
   1403                 return "A dummy store";
   1404             }
   1405 
   1406             public void add(URI uri, HttpCookie cookie) {
   1407                 // expected
   1408             }
   1409 
   1410             public List<HttpCookie> get(URI uri) {
   1411                 return null;
   1412             }
   1413 
   1414             public List<HttpCookie> getCookies() {
   1415                 return null;
   1416             }
   1417 
   1418             public List<URI> getURIs() {
   1419                 return null;
   1420             }
   1421 
   1422             public boolean remove(URI uri, HttpCookie cookie) {
   1423                 return false;
   1424             }
   1425 
   1426             public boolean removeAll() {
   1427                 return false;
   1428             }
   1429         }
   1430         CookieStore store = new DummyStore();
   1431         CookieManager cookieManager = new CookieManager(store,
   1432                 CookiePolicy.ACCEPT_ALL);
   1433         assertEquals("A dummy store", ((DummyStore) cookieManager
   1434                 .getCookieStore()).getName());
   1435         assertSame(store, cookieManager.getCookieStore());
   1436     }
   1437 
   1438     /**
   1439      * {@link java.net.CookieManager#setCookiePolicy(java.net.CookiePolicy)}
   1440      * @since 1.6
   1441      */
   1442     public void test_SetCookiePolicy_LCookiePolicy() throws URISyntaxException,
   1443             IOException {
   1444 
   1445         // Policy = ACCEPT_NONE
   1446         CookieManager manager = new CookieManager(createCookieStore(), null);
   1447         manager.setCookiePolicy(CookiePolicy.ACCEPT_NONE);
   1448         Map<String, List<String>> responseHeaders = new TreeMap<String, List<String>>();
   1449         URI uri = new URI("http://a.b.c");
   1450         manager.put(uri, responseHeaders);
   1451         Map<String, List<String>> map = manager.get(uri,
   1452                 new HashMap<String, List<String>>());
   1453 
   1454         assertEquals(0, map.size());
   1455 
   1456         // Policy = ACCEPT_ALL
   1457         manager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
   1458         responseHeaders = new TreeMap<String, List<String>>();
   1459         ArrayList<String> list = new ArrayList<String>();
   1460         list.add("test=null");
   1461         responseHeaders.put("Set-cookie", list);
   1462         uri = new URI("http://b.c.d");
   1463         manager.put(uri, responseHeaders);
   1464         map = manager.get(uri, new HashMap<String, List<String>>());
   1465         assertEquals(1, map.size());
   1466     }
   1467 
   1468     /**
   1469      * {@link java.net.CookieManager#getCookieStore()}
   1470      * @since 1.6
   1471      */
   1472     public void test_GetCookieStore() {
   1473         CookieManager cookieManager = new CookieManager(createCookieStore(), null);
   1474         CookieStore store = cookieManager.getCookieStore();
   1475         assertNotNull(store);
   1476     }
   1477 
   1478     // http://b/25763487
   1479     public void testCookieWithNullPath() throws Exception {
   1480         FakeSingleCookieStore fscs = new FakeSingleCookieStore();
   1481         CookieManager cm = new CookieManager(fscs, CookiePolicy.ACCEPT_ALL);
   1482 
   1483         HttpCookie cookie = new HttpCookie("foo", "bar");
   1484         cookie.setDomain("http://www.foo.com");
   1485         cookie.setVersion(0);
   1486 
   1487         fscs.setNextCookie(cookie);
   1488 
   1489         Map<String, List<String>> cookieHeaders = cm.get(
   1490                 new URI("http://www.foo.com/log/me/in"), Collections.EMPTY_MAP);
   1491 
   1492         List<String> cookies = cookieHeaders.get("Cookie");
   1493         assertEquals("foo=bar", cookies.get(0));
   1494     }
   1495 
   1496     /**
   1497      * A cookie store that always returns one cookie per URI (without any sort of
   1498      * rule matching). The cookie that's returned is provided via a call to setNextCookie
   1499      */
   1500     public static class FakeSingleCookieStore implements CookieStore {
   1501         private List<HttpCookie> cookies;
   1502 
   1503         void setNextCookie(HttpCookie cookie) {
   1504             cookies = Collections.singletonList(cookie);
   1505         }
   1506 
   1507         @Override
   1508         public void add(URI uri, HttpCookie cookie) {
   1509         }
   1510 
   1511         @Override
   1512         public List<HttpCookie> get(URI uri) {
   1513             return cookies;
   1514         }
   1515 
   1516         @Override
   1517         public List<HttpCookie> getCookies() {
   1518             return cookies;
   1519         }
   1520 
   1521         @Override
   1522         public List<URI> getURIs() {
   1523             return null;
   1524         }
   1525 
   1526         @Override
   1527         public boolean remove(URI uri, HttpCookie cookie) {
   1528             cookies = Collections.EMPTY_LIST;
   1529             return true;
   1530         }
   1531 
   1532         @Override
   1533         public boolean removeAll() {
   1534             cookies = Collections.EMPTY_LIST;
   1535             return true;
   1536         }
   1537     }
   1538 }
   1539