This source file includes following definitions.
- GetCookieDomain
- CanonPathWithString
- httponly_
- priority_
- priority_
- GetCookieSourceFromURL
- CanonPath
- CanonExpiration
- Create
- Create
- IsOnPath
- IsDomainMatch
- IncludeForRequestURL
- DebugString
#include "net/cookies/canonical_cookie.h"
#include "base/basictypes.h"
#include "base/format_macros.h"
#include "base/logging.h"
#include "base/strings/stringprintf.h"
#include "net/cookies/cookie_util.h"
#include "net/cookies/parsed_cookie.h"
#include "url/gurl.h"
#include "url/url_canon.h"
using base::Time;
using base::TimeDelta;
namespace net {
namespace {
const int kVlogSetCookies = 7;
bool GetCookieDomain(const GURL& url,
const ParsedCookie& pc,
std::string* result) {
std::string domain_string;
if (pc.HasDomain())
domain_string = pc.Domain();
return cookie_util::GetCookieDomainWithString(url, domain_string, result);
}
std::string CanonPathWithString(const GURL& url,
const std::string& path_string) {
if (!path_string.empty() && path_string[0] == '/')
return path_string;
const std::string& url_path = url.path();
size_t idx = url_path.find_last_of('/');
if (idx == 0 || idx == std::string::npos)
return std::string("/");
return url_path.substr(0, idx);
}
}
CanonicalCookie::CanonicalCookie()
: secure_(false),
httponly_(false) {
}
CanonicalCookie::CanonicalCookie(
const GURL& url, const std::string& name, const std::string& value,
const std::string& domain, const std::string& path,
const base::Time& creation, const base::Time& expiration,
const base::Time& last_access, bool secure, bool httponly,
CookiePriority priority)
: source_(GetCookieSourceFromURL(url)),
name_(name),
value_(value),
domain_(domain),
path_(path),
creation_date_(creation),
expiry_date_(expiration),
last_access_date_(last_access),
secure_(secure),
httponly_(httponly),
priority_(priority) {
}
CanonicalCookie::CanonicalCookie(const GURL& url, const ParsedCookie& pc)
: source_(GetCookieSourceFromURL(url)),
name_(pc.Name()),
value_(pc.Value()),
path_(CanonPath(url, pc)),
creation_date_(Time::Now()),
last_access_date_(Time()),
secure_(pc.IsSecure()),
httponly_(pc.IsHttpOnly()),
priority_(pc.Priority()) {
if (pc.HasExpires())
expiry_date_ = CanonExpiration(pc, creation_date_, creation_date_);
std::string cookie_domain;
std::string domain_string;
if (pc.HasDomain()) {
domain_string = pc.Domain();
}
bool result
= cookie_util::GetCookieDomainWithString(url, domain_string,
&cookie_domain);
DCHECK(result);
domain_ = cookie_domain;
}
CanonicalCookie::~CanonicalCookie() {
}
std::string CanonicalCookie::GetCookieSourceFromURL(const GURL& url) {
if (url.SchemeIsFile())
return url.spec();
url_canon::Replacements<char> replacements;
replacements.ClearPort();
if (url.SchemeIsSecure())
replacements.SetScheme("http", url_parse::Component(0, 4));
return url.GetOrigin().ReplaceComponents(replacements).spec();
}
std::string CanonicalCookie::CanonPath(const GURL& url,
const ParsedCookie& pc) {
std::string path_string;
if (pc.HasPath())
path_string = pc.Path();
return CanonPathWithString(url, path_string);
}
Time CanonicalCookie::CanonExpiration(const ParsedCookie& pc,
const Time& current,
const Time& server_time) {
uint64 max_age = 0;
if (pc.HasMaxAge() &&
#ifdef COMPILER_MSVC
sscanf_s(
#else
sscanf(
#endif
pc.MaxAge().c_str(), " %" PRIu64, &max_age) == 1) {
return current + TimeDelta::FromSeconds(max_age);
}
if (pc.HasExpires() && !pc.Expires().empty()) {
base::Time parsed_expiry = cookie_util::ParseCookieTime(pc.Expires());
if (!parsed_expiry.is_null())
return parsed_expiry + (current - server_time);
}
return Time();
}
CanonicalCookie* CanonicalCookie::Create(const GURL& url,
const std::string& cookie_line,
const base::Time& creation_time,
const CookieOptions& options) {
ParsedCookie parsed_cookie(cookie_line);
if (!parsed_cookie.IsValid()) {
VLOG(kVlogSetCookies) << "WARNING: Couldn't parse cookie";
return NULL;
}
if (options.exclude_httponly() && parsed_cookie.IsHttpOnly()) {
VLOG(kVlogSetCookies) << "Create() is not creating a httponly cookie";
return NULL;
}
std::string cookie_domain;
if (!GetCookieDomain(url, parsed_cookie, &cookie_domain)) {
return NULL;
}
std::string cookie_path = CanonicalCookie::CanonPath(url, parsed_cookie);
Time server_time(creation_time);
if (options.has_server_time())
server_time = options.server_time();
Time cookie_expires = CanonicalCookie::CanonExpiration(parsed_cookie,
creation_time,
server_time);
return new CanonicalCookie(url, parsed_cookie.Name(), parsed_cookie.Value(),
cookie_domain, cookie_path, creation_time,
cookie_expires, creation_time,
parsed_cookie.IsSecure(),
parsed_cookie.IsHttpOnly(),
parsed_cookie.Priority());
}
CanonicalCookie* CanonicalCookie::Create(const GURL& url,
const std::string& name,
const std::string& value,
const std::string& domain,
const std::string& path,
const base::Time& creation,
const base::Time& expiration,
bool secure,
bool http_only,
CookiePriority priority) {
std::string parsed_name = ParsedCookie::ParseTokenString(name);
if (parsed_name != name)
return NULL;
std::string parsed_value = ParsedCookie::ParseValueString(value);
if (parsed_value != value)
return NULL;
std::string parsed_domain = ParsedCookie::ParseValueString(domain);
if (parsed_domain != domain)
return NULL;
std::string cookie_domain;
if (!cookie_util::GetCookieDomainWithString(url, parsed_domain,
&cookie_domain)) {
return NULL;
}
std::string parsed_path = ParsedCookie::ParseValueString(path);
if (parsed_path != path)
return NULL;
std::string cookie_path = CanonPathWithString(url, parsed_path);
if (!parsed_path.empty() && cookie_path != parsed_path)
return NULL;
url_parse::Component path_component(0, cookie_path.length());
url_canon::RawCanonOutputT<char> canon_path;
url_parse::Component canon_path_component;
url_canon::CanonicalizePath(cookie_path.data(), path_component,
&canon_path, &canon_path_component);
cookie_path = std::string(canon_path.data() + canon_path_component.begin,
canon_path_component.len);
return new CanonicalCookie(url, parsed_name, parsed_value, cookie_domain,
cookie_path, creation, expiration, creation,
secure, http_only, priority);
}
bool CanonicalCookie::IsOnPath(const std::string& url_path) const {
if (path_.empty())
return false;
if (url_path.find(path_) != 0)
return false;
if (path_.length() != url_path.length() &&
path_[path_.length() - 1] != '/' &&
url_path[path_.length()] != '/')
return false;
return true;
}
bool CanonicalCookie::IsDomainMatch(const std::string& host) const {
if (host == domain_)
return true;
if (domain_.empty() || domain_[0] != '.')
return false;
if (domain_.compare(1, std::string::npos, host) == 0)
return true;
return (host.length() > domain_.length() &&
host.compare(host.length() - domain_.length(),
domain_.length(), domain_) == 0);
}
bool CanonicalCookie::IncludeForRequestURL(const GURL& url,
const CookieOptions& options) const {
if (options.exclude_httponly() && IsHttpOnly())
return false;
if (IsSecure() && !url.SchemeIsSecure())
return false;
if (!IsDomainMatch(url.host()))
return false;
if (!IsOnPath(url.path()))
return false;
return true;
}
std::string CanonicalCookie::DebugString() const {
return base::StringPrintf(
"name: %s value: %s domain: %s path: %s creation: %"
PRId64,
name_.c_str(), value_.c_str(),
domain_.c_str(), path_.c_str(),
static_cast<int64>(creation_date_.ToTimeT()));
}
}