Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: net/base/cookie_monster.cc

Issue 4630001: Implement Origin cookies. Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/base/cookie_monster.h ('k') | net/base/cookie_monster_store_test.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 631 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 642
643 *result = cookie_domain; 643 *result = cookie_domain;
644 return true; 644 return true;
645 } 645 }
646 646
647 // Determine the cookie domain to use for setting the specified cookie. 647 // Determine the cookie domain to use for setting the specified cookie.
648 static bool GetCookieDomain(const GURL& url, 648 static bool GetCookieDomain(const GURL& url,
649 const CookieMonster::ParsedCookie& pc, 649 const CookieMonster::ParsedCookie& pc,
650 std::string* result) { 650 std::string* result) {
651 std::string domain_string; 651 std::string domain_string;
652 if (pc.HasDomain()) 652 if (pc.HasDomain() && !pc.IsOrigin())
653 domain_string = pc.Domain(); 653 domain_string = pc.Domain();
654 return GetCookieDomainWithString(url, domain_string, result); 654 return GetCookieDomainWithString(url, domain_string, result);
655 } 655 }
656 656
657 static std::string CanonPathWithString(const GURL& url, 657 static std::string CanonPathWithString(const GURL& url,
658 const std::string& path_string) { 658 const std::string& path_string) {
659 // The RFC says the path should be a prefix of the current URL path. 659 // The RFC says the path should be a prefix of the current URL path.
660 // However, Mozilla allows you to set any path for compatibility with 660 // However, Mozilla allows you to set any path for compatibility with
661 // broken websites. We unfortunately will mimic this behavior. We try 661 // broken websites. We unfortunately will mimic this behavior. We try
662 // to be generous and accept cookies with an invalid path attribute, and 662 // to be generous and accept cookies with an invalid path attribute, and
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
776 return false; 776 return false;
777 } 777 }
778 778
779 std::string cookie_domain; 779 std::string cookie_domain;
780 if (!GetCookieDomain(url, pc, &cookie_domain)) { 780 if (!GetCookieDomain(url, pc, &cookie_domain)) {
781 return false; 781 return false;
782 } 782 }
783 783
784 std::string cookie_path = CanonPath(url, pc); 784 std::string cookie_path = CanonPath(url, pc);
785 785
786 bool cookie_secure = pc.IsOrigin() ? url.SchemeIsSecure() : pc.IsSecure();
787
786 scoped_ptr<CanonicalCookie> cc; 788 scoped_ptr<CanonicalCookie> cc;
787 Time cookie_expires = CanonExpiration(pc, creation_time, options); 789 Time cookie_expires = CanonExpiration(pc, creation_time, options);
788 790
789 cc.reset(new CanonicalCookie(pc.Name(), pc.Value(), cookie_domain, 791 cc.reset(new CanonicalCookie(pc.Name(), pc.Value(), cookie_domain,
790 cookie_path, 792 cookie_path, cookie_secure,
791 pc.IsSecure(), pc.IsHttpOnly(), 793 pc.IsHttpOnly(), pc.IsOrigin(),
792 creation_time, creation_time, 794 creation_time, creation_time,
793 !cookie_expires.is_null(), cookie_expires)); 795 !cookie_expires.is_null(), cookie_expires));
794 796
795 if (!cc.get()) { 797 if (!cc.get()) {
796 VLOG(kVlogSetCookies) << "WARNING: Failed to allocate CanonicalCookie"; 798 VLOG(kVlogSetCookies) << "WARNING: Failed to allocate CanonicalCookie";
797 return false; 799 return false;
798 } 800 }
799 return SetCanonicalCookie(&cc, creation_time, options); 801 return SetCanonicalCookie(&cc, creation_time, options);
800 } 802 }
801 803
802 bool CookieMonster::SetCookieWithCreationTime(const GURL& url, 804 bool CookieMonster::SetCookieWithCreationTime(const GURL& url,
803 const std::string& cookie_line, 805 const std::string& cookie_line,
804 const base::Time& creation_time) { 806 const base::Time& creation_time) {
805 AutoLock autolock(lock_); 807 AutoLock autolock(lock_);
806 808
807 if (!HasCookieableScheme(url)) { 809 if (!HasCookieableScheme(url)) {
808 return false; 810 return false;
809 } 811 }
810 812
811 InitIfNecessary(); 813 InitIfNecessary();
812 return SetCookieWithCreationTimeAndOptions(url, cookie_line, creation_time, 814 return SetCookieWithCreationTimeAndOptions(url, cookie_line, creation_time,
813 CookieOptions()); 815 CookieOptions());
814 } 816 }
815 817
816 bool CookieMonster::SetCookieWithDetails( 818 bool CookieMonster::SetCookieWithDetails(
817 const GURL& url, const std::string& name, const std::string& value, 819 const GURL& url, const std::string& name, const std::string& value,
818 const std::string& domain, const std::string& path, 820 const std::string& domain, const std::string& path,
819 const base::Time& expiration_time, bool secure, bool http_only) { 821 const base::Time& expiration_time,
822 bool secure, bool http_only, bool origin) {
820 823
821 AutoLock autolock(lock_); 824 AutoLock autolock(lock_);
822 825
823 if (!HasCookieableScheme(url)) 826 if (!HasCookieableScheme(url))
824 return false; 827 return false;
825 828
826 InitIfNecessary(); 829 InitIfNecessary();
827 830
828 Time creation_time = CurrentTime(); 831 Time creation_time = CurrentTime();
829 last_time_seen_ = creation_time; 832 last_time_seen_ = creation_time;
830 833
831 scoped_ptr<CanonicalCookie> cc; 834 scoped_ptr<CanonicalCookie> cc;
832 cc.reset(CanonicalCookie::Create( 835 cc.reset(CanonicalCookie::Create(
833 url, name, value, domain, path, 836 url, name, value, domain, path,
834 creation_time, expiration_time, 837 creation_time, expiration_time,
835 secure, http_only)); 838 secure, http_only, origin));
836 839
837 if (!cc.get()) 840 if (!cc.get())
838 return false; 841 return false;
839 842
840 CookieOptions options; 843 CookieOptions options;
841 options.set_include_httponly(); 844 options.set_include_httponly();
842 return SetCanonicalCookie(&cc, creation_time, options); 845 return SetCanonicalCookie(&cc, creation_time, options);
843 } 846 }
844 847
845 bool CookieMonster::SetCanonicalCookie(scoped_ptr<CanonicalCookie>* cc, 848 bool CookieMonster::SetCanonicalCookie(scoped_ptr<CanonicalCookie>* cc,
(...skipping 585 matching lines...) Expand 10 before | Expand all | Expand 10 after
1431 // If the cookie is expired, delete it. 1434 // If the cookie is expired, delete it.
1432 if (cc->IsExpired(current)) { 1435 if (cc->IsExpired(current)) {
1433 InternalDeleteCookie(curit, true, DELETE_COOKIE_EXPIRED); 1436 InternalDeleteCookie(curit, true, DELETE_COOKIE_EXPIRED);
1434 continue; 1437 continue;
1435 } 1438 }
1436 1439
1437 // Filter out HttpOnly cookies, per options. 1440 // Filter out HttpOnly cookies, per options.
1438 if (options.exclude_httponly() && cc->IsHttpOnly()) 1441 if (options.exclude_httponly() && cc->IsHttpOnly())
1439 continue; 1442 continue;
1440 1443
1444 if (options.read_origin() != cc->IsOrigin())
1445 continue;
1446
1441 // Filter out secure cookies unless we're https. 1447 // Filter out secure cookies unless we're https.
1442 if (!secure && cc->IsSecure()) 1448 if (!secure && cc->IsSecure())
1443 continue; 1449 continue;
1444 1450
1445 // Filter out cookies that don't apply to this domain. 1451 // Filter out cookies that don't apply to this domain.
1446 if (expiry_and_key_scheme_ == EKS_KEEP_RECENT_AND_PURGE_ETLDP1 1452 if (expiry_and_key_scheme_ == EKS_KEEP_RECENT_AND_PURGE_ETLDP1
1447 && !cc->IsDomainMatch(scheme, host)) 1453 && !cc->IsDomainMatch(scheme, host))
1448 continue; 1454 continue;
1449 1455
1450 if (!cc->IsOnPath(url.path())) 1456 if (!cc->IsOnPath(url.path()))
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1514 last_statistic_record_time_ = current_time; 1520 last_statistic_record_time_ = current_time;
1515 } 1521 }
1516 1522
1517 CookieMonster::ParsedCookie::ParsedCookie(const std::string& cookie_line) 1523 CookieMonster::ParsedCookie::ParsedCookie(const std::string& cookie_line)
1518 : is_valid_(false), 1524 : is_valid_(false),
1519 path_index_(0), 1525 path_index_(0),
1520 domain_index_(0), 1526 domain_index_(0),
1521 expires_index_(0), 1527 expires_index_(0),
1522 maxage_index_(0), 1528 maxage_index_(0),
1523 secure_index_(0), 1529 secure_index_(0),
1524 httponly_index_(0) { 1530 httponly_index_(0),
1531 origin_index_(0) {
1525 1532
1526 if (cookie_line.size() > kMaxCookieSize) { 1533 if (cookie_line.size() > kMaxCookieSize) {
1527 VLOG(1) << "Not parsing cookie, too large: " << cookie_line.size(); 1534 VLOG(1) << "Not parsing cookie, too large: " << cookie_line.size();
1528 return; 1535 return;
1529 } 1536 }
1530 1537
1531 ParseTokenValuePairs(cookie_line); 1538 ParseTokenValuePairs(cookie_line);
1532 if (pairs_.size() > 0) { 1539 if (pairs_.size() > 0) {
1533 is_valid_ = true; 1540 is_valid_ = true;
1534 SetupAttributes(); 1541 SetupAttributes();
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
1749 } 1756 }
1750 } 1757 }
1751 1758
1752 void CookieMonster::ParsedCookie::SetupAttributes() { 1759 void CookieMonster::ParsedCookie::SetupAttributes() {
1753 static const char kPathTokenName[] = "path"; 1760 static const char kPathTokenName[] = "path";
1754 static const char kDomainTokenName[] = "domain"; 1761 static const char kDomainTokenName[] = "domain";
1755 static const char kExpiresTokenName[] = "expires"; 1762 static const char kExpiresTokenName[] = "expires";
1756 static const char kMaxAgeTokenName[] = "max-age"; 1763 static const char kMaxAgeTokenName[] = "max-age";
1757 static const char kSecureTokenName[] = "secure"; 1764 static const char kSecureTokenName[] = "secure";
1758 static const char kHttpOnlyTokenName[] = "httponly"; 1765 static const char kHttpOnlyTokenName[] = "httponly";
1766 static const char kOriginTokenName[] = "origin";
1759 1767
1760 // We skip over the first token/value, the user supplied one. 1768 // We skip over the first token/value, the user supplied one.
1761 for (size_t i = 1; i < pairs_.size(); ++i) { 1769 for (size_t i = 1; i < pairs_.size(); ++i) {
1762 if (pairs_[i].first == kPathTokenName) { 1770 if (pairs_[i].first == kPathTokenName) {
1763 path_index_ = i; 1771 path_index_ = i;
1764 } else if (pairs_[i].first == kDomainTokenName) { 1772 } else if (pairs_[i].first == kDomainTokenName) {
1765 domain_index_ = i; 1773 domain_index_ = i;
1766 } else if (pairs_[i].first == kExpiresTokenName) { 1774 } else if (pairs_[i].first == kExpiresTokenName) {
1767 expires_index_ = i; 1775 expires_index_ = i;
1768 } else if (pairs_[i].first == kMaxAgeTokenName) { 1776 } else if (pairs_[i].first == kMaxAgeTokenName) {
1769 maxage_index_ = i; 1777 maxage_index_ = i;
1770 } else if (pairs_[i].first == kSecureTokenName) { 1778 } else if (pairs_[i].first == kSecureTokenName) {
1771 secure_index_ = i; 1779 secure_index_ = i;
1772 } else if (pairs_[i].first == kHttpOnlyTokenName) { 1780 } else if (pairs_[i].first == kHttpOnlyTokenName) {
1773 httponly_index_ = i; 1781 httponly_index_ = i;
1782 } else if (pairs_[i].first == kOriginTokenName) {
1783 origin_index_ = i;
1774 } else { 1784 } else {
1775 /* some attribute we don't know or don't care about. */ 1785 /* some attribute we don't know or don't care about. */
1776 } 1786 }
1777 } 1787 }
1778 } 1788 }
1779 1789
1780 // Create a cookie-line for the cookie. For debugging only! 1790 // Create a cookie-line for the cookie. For debugging only!
1781 // If we want to use this for something more than debugging, we 1791 // If we want to use this for something more than debugging, we
1782 // should rewrite it better... 1792 // should rewrite it better...
1783 std::string CookieMonster::ParsedCookie::DebugString() const { 1793 std::string CookieMonster::ParsedCookie::DebugString() const {
1784 std::string out; 1794 std::string out;
1785 for (PairList::const_iterator it = pairs_.begin(); 1795 for (PairList::const_iterator it = pairs_.begin();
1786 it != pairs_.end(); ++it) { 1796 it != pairs_.end(); ++it) {
1787 out.append(it->first); 1797 out.append(it->first);
1788 out.append("="); 1798 out.append("=");
1789 out.append(it->second); 1799 out.append(it->second);
1790 out.append("; "); 1800 out.append("; ");
1791 } 1801 }
1792 return out; 1802 return out;
1793 } 1803 }
1794 1804
1805 // TODO(abarth): Do we need to initialize the boolean members here?
1795 CookieMonster::CanonicalCookie::CanonicalCookie() { 1806 CookieMonster::CanonicalCookie::CanonicalCookie() {
1796 } 1807 }
1797 1808
1798 CookieMonster::CanonicalCookie::CanonicalCookie(const std::string& name, 1809 CookieMonster::CanonicalCookie::CanonicalCookie(const std::string& name,
1799 const std::string& value, 1810 const std::string& value,
1800 const std::string& domain, 1811 const std::string& domain,
1801 const std::string& path, 1812 const std::string& path,
1802 bool secure, 1813 bool secure,
1803 bool httponly, 1814 bool httponly,
1815 bool origin,
1804 const base::Time& creation, 1816 const base::Time& creation,
1805 const base::Time& last_access, 1817 const base::Time& last_access,
1806 bool has_expires, 1818 bool has_expires,
1807 const base::Time& expires) 1819 const base::Time& expires)
1808 : name_(name), 1820 : name_(name),
1809 value_(value), 1821 value_(value),
1810 domain_(domain), 1822 domain_(domain),
1811 path_(path), 1823 path_(path),
1812 creation_date_(creation), 1824 creation_date_(creation),
1813 last_access_date_(last_access), 1825 last_access_date_(last_access),
1814 expiry_date_(expires), 1826 expiry_date_(expires),
1815 has_expires_(has_expires), 1827 has_expires_(has_expires),
1816 secure_(secure), 1828 secure_(secure),
1817 httponly_(httponly) { 1829 httponly_(httponly),
1830 origin_(origin) {
1818 } 1831 }
1819 1832
1820 CookieMonster::CanonicalCookie::CanonicalCookie(const GURL& url, 1833 CookieMonster::CanonicalCookie::CanonicalCookie(const GURL& url,
1821 const ParsedCookie& pc) 1834 const ParsedCookie& pc)
1822 : name_(pc.Name()), 1835 : name_(pc.Name()),
1823 value_(pc.Value()), 1836 value_(pc.Value()),
1824 path_(CanonPath(url, pc)), 1837 path_(CanonPath(url, pc)),
1825 creation_date_(Time::Now()), 1838 creation_date_(Time::Now()),
1826 last_access_date_(Time()), 1839 last_access_date_(Time()),
1827 has_expires_(pc.HasExpires()), 1840 has_expires_(pc.HasExpires()),
1828 secure_(pc.IsSecure()), 1841 secure_(pc.IsSecure()),
1829 httponly_(pc.IsHttpOnly()) { 1842 httponly_(pc.IsHttpOnly()),
1843 origin_(pc.IsOrigin()) {
1830 if (has_expires_) 1844 if (has_expires_)
1831 expiry_date_ = CanonExpiration(pc, creation_date_, CookieOptions()); 1845 expiry_date_ = CanonExpiration(pc, creation_date_, CookieOptions());
1832 1846
1833 // Do the best we can with the domain. 1847 // Do the best we can with the domain.
1834 std::string cookie_domain; 1848 std::string cookie_domain;
1835 std::string domain_string; 1849 std::string domain_string;
1836 if (pc.HasDomain()) { 1850 if (pc.HasDomain()) {
1837 domain_string = pc.Domain(); 1851 domain_string = pc.Domain();
1838 } 1852 }
1839 bool result 1853 bool result
(...skipping 18 matching lines...) Expand all
1858 SetDefaultCookieableSchemes(); 1872 SetDefaultCookieableSchemes();
1859 } 1873 }
1860 1874
1861 CookieMonster::CanonicalCookie::~CanonicalCookie() { 1875 CookieMonster::CanonicalCookie::~CanonicalCookie() {
1862 } 1876 }
1863 1877
1864 CookieMonster::CanonicalCookie* CookieMonster::CanonicalCookie::Create( 1878 CookieMonster::CanonicalCookie* CookieMonster::CanonicalCookie::Create(
1865 const GURL& url, const std::string& name, const std::string& value, 1879 const GURL& url, const std::string& name, const std::string& value,
1866 const std::string& domain, const std::string& path, 1880 const std::string& domain, const std::string& path,
1867 const base::Time& creation_time, const base::Time& expiration_time, 1881 const base::Time& creation_time, const base::Time& expiration_time,
1868 bool secure, bool http_only) { 1882 bool secure, bool http_only, bool origin) {
1869 // Expect valid attribute tokens and values, as defined by the ParsedCookie 1883 // Expect valid attribute tokens and values, as defined by the ParsedCookie
1870 // logic, otherwise don't create the cookie. 1884 // logic, otherwise don't create the cookie.
1871 std::string parsed_name = ParsedCookie::ParseTokenString(name); 1885 std::string parsed_name = ParsedCookie::ParseTokenString(name);
1872 if (parsed_name != name) 1886 if (parsed_name != name)
1873 return NULL; 1887 return NULL;
1874 std::string parsed_value = ParsedCookie::ParseValueString(value); 1888 std::string parsed_value = ParsedCookie::ParseValueString(value);
1875 if (parsed_value != value) 1889 if (parsed_value != value)
1876 return NULL; 1890 return NULL;
1877 1891
1878 std::string parsed_domain = ParsedCookie::ParseValueString(domain); 1892 std::string parsed_domain = ParsedCookie::ParseValueString(domain);
(...skipping 14 matching lines...) Expand all
1893 // Canonicalize path again to make sure it escapes characters as needed. 1907 // Canonicalize path again to make sure it escapes characters as needed.
1894 url_parse::Component path_component(0, cookie_path.length()); 1908 url_parse::Component path_component(0, cookie_path.length());
1895 url_canon::RawCanonOutputT<char> canon_path; 1909 url_canon::RawCanonOutputT<char> canon_path;
1896 url_parse::Component canon_path_component; 1910 url_parse::Component canon_path_component;
1897 url_canon::CanonicalizePath(cookie_path.data(), path_component, 1911 url_canon::CanonicalizePath(cookie_path.data(), path_component,
1898 &canon_path, &canon_path_component); 1912 &canon_path, &canon_path_component);
1899 cookie_path = std::string(canon_path.data() + canon_path_component.begin, 1913 cookie_path = std::string(canon_path.data() + canon_path_component.begin,
1900 canon_path_component.len); 1914 canon_path_component.len);
1901 1915
1902 return new CanonicalCookie(parsed_name, parsed_value, cookie_domain, 1916 return new CanonicalCookie(parsed_name, parsed_value, cookie_domain,
1903 cookie_path, secure, http_only, 1917 cookie_path, secure, http_only, origin,
1904 creation_time, creation_time, 1918 creation_time, creation_time,
1905 !expiration_time.is_null(), expiration_time); 1919 !expiration_time.is_null(), expiration_time);
1906 } 1920 }
1907 1921
1908 bool CookieMonster::CanonicalCookie::IsOnPath( 1922 bool CookieMonster::CanonicalCookie::IsOnPath(
1909 const std::string& url_path) const { 1923 const std::string& url_path) const {
1910 1924
1911 // A zero length would be unsafe for our trailing '/' checks, and 1925 // A zero length would be unsafe for our trailing '/' checks, and
1912 // would also make no sense for our prefix match. The code that 1926 // would also make no sense for our prefix match. The code that
1913 // creates a CanonicalCookie should make sure the path is never zero length, 1927 // creates a CanonicalCookie should make sure the path is never zero length,
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1980 return base::StringPrintf( 1994 return base::StringPrintf(
1981 "name: %s value: %s domain: %s path: %s creation: %" 1995 "name: %s value: %s domain: %s path: %s creation: %"
1982 PRId64, 1996 PRId64,
1983 name_.c_str(), value_.c_str(), 1997 name_.c_str(), value_.c_str(),
1984 domain_.c_str(), path_.c_str(), 1998 domain_.c_str(), path_.c_str(),
1985 static_cast<int64>(creation_date_.ToTimeT())); 1999 static_cast<int64>(creation_date_.ToTimeT()));
1986 } 2000 }
1987 2001
1988 } // namespace 2002 } // namespace
1989 2003
OLDNEW
« no previous file with comments | « net/base/cookie_monster.h ('k') | net/base/cookie_monster_store_test.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698