• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 package libcore.java.net;
18 
19 import com.google.mockwebserver.MockResponse;
20 import com.google.mockwebserver.MockWebServer;
21 import com.google.mockwebserver.RecordedRequest;
22 import java.io.IOException;
23 import java.net.CookieHandler;
24 import java.net.CookieManager;
25 import static java.net.CookiePolicy.ACCEPT_ORIGINAL_SERVER;
26 import java.net.CookieStore;
27 import java.net.HttpCookie;
28 import java.net.HttpURLConnection;
29 import java.net.URI;
30 import java.net.URISyntaxException;
31 import java.net.URLConnection;
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.Collection;
35 import java.util.Collections;
36 import java.util.Comparator;
37 import java.util.HashMap;
38 import java.util.List;
39 import java.util.Locale;
40 import java.util.Map;
41 import junit.framework.TestCase;
42 
43 public class CookiesTest extends TestCase {
44 
45     private static final Map<String, List<String>> EMPTY_COOKIES_MAP = Collections.emptyMap();
46 
testNetscapeResponse()47     public void testNetscapeResponse() throws Exception {
48         CookieManager cookieManager = new CookieManager(null, ACCEPT_ORIGINAL_SERVER);
49         CookieHandler.setDefault(cookieManager);
50         MockWebServer server = new MockWebServer();
51         server.play();
52 
53         server.enqueue(new MockResponse().addHeader("Set-Cookie: a=android; "
54                 + "expires=Fri, 31-Dec-9999 23:59:59 GMT; "
55                 + "path=/path; "
56                 + "domain=" + server.getCookieDomain() + "; "
57                 + "secure"));
58         get(server, "/path/foo");
59 
60         List<HttpCookie> cookies = cookieManager.getCookieStore().getCookies();
61         assertEquals(1, cookies.size());
62         HttpCookie cookie = cookies.get(0);
63         assertEquals("a", cookie.getName());
64         assertEquals("android", cookie.getValue());
65         assertEquals(null, cookie.getComment());
66         assertEquals(null, cookie.getCommentURL());
67         assertEquals(false, cookie.getDiscard());
68         assertEquals(server.getCookieDomain(), cookie.getDomain());
69         assertTrue(cookie.getMaxAge() > 100000000000L);
70         assertEquals("/path", cookie.getPath());
71         assertEquals(true, cookie.getSecure());
72         assertEquals(0, cookie.getVersion());
73     }
74 
testRfc2109Response()75     public void testRfc2109Response() throws Exception {
76         CookieManager cookieManager = new CookieManager(null, ACCEPT_ORIGINAL_SERVER);
77         CookieHandler.setDefault(cookieManager);
78         MockWebServer server = new MockWebServer();
79         server.play();
80 
81         server.enqueue(new MockResponse().addHeader("Set-Cookie: a=android; "
82                 + "Comment=this cookie is delicious; "
83                 + "Domain=" + server.getCookieDomain() + "; "
84                 + "Max-Age=60; "
85                 + "Path=/path; "
86                 + "Secure; "
87                 + "Version=1"));
88         get(server, "/path/foo");
89 
90         List<HttpCookie> cookies = cookieManager.getCookieStore().getCookies();
91         assertEquals(1, cookies.size());
92         HttpCookie cookie = cookies.get(0);
93         assertEquals("a", cookie.getName());
94         assertEquals("android", cookie.getValue());
95         assertEquals("this cookie is delicious", cookie.getComment());
96         assertEquals(null, cookie.getCommentURL());
97         assertEquals(false, cookie.getDiscard());
98         assertEquals(server.getCookieDomain(), cookie.getDomain());
99         assertEquals(60, cookie.getMaxAge());
100         assertEquals("/path", cookie.getPath());
101         assertEquals(true, cookie.getSecure());
102         assertEquals(1, cookie.getVersion());
103     }
104 
testRfc2965Response()105     public void testRfc2965Response() throws Exception {
106         CookieManager cookieManager = new CookieManager(null, ACCEPT_ORIGINAL_SERVER);
107         CookieHandler.setDefault(cookieManager);
108         MockWebServer server = new MockWebServer();
109         server.play();
110 
111         server.enqueue(new MockResponse().addHeader("Set-Cookie2: a=android; "
112                 + "Comment=this cookie is delicious; "
113                 + "CommentURL=http://google.com/; "
114                 + "Discard; "
115                 + "Domain=" + server.getCookieDomain() + "; "
116                 + "Max-Age=60; "
117                 + "Path=/path; "
118                 + "Port=\"80,443," + server.getPort() + "\"; "
119                 + "Secure; "
120                 + "Version=1"));
121         get(server, "/path/foo");
122 
123         List<HttpCookie> cookies = cookieManager.getCookieStore().getCookies();
124         assertEquals(1, cookies.size());
125         HttpCookie cookie = cookies.get(0);
126         assertEquals("a", cookie.getName());
127         assertEquals("android", cookie.getValue());
128         assertEquals("this cookie is delicious", cookie.getComment());
129         assertEquals("http://google.com/", cookie.getCommentURL());
130         assertEquals(true, cookie.getDiscard());
131         assertEquals(server.getCookieDomain(), cookie.getDomain());
132         assertEquals(60, cookie.getMaxAge());
133         assertEquals("/path", cookie.getPath());
134         assertEquals("80,443," + server.getPort(), cookie.getPortlist());
135         assertEquals(true, cookie.getSecure());
136         assertEquals(1, cookie.getVersion());
137     }
138 
testQuotedAttributeValues()139     public void testQuotedAttributeValues() throws Exception {
140         CookieManager cookieManager = new CookieManager(null, ACCEPT_ORIGINAL_SERVER);
141         CookieHandler.setDefault(cookieManager);
142         MockWebServer server = new MockWebServer();
143         server.play();
144 
145         server.enqueue(new MockResponse().addHeader("Set-Cookie2: a=\"android\"; "
146                 + "Comment=\"this cookie is delicious\"; "
147                 + "CommentURL=\"http://google.com/\"; "
148                 + "Discard; "
149                 + "Domain=\"" + server.getCookieDomain() + "\"; "
150                 + "Max-Age=\"60\"; "
151                 + "Path=\"/path\"; "
152                 + "Port=\"80,443," + server.getPort() + "\"; "
153                 + "Secure; "
154                 + "Version=\"1\""));
155         get(server, "/path/foo");
156 
157         List<HttpCookie> cookies = cookieManager.getCookieStore().getCookies();
158         assertEquals(1, cookies.size());
159         HttpCookie cookie = cookies.get(0);
160         assertEquals("a", cookie.getName());
161         assertEquals("android", cookie.getValue());
162         assertEquals("this cookie is delicious", cookie.getComment());
163         assertEquals("http://google.com/", cookie.getCommentURL());
164         assertEquals(true, cookie.getDiscard());
165         assertEquals(server.getCookieDomain(), cookie.getDomain());
166         assertEquals(60, cookie.getMaxAge());
167         assertEquals("/path", cookie.getPath());
168         assertEquals("80,443," + server.getPort(), cookie.getPortlist());
169         assertEquals(true, cookie.getSecure());
170         assertEquals(1, cookie.getVersion());
171     }
172 
testResponseWithMultipleCookieHeaderLines()173     public void testResponseWithMultipleCookieHeaderLines() throws Exception {
174         TestCookieStore cookieStore = new TestCookieStore();
175         CookieManager cookieManager = new CookieManager(cookieStore, ACCEPT_ORIGINAL_SERVER);
176         cookieManager.put(new URI("http://android.com"), cookieHeaders("a=android", "b=banana"));
177         List<HttpCookie> cookies = sortedCopy(cookieStore.cookies);
178         assertEquals(2, cookies.size());
179         HttpCookie cookieA = cookies.get(0);
180         assertEquals("a", cookieA.getName());
181         assertEquals("android", cookieA.getValue());
182         HttpCookie cookieB = cookies.get(1);
183         assertEquals("b", cookieB.getName());
184         assertEquals("banana", cookieB.getValue());
185     }
186 
testDomainDefaulting()187     public void testDomainDefaulting() throws Exception {
188         TestCookieStore cookieStore = new TestCookieStore();
189         CookieManager cookieManager = new CookieManager(cookieStore, ACCEPT_ORIGINAL_SERVER);
190         cookieManager.put(new URI("http://android.com/"), cookieHeaders("a=android"));
191         assertEquals("android.com", cookieStore.getCookie("a").getDomain());
192     }
193 
testNonMatchingDomainsRejected()194     public void testNonMatchingDomainsRejected() throws Exception {
195         TestCookieStore cookieStore = new TestCookieStore();
196         CookieManager cookieManager = new CookieManager(cookieStore, ACCEPT_ORIGINAL_SERVER);
197         cookieManager.put(new URI("http://android.com/"),
198                 cookieHeaders("a=android;domain=google.com"));
199         assertEquals(Collections.<HttpCookie>emptyList(), cookieStore.cookies);
200     }
201 
testMatchingDomainsAccepted()202     public void testMatchingDomainsAccepted() throws Exception {
203         TestCookieStore cookieStore = new TestCookieStore();
204         CookieManager cookieManager = new CookieManager(cookieStore, ACCEPT_ORIGINAL_SERVER);
205         cookieManager.put(new URI("http://www.android.com/"),
206                 cookieHeaders("a=android;domain=.android.com"));
207         assertEquals(".android.com", cookieStore.getCookie("a").getDomain());
208     }
209 
testPathDefaulting()210     public void testPathDefaulting() throws Exception {
211         TestCookieStore cookieStore = new TestCookieStore();
212         CookieManager cookieManager = new CookieManager(cookieStore, ACCEPT_ORIGINAL_SERVER);
213         cookieManager.put(new URI("http://android.com/foo/bar"), cookieHeaders("a=android"));
214         assertEquals("/foo/", cookieStore.getCookie("a").getPath());
215         cookieManager.put(new URI("http://android.com/"), cookieHeaders("b=banana"));
216         assertEquals("/", cookieStore.getCookie("b").getPath());
217         cookieManager.put(new URI("http://android.com/foo/"), cookieHeaders("c=carrot"));
218         assertEquals("/foo/", cookieStore.getCookie("c").getPath());
219     }
220 
testNonMatchingPathsRejected()221     public void testNonMatchingPathsRejected() throws Exception {
222         TestCookieStore cookieStore = new TestCookieStore();
223         CookieManager cookieManager = new CookieManager(cookieStore, ACCEPT_ORIGINAL_SERVER);
224         cookieManager.put(new URI("http://android.com/foo/bar"),
225                 cookieHeaders("a=android;path=/baz/bar"));
226         assertEquals("Expected to reject cookies whose path is not a prefix of the request path",
227                 Collections.<HttpCookie>emptyList(), cookieStore.cookies); // RI6 fails this
228     }
229 
testMatchingPathsAccepted()230     public void testMatchingPathsAccepted() throws Exception {
231         TestCookieStore cookieStore = new TestCookieStore();
232         CookieManager cookieManager = new CookieManager(cookieStore, ACCEPT_ORIGINAL_SERVER);
233         cookieManager.put(new URI("http://android.com/foo/bar/"),
234                 cookieHeaders("a=android;path=/foo"));
235         assertEquals("/foo", cookieStore.getCookie("a").getPath());
236     }
237 
testNoCookieHeaderSentIfNoCookiesMatch()238     public void testNoCookieHeaderSentIfNoCookiesMatch() throws IOException, URISyntaxException {
239         CookieManager cookieManager = new CookieManager(null, ACCEPT_ORIGINAL_SERVER);
240         Map<String, List<String>> cookieHeaders = cookieManager.get(
241                 new URI("http://android.com/foo/bar/"), EMPTY_COOKIES_MAP);
242         assertTrue(cookieHeaders.toString(), cookieHeaders.isEmpty()
243                 || (cookieHeaders.size() == 1 && cookieHeaders.get("Cookie").isEmpty()));
244     }
245 
testSendingCookiesFromStore()246     public void testSendingCookiesFromStore() throws Exception {
247         MockWebServer server = new MockWebServer();
248         server.enqueue(new MockResponse());
249         server.play();
250 
251         CookieManager cookieManager = new CookieManager(null, ACCEPT_ORIGINAL_SERVER);
252         HttpCookie cookieA = new HttpCookie("a", "android");
253         cookieA.setDomain(server.getCookieDomain());
254         cookieA.setPath("/");
255         cookieManager.getCookieStore().add(server.getUrl("/").toURI(), cookieA);
256         HttpCookie cookieB = new HttpCookie("b", "banana");
257         cookieB.setDomain(server.getCookieDomain());
258         cookieB.setPath("/");
259         cookieManager.getCookieStore().add(server.getUrl("/").toURI(), cookieB);
260         CookieHandler.setDefault(cookieManager);
261 
262         get(server, "/");
263         RecordedRequest request = server.takeRequest();
264 
265         List<String> receivedHeaders = request.getHeaders();
266         assertContains(receivedHeaders, "Cookie: $Version=\"1\"; "
267                 + "a=\"android\";$Path=\"/\";$Domain=\"" + server.getCookieDomain() + "\"; "
268                 + "b=\"banana\";$Path=\"/\";$Domain=\"" + server.getCookieDomain() + "\"");
269     }
270 
testRedirectsDoNotIncludeTooManyCookies()271     public void testRedirectsDoNotIncludeTooManyCookies() throws Exception {
272         MockWebServer redirectTarget = new MockWebServer();
273         redirectTarget.enqueue(new MockResponse().setBody("A"));
274         redirectTarget.play();
275 
276         MockWebServer redirectSource = new MockWebServer();
277         redirectSource.enqueue(new MockResponse()
278                 .setResponseCode(HttpURLConnection.HTTP_MOVED_TEMP)
279                 .addHeader("Location: " + redirectTarget.getUrl("/")));
280         redirectSource.play();
281 
282         CookieManager cookieManager = new CookieManager(null, ACCEPT_ORIGINAL_SERVER);
283         HttpCookie cookie = new HttpCookie("c", "cookie");
284         cookie.setDomain(redirectSource.getCookieDomain());
285         cookie.setPath("/");
286         String portList = Integer.toString(redirectSource.getPort());
287         cookie.setPortlist(portList);
288         cookieManager.getCookieStore().add(redirectSource.getUrl("/").toURI(), cookie);
289         CookieHandler.setDefault(cookieManager);
290 
291         get(redirectSource, "/");
292         RecordedRequest request = redirectSource.takeRequest();
293 
294         assertContains(request.getHeaders(), "Cookie: $Version=\"1\"; "
295                 + "c=\"cookie\";$Path=\"/\";$Domain=\"" + redirectSource.getCookieDomain()
296                 + "\";$Port=\"" + portList + "\"");
297 
298         for (String header : redirectTarget.takeRequest().getHeaders()) {
299             if (header.startsWith("Cookie")) {
300                 fail(header);
301             }
302         }
303     }
304 
305     /**
306      * Test which headers show up where. The cookie manager should be notified
307      * of both user-specified and derived headers like {@code Host}. Headers
308      * named {@code Cookie} or {@code Cookie2} that are returned by the cookie
309      * manager should show up in the request and in {@code
310      * getRequestProperties}.
311      */
testHeadersSentToCookieHandler()312     public void testHeadersSentToCookieHandler() throws IOException, InterruptedException {
313         final Map<String, List<String>> cookieHandlerHeaders = new HashMap<String, List<String>>();
314         CookieHandler.setDefault(new CookieManager() {
315             @Override public Map<String, List<String>> get(URI uri,
316                     Map<String, List<String>> requestHeaders) throws IOException {
317                 cookieHandlerHeaders.putAll(requestHeaders);
318                 Map<String, List<String>> result = new HashMap<String, List<String>>();
319                 result.put("Cookie", Collections.singletonList("Bar=bar"));
320                 result.put("Cookie2", Collections.singletonList("Baz=baz"));
321                 result.put("Quux", Collections.singletonList("quux"));
322                 return result;
323             }
324         });
325         MockWebServer server = new MockWebServer();
326         server.enqueue(new MockResponse());
327         server.play();
328 
329         HttpURLConnection connection = (HttpURLConnection) server.getUrl("/").openConnection();
330         assertEquals(Collections.<String, List<String>>emptyMap(),
331                 connection.getRequestProperties());
332 
333         connection.setRequestProperty("Foo", "foo");
334         connection.setDoOutput(true);
335         connection.getOutputStream().write(5);
336         connection.getOutputStream().close();
337         connection.getInputStream().close();
338 
339         RecordedRequest request = server.takeRequest();
340 
341         assertContainsAll(cookieHandlerHeaders.keySet(), "Foo");
342         assertContainsAll(cookieHandlerHeaders.keySet(),
343                 "Content-Type", "User-Agent", "Connection", "Host");
344         assertFalse(cookieHandlerHeaders.containsKey("Cookie"));
345 
346         /*
347          * The API specifies that calling getRequestProperties() on a connected instance should fail
348          * with an IllegalStateException, but the RI violates the spec and returns a valid map.
349          * http://www.mail-archive.com/net-dev@openjdk.java.net/msg01768.html
350          */
351         try {
352             assertContainsAll(connection.getRequestProperties().keySet(), "Foo");
353             assertContainsAll(connection.getRequestProperties().keySet(),
354                     "Content-Type", "Content-Length", "User-Agent", "Connection", "Host");
355             assertContainsAll(connection.getRequestProperties().keySet(), "Cookie", "Cookie2");
356             assertFalse(connection.getRequestProperties().containsKey("Quux"));
357         } catch (IllegalStateException expected) {
358         }
359 
360         assertContainsAll(request.getHeaders(), "Foo: foo", "Cookie: Bar=bar", "Cookie2: Baz=baz");
361         assertFalse(request.getHeaders().contains("Quux: quux"));
362     }
363 
testCookiesSentIgnoresCase()364     public void testCookiesSentIgnoresCase() throws Exception {
365         CookieHandler.setDefault(new CookieManager() {
366             @Override public Map<String, List<String>> get(URI uri,
367                     Map<String, List<String>> requestHeaders) throws IOException {
368                 Map<String, List<String>> result = new HashMap<String, List<String>>();
369                 result.put("COOKIE", Collections.singletonList("Bar=bar"));
370                 result.put("cooKIE2", Collections.singletonList("Baz=baz"));
371                 return result;
372             }
373         });
374         MockWebServer server = new MockWebServer();
375         server. enqueue(new MockResponse());
376         server.play();
377 
378         get(server, "/");
379 
380         RecordedRequest request = server.takeRequest();
381         assertContainsAll(request.getHeaders(), "COOKIE: Bar=bar", "cooKIE2: Baz=baz");
382         assertFalse(request.getHeaders().contains("Quux: quux"));
383     }
384 
385     /**
386      * RFC 2109 and RFC 2965 disagree here. 2109 says two equals strings match only if they are
387      * fully-qualified domain names. 2965 says two equal strings always match. We're testing for
388      * 2109 behavior because it's more widely used, it's more conservative, and it's what the RI
389      * does.
390      */
testDomainMatchesOnLocalAddresses()391     public void testDomainMatchesOnLocalAddresses() {
392         assertFalse(HttpCookie.domainMatches("localhost", "localhost"));
393         assertFalse(HttpCookie.domainMatches("b", "b"));
394     }
395 
testDomainMatchesOnIpAddress()396     public void testDomainMatchesOnIpAddress() {
397         assertTrue(HttpCookie.domainMatches("127.0.0.1", "127.0.0.1"));
398         assertFalse(HttpCookie.domainMatches("127.0.0.1", "127.0.0.0"));
399         assertFalse(HttpCookie.domainMatches("127.0.0.1", "localhost"));
400     }
401 
testDomainMatchesCaseMapping()402     public void testDomainMatchesCaseMapping() {
403         testDomainMatchesCaseMapping(Locale.US);
404     }
405 
testDomainMatchesCaseMappingExoticLocale()406     public void testDomainMatchesCaseMappingExoticLocale() {
407         testDomainMatchesCaseMapping(new Locale("tr", "TR"));
408     }
409 
testDomainMatchesCaseMapping(Locale locale)410     private void testDomainMatchesCaseMapping(Locale locale) {
411         Locale defaultLocale = Locale.getDefault();
412         Locale.setDefault(locale);
413         try {
414             assertTrue(HttpCookie.domainMatches(".android.com", "WWW.ANDROID.COM"));
415             assertFalse(HttpCookie.domainMatches("android.com", "WWW.ANDROID.COM"));
416         } finally {
417             Locale.setDefault(defaultLocale);
418         }
419     }
420 
421     /**
422      * From the spec, "If an explicitly specified value does not start with a dot, the user agent
423      * supplies a leading dot.". This prepending doesn't happen in setDomain.
424      */
testDomainNotAutomaticallyPrefixedWithDot()425     public void testDomainNotAutomaticallyPrefixedWithDot() {
426         HttpCookie cookie = new HttpCookie("Foo", "foo");
427         cookie.setDomain("localhost");
428         assertEquals("localhost", cookie.getDomain());
429     }
430 
testCookieStoreNullUris()431     public void testCookieStoreNullUris() {
432         CookieStore cookieStore = new CookieManager().getCookieStore();
433         HttpCookie cookieA = new HttpCookie("a", "android");
434         cookieA.setDomain(".android.com");
435         cookieA.setPath("/source");
436         HttpCookie cookieB = new HttpCookie("b", "banana");
437         cookieA.setDomain("code.google.com");
438         cookieA.setPath("/p/android");
439 
440         try {
441             cookieStore.add(null, cookieA);
442         } catch (NullPointerException expected) {
443             // the RI crashes even though the cookie does get added to the store; sigh
444             expected.printStackTrace();
445         }
446         assertEquals(Arrays.asList(cookieA), cookieStore.getCookies());
447         try {
448             cookieStore.add(null, cookieB);
449         } catch (NullPointerException expected) {
450         }
451         assertEquals(Arrays.asList(cookieA, cookieB), cookieStore.getCookies());
452 
453         try {
454             cookieStore.get(null);
455             fail();
456         } catch (NullPointerException expected) {
457         }
458 
459         assertEquals(Collections.<URI>emptyList(), cookieStore.getURIs());
460         assertTrue(cookieStore.remove(null, cookieA));
461         assertEquals(Arrays.asList(cookieB), cookieStore.getCookies());
462 
463         assertTrue(cookieStore.removeAll());
464         assertEquals(Collections.<URI>emptyList(), cookieStore.getURIs());
465         assertEquals(Collections.<HttpCookie>emptyList(), cookieStore.getCookies());
466     }
467 
testCookieStoreRemoveAll()468     public void testCookieStoreRemoveAll() throws URISyntaxException {
469         CookieStore cookieStore = new CookieManager().getCookieStore();
470         cookieStore.add(new URI("http://code.google.com/"), new HttpCookie("a", "android"));
471         assertTrue(cookieStore.removeAll());
472         assertEquals(Collections.<URI>emptyList(), cookieStore.getURIs());
473         assertEquals(Collections.<HttpCookie>emptyList(), cookieStore.getCookies());
474         assertFalse("Expected removeAll() to return false when the call doesn't mutate the store",
475                 cookieStore.removeAll());  // RI6 fails this
476     }
477 
testCookieStoreAddAcceptsConflictingUri()478     public void testCookieStoreAddAcceptsConflictingUri() throws URISyntaxException {
479         CookieStore cookieStore = new CookieManager().getCookieStore();
480         HttpCookie cookieA = new HttpCookie("a", "android");
481         cookieA.setDomain(".android.com");
482         cookieA.setPath("/source/");
483         cookieStore.add(new URI("http://google.com/source/"), cookieA);
484         assertEquals(Arrays.asList(cookieA), cookieStore.getCookies());
485     }
486 
testCookieStoreRemoveRequiresUri()487     public void testCookieStoreRemoveRequiresUri() throws URISyntaxException {
488         CookieStore cookieStore = new CookieManager().getCookieStore();
489         HttpCookie cookieA = new HttpCookie("a", "android");
490         cookieStore.add(new URI("http://android.com/source/"), cookieA);
491         assertFalse("Expected remove() to take the cookie URI into account.", // RI6 fails this
492                 cookieStore.remove(new URI("http://code.google.com/"), cookieA));
493         assertEquals(Arrays.asList(cookieA), cookieStore.getCookies());
494     }
495 
testCookieStoreUriUsesHttpSchemeAlways()496     public void testCookieStoreUriUsesHttpSchemeAlways() throws URISyntaxException {
497         CookieStore cookieStore = new CookieManager().getCookieStore();
498         cookieStore.add(new URI("https://a.com/"), new HttpCookie("a", "android"));
499         assertEquals(Arrays.asList(new URI("http://a.com")), cookieStore.getURIs());
500     }
501 
testCookieStoreUriDropsUserInfo()502     public void testCookieStoreUriDropsUserInfo() throws URISyntaxException {
503         CookieStore cookieStore = new CookieManager().getCookieStore();
504         cookieStore.add(new URI("http://jesse:secret@a.com/"), new HttpCookie("a", "android"));
505         assertEquals(Arrays.asList(new URI("http://a.com")), cookieStore.getURIs());
506     }
507 
testCookieStoreUriKeepsHost()508     public void testCookieStoreUriKeepsHost() throws URISyntaxException {
509         CookieStore cookieStore = new CookieManager().getCookieStore();
510         cookieStore.add(new URI("http://b.com/"), new HttpCookie("a", "android"));
511         assertEquals(Arrays.asList(new URI("http://b.com")), cookieStore.getURIs());
512     }
513 
testCookieStoreUriDropsPort()514     public void testCookieStoreUriDropsPort() throws URISyntaxException {
515         CookieStore cookieStore = new CookieManager().getCookieStore();
516         cookieStore.add(new URI("http://a.com:443/"), new HttpCookie("a", "android"));
517         assertEquals(Arrays.asList(new URI("http://a.com")), cookieStore.getURIs());
518     }
519 
testCookieStoreUriDropsPath()520     public void testCookieStoreUriDropsPath() throws URISyntaxException {
521         CookieStore cookieStore = new CookieManager().getCookieStore();
522         cookieStore.add(new URI("http://a.com/a/"), new HttpCookie("a", "android"));
523         assertEquals(Arrays.asList(new URI("http://a.com")), cookieStore.getURIs());
524     }
525 
testCookieStoreUriDropsFragment()526     public void testCookieStoreUriDropsFragment() throws URISyntaxException {
527         CookieStore cookieStore = new CookieManager().getCookieStore();
528         cookieStore.add(new URI("http://a.com/a/foo#fragment"), new HttpCookie("a", "android"));
529         assertEquals(Arrays.asList(new URI("http://a.com")), cookieStore.getURIs());
530     }
531 
testCookieStoreUriDropsQuery()532     public void testCookieStoreUriDropsQuery() throws URISyntaxException {
533         CookieStore cookieStore = new CookieManager().getCookieStore();
534         cookieStore.add(new URI("http://a.com/a/foo?query=value"), new HttpCookie("a", "android"));
535         assertEquals(Arrays.asList(new URI("http://a.com")), cookieStore.getURIs());
536     }
537 
assertContains(Collection<String> collection, String element)538     private void assertContains(Collection<String> collection, String element) {
539         for (String c : collection) {
540             if (c != null && c.equalsIgnoreCase(element)) {
541                 return;
542             }
543         }
544         fail("No " + element + " in " + collection);
545     }
546 
assertContainsAll(Collection<String> collection, String... toFind)547     private void assertContainsAll(Collection<String> collection, String... toFind) {
548         for (String s : toFind) {
549             assertContains(collection, s);
550         }
551     }
552 
sortedCopy(List<HttpCookie> cookies)553     private List<HttpCookie> sortedCopy(List<HttpCookie> cookies) {
554         List<HttpCookie> result = new ArrayList<HttpCookie>(cookies);
555         Collections.sort(result, new Comparator<HttpCookie>() {
556             public int compare(HttpCookie a, HttpCookie b) {
557                 return a.getName().compareTo(b.getName());
558             }
559         });
560         return result;
561     }
562 
get(MockWebServer server, String path)563     private Map<String,List<String>> get(MockWebServer server, String path) throws Exception {
564         URLConnection connection = server.getUrl(path).openConnection();
565         Map<String, List<String>> headers = connection.getHeaderFields();
566         connection.getInputStream().close();
567         return headers;
568     }
569 
cookieHeaders(String... headers)570     private Map<String, List<String>> cookieHeaders(String... headers) {
571         return Collections.singletonMap("Set-Cookie", Arrays.asList(headers));
572     }
573 
574     static class TestCookieStore implements CookieStore {
575         private final List<HttpCookie> cookies = new ArrayList<HttpCookie>();
576 
add(URI uri, HttpCookie cookie)577         public void add(URI uri, HttpCookie cookie) {
578             cookies.add(cookie);
579         }
580 
getCookie(String name)581         public HttpCookie getCookie(String name) {
582             for (HttpCookie cookie : cookies) {
583                 if (cookie.getName().equals(name)) {
584                     return cookie;
585                 }
586             }
587             throw new IllegalArgumentException("No cookie " + name + " in " + cookies);
588         }
589 
get(URI uri)590         public List<HttpCookie> get(URI uri) {
591             throw new UnsupportedOperationException();
592         }
593 
getCookies()594         public List<HttpCookie> getCookies() {
595             throw new UnsupportedOperationException();
596         }
597 
getURIs()598         public List<URI> getURIs() {
599             throw new UnsupportedOperationException();
600         }
601 
remove(URI uri, HttpCookie cookie)602         public boolean remove(URI uri, HttpCookie cookie) {
603             throw new UnsupportedOperationException();
604         }
605 
removeAll()606         public boolean removeAll() {
607             throw new UnsupportedOperationException();
608         }
609     }
610 }
611