@Test public void testNetscapeResponse() throws Exception { CookieManager cookieManager = new CookieManager(null, ACCEPT_ORIGINAL_SERVER); CookieHandler.setDefault(cookieManager); MockWebServer server = new MockWebServer(); server.play(); server.enqueue( new MockResponse() .addHeader( "Set-Cookie: a=android; " + "expires=Fri, 31-Dec-9999 23:59:59 GMT; " + "path=/path; " + "domain=" + server.getCookieDomain() + "; " + "secure")); get(server, "/path/foo"); List<HttpCookie> cookies = cookieManager.getCookieStore().getCookies(); assertEquals(1, cookies.size()); HttpCookie cookie = cookies.get(0); assertEquals("a", cookie.getName()); assertEquals("android", cookie.getValue()); assertEquals(null, cookie.getComment()); assertEquals(null, cookie.getCommentURL()); assertEquals(false, cookie.getDiscard()); assertTrue(server.getCookieDomain().equalsIgnoreCase(cookie.getDomain())); assertTrue(cookie.getMaxAge() > 100000000000L); assertEquals("/path", cookie.getPath()); assertEquals(true, cookie.getSecure()); assertEquals(0, cookie.getVersion()); }
@Test public void testRfc2109Response() throws Exception { CookieManager cookieManager = new CookieManager(null, ACCEPT_ORIGINAL_SERVER); CookieHandler.setDefault(cookieManager); MockWebServer server = new MockWebServer(); server.play(); server.enqueue( new MockResponse() .addHeader( "Set-Cookie: a=android; " + "Comment=this cookie is delicious; " + "Domain=" + server.getCookieDomain() + "; " + "Max-Age=60; " + "Path=/path; " + "Secure; " + "Version=1")); get(server, "/path/foo"); List<HttpCookie> cookies = cookieManager.getCookieStore().getCookies(); assertEquals(1, cookies.size()); HttpCookie cookie = cookies.get(0); assertEquals("a", cookie.getName()); assertEquals("android", cookie.getValue()); assertEquals("this cookie is delicious", cookie.getComment()); assertEquals(null, cookie.getCommentURL()); assertEquals(false, cookie.getDiscard()); assertTrue(server.getCookieDomain().equalsIgnoreCase(cookie.getDomain())); assertEquals(60, cookie.getMaxAge()); assertEquals("/path", cookie.getPath()); assertEquals(true, cookie.getSecure()); assertEquals(1, cookie.getVersion()); }
/** * Sets cookies according to uri and responseHeaders * * @param uri the specified uri * @param responseHeaders a list of request headers * @throws IOException if some error of I/O operation occurs */ @Override public void put(URI uri, Map<String, List<String>> responseHeaders) throws IOException { if (uri == null || responseHeaders == null) { throw new IllegalArgumentException(); } // parse and construct cookies according to the map List<HttpCookie> cookies = parseCookie(responseHeaders); for (HttpCookie cookie : cookies) { // if the cookie doesn't have a domain, set one. The policy will do validation. if (cookie.getDomain() == null) { cookie.setDomain(uri.getHost()); } // if the cookie doesn't have a path, set one. If it does, validate it. if (cookie.getPath() == null) { cookie.setPath(pathToCookiePath(uri.getPath())); } else if (!HttpCookie.pathMatches(cookie, uri)) { continue; } // if the cookie has the placeholder port list "", set the port. Otherwise validate it. if ("".equals(cookie.getPortlist())) { cookie.setPortlist(Integer.toString(uri.getEffectivePort())); } else if (cookie.getPortlist() != null && !HttpCookie.portMatches(cookie, uri)) { continue; } // if the cookie conforms to the policy, add it into the store if (policy.shouldAccept(uri, cookie)) { store.add(uri, cookie); } } }
/** * Get the real URI from the cookie "domain" and "path" attributes, if they are not set then uses * the URI provided (coming from the response) * * @param uri * @param cookie * @return */ private static URI cookieUri(URI uri, HttpCookie cookie) { URI cookieUri = uri; if (cookie.getDomain() != null) { // Remove the starting dot character of the domain, if exists (e.g: // .domain.com -> domain.com) String domain = cookie.getDomain(); if (domain.charAt(0) == '.') { domain = domain.substring(1); } try { cookieUri = new URI( uri.getScheme() == null ? "http" : uri.getScheme(), domain, cookie.getPath() == null ? "/" : cookie.getPath(), null); } catch (URISyntaxException e) { Log.w(TAG, e); } } return cookieUri; }
@Override public NettyHttpResponse cookie(HttpCookie httpCookie) { Cookie nettyCookie = new DefaultCookie(httpCookie.getName(), httpCookie.getValue()); nettyCookie.setDomain(httpCookie.getDomain()); nettyCookie.setPath(httpCookie.getPath()); nettyCookie.setSecure(httpCookie.getSecure()); if (0 <= (int) httpCookie.getMaxAge()) nettyCookie.setMaxAge((int) httpCookie.getMaxAge()); nettyCookie.setVersion(httpCookie.getVersion()); nettyCookie.setDiscard(httpCookie.getDiscard()); nettyCookie.setHttpOnly(true); CookieEncoder encoder = new CookieEncoder(true); encoder.addCookie(nettyCookie); return header(HttpHeaders.Names.SET_COOKIE, encoder.encode()); }
/** * Test the equality of two http cookies. * * <p>The result is <tt>true</tt> only if two cookies come from same domain (case-insensitive), * have same name (case-insensitive), and have same path (case-sensitive). * * @return <tt>true</tt> if 2 http cookies equal to each other; otherwise, <tt>false</tt> */ @Override public boolean equals(Object obj) { if (obj == this) return true; if (!(obj instanceof HttpCookie)) return false; HttpCookie other = (HttpCookie) obj; // One http cookie equals to another cookie (RFC 2965 sec. 3.3.3) if: // 1. they come from same domain (case-insensitive), // 2. have same name (case-insensitive), // 3. and have same path (case-sensitive). return equalsIgnoreCase(getName(), other.getName()) && equalsIgnoreCase(getDomain(), other.getDomain()) && Objects.equals(getPath(), other.getPath()); }
@Test public void testQuotedAttributeValues() throws Exception { CookieManager cookieManager = new CookieManager(null, ACCEPT_ORIGINAL_SERVER); CookieHandler.setDefault(cookieManager); MockWebServer server = new MockWebServer(); server.play(); server.enqueue( new MockResponse() .addHeader( "Set-Cookie2: a=\"android\"; " + "Comment=\"this cookie is delicious\"; " + "CommentURL=\"http://google.com/\"; " + "Discard; " + "Domain=\"" + server.getCookieDomain() + "\"; " + "Max-Age=\"60\"; " + "Path=\"/path\"; " + "Port=\"80,443," + server.getPort() + "\"; " + "Secure; " + "Version=\"1\"")); get(server, "/path/foo"); List<HttpCookie> cookies = cookieManager.getCookieStore().getCookies(); assertEquals(1, cookies.size()); HttpCookie cookie = cookies.get(0); assertEquals("a", cookie.getName()); assertEquals("android", cookie.getValue()); assertEquals("this cookie is delicious", cookie.getComment()); assertEquals("http://google.com/", cookie.getCommentURL()); assertEquals(true, cookie.getDiscard()); assertTrue(server.getCookieDomain().equalsIgnoreCase(cookie.getDomain())); assertEquals(60, cookie.getMaxAge()); assertEquals("/path", cookie.getPath()); assertEquals("80,443," + server.getPort(), cookie.getPortlist()); assertEquals(true, cookie.getSecure()); assertEquals(1, cookie.getVersion()); }
/** * @param uri cookie corresponding uri. * @param cookie cookie. */ public CookieEntity(URI uri, HttpCookie cookie) { this.uri = uri == null ? null : uri.toString(); this.name = cookie.getName(); this.value = cookie.getValue(); this.comment = cookie.getComment(); this.commentURL = cookie.getCommentURL(); this.discard = cookie.getDiscard(); this.domain = cookie.getDomain(); long maxAge = cookie.getMaxAge(); if (maxAge > 0L) { // session, temp cookie this.expiry = (maxAge * 1000L) + System.currentTimeMillis(); // 溢出 if (this.expiry < 0) this.expiry = HttpDateTime.getMaxExpiryMillis(); } else { this.expiry = -1L; } this.path = cookie.getPath(); if (!TextUtils.isEmpty(path) && path.length() > 1 && path.endsWith("/")) { this.path = path.substring(0, path.length() - 1); } this.portList = cookie.getPortlist(); this.secure = cookie.getSecure(); this.version = cookie.getVersion(); }
public void put(URI uri, Map<String, List<String>> responseHeaders) throws IOException { // pre-condition check if (uri == null || responseHeaders == null) { throw new IllegalArgumentException("Argument is null"); } // if there's no default CookieStore, no need to remember any cookie if (cookieJar == null) return; PlatformLogger logger = PlatformLogger.getLogger("java.net.CookieManager"); for (String headerKey : responseHeaders.keySet()) { // RFC 2965 3.2.2, key must be 'Set-Cookie2' // we also accept 'Set-Cookie' here for backward compatibility if (headerKey == null || !(headerKey.equalsIgnoreCase("Set-Cookie2") || headerKey.equalsIgnoreCase("Set-Cookie"))) { continue; } for (String headerValue : responseHeaders.get(headerKey)) { try { List<HttpCookie> cookies; try { cookies = HttpCookie.parse(headerValue); } catch (IllegalArgumentException e) { // Bogus header, make an empty list and log the error cookies = java.util.Collections.EMPTY_LIST; if (logger.isLoggable(PlatformLogger.SEVERE)) { logger.severe("Invalid cookie for " + uri + ": " + headerValue); } } for (HttpCookie cookie : cookies) { if (cookie.getPath() == null) { // If no path is specified, then by default // the path is the directory of the page/doc String path = uri.getPath(); if (!path.endsWith("/")) { int i = path.lastIndexOf("/"); if (i > 0) { path = path.substring(0, i + 1); } else { path = "/"; } } cookie.setPath(path); } // As per RFC 2965, section 3.3.1: // Domain Defaults to the effective request-host. (Note that because // there is no dot at the beginning of effective request-host, // the default Domain can only domain-match itself.) if (cookie.getDomain() == null) { cookie.setDomain(uri.getHost()); } String ports = cookie.getPortlist(); if (ports != null) { int port = uri.getPort(); if (port == -1) { port = "https".equals(uri.getScheme()) ? 443 : 80; } if (ports.isEmpty()) { // Empty port list means this should be restricted // to the incoming URI port cookie.setPortlist("" + port); if (shouldAcceptInternal(uri, cookie)) { cookieJar.add(uri, cookie); } } else { // Only store cookies with a port list // IF the URI port is in that list, as per // RFC 2965 section 3.3.2 if (isInPortList(ports, port) && shouldAcceptInternal(uri, cookie)) { cookieJar.add(uri, cookie); } } } else { if (shouldAcceptInternal(uri, cookie)) { cookieJar.add(uri, cookie); } } } } catch (IllegalArgumentException e) { // invalid set-cookie header string // no-op } } } }