| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Portions of this code based on Mozilla: | 5 // Portions of this code based on Mozilla: |
| 6 // (netwerk/cookie/src/nsCookieService.cpp) | 6 // (netwerk/cookie/src/nsCookieService.cpp) |
| 7 /* ***** BEGIN LICENSE BLOCK ***** | 7 /* ***** BEGIN LICENSE BLOCK ***** |
| 8 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 | 8 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
| 9 * | 9 * |
| 10 * The contents of this file are subject to the Mozilla Public License Version | 10 * The contents of this file are subject to the Mozilla Public License Version |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 210 base::Time parsed_expiry = cookie_util::ParseCookieTime(pc.Expires()); | 210 base::Time parsed_expiry = cookie_util::ParseCookieTime(pc.Expires()); |
| 211 if (!parsed_expiry.is_null()) | 211 if (!parsed_expiry.is_null()) |
| 212 return parsed_expiry + (current - server_time); | 212 return parsed_expiry + (current - server_time); |
| 213 } | 213 } |
| 214 | 214 |
| 215 // Invalid or no expiration, persistent cookie. | 215 // Invalid or no expiration, persistent cookie. |
| 216 return Time(); | 216 return Time(); |
| 217 } | 217 } |
| 218 | 218 |
| 219 // static | 219 // static |
| 220 CanonicalCookie* CanonicalCookie::Create(const GURL& url, | 220 scoped_ptr<CanonicalCookie> CanonicalCookie::Create( |
| 221 const std::string& cookie_line, | 221 const GURL& url, |
| 222 const base::Time& creation_time, | 222 const std::string& cookie_line, |
| 223 const CookieOptions& options) { | 223 const base::Time& creation_time, |
| 224 const CookieOptions& options) { |
| 224 ParsedCookie parsed_cookie(cookie_line); | 225 ParsedCookie parsed_cookie(cookie_line); |
| 225 | 226 |
| 226 if (!parsed_cookie.IsValid()) { | 227 if (!parsed_cookie.IsValid()) { |
| 227 VLOG(kVlogSetCookies) << "WARNING: Couldn't parse cookie"; | 228 VLOG(kVlogSetCookies) << "WARNING: Couldn't parse cookie"; |
| 228 return NULL; | 229 return nullptr; |
| 229 } | 230 } |
| 230 | 231 |
| 231 if (options.exclude_httponly() && parsed_cookie.IsHttpOnly()) { | 232 if (options.exclude_httponly() && parsed_cookie.IsHttpOnly()) { |
| 232 VLOG(kVlogSetCookies) << "Create() is not creating a httponly cookie"; | 233 VLOG(kVlogSetCookies) << "Create() is not creating a httponly cookie"; |
| 233 return NULL; | 234 return nullptr; |
| 234 } | 235 } |
| 235 | 236 |
| 236 std::string cookie_domain; | 237 std::string cookie_domain; |
| 237 if (!GetCookieDomain(url, parsed_cookie, &cookie_domain)) { | 238 if (!GetCookieDomain(url, parsed_cookie, &cookie_domain)) { |
| 238 VLOG(kVlogSetCookies) << "Create() failed to get a cookie domain"; | 239 VLOG(kVlogSetCookies) << "Create() failed to get a cookie domain"; |
| 239 return NULL; | 240 return nullptr; |
| 240 } | 241 } |
| 241 | 242 |
| 242 // Per 3.2.1 of "Deprecate modification of 'secure' cookies from non-secure | 243 // Per 3.2.1 of "Deprecate modification of 'secure' cookies from non-secure |
| 243 // origins", if the cookie's "secure-only-flag" is "true" and the requesting | 244 // origins", if the cookie's "secure-only-flag" is "true" and the requesting |
| 244 // URL does not have a secure scheme, the cookie should be thrown away. | 245 // URL does not have a secure scheme, the cookie should be thrown away. |
| 245 // https://tools.ietf.org/html/draft-west-leave-secure-cookies-alone | 246 // https://tools.ietf.org/html/draft-west-leave-secure-cookies-alone |
| 246 if (options.enforce_strict_secure() && parsed_cookie.IsSecure() && | 247 if (options.enforce_strict_secure() && parsed_cookie.IsSecure() && |
| 247 !url.SchemeIsCryptographic()) { | 248 !url.SchemeIsCryptographic()) { |
| 248 VLOG(kVlogSetCookies) | 249 VLOG(kVlogSetCookies) |
| 249 << "Create() is trying to create a secure cookie from an insecure URL"; | 250 << "Create() is trying to create a secure cookie from an insecure URL"; |
| 250 return NULL; | 251 return nullptr; |
| 251 } | 252 } |
| 252 | 253 |
| 253 std::string cookie_path = CanonicalCookie::CanonPath(url, parsed_cookie); | 254 std::string cookie_path = CanonicalCookie::CanonPath(url, parsed_cookie); |
| 254 Time server_time(creation_time); | 255 Time server_time(creation_time); |
| 255 if (options.has_server_time()) | 256 if (options.has_server_time()) |
| 256 server_time = options.server_time(); | 257 server_time = options.server_time(); |
| 257 | 258 |
| 258 Time cookie_expires = CanonicalCookie::CanonExpiration(parsed_cookie, | 259 Time cookie_expires = CanonicalCookie::CanonExpiration(parsed_cookie, |
| 259 creation_time, | 260 creation_time, |
| 260 server_time); | 261 server_time); |
| 261 | 262 |
| 262 CookiePrefix prefix = CanonicalCookie::GetCookiePrefix(parsed_cookie.Name()); | 263 CookiePrefix prefix = CanonicalCookie::GetCookiePrefix(parsed_cookie.Name()); |
| 263 bool is_cookie_valid = | 264 bool is_cookie_valid = |
| 264 CanonicalCookie::IsCookiePrefixValid(prefix, url, parsed_cookie); | 265 CanonicalCookie::IsCookiePrefixValid(prefix, url, parsed_cookie); |
| 265 CanonicalCookie::RecordCookiePrefixMetrics(prefix, is_cookie_valid); | 266 CanonicalCookie::RecordCookiePrefixMetrics(prefix, is_cookie_valid); |
| 266 if (!is_cookie_valid) { | 267 if (!is_cookie_valid) { |
| 267 VLOG(kVlogSetCookies) | 268 VLOG(kVlogSetCookies) |
| 268 << "Create() failed because the cookie violated prefix rules."; | 269 << "Create() failed because the cookie violated prefix rules."; |
| 269 return nullptr; | 270 return nullptr; |
| 270 } | 271 } |
| 271 | 272 |
| 272 return new CanonicalCookie( | 273 return make_scoped_ptr(new CanonicalCookie( |
| 273 url, parsed_cookie.Name(), parsed_cookie.Value(), cookie_domain, | 274 url, parsed_cookie.Name(), parsed_cookie.Value(), cookie_domain, |
| 274 cookie_path, creation_time, cookie_expires, creation_time, | 275 cookie_path, creation_time, cookie_expires, creation_time, |
| 275 parsed_cookie.IsSecure(), parsed_cookie.IsHttpOnly(), | 276 parsed_cookie.IsSecure(), parsed_cookie.IsHttpOnly(), |
| 276 parsed_cookie.IsFirstPartyOnly(), parsed_cookie.Priority()); | 277 parsed_cookie.IsFirstPartyOnly(), parsed_cookie.Priority())); |
| 277 } | 278 } |
| 278 | 279 |
| 279 CanonicalCookie* CanonicalCookie::Create(const GURL& url, | 280 // static |
| 280 const std::string& name, | 281 scoped_ptr<CanonicalCookie> CanonicalCookie::Create( |
| 281 const std::string& value, | 282 const GURL& url, |
| 282 const std::string& domain, | 283 const std::string& name, |
| 283 const std::string& path, | 284 const std::string& value, |
| 284 const base::Time& creation, | 285 const std::string& domain, |
| 285 const base::Time& expiration, | 286 const std::string& path, |
| 286 bool secure, | 287 const base::Time& creation, |
| 287 bool http_only, | 288 const base::Time& expiration, |
| 288 bool first_party_only, | 289 bool secure, |
| 289 bool enforce_strict_secure, | 290 bool http_only, |
| 290 CookiePriority priority) { | 291 bool first_party_only, |
| 292 bool enforce_strict_secure, |
| 293 CookiePriority priority) { |
| 291 // Expect valid attribute tokens and values, as defined by the ParsedCookie | 294 // Expect valid attribute tokens and values, as defined by the ParsedCookie |
| 292 // logic, otherwise don't create the cookie. | 295 // logic, otherwise don't create the cookie. |
| 293 std::string parsed_name = ParsedCookie::ParseTokenString(name); | 296 std::string parsed_name = ParsedCookie::ParseTokenString(name); |
| 294 if (parsed_name != name) | 297 if (parsed_name != name) |
| 295 return NULL; | 298 return nullptr; |
| 296 std::string parsed_value = ParsedCookie::ParseValueString(value); | 299 std::string parsed_value = ParsedCookie::ParseValueString(value); |
| 297 if (parsed_value != value) | 300 if (parsed_value != value) |
| 298 return NULL; | 301 return nullptr; |
| 299 | 302 |
| 300 std::string parsed_domain = ParsedCookie::ParseValueString(domain); | 303 std::string parsed_domain = ParsedCookie::ParseValueString(domain); |
| 301 if (parsed_domain != domain) | 304 if (parsed_domain != domain) |
| 302 return NULL; | 305 return nullptr; |
| 303 std::string cookie_domain; | 306 std::string cookie_domain; |
| 304 if (!cookie_util::GetCookieDomainWithString(url, parsed_domain, | 307 if (!cookie_util::GetCookieDomainWithString(url, parsed_domain, |
| 305 &cookie_domain)) { | 308 &cookie_domain)) { |
| 306 return NULL; | 309 return nullptr; |
| 307 } | 310 } |
| 308 | 311 |
| 309 if (enforce_strict_secure && secure && !url.SchemeIsCryptographic()) | 312 if (enforce_strict_secure && secure && !url.SchemeIsCryptographic()) |
| 310 return NULL; | 313 return nullptr; |
| 311 | 314 |
| 312 std::string parsed_path = ParsedCookie::ParseValueString(path); | 315 std::string parsed_path = ParsedCookie::ParseValueString(path); |
| 313 if (parsed_path != path) | 316 if (parsed_path != path) |
| 314 return NULL; | 317 return nullptr; |
| 315 | 318 |
| 316 std::string cookie_path = CanonPathWithString(url, parsed_path); | 319 std::string cookie_path = CanonPathWithString(url, parsed_path); |
| 317 // Expect that the path was either not specified (empty), or is valid. | 320 // Expect that the path was either not specified (empty), or is valid. |
| 318 if (!parsed_path.empty() && cookie_path != parsed_path) | 321 if (!parsed_path.empty() && cookie_path != parsed_path) |
| 319 return NULL; | 322 return nullptr; |
| 320 // Canonicalize path again to make sure it escapes characters as needed. | 323 // Canonicalize path again to make sure it escapes characters as needed. |
| 321 url::Component path_component(0, cookie_path.length()); | 324 url::Component path_component(0, cookie_path.length()); |
| 322 url::RawCanonOutputT<char> canon_path; | 325 url::RawCanonOutputT<char> canon_path; |
| 323 url::Component canon_path_component; | 326 url::Component canon_path_component; |
| 324 url::CanonicalizePath(cookie_path.data(), path_component, &canon_path, | 327 url::CanonicalizePath(cookie_path.data(), path_component, &canon_path, |
| 325 &canon_path_component); | 328 &canon_path_component); |
| 326 cookie_path = std::string(canon_path.data() + canon_path_component.begin, | 329 cookie_path = std::string(canon_path.data() + canon_path_component.begin, |
| 327 canon_path_component.len); | 330 canon_path_component.len); |
| 328 | 331 |
| 329 return new CanonicalCookie(url, parsed_name, parsed_value, cookie_domain, | 332 return make_scoped_ptr(new CanonicalCookie( |
| 330 cookie_path, creation, expiration, creation, | 333 url, parsed_name, parsed_value, cookie_domain, cookie_path, creation, |
| 331 secure, http_only, first_party_only, priority); | 334 expiration, creation, secure, http_only, first_party_only, priority)); |
| 332 } | 335 } |
| 333 | 336 |
| 334 bool CanonicalCookie::IsOnPath(const std::string& url_path) const { | 337 bool CanonicalCookie::IsOnPath(const std::string& url_path) const { |
| 335 | 338 |
| 336 // A zero length would be unsafe for our trailing '/' checks, and | 339 // A zero length would be unsafe for our trailing '/' checks, and |
| 337 // would also make no sense for our prefix match. The code that | 340 // would also make no sense for our prefix match. The code that |
| 338 // creates a CanonicalCookie should make sure the path is never zero length, | 341 // creates a CanonicalCookie should make sure the path is never zero length, |
| 339 // but we double check anyway. | 342 // but we double check anyway. |
| 340 if (path_.empty()) | 343 if (path_.empty()) |
| 341 return false; | 344 return false; |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 502 if (prefix == CanonicalCookie::COOKIE_PREFIX_SECURE) | 505 if (prefix == CanonicalCookie::COOKIE_PREFIX_SECURE) |
| 503 return parsed_cookie.IsSecure() && url.SchemeIsCryptographic(); | 506 return parsed_cookie.IsSecure() && url.SchemeIsCryptographic(); |
| 504 if (prefix == CanonicalCookie::COOKIE_PREFIX_HOST) { | 507 if (prefix == CanonicalCookie::COOKIE_PREFIX_HOST) { |
| 505 return parsed_cookie.IsSecure() && url.SchemeIsCryptographic() && | 508 return parsed_cookie.IsSecure() && url.SchemeIsCryptographic() && |
| 506 !parsed_cookie.HasDomain() && parsed_cookie.Path() == "/"; | 509 !parsed_cookie.HasDomain() && parsed_cookie.Path() == "/"; |
| 507 } | 510 } |
| 508 return true; | 511 return true; |
| 509 } | 512 } |
| 510 | 513 |
| 511 } // namespace net | 514 } // namespace net |
| OLD | NEW |