mirror of
https://github.com/klzgrad/naiveproxy.git
synced 2024-12-01 01:36:09 +03:00
234 lines
9.2 KiB
C
234 lines
9.2 KiB
C
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||
|
// Use of this source code is governed by a BSD-style license that can be
|
||
|
// found in the LICENSE file.
|
||
|
|
||
|
#ifndef NET_COOKIES_CANONICAL_COOKIE_H_
|
||
|
#define NET_COOKIES_CANONICAL_COOKIE_H_
|
||
|
|
||
|
#include <memory>
|
||
|
#include <string>
|
||
|
#include <vector>
|
||
|
|
||
|
#include "base/gtest_prod_util.h"
|
||
|
#include "base/time/time.h"
|
||
|
#include "net/base/net_export.h"
|
||
|
#include "net/cookies/cookie_constants.h"
|
||
|
#include "net/cookies/cookie_options.h"
|
||
|
|
||
|
class GURL;
|
||
|
|
||
|
namespace net {
|
||
|
|
||
|
class ParsedCookie;
|
||
|
|
||
|
class NET_EXPORT CanonicalCookie {
|
||
|
public:
|
||
|
CanonicalCookie();
|
||
|
CanonicalCookie(const CanonicalCookie& other);
|
||
|
|
||
|
// This constructor does not validate or canonicalize their inputs;
|
||
|
// the resulting CanonicalCookies should not be relied on to be canonical
|
||
|
// unless the caller has done appropriate validation and canonicalization
|
||
|
// themselves.
|
||
|
CanonicalCookie(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,
|
||
|
CookieSameSite same_site,
|
||
|
CookiePriority priority);
|
||
|
|
||
|
~CanonicalCookie();
|
||
|
|
||
|
// Supports the default copy constructor.
|
||
|
|
||
|
// Creates a new |CanonicalCookie| from the |cookie_line| and the
|
||
|
// |creation_time|. Canonicalizes and validates inputs. May return NULL if
|
||
|
// an attribute value is invalid. |creation_time| may not be null.
|
||
|
static std::unique_ptr<CanonicalCookie> Create(
|
||
|
const GURL& url,
|
||
|
const std::string& cookie_line,
|
||
|
const base::Time& creation_time,
|
||
|
const CookieOptions& options);
|
||
|
|
||
|
// Create a canonical cookie based on sanitizing the passed inputs in the
|
||
|
// context of the passed URL. Returns a null unique pointer if the inputs
|
||
|
// cannot be sanitized. If a cookie is created, |cookie->IsCanonical()|
|
||
|
// will be true.
|
||
|
static std::unique_ptr<CanonicalCookie> CreateSanitizedCookie(
|
||
|
const GURL& url,
|
||
|
const std::string& name,
|
||
|
const std::string& value,
|
||
|
const std::string& domain,
|
||
|
const std::string& path,
|
||
|
base::Time creation_time,
|
||
|
base::Time expiration_time,
|
||
|
base::Time last_access_time,
|
||
|
bool secure,
|
||
|
bool http_only,
|
||
|
CookieSameSite same_site,
|
||
|
CookiePriority priority);
|
||
|
|
||
|
const std::string& Name() const { return name_; }
|
||
|
const std::string& Value() const { return value_; }
|
||
|
const std::string& Domain() const { return domain_; }
|
||
|
const std::string& Path() const { return path_; }
|
||
|
const base::Time& CreationDate() const { return creation_date_; }
|
||
|
const base::Time& LastAccessDate() const { return last_access_date_; }
|
||
|
bool IsPersistent() const { return !expiry_date_.is_null(); }
|
||
|
const base::Time& ExpiryDate() const { return expiry_date_; }
|
||
|
bool IsSecure() const { return secure_; }
|
||
|
bool IsHttpOnly() const { return httponly_; }
|
||
|
CookieSameSite SameSite() const { return same_site_; }
|
||
|
CookiePriority Priority() const { return priority_; }
|
||
|
bool IsDomainCookie() const {
|
||
|
return !domain_.empty() && domain_[0] == '.'; }
|
||
|
bool IsHostCookie() const { return !IsDomainCookie(); }
|
||
|
|
||
|
bool IsExpired(const base::Time& current) const {
|
||
|
return !expiry_date_.is_null() && current >= expiry_date_;
|
||
|
}
|
||
|
|
||
|
// Are the cookies considered equivalent in the eyes of RFC 2965.
|
||
|
// The RFC says that name must match (case-sensitive), domain must
|
||
|
// match (case insensitive), and path must match (case sensitive).
|
||
|
// For the case insensitive domain compare, we rely on the domain
|
||
|
// having been canonicalized (in
|
||
|
// GetCookieDomainWithString->CanonicalizeHost).
|
||
|
bool IsEquivalent(const CanonicalCookie& ecc) const {
|
||
|
// It seems like it would make sense to take secure and httponly into
|
||
|
// account, but the RFC doesn't specify this.
|
||
|
// NOTE: Keep this logic in-sync with TrimDuplicateCookiesForHost().
|
||
|
return (name_ == ecc.Name() && domain_ == ecc.Domain()
|
||
|
&& path_ == ecc.Path());
|
||
|
}
|
||
|
|
||
|
// Checks a looser set of equivalency rules than 'IsEquivalent()' in order
|
||
|
// to support the stricter 'Secure' behaviors specified in
|
||
|
// https://tools.ietf.org/html/draft-ietf-httpbis-cookie-alone#section-3
|
||
|
//
|
||
|
// Returns 'true' if this cookie's name matches |ecc|, and this cookie is
|
||
|
// a domain-match for |ecc| (or vice versa), and |ecc|'s path is "on" this
|
||
|
// cookie's path (as per 'IsOnPath()').
|
||
|
//
|
||
|
// Note that while the domain-match cuts both ways (e.g. 'example.com'
|
||
|
// matches 'www.example.com' in either direction), the path-match is
|
||
|
// unidirectional (e.g. '/login/en' matches '/login' and '/', but
|
||
|
// '/login' and '/' do not match '/login/en').
|
||
|
bool IsEquivalentForSecureCookieMatching(const CanonicalCookie& ecc) const;
|
||
|
|
||
|
void SetLastAccessDate(const base::Time& date) {
|
||
|
last_access_date_ = date;
|
||
|
}
|
||
|
void SetCreationDate(const base::Time& date) { creation_date_ = date; }
|
||
|
|
||
|
// Returns true if the given |url_path| path-matches the cookie-path as
|
||
|
// described in section 5.1.4 in RFC 6265.
|
||
|
bool IsOnPath(const std::string& url_path) const;
|
||
|
|
||
|
// Returns true if the cookie domain matches the given |host| as described in
|
||
|
// section 5.1.3 of RFC 6265.
|
||
|
bool IsDomainMatch(const std::string& host) const;
|
||
|
|
||
|
// Returns true if the cookie should be included for the given request |url|.
|
||
|
// HTTP only cookies can be filter by using appropriate cookie |options|.
|
||
|
// PLEASE NOTE that this method does not check whether a cookie is expired or
|
||
|
// not!
|
||
|
bool IncludeForRequestURL(const GURL& url,
|
||
|
const CookieOptions& options) const;
|
||
|
|
||
|
std::string DebugString() const;
|
||
|
|
||
|
static std::string CanonPathWithString(const GURL& url,
|
||
|
const std::string& path_string);
|
||
|
|
||
|
// Returns a "null" time if expiration was unspecified or invalid.
|
||
|
static base::Time CanonExpiration(const ParsedCookie& pc,
|
||
|
const base::Time& current,
|
||
|
const base::Time& server_time);
|
||
|
|
||
|
// Cookie ordering methods.
|
||
|
|
||
|
// Returns true if the cookie is less than |other|, considering only name,
|
||
|
// domain and path. In particular, two equivalent cookies (see IsEquivalent())
|
||
|
// are identical for PartialCompare().
|
||
|
bool PartialCompare(const CanonicalCookie& other) const;
|
||
|
|
||
|
// Returns true if the cookie is less than |other|, considering all fields.
|
||
|
// FullCompare() is consistent with PartialCompare(): cookies sorted using
|
||
|
// FullCompare() are also sorted with respect to PartialCompare().
|
||
|
bool FullCompare(const CanonicalCookie& other) const;
|
||
|
|
||
|
// Return whether this object is a valid CanonicalCookie(). Invalid
|
||
|
// cookies may be constructed by the detailed constructor.
|
||
|
// A cookie is considered canonical if-and-only-if:
|
||
|
// * It can be created by CanonicalCookie::Create, or
|
||
|
// * It is identical to a cookie created by CanonicalCookie::Create except
|
||
|
// that the creation time is null, or
|
||
|
// * It can be derived from a cookie created by CanonicalCookie::Create by
|
||
|
// entry into and retrieval from a cookie store (specifically, this means
|
||
|
// by the setting of an creation time in place of a null creation time, and
|
||
|
// the setting of a last access time).
|
||
|
// An additional requirement on a CanonicalCookie is that if the last
|
||
|
// access time is non-null, the creation time must also be non-null and
|
||
|
// greater than the last access time.
|
||
|
bool IsCanonical() const;
|
||
|
|
||
|
// Returns the cookie line (e.g. "cookie1=value1; cookie2=value2") represented
|
||
|
// by |cookies|. The string is built in the same order as the given list.
|
||
|
static std::string BuildCookieLine(
|
||
|
const std::vector<CanonicalCookie>& cookies);
|
||
|
|
||
|
private:
|
||
|
FRIEND_TEST_ALL_PREFIXES(CanonicalCookieTest, TestPrefixHistograms);
|
||
|
|
||
|
// The special cookie prefixes as defined in
|
||
|
// https://tools.ietf.org/html/draft-west-cookie-prefixes
|
||
|
//
|
||
|
// This enum is being histogrammed; do not reorder or remove values.
|
||
|
enum CookiePrefix {
|
||
|
COOKIE_PREFIX_NONE = 0,
|
||
|
COOKIE_PREFIX_SECURE,
|
||
|
COOKIE_PREFIX_HOST,
|
||
|
COOKIE_PREFIX_LAST
|
||
|
};
|
||
|
|
||
|
// Returns the CookiePrefix (or COOKIE_PREFIX_NONE if none) that
|
||
|
// applies to the given cookie |name|.
|
||
|
static CookiePrefix GetCookiePrefix(const std::string& name);
|
||
|
// Records histograms to measure how often cookie prefixes appear in
|
||
|
// the wild and how often they would be blocked.
|
||
|
static void RecordCookiePrefixMetrics(CookiePrefix prefix,
|
||
|
bool is_cookie_valid);
|
||
|
// Returns true if a prefixed cookie does not violate any of the rules
|
||
|
// for that cookie.
|
||
|
static bool IsCookiePrefixValid(CookiePrefix prefix,
|
||
|
const GURL& url,
|
||
|
const ParsedCookie& parsed_cookie);
|
||
|
|
||
|
// Returns the cookie's domain, with the leading dot removed, if present.
|
||
|
std::string DomainWithoutDot() const;
|
||
|
|
||
|
std::string name_;
|
||
|
std::string value_;
|
||
|
std::string domain_;
|
||
|
std::string path_;
|
||
|
base::Time creation_date_;
|
||
|
base::Time expiry_date_;
|
||
|
base::Time last_access_date_;
|
||
|
bool secure_;
|
||
|
bool httponly_;
|
||
|
CookieSameSite same_site_;
|
||
|
CookiePriority priority_;
|
||
|
};
|
||
|
|
||
|
typedef std::vector<CanonicalCookie> CookieList;
|
||
|
|
||
|
} // namespace net
|
||
|
|
||
|
#endif // NET_COOKIES_CANONICAL_COOKIE_H_
|