// 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.

// Portions of this code based on Mozilla:
//   (netwerk/cookie/src/nsCookieService.cpp)
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is mozilla.org code.
 *
 * The Initial Developer of the Original Code is
 * Netscape Communications Corporation.
 * Portions created by the Initial Developer are Copyright (C) 2003
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *   Daniel Witte (dwitte@stanford.edu)
 *   Michiel van Leeuwen (mvl@exedo.nl)
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

#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;

// Determine the cookie domain to use for setting the specified cookie.
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) {
  // The RFC says the path should be a prefix of the current URL path.
  // However, Mozilla allows you to set any path for compatibility with
  // broken websites.  We unfortunately will mimic this behavior.  We try
  // to be generous and accept cookies with an invalid path attribute, and
  // default the path to something reasonable.

  // The path was supplied in the cookie, we'll take it.
  if (!path_string.empty() && path_string[0] == '/')
    return path_string;

  // The path was not supplied in the cookie or invalid, we will default
  // to the current URL path.
  // """Defaults to the path of the request URL that generated the
  //    Set-Cookie response, up to, but not including, the
  //    right-most /."""
  // How would this work for a cookie on /?  We will include it then.
  const std::string& url_path = url.path();

  size_t idx = url_path.find_last_of('/');

  // The cookie path was invalid or a single '/'.
  if (idx == 0 || idx == std::string::npos)
    return std::string("/");

  // Return up to the rightmost '/'.
  return url_path.substr(0, idx);
}

// Compares cookies using name, domain and path, so that "equivalent" cookies
// (per RFC 2965) are equal to each other.
int PartialCookieOrdering(const CanonicalCookie& a, const CanonicalCookie& b) {
  int diff = a.Name().compare(b.Name());
  if (diff != 0)
    return diff;

  diff = a.Domain().compare(b.Domain());
  if (diff != 0)
    return diff;

  return a.Path().compare(b.Path());
}

}  // namespace

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,
                                 bool firstpartyonly,
                                 CookiePriority priority)
    : source_(url.SchemeIsFile() ? url : url.GetOrigin()),
      name_(name),
      value_(value),
      domain_(domain),
      path_(path),
      creation_date_(creation),
      expiry_date_(expiration),
      last_access_date_(last_access),
      secure_(secure),
      httponly_(httponly),
      first_party_only_(firstpartyonly),
      priority_(priority) {}

CanonicalCookie::CanonicalCookie(const GURL& url, const ParsedCookie& pc)
    : source_(url.SchemeIsFile() ? url : url.GetOrigin()),
      name_(pc.Name()),
      value_(pc.Value()),
      path_(CanonPath(url, pc)),
      creation_date_(Time::Now()),
      last_access_date_(Time()),
      secure_(pc.IsSecure()),
      httponly_(pc.IsHttpOnly()),
      first_party_only_(pc.IsFirstPartyOnly()),
      priority_(pc.Priority()) {
  if (pc.HasExpires())
    expiry_date_ = CanonExpiration(pc, creation_date_, creation_date_);

  // Do the best we can with the domain.
  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);
  // Caller is responsible for passing in good arguments.
  DCHECK(result);
  domain_ = cookie_domain;
}

CanonicalCookie::~CanonicalCookie() {
}

// static
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);
}

// static
Time CanonicalCookie::CanonExpiration(const ParsedCookie& pc,
                                      const Time& current,
                                      const Time& server_time) {
  // First, try the Max-Age attribute.
  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);
  }

  // Try the Expires attribute.
  if (pc.HasExpires() && !pc.Expires().empty()) {
    // Adjust for clock skew between server and host.
    base::Time parsed_expiry = cookie_util::ParseCookieTime(pc.Expires());
    if (!parsed_expiry.is_null())
      return parsed_expiry + (current - server_time);
  }

  // Invalid or no expiration, persistent cookie.
  return Time();
}

// static
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)) {
    VLOG(kVlogSetCookies) << "Create() failed to get a 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.IsFirstPartyOnly(), 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,
                                         bool first_party_only,
                                         CookiePriority priority) {
  // Expect valid attribute tokens and values, as defined by the ParsedCookie
  // logic, otherwise don't create the cookie.
  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);
  // Expect that the path was either not specified (empty), or is valid.
  if (!parsed_path.empty() && cookie_path != parsed_path)
    return NULL;
  // Canonicalize path again to make sure it escapes characters as needed.
  url::Component path_component(0, cookie_path.length());
  url::RawCanonOutputT<char> canon_path;
  url::Component canon_path_component;
  url::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, first_party_only, priority);
}

bool CanonicalCookie::IsOnPath(const std::string& url_path) const {

  // A zero length would be unsafe for our trailing '/' checks, and
  // would also make no sense for our prefix match.  The code that
  // creates a CanonicalCookie should make sure the path is never zero length,
  // but we double check anyway.
  if (path_.empty())
    return false;

  // The Mozilla code broke this into three cases, based on if the cookie path
  // was longer, the same length, or shorter than the length of the url path.
  // I think the approach below is simpler.

  // Make sure the cookie path is a prefix of the url path.  If the
  // url path is shorter than the cookie path, then the cookie path
  // can't be a prefix.
  if (url_path.find(path_) != 0)
    return false;

  // Now we know that url_path is >= cookie_path, and that cookie_path
  // is a prefix of url_path.  If they are the are the same length then
  // they are identical, otherwise we need an additional check:

  // In order to avoid in correctly matching a cookie path of /blah
  // with a request path of '/blahblah/', we need to make sure that either
  // the cookie path ends in a trailing '/', or that we prefix up to a '/'
  // in the url path.  Since we know that the url path length is greater
  // than the cookie path length, it's safe to index one byte past.
  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 {
  // Can domain match in two ways; as a domain cookie (where the cookie
  // domain begins with ".") or as a host cookie (where it doesn't).

  // Some consumers of the CookieMonster expect to set cookies on
  // URLs like http://.strange.url.  To retrieve cookies in this instance,
  // we allow matching as a host cookie even when the domain_ starts with
  // a period.
  if (host == domain_)
    return true;

  // Domain cookie must have an initial ".".  To match, it must be
  // equal to url's host with initial period removed, or a suffix of
  // it.

  // Arguably this should only apply to "http" or "https" cookies, but
  // extension cookie tests currently use the funtionality, and if we
  // ever decide to implement that it should be done by preventing
  // such cookies from being set.
  if (domain_.empty() || domain_[0] != '.')
    return false;

  // The host with a "." prefixed.
  if (domain_.compare(1, std::string::npos, host) == 0)
    return true;

  // A pure suffix of the host (ok since we know the domain already
  // starts with a ".")
  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 {
  // Filter out HttpOnly cookies, per options.
  if (options.exclude_httponly() && IsHttpOnly())
    return false;
  // Secure cookies should not be included in requests for URLs with an
  // insecure scheme.
  if (IsSecure() && !url.SchemeIsCryptographic())
    return false;
  // Don't include cookies for requests that don't apply to the cookie domain.
  if (!IsDomainMatch(url.host()))
    return false;
  // Don't include cookies for requests with a url path that does not path
  // match the cookie-path.
  if (!IsOnPath(url.path()))
    return false;

  // Include first-party-only cookies if:
  //
  // * |options| tells us to include all of them
  // * a first-party origin is set, and they matches the origin of |url|
  if (IsFirstPartyOnly() && !options.include_first_party_only() &&
      !options.first_party().IsSameOriginWith(url::Origin(url))) {
    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()));
}

bool CanonicalCookie::PartialCompare(const CanonicalCookie& other) const {
  return PartialCookieOrdering(*this, other) < 0;
}

bool CanonicalCookie::FullCompare(const CanonicalCookie& other) const {
  // Do the partial comparison first.
  int diff = PartialCookieOrdering(*this, other);
  if (diff != 0)
    return diff < 0;

  DCHECK(IsEquivalent(other));

  // Compare other fields.
  diff = Value().compare(other.Value());
  if (diff != 0)
    return diff < 0;

  if (CreationDate() != other.CreationDate())
    return CreationDate() < other.CreationDate();

  if (ExpiryDate() != other.ExpiryDate())
    return ExpiryDate() < other.ExpiryDate();

  if (LastAccessDate() != other.LastAccessDate())
    return LastAccessDate() < other.LastAccessDate();

  if (IsSecure() != other.IsSecure())
    return IsSecure();

  if (IsHttpOnly() != other.IsHttpOnly())
    return IsHttpOnly();

  return Priority() < other.Priority();
}

}  // namespace net
