15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Portions of this code based on Mozilla: 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (netwerk/cookie/src/nsCookieService.cpp) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* ***** BEGIN LICENSE BLOCK ***** 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Version: MPL 1.1/GPL 2.0/LGPL 2.1 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The contents of this file are subject to the Mozilla Public License Version 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1.1 (the "License"); you may not use this file except in compliance with 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the License. You may obtain a copy of the License at 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * http://www.mozilla.org/MPL/ 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Software distributed under the License is distributed on an "AS IS" basis, 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * for the specific language governing rights and limitations under the 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * License. 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The Original Code is mozilla.org code. 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The Initial Developer of the Original Code is 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Netscape Communications Corporation. 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Portions created by the Initial Developer are Copyright (C) 2003 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the Initial Developer. All Rights Reserved. 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Contributor(s): 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Daniel Witte (dwitte@stanford.edu) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Michiel van Leeuwen (mvl@exedo.nl) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Alternatively, the contents of this file may be used under the terms of 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * either the GNU General Public License Version 2 or later (the "GPL"), or 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in which case the provisions of the GPL or the LGPL are applicable instead 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of those above. If you wish to allow use of your version of this file only 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * under the terms of either the GPL or the LGPL, and not to allow others to 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * use your version of this file under the terms of the MPL, indicate your 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * decision by deleting the provisions above and replace them with the notice 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and other provisions required by the GPL or the LGPL. If you do not delete 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the provisions above, a recipient may use your version of this file under 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the terms of any one of the MPL, the GPL or the LGPL. 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ***** END LICENSE BLOCK ***** */ 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/cookies/parsed_cookie.h" 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 485e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h" 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPathTokenName[] = "path"; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kDomainTokenName[] = "domain"; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kExpiresTokenName[] = "expires"; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kMaxAgeTokenName[] = "max-age"; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kSecureTokenName[] = "secure"; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kHttpOnlyTokenName[] = "httponly"; 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kPriorityTokenName[] = "priority"; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kTerminator[] = "\n\r\0"; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kTerminatorLen = sizeof(kTerminator) - 1; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kWhitespace[] = " \t"; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kValueSeparator[] = ";"; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kTokenSeparator[] = ";="; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns true if |c| occurs in |chars| 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(erikwright): maybe make this take an iterator, could check for end also? 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline bool CharIsA(const char c, const char* chars) { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return strchr(chars, c) != NULL; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Seek the iterator to the first occurrence of a character in |chars|. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns true if it hit the end, false otherwise. 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline bool SeekTo(std::string::const_iterator* it, 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string::const_iterator& end, 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* chars) { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (; *it != end && !CharIsA(**it, chars); ++(*it)) {} 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *it == end; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Seek the iterator to the first occurrence of a character not in |chars|. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns true if it hit the end, false otherwise. 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline bool SeekPast(std::string::const_iterator* it, 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string::const_iterator& end, 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* chars) { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (; *it != end && CharIsA(**it, chars); ++(*it)) {} 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *it == end; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline bool SeekBackPast(std::string::const_iterator* it, 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string::const_iterator& end, 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* chars) { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (; *it != end && CharIsA(**it, chars); --(*it)) {} 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *it == end; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Validate whether |value| is a valid token according to [RFC2616], 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Section 2.2. 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsValidToken(const std::string& value) { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (value.empty()) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check that |value| has no separators. 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string separators = "()<>@,;:\\\"/[]?={} \t"; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (value.find_first_of(separators) != std::string::npos) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check that |value| has no CTLs. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::string::const_iterator i = value.begin(); i != value.end(); ++i) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((*i >= 0 && *i <= 31) || *i >= 127) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Validate value, which may be according to RFC 6265 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE ) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ; US-ASCII characters excluding CTLs, 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ; whitespace DQUOTE, comma, semicolon, 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ; and backslash 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsValidCookieValue(const std::string& value) { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Number of characters to skip in validation at beginning and end of string. 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t skip = 0; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (value.size() >= 2 && *value.begin() == '"' && *(value.end()-1) == '"') 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) skip = 1; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::string::const_iterator i = value.begin() + skip; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != value.end() - skip; ++i) { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool valid_octet = 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*i == 0x21 || 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*i >= 0x23 && *i <= 0x2B) || 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*i >= 0x2D && *i <= 0x3A) || 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*i >= 0x3C && *i <= 0x5B) || 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*i >= 0x5D && *i <= 0x7E)); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!valid_octet) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool IsControlCharacter(unsigned char c) { 14068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return (c >= 0) && (c <= 31); 14168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 14268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsValidCookieAttributeValue(const std::string& value) { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The greatest common denominator of cookie attribute values is 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // <any CHAR except CTLs or ";"> according to RFC 6265. 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::string::const_iterator i = value.begin(); i != value.end(); ++i) { 14768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (IsControlCharacter(*i) || *i == ';') 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ParsedCookie::ParsedCookie(const std::string& cookie_line) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : path_index_(0), 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) domain_index_(0), 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expires_index_(0), 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) maxage_index_(0), 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) secure_index_(0), 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) httponly_index_(0), 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) priority_index_(0) { 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cookie_line.size() > kMaxCookieSize) { 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "Not parsing cookie, too large: " << cookie_line.size(); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ParseTokenValuePairs(cookie_line); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pairs_.empty()) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetupAttributes(); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ParsedCookie::~ParsedCookie() { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ParsedCookie::IsValid() const { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !pairs_.empty(); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)CookiePriority ParsedCookie::Priority() const { 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return (priority_index_ == 0) ? COOKIE_PRIORITY_DEFAULT : 185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StringToCookiePriority(pairs_[priority_index_].second); 186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ParsedCookie::SetName(const std::string& name) { 18968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!IsValidToken(name)) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pairs_.empty()) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pairs_.push_back(std::make_pair("", "")); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pairs_[0].first = name; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ParsedCookie::SetValue(const std::string& value) { 19868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!IsValidCookieValue(value)) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pairs_.empty()) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pairs_.push_back(std::make_pair("", "")); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pairs_[0].second = value; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ParsedCookie::SetPath(const std::string& path) { 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SetString(&path_index_, kPathTokenName, path); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ParsedCookie::SetDomain(const std::string& domain) { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SetString(&domain_index_, kDomainTokenName, domain); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ParsedCookie::SetExpires(const std::string& expires) { 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SetString(&expires_index_, kExpiresTokenName, expires); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ParsedCookie::SetMaxAge(const std::string& maxage) { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SetString(&maxage_index_, kMaxAgeTokenName, maxage); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ParsedCookie::SetIsSecure(bool is_secure) { 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SetBool(&secure_index_, kSecureTokenName, is_secure); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ParsedCookie::SetIsHttpOnly(bool is_http_only) { 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SetBool(&httponly_index_, kHttpOnlyTokenName, is_http_only); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool ParsedCookie::SetPriority(const std::string& priority) { 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return SetString(&priority_index_, kPriorityTokenName, priority); 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ParsedCookie::ToCookieLine() const { 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string out; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (PairList::const_iterator it = pairs_.begin(); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != pairs_.end(); ++it) { 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!out.empty()) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.append("; "); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.append(it->first); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it->first != kSecureTokenName && it->first != kHttpOnlyTokenName) { 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.append("="); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.append(it->second); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return out; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string::const_iterator ParsedCookie::FindFirstTerminator( 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& s) { 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::const_iterator end = s.end(); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t term_pos = 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s.find_first_of(std::string(kTerminator, kTerminatorLen)); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (term_pos != std::string::npos) { 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We found a character we should treat as an end of string. 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end = s.begin() + term_pos; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return end; 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ParsedCookie::ParseToken(std::string::const_iterator* it, 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string::const_iterator& end, 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::const_iterator* token_start, 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::const_iterator* token_end) { 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(it && token_start && token_end); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::const_iterator token_real_end; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Seek past any whitespace before the "token" (the name). 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // token_start should point at the first character in the token 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SeekPast(it, end, kWhitespace)) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; // No token, whitespace or empty. 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *token_start = *it; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Seek over the token, to the token separator. 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // token_real_end should point at the token separator, i.e. '='. 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If it == end after the seek, we probably have a token-value. 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SeekTo(it, end, kTokenSeparator); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) token_real_end = *it; 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ignore any whitespace between the token and the token separator. 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // token_end should point after the last interesting token character, 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pointing at either whitespace, or at '=' (and equal to token_real_end). 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*it != *token_start) { // We could have an empty token name. 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) --(*it); // Go back before the token separator. 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Skip over any whitespace to the first non-whitespace character. 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SeekBackPast(it, *token_start, kWhitespace); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Point after it. 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++(*it); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *token_end = *it; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Seek us back to the end of the token. 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *it = token_real_end; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ParsedCookie::ParseValue(std::string::const_iterator* it, 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string::const_iterator& end, 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::const_iterator* value_start, 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::const_iterator* value_end) { 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(it && value_start && value_end); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Seek past any whitespace that might in-between the token and value. 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SeekPast(it, end, kWhitespace); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // value_start should point at the first character of the value. 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *value_start = *it; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Just look for ';' to terminate ('=' allowed). 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We can hit the end, maybe they didn't terminate. 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SeekTo(it, end, kValueSeparator); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Will be pointed at the ; seperator or the end. 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *value_end = *it; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ignore any unwanted whitespace after the value. 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*value_end != *value_start) { // Could have an empty value 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) --(*value_end); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SeekBackPast(value_end, *value_start, kWhitespace); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++(*value_end); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ParsedCookie::ParseTokenString(const std::string& token) { 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::const_iterator it = token.begin(); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::const_iterator end = FindFirstTerminator(token); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::const_iterator token_start, token_end; 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ParseToken(&it, end, &token_start, &token_end)) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::string(token_start, token_end); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::string(); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ParsedCookie::ParseValueString(const std::string& value) { 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::const_iterator it = value.begin(); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::const_iterator end = FindFirstTerminator(value); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::const_iterator value_start, value_end; 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ParseValue(&it, end, &value_start, &value_end); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::string(value_start, value_end); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Parse all token/value pairs and populate pairs_. 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ParsedCookie::ParseTokenValuePairs(const std::string& cookie_line) { 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pairs_.clear(); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ok, here we go. We should be expecting to be starting somewhere 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // before the cookie line, not including any header name... 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::const_iterator start = cookie_line.begin(); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::const_iterator it = start; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(erikwright): Make sure we're stripping \r\n in the network code. 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Then we can log any unexpected terminators. 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::const_iterator end = FindFirstTerminator(cookie_line); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int pair_num = 0; pair_num < kMaxPairs && it != end; ++pair_num) { 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TokenValuePair pair; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::const_iterator token_start, token_end; 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ParseToken(&it, end, &token_start, &token_end)) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it == end || *it != '=') { 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We have a token-value, we didn't have any token name. 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pair_num == 0) { 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For the first time around, we want to treat single values 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // as a value with an empty name. (Mozilla bug 169091). 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // IE seems to also have this behavior, ex "AAA", and "AAA=10" will 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // set 2 different cookies, and setting "BBB" will then replace "AAA". 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pair.first = ""; 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Rewind to the beginning of what we thought was the token name, 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and let it get parsed as a value. 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it = token_start; 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Any not-first attribute we want to treat a value as a 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // name with an empty value... This is so something like 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // "secure;" will get parsed as a Token name, and not a value. 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pair.first = std::string(token_start, token_end); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We have a TOKEN=VALUE. 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pair.first = std::string(token_start, token_end); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++it; // Skip past the '='. 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OK, now try to parse a value. 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::const_iterator value_start, value_end; 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ParseValue(&it, end, &value_start, &value_end); 38868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OK, we're finished with a Token/Value. 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pair.second = std::string(value_start, value_end); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // From RFC2109: "Attributes (names) (attr) are case-insensitive." 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pair_num != 0) 3946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::StringToLowerASCII(&pair.first); 39568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Ignore Set-Cookie directives contaning control characters. See 39668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // http://crbug.com/238041. 39768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!IsValidCookieAttributeValue(pair.first) || 39868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) !IsValidCookieAttributeValue(pair.second)) { 39968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pairs_.clear(); 40068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 40168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 40268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pairs_.push_back(pair); 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We've processed a token/value pair, we're either at the end of 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the string or a ValueSeparator like ';', which we want to skip. 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it != end) 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++it; 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ParsedCookie::SetupAttributes() { 4135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Ignore Set-Cookie directive where name and value are both empty. 4145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (pairs_[0].first.empty() && pairs_[0].second.empty()) { 4155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pairs_.clear(); 4165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 4175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 4185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We skip over the first token/value, the user supplied one. 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 1; i < pairs_.size(); ++i) { 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pairs_[i].first == kPathTokenName) { 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) path_index_ = i; 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (pairs_[i].first == kDomainTokenName) { 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) domain_index_ = i; 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (pairs_[i].first == kExpiresTokenName) { 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expires_index_ = i; 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (pairs_[i].first == kMaxAgeTokenName) { 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) maxage_index_ = i; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (pairs_[i].first == kSecureTokenName) { 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) secure_index_ = i; 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (pairs_[i].first == kHttpOnlyTokenName) { 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) httponly_index_ = i; 433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (pairs_[i].first == kPriorityTokenName) { 434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) priority_index_ = i; 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* some attribute we don't know or don't care about. */ 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ParsedCookie::SetString(size_t* index, 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& key, 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& value) { 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (value.empty()) { 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearAttributePair(*index); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SetAttributePair(index, key, value); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ParsedCookie::SetBool(size_t* index, 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& key, 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool value) { 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!value) { 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearAttributePair(*index); 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return SetAttributePair(index, key, std::string()); 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ParsedCookie::SetAttributePair(size_t* index, 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& key, 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& value) { 46668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!(IsValidToken(key) && IsValidCookieAttributeValue(value))) 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsValid()) 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*index) { 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pairs_[*index].second = value; 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pairs_.push_back(std::make_pair(key, value)); 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *index = pairs_.size() - 1; 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ParsedCookie::ClearAttributePair(size_t index) { 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The first pair (name/value of cookie at pairs_[0]) cannot be cleared. 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cookie attributes that don't have a value at the moment, are represented 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with an index being equal to 0. 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index == 0) 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t* indexes[] = { &path_index_, &domain_index_, &expires_index_, 487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &maxage_index_, &secure_index_, &httponly_index_, 488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &priority_index_ }; 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < arraysize(indexes); ++i) { 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*indexes[i] == index) 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *indexes[i] = 0; 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (*indexes[i] > index) 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) --*indexes[i]; 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pairs_.erase(pairs_.begin() + index); 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 499