/** * 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); } } }
public Map<String, List<String>> get(URI uri, Map<String, List<String>> requestHeaders) throws IOException { // pre-condition check if (uri == null || requestHeaders == null) { throw new IllegalArgumentException("Argument is null"); } Map<String, List<String>> cookieMap = new java.util.HashMap<String, List<String>>(); // if there's no default CookieStore, no way for us to get any cookie if (cookieJar == null) return Collections.unmodifiableMap(cookieMap); boolean secureLink = "https".equalsIgnoreCase(uri.getScheme()); List<HttpCookie> cookies = new java.util.ArrayList<HttpCookie>(); String path = uri.getPath(); if (path == null || path.isEmpty()) { path = "/"; } for (HttpCookie cookie : cookieJar.get(uri)) { // apply path-matches rule (RFC 2965 sec. 3.3.4) // and check for the possible "secure" tag (i.e. don't send // 'secure' cookies over unsecure links) if (pathMatches(path, cookie.getPath()) && (secureLink || !cookie.getSecure())) { // Enforce httponly attribute if (cookie.isHttpOnly()) { String s = uri.getScheme(); if (!"http".equalsIgnoreCase(s) && !"https".equalsIgnoreCase(s)) { continue; } } // Let's check the authorize port list if it exists String ports = cookie.getPortlist(); if (ports != null && !ports.isEmpty()) { int port = uri.getPort(); if (port == -1) { port = "https".equals(uri.getScheme()) ? 443 : 80; } if (isInPortList(ports, port)) { cookies.add(cookie); } } else { cookies.add(cookie); } } } // apply sort rule (RFC 2965 sec. 3.3.4) List<String> cookieHeader = sortByPath(cookies); cookieMap.put("Cookie", cookieHeader); return Collections.unmodifiableMap(cookieMap); }
@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 } } } }