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