2010-10-09 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

Rewritten Cookie class and Cookie parser based on
	http://tools.ietf.org/html/draft-ietf-httpstate-cookie-14 with
	some modifications. When parsing cookie date, match time first so
	that it parses asctime() format. The request-path must be ends
	with '/' so that request-path '/foo/' path-matches cookie-path
	'/foo' and '/foo/' in the proposed algorithm.
	* src/Cookie.cc
	* src/Cookie.h
	* src/CookieParser.cc: Removed
	* src/CookieParser.h: Removed
	* src/CookieStorage.cc
	* src/CookieStorage.h
	* src/HttpResponse.cc
	* src/Makefile.am
	* src/Makefile.in
	* src/MultiUrlRequestInfo.cc
	* src/NsCookieParser.cc
	* src/NsCookieParser.h
	* src/Sqlite3CookieParser.cc
	* src/Sqlite3CookieParser.h
	* src/a2functional.h
	* src/cookie_helper.cc
	* src/cookie_helper.h
	* src/util.cc
	* src/util.h
	* test/CookieBoxFactoryTest.cc: Removed
	* test/CookieHelperTest.cc
	* test/CookieParserTest.cc: Removed
	* test/CookieStorageTest.cc
	* test/CookieTest.cc
	* test/HttpRequestTest.cc
	* test/Makefile.am
	* test/Makefile.in
	* test/NsCookieParserTest.cc
	* test/Sqlite3CookieParserTest.cc
	* test/TestUtil.cc
	* test/TestUtil.h
	* test/a2functionalTest.cc
	* test/chromium_cookies.sqlite
	* test/cookies.sqlite
	* test/nscookietest.txt
pull/1/head
Tatsuhiro Tsujikawa 2010-10-09 14:22:49 +00:00
parent 9b1280f7a3
commit 8b17d4b276
35 changed files with 1499 additions and 1087 deletions

View File

@ -1,3 +1,47 @@
2010-10-09 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Rewritten Cookie class and Cookie parser based on
http://tools.ietf.org/html/draft-ietf-httpstate-cookie-14 with
some modifications. When parsing cookie date, match time first so
that it parses asctime() format. The request-path must be ends
with '/' so that request-path '/foo/' path-matches cookie-path
'/foo' and '/foo/' in the proposed algorithm.
* src/Cookie.cc
* src/Cookie.h
* src/CookieParser.cc: Removed
* src/CookieParser.h: Removed
* src/CookieStorage.cc
* src/CookieStorage.h
* src/HttpResponse.cc
* src/Makefile.am
* src/Makefile.in
* src/MultiUrlRequestInfo.cc
* src/NsCookieParser.cc
* src/NsCookieParser.h
* src/Sqlite3CookieParser.cc
* src/Sqlite3CookieParser.h
* src/a2functional.h
* src/cookie_helper.cc
* src/cookie_helper.h
* src/util.cc
* src/util.h
* test/CookieBoxFactoryTest.cc: Removed
* test/CookieHelperTest.cc
* test/CookieParserTest.cc: Removed
* test/CookieStorageTest.cc
* test/CookieTest.cc
* test/HttpRequestTest.cc
* test/Makefile.am
* test/Makefile.in
* test/NsCookieParserTest.cc
* test/Sqlite3CookieParserTest.cc
* test/TestUtil.cc
* test/TestUtil.h
* test/a2functionalTest.cc
* test/chromium_cookies.sqlite
* test/cookies.sqlite
* test/nscookietest.txt
2010-10-05 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Supported ANSI C's asctime() format in Time::parseHTTPDate().

View File

@ -2,7 +2,7 @@
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
* Copyright (C) 2010 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -34,194 +34,91 @@
/* copyright --> */
#include "Cookie.h"
#include <algorithm>
#include <sstream>
#include "util.h"
#include "A2STR.h"
#include "TimeA2.h"
#include "a2functional.h"
#include "cookie_helper.h"
namespace aria2 {
static std::string prependDotIfNotExists(const std::string& domain)
{
// From RFC2965:
// * Domain=value
// OPTIONAL. The value of the Domain attribute specifies the domain
// for which the cookie is valid. If an explicitly specified value
// does not start with a dot, the user agent supplies a leading dot.
return (!domain.empty() && domain[0] != '.') ? A2STR::DOT_C+domain : domain;
}
std::string Cookie::normalizeDomain(const std::string& domain)
{
if(domain.empty() || util::isNumericHost(domain)) {
return domain;
}
std::string md = prependDotIfNotExists(domain);
// TODO use util::split to strict verification
std::string::size_type p = md.find_last_of(A2STR::DOT_C);
if(p == 0 || p == std::string::npos) {
md += ".local";
}
return util::toLower(prependDotIfNotExists(md));
}
Cookie::Cookie(const std::string& name,
const std::string& value,
time_t expiry,
const std::string& path,
const std::string& domain,
bool secure):
Cookie::Cookie
(const std::string& name,
const std::string& value,
time_t expiryTime,
bool persistent,
const std::string& domain,
bool hostOnly,
const std::string& path,
bool secure,
bool httpOnly,
time_t creationTime):
name_(name),
value_(value),
expiry_(expiry),
expiryTime_(expiryTime),
persistent_(persistent),
domain_(domain),
hostOnly_(hostOnly),
path_(path),
domain_(normalizeDomain(domain)),
secure_(secure),
creationTime_(time(0)),
lastAccess_(creationTime_) {}
httpOnly_(httpOnly),
creationTime_(creationTime),
lastAccessTime_(creationTime) {}
Cookie::Cookie(const std::string& name,
const std::string& value,
const std::string& path,
const std::string& domain,
bool secure):
name_(name),
value_(value),
expiry_(0),
path_(path),
domain_(normalizeDomain(domain)),
secure_(secure),
creationTime_(time(0)),
lastAccess_(creationTime_) {}
Cookie::Cookie():expiry_(0), secure_(false), lastAccess_(time(0)) {}
Cookie::Cookie():
expiryTime_(0),
persistent_(false),
hostOnly_(false),
secure_(false),
httpOnly_(false),
creationTime_(0),
lastAccessTime_(0) {}
Cookie::~Cookie() {}
std::string Cookie::toString() const
{
return strconcat(name_, "=", value_);
return strconcat(name_, '=', value_);
}
bool Cookie::good() const
bool Cookie::match
(const std::string& requestHost,
const std::string& requestPath,
time_t date, bool secure) const
{
return !name_.empty();
}
static bool pathInclude(const std::string& requestPath, const std::string& path)
{
if(requestPath == path) {
return true;
}
if(util::startsWith(requestPath, path)) {
if(*path.rbegin() != '/' && requestPath[path.size()] != '/') {
return false;
}
} else if(*path.rbegin() != '/' || *requestPath.rbegin() == '/' ||
!util::startsWith(requestPath+"/", path)) {
if((secure_ && !secure) || isExpired(date) ||
!cookie::pathMatch(requestPath, path_)) {
return false;
}
return true;
}
static bool domainMatch(const std::string& normReqHost,
const std::string& domain)
{
// RFC2965 stated that:
//
// A Set-Cookie2 with Domain=ajax.com will be accepted, and the
// value for Domain will be taken to be .ajax.com, because a dot
// gets prepended to the value.
//
// Also original Netscape implementation behaves exactly the same.
// domain_ always starts ".". See Cookie::Cookie().
return util::endsWith(normReqHost, domain);
}
bool Cookie::match(const std::string& requestHost,
const std::string& requestPath,
time_t date, bool secure) const
{
if((secure || (!secure_ && !secure)) &&
(requestHost == domain_ || // For default domain or IP address
domainMatch(normalizeDomain(requestHost), domain_)) &&
pathInclude(requestPath, path_) &&
(isSessionCookie() || (date < expiry_))) {
return true;
if(hostOnly_) {
return requestHost == domain_ ;
} else {
return false;
return cookie::domainMatch(requestHost, domain_);
}
}
bool Cookie::validate(const std::string& requestHost,
const std::string& requestPath) const
{
// If domain_ doesn't start with "." or it is IP address, then it
// must equal to requestHost. Otherwise, do domain tail match.
if(requestHost != domain_) {
std::string normReqHost = normalizeDomain(requestHost);
if(normReqHost != domain_) {
// domain must start with '.'
if(*domain_.begin() != '.') {
return false;
}
// domain must not end with '.'
if(*domain_.rbegin() == '.') {
return false;
}
// domain must include at least one embeded '.'
if(domain_.size() < 4 ||
domain_.find(A2STR::DOT_C, 1) == std::string::npos) {
return false;
}
if(!util::endsWith(normReqHost, domain_)) {
return false;
}
// From RFC2965 3.3.2 Rejecting Cookies
// * The request-host is a HDN (not IP address) and has the form HD,
// where D is the value of the Domain attribute, and H is a string
// that contains one or more dots.
size_t dotCount = std::count(normReqHost.begin(),
normReqHost.begin()+
(normReqHost.size()-domain_.size()), '.');
if(dotCount > 1 || (dotCount == 1 && normReqHost[0] != '.')) {
return false;
}
}
}
if(requestPath != path_) {
// From RFC2965 3.3.2 Rejecting Cookies
// * The value for the Path attribute is not a prefix of the request-URI.
if(!pathInclude(requestPath, path_)) {
return false;
}
}
return good();
}
bool Cookie::operator==(const Cookie& cookie) const
{
return domain_ == cookie.domain_ && path_ == cookie.path_ &&
name_ == cookie.name_;
}
bool Cookie::isExpired() const
bool Cookie::isExpired(time_t base) const
{
return !expiry_ == 0 && Time().getTime() >= expiry_;
return persistent_ && base > expiryTime_;
}
std::string Cookie::toNsCookieFormat() const
{
std::stringstream ss;
if(!hostOnly_) {
ss << A2STR::DOT_C;
}
ss << domain_ << "\t";
if(util::startsWith(domain_, A2STR::DOT_C)) {
ss << "TRUE";
} else {
if(hostOnly_) {
ss << "FALSE";
} else {
ss << "TRUE";
}
ss << "\t";
ss << path_ << "\t";
@ -231,22 +128,15 @@ std::string Cookie::toNsCookieFormat() const
ss << "FALSE";
}
ss << "\t";
ss << expiry_ << "\t";
if(persistent_) {
ss << expiryTime_;
} else {
ss << 0;
}
ss << "\t";
ss << name_ << "\t";
ss << value_;
return ss.str();
}
void Cookie::markOriginServerOnly()
{
if(util::startsWith(domain_, A2STR::DOT_C)) {
domain_.erase(domain_.begin(), domain_.begin()+1);
}
}
void Cookie::updateLastAccess()
{
lastAccess_ = time(0);
}
} // namespace aria2

View File

@ -2,7 +2,7 @@
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
* Copyright (C) 2010 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -32,8 +32,8 @@
* files in the program, then also delete it here.
*/
/* copyright --> */
#ifndef _D_COOKIE_H_
#define _D_COOKIE_H_
#ifndef D_COOKIE_H
#define D_COOKIE_H
#include "common.h"
@ -47,70 +47,83 @@ class Cookie {
private:
std::string name_;
std::string value_;
time_t expiry_;
std::string path_;
time_t expiryTime_;
// If persistent_ is false, this is a session scope cookie and it is
// never expired during session. So isExpired() always returns
// false.
bool persistent_;
std::string domain_;
bool hostOnly_;
std::string path_;
bool secure_;
bool httpOnly_;
time_t creationTime_;
time_t lastAccess_;
time_t lastAccessTime_;
public:
/*
* If expires = 0 is given, then the cookie becomes session cookie.
* domain is normalized using normalizeDomain() function and
* assigned to domain_. If domain is not specified in cookie, call
* markOriginServerOnly() after construction.
*/
Cookie(const std::string& name,
const std::string& value,
time_t expires,
const std::string& path,
const std::string& domain,
bool secure);
/*
* Creates session cookie. This is equivalent to Cookie(name, value,
* 0, path, domain, secure); domain is normalized using
* normalizeDomain() function and assigned to domain_. If domain is
* not specified in cookie, call markOriginServerOnly() after
* construction.
*/
Cookie(const std::string& name,
const std::string& value,
const std::string& path,
const std::string& domain,
bool secure);
Cookie();
Cookie
(const std::string& name,
const std::string& value,
time_t expiryTime,
bool persistent,
const std::string& domain,
bool hostOnly,
const std::string& path,
bool secure,
bool httpOnly,
time_t creationTime);
~Cookie();
std::string toString() const;
bool good() const;
bool match(const std::string& requestHost, const std::string& requestPath,
time_t date, bool secure) const;
bool validate(const std::string& requestHost,
const std::string& requestPath) const;
bool match
(const std::string& requestHost, const std::string& requestPath,
time_t date, bool secure) const;
bool operator==(const Cookie& cookie) const;
bool isExpired() const;
bool isExpired(time_t base) const;
const std::string& getName() const
{
return name_;
}
void setName(const std::string& name)
{
name_ = name;
}
const std::string& getValue() const
{
return value_;
}
const std::string& getPath() const
void setValue(const std::string& value)
{
return path_;
value_ = value;
}
time_t getExpiryTime() const
{
return expiryTime_;
}
void setExpiryTime(time_t expiryTime)
{
expiryTime_ = expiryTime;
}
bool getPersistent() const
{
return persistent_;
}
void setPersistent(bool persistent)
{
persistent_ = persistent;
}
const std::string& getDomain() const
@ -118,42 +131,74 @@ public:
return domain_;
}
time_t getExpiry() const
void setDomain(const std::string& domain)
{
return expiry_;
domain_ = domain;
}
bool isSecureCookie() const
bool getHostOnly() const
{
return hostOnly_;
}
void setHostOnly(bool hostOnly)
{
hostOnly_ = hostOnly;
}
const std::string& getPath() const
{
return path_;
}
void setPath(const std::string& path)
{
path_ = path;
}
bool getSecure() const
{
return secure_;
}
bool isSessionCookie() const
void setSecure(bool secure)
{
return expiry_ == 0;
secure_ = secure;
}
std::string toNsCookieFormat() const;
bool getHttpOnly() const
{
return httpOnly_;
}
// Makes this Cookie only sent to the origin server. This function
// removes first "." from domain_ if domain_ starts with ".".
void markOriginServerOnly();
void setHttpOnly(bool httpOnly)
{
httpOnly_ = httpOnly;
}
time_t getCreationTime() const
{
return creationTime_;
}
void updateLastAccess();
time_t getLastAccess() const
void setCreationTime(time_t creationTime)
{
return lastAccess_;
creationTime_ = creationTime;
}
static std::string normalizeDomain(const std::string& domain);
time_t getLastAccessTime() const
{
return lastAccessTime_;
}
void setLastAccessTime(time_t lastAccessTime)
{
lastAccessTime_ = lastAccessTime;
}
std::string toNsCookieFormat() const;
};
} // namespace aria2
#endif // _D_COOKIE_H_
#endif // D_COOKIE_H

View File

@ -1,103 +0,0 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#include "CookieParser.h"
#include <strings.h>
#include <utility>
#include <istream>
#include <map>
#include <vector>
#include "util.h"
#include "A2STR.h"
#include "TimeA2.h"
namespace aria2 {
const std::string CookieParser::C_SECURE("secure");
const std::string CookieParser::C_DOMAIN("domain");
const std::string CookieParser::C_PATH("path");
const std::string CookieParser::C_EXPIRES("expires");
Cookie CookieParser::parse(const std::string& cookieStr, const std::string& defaultDomain, const std::string& defaultPath) const
{
std::vector<std::string> terms;
util::split(cookieStr, std::back_inserter(terms), ";", true);
if(terms.empty()) {
return Cookie();
}
std::pair<std::string, std::string> nameValue;
util::split(nameValue, terms.front(), '=');
std::map<std::string, std::string> values;
for(std::vector<std::string>::iterator itr = terms.begin()+1,
eoi = terms.end(); itr != eoi; ++itr) {
std::pair<std::string, std::string> nv;
util::split(nv, *itr, '=');
values[nv.first] = nv.second;
}
bool useDefaultDomain = false;
std::map<std::string, std::string>::iterator mitr;
mitr = values.find(C_DOMAIN);
if(mitr == values.end() || (*mitr).second.empty()) {
useDefaultDomain = true;
values[C_DOMAIN] = defaultDomain;
}
mitr = values.find(C_PATH);
if(mitr == values.end() || (*mitr).second.empty()) {
values[C_PATH] = defaultPath;
}
time_t expiry = 0;
if(values.count(C_EXPIRES)) {
Time expiryTime = Time::parseHTTPDate(values[C_EXPIRES]);
if(expiryTime.good()) {
expiry = expiryTime.getTime();
}
}
Cookie cookie(nameValue.first, nameValue.second,
expiry,
values[C_PATH], values[C_DOMAIN],
values.find(C_SECURE) != values.end());
if(useDefaultDomain) {
cookie.markOriginServerOnly();
}
return cookie;
}
} // namespace aria2

View File

@ -48,6 +48,7 @@
#include "a2functional.h"
#include "A2STR.h"
#include "message.h"
#include "cookie_helper.h"
#ifdef HAVE_SQLITE3
# include "Sqlite3CookieParserImpl.h"
#endif // HAVE_SQLITE3
@ -55,26 +56,21 @@
namespace aria2 {
CookieStorage::DomainEntry::DomainEntry
(const std::string& domain):key_(domain)
{
std::reverse(key_.begin(), key_.end());
}
(const std::string& domain):
key_(util::isNumericHost(domain)?domain:cookie::reverseDomainLevel(domain))
{}
void CookieStorage::DomainEntry::updateLastAccess()
bool CookieStorage::DomainEntry::addCookie(const Cookie& cookie, time_t now)
{
lastAccess_ = time(0);
}
bool CookieStorage::DomainEntry::addCookie(const Cookie& cookie)
{
updateLastAccess();
std::deque<Cookie>::iterator i = std::find(cookies_.begin(), cookies_.end(),
cookie);
setLastAccessTime(now);
std::deque<Cookie>::iterator i =
std::find(cookies_.begin(), cookies_.end(), cookie);
if(i == cookies_.end()) {
if(cookie.isExpired()) {
if(cookie.isExpired(now)) {
return false;
} else {
if(cookies_.size() >= CookieStorage::MAX_COOKIE_PER_DOMAIN) {
// TODO First remove expired cookie
std::deque<Cookie>::iterator m = std::min_element
(cookies_.begin(), cookies_.end(), LeastRecentAccess<Cookie>());
*m = cookie;
@ -83,7 +79,7 @@ bool CookieStorage::DomainEntry::addCookie(const Cookie& cookie)
}
return true;
}
} else if(cookie.isExpired()) {
} else if(cookie.isExpired(now)) {
cookies_.erase(i);
return false;
} else {
@ -114,12 +110,11 @@ static const size_t DOMAIN_EVICTION_TRIGGER = 2000;
static const double DOMAIN_EVICTION_RATE = 0.1;
bool CookieStorage::store(const Cookie& cookie)
bool CookieStorage::store(const Cookie& cookie, time_t now)
{
if(!cookie.good()) {
return false;
}
if(domains_.size() >= DOMAIN_EVICTION_TRIGGER) {
// TODO Do this in a separete Command.
// TODO Erase expired cookie first
std::sort(domains_.begin(), domains_.end(),
LeastRecentAccess<DomainEntry>());
size_t delnum = (size_t)(domains_.size()*DOMAIN_EVICTION_RATE);
@ -131,9 +126,9 @@ bool CookieStorage::store(const Cookie& cookie)
std::lower_bound(domains_.begin(), domains_.end(), v);
bool added = false;
if(i != domains_.end() && (*i).getKey() == v.getKey()) {
added = (*i).addCookie(cookie);
added = (*i).addCookie(cookie, now);
} else {
added = v.addCookie(cookie);
added = v.addCookie(cookie, now);
if(added) {
domains_.insert(i, v);
}
@ -141,13 +136,15 @@ bool CookieStorage::store(const Cookie& cookie)
return added;
}
bool CookieStorage::parseAndStore(const std::string& setCookieString,
const std::string& requestHost,
const std::string& requestPath)
bool CookieStorage::parseAndStore
(const std::string& setCookieString,
const std::string& requestHost,
const std::string& defaultPath,
time_t now)
{
Cookie cookie = parser_.parse(setCookieString, requestHost, requestPath);
if(cookie.validate(requestHost, requestPath)) {
return store(cookie);
Cookie cookie;
if(cookie::parse(cookie, setCookieString, requestHost, defaultPath, now)) {
return store(cookie, now);
} else {
return false;
}
@ -198,32 +195,34 @@ public:
// "name1=foo" with a path mapping of "/" should be sent after a
// cookie "name1=foo2" with a path mapping of "/bar" if they are
// both to be sent.
int comp = lhs.pathDepth_-rhs.pathDepth_;
if(comp == 0) {
return lhs.cookie_.getCreationTime() < rhs.cookie_.getCreationTime();
} else {
return comp > 0;
}
//
// See also http://tools.ietf.org/html/draft-ietf-httpstate-cookie-14
// section5.4
return lhs.pathDepth_ > rhs.pathDepth_ ||
(!(rhs.pathDepth_ > lhs.pathDepth_) &&
lhs.cookie_.getCreationTime() < rhs.cookie_.getCreationTime());
}
};
}
namespace {
template<typename DomainInputIterator, typename CookieOutputIterator>
static void searchCookieByDomainSuffix
void searchCookieByDomainSuffix
(const std::string& domain,
DomainInputIterator first, DomainInputIterator last, CookieOutputIterator out,
const std::string& requestHost,
const std::string& requestPath,
time_t date, bool secure)
time_t now, bool secure)
{
CookieStorage::DomainEntry v(domain);
std::deque<CookieStorage::DomainEntry>::iterator i =
std::lower_bound(first, last, v);
if(i != last && (*i).getKey() == v.getKey()) {
(*i).updateLastAccess();
(*i).findCookie(out, requestHost, requestPath, date, secure);
(*i).setLastAccessTime(now);
(*i).findCookie(out, requestHost, requestPath, now, secure);
}
}
}
bool CookieStorage::contains(const Cookie& cookie) const
{
@ -237,36 +236,34 @@ bool CookieStorage::contains(const Cookie& cookie) const
}
}
std::vector<Cookie> CookieStorage::criteriaFind(const std::string& requestHost,
const std::string& requestPath,
time_t date, bool secure)
std::vector<Cookie> CookieStorage::criteriaFind
(const std::string& requestHost,
const std::string& requestPath,
time_t now,
bool secure)
{
std::vector<Cookie> res;
bool numericHost = util::isNumericHost(requestHost);
searchCookieByDomainSuffix
((!numericHost && requestHost.find(A2STR::DOT_C) == std::string::npos)?
requestHost+".local":requestHost,
domains_.begin(), domains_.end(),
std::back_inserter(res),
requestHost, requestPath, date, secure);
if(!numericHost) {
std::string normRequestHost = Cookie::normalizeDomain(requestHost);
std::vector<std::string> domainComponents;
util::split(normRequestHost, std::back_inserter(domainComponents),
A2STR::DOT_C);
if(domainComponents.size() <= 1) {
return res;
}
std::reverse(domainComponents.begin(), domainComponents.end());
std::string domain = A2STR::DOT_C;
domain += domainComponents[0];
for(std::vector<std::string>::const_iterator di =
domainComponents.begin()+1, eoi = domainComponents.end();
di != eoi; ++di) {
domain = strconcat(A2STR::DOT_C, *di, domain);
searchCookieByDomainSuffix(domain, domains_.begin(), domains_.end(),
std::back_inserter(res),
normRequestHost, requestPath, date, secure);
if(requestPath.empty()) {
return res;
}
std::string normRequestPath =
requestPath == A2STR::SLASH_C?requestPath:requestPath+A2STR::SLASH_C;
if(util::isNumericHost(requestHost)) {
searchCookieByDomainSuffix
(requestHost, domains_.begin(), domains_.end(), std::back_inserter(res),
requestHost, normRequestPath, now, secure);
} else {
std::vector<std::string> levels;
util::split(requestHost, std::back_inserter(levels),A2STR::DOT_C);
std::reverse(levels.begin(), levels.end());
std::string domain;
for(std::vector<std::string>::const_iterator i =
levels.begin(), eoi = levels.end();
i != eoi; ++i, domain.insert(domain.begin(), '.')) {
domain.insert(domain.begin(), (*i).begin(), (*i).end());
searchCookieByDomainSuffix
(domain, domains_.begin(), domains_.end(),
std::back_inserter(res), requestHost, normRequestPath, now, secure);
}
}
std::vector<CookiePathDivider> divs;
@ -288,7 +285,7 @@ size_t CookieStorage::size() const
return numCookie;
}
bool CookieStorage::load(const std::string& filename)
bool CookieStorage::load(const std::string& filename, time_t now)
{
char header[16]; // "SQLite format 3" plus \0
std::ifstream s(filename.c_str(), std::ios::binary);
@ -307,7 +304,7 @@ bool CookieStorage::load(const std::string& filename)
#ifdef HAVE_SQLITE3
std::vector<Cookie> cookies;
try {
Sqlite3MozCookieParser(filename).parse(cookies);
Sqlite3MozCookieParser(filename).parse(cookies, now);
} catch(RecoverableException& e) {
if(logger_->info()) {
logger_->info(EX_EXCEPTION_CAUGHT, e);
@ -315,17 +312,17 @@ bool CookieStorage::load(const std::string& filename)
" Retrying, assuming it is Chromium cookie file.");
}
// Try chrome cookie format
Sqlite3ChromiumCookieParser(filename).parse(cookies);
Sqlite3ChromiumCookieParser(filename).parse(cookies, now);
}
storeCookies(cookies.begin(), cookies.end());
storeCookies(cookies.begin(), cookies.end(), now);
#else // !HAVE_SQLITE3
throw DL_ABORT_EX
("Cannot read SQLite3 database because SQLite3 support is disabled by"
" configuration.");
#endif // !HAVE_SQLITE3
} else {
std::vector<Cookie> cookies = NsCookieParser().parse(filename);
storeCookies(cookies.begin(), cookies.end());
std::vector<Cookie> cookies = NsCookieParser().parse(filename, now);
storeCookies(cookies.begin(), cookies.end(), now);
}
return true;
} catch(RecoverableException& e) {

View File

@ -44,7 +44,6 @@
#include "a2time.h"
#include "Cookie.h"
#include "CookieParser.h"
namespace aria2 {
@ -57,9 +56,12 @@ public:
class DomainEntry {
private:
// This is reversed domain level string.
// e.g. net.sourceforge.aria2
// e.g. 192.168.0.1
std::string key_;
time_t lastAccess_;
time_t lastAccessTime_;
std::deque<Cookie> cookies_;
public:
@ -75,12 +77,12 @@ public:
(OutputIterator out,
const std::string& requestHost,
const std::string& requestPath,
time_t date, bool secure)
time_t now, bool secure)
{
for(std::deque<Cookie>::iterator i = cookies_.begin();
i != cookies_.end(); ++i) {
if((*i).match(requestHost, requestPath, date, secure)) {
(*i).updateLastAccess();
for(std::deque<Cookie>::iterator i = cookies_.begin(),
eoi = cookies_.end(); i != eoi; ++i) {
if((*i).match(requestHost, requestPath, now, secure)) {
(*i).setLastAccessTime(now);
out++ = *i;
}
}
@ -92,13 +94,16 @@ public:
return cookies_.size();
}
bool addCookie(const Cookie& cookie);
bool addCookie(const Cookie& cookie, time_t now);
void updateLastAccess();
time_t getLastAccess() const
void setLastAccessTime(time_t lastAccessTime)
{
return lastAccess_;
lastAccessTime_ = lastAccessTime;
}
time_t getLastAccessTime() const
{
return lastAccessTime_;
}
void writeCookie(std::ostream& o) const;
@ -119,15 +124,13 @@ public:
private:
std::deque<DomainEntry> domains_;
CookieParser parser_;
Logger* logger_;
template<typename InputIterator>
void storeCookies(InputIterator first, InputIterator last)
void storeCookies(InputIterator first, InputIterator last, time_t now)
{
for(; first != last; ++first) {
store(*first);
store(*first, now);
}
}
public:
@ -136,27 +139,32 @@ public:
~CookieStorage();
// Returns true if cookie is stored or updated existing cookie.
// Returns false if cookie is expired.
bool store(const Cookie& cookie);
// Returns false if cookie is expired. now is used as last access
// time.
bool store(const Cookie& cookie, time_t now);
// Returns true if cookie is stored or updated existing cookie.
// Otherwise, returns false.
bool parseAndStore(const std::string& setCookieString,
const std::string& requestHost,
const std::string& requestPath);
// Otherwise, returns false. now is used as creation time and last
// access time.
bool parseAndStore
(const std::string& setCookieString,
const std::string& requestHost,
const std::string& requestPath,
time_t now);
// Finds cookies matched with given criteria and returns them.
// Matched cookies' lastAccess_ property is updated.
std::vector<Cookie> criteriaFind(const std::string& requestHost,
const std::string& requestPath,
time_t date, bool secure);
time_t now, bool secure);
// Loads Cookies from file denoted by filename. If compiled with
// libsqlite3, this method automatically detects the specified file
// is sqlite3 or just plain text file and calls appropriate parser
// implementation class. If Cookies are successfully loaded, this
// method returns true. Otherwise, this method returns false.
bool load(const std::string& filename);
// method returns true. Otherwise, this method returns false. now
// is used as creation time and last access time.
bool load(const std::string& filename, time_t now);
// Saves Cookies in Netspace format which is used in
// Firefox1.2/Netscape/Mozilla. If Cookies are successfully saved,

View File

@ -129,12 +129,12 @@ std::string HttpResponse::determinFilename() const
void HttpResponse::retrieveCookie()
{
Time now;
std::vector<std::string> v = httpHeader_->get(HttpHeader::SET_COOKIE);
for(std::vector<std::string>::const_iterator itr = v.begin(), eoi = v.end();
itr != eoi; ++itr) {
httpRequest_->getCookieStorage()->parseAndStore(*itr,
httpRequest_->getHost(),
httpRequest_->getDir());
httpRequest_->getCookieStorage()->parseAndStore
(*itr, httpRequest_->getHost(), httpRequest_->getDir(), now.getTime());
}
}

View File

@ -94,7 +94,6 @@ SRCS = Socket.h\
ProgressAwareEntry.h\
RequestGroupEntry.cc RequestGroupEntry.h\
Cookie.cc Cookie.h\
CookieParser.cc CookieParser.h\
HttpHeaderProcessor.cc HttpHeaderProcessor.h\
FileEntry.cc FileEntry.h\
Platform.cc Platform.h\
@ -211,7 +210,8 @@ SRCS = Socket.h\
ChunkedDecodingStreamFilter.cc ChunkedDecodingStreamFilter.h\
NullSinkStreamFilter.cc NullSinkStreamFilter.h\
uri.cc uri.h\
Triplet.h
Triplet.h\
cookie_helper.cc cookie_helper.h
if ENABLE_XML_RPC
SRCS += XmlRpcRequestParserController.cc XmlRpcRequestParserController.h\

View File

@ -379,16 +379,15 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
MultiUrlRequestInfo.h UriListParser.cc UriListParser.h \
RealtimeCommand.cc RealtimeCommand.h ProgressAwareEntry.h \
RequestGroupEntry.cc RequestGroupEntry.h Cookie.cc Cookie.h \
CookieParser.cc CookieParser.h HttpHeaderProcessor.cc \
HttpHeaderProcessor.h FileEntry.cc FileEntry.h Platform.cc \
Platform.h PStringDatum.h PStringSegment.cc PStringSegment.h \
PStringNumLoop.h PStringSelect.h PStringVisitor.h \
PStringBuildVisitor.cc PStringBuildVisitor.h \
ParameterizedStringParser.cc ParameterizedStringParser.h \
FixedWidthNumberDecorator.h NumberDecorator.h \
AlphaNumberDecorator.h TimeBasedCommand.cc TimeBasedCommand.h \
AutoSaveCommand.cc AutoSaveCommand.h PieceStorage.h \
DefaultPieceStorage.cc DefaultPieceStorage.h \
HttpHeaderProcessor.cc HttpHeaderProcessor.h FileEntry.cc \
FileEntry.h Platform.cc Platform.h PStringDatum.h \
PStringSegment.cc PStringSegment.h PStringNumLoop.h \
PStringSelect.h PStringVisitor.h PStringBuildVisitor.cc \
PStringBuildVisitor.h ParameterizedStringParser.cc \
ParameterizedStringParser.h FixedWidthNumberDecorator.h \
NumberDecorator.h AlphaNumberDecorator.h TimeBasedCommand.cc \
TimeBasedCommand.h AutoSaveCommand.cc AutoSaveCommand.h \
PieceStorage.h DefaultPieceStorage.cc DefaultPieceStorage.h \
UnknownLengthPieceStorage.cc UnknownLengthPieceStorage.h \
PieceStatMan.cc PieceStatMan.h StatCalc.h ConsoleStatCalc.cc \
ConsoleStatCalc.h TransferStat.cc TransferStat.h Dependency.h \
@ -448,7 +447,8 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
StreamFilter.h SinkStreamFilter.cc SinkStreamFilter.h \
ChunkedDecodingStreamFilter.cc ChunkedDecodingStreamFilter.h \
NullSinkStreamFilter.cc NullSinkStreamFilter.h uri.cc uri.h \
Triplet.h XmlRpcRequestParserController.cc \
Triplet.h cookie_helper.cc cookie_helper.h \
XmlRpcRequestParserController.cc \
XmlRpcRequestParserController.h \
XmlRpcRequestParserStateMachine.cc \
XmlRpcRequestParserStateMachine.h XmlRpcRequestParserState.h \
@ -854,10 +854,9 @@ am__objects_32 = SocketCore.$(OBJEXT) Command.$(OBJEXT) \
StreamFileAllocationEntry.$(OBJEXT) \
MultiUrlRequestInfo.$(OBJEXT) UriListParser.$(OBJEXT) \
RealtimeCommand.$(OBJEXT) RequestGroupEntry.$(OBJEXT) \
Cookie.$(OBJEXT) CookieParser.$(OBJEXT) \
HttpHeaderProcessor.$(OBJEXT) FileEntry.$(OBJEXT) \
Platform.$(OBJEXT) PStringSegment.$(OBJEXT) \
PStringBuildVisitor.$(OBJEXT) \
Cookie.$(OBJEXT) HttpHeaderProcessor.$(OBJEXT) \
FileEntry.$(OBJEXT) Platform.$(OBJEXT) \
PStringSegment.$(OBJEXT) PStringBuildVisitor.$(OBJEXT) \
ParameterizedStringParser.$(OBJEXT) TimeBasedCommand.$(OBJEXT) \
AutoSaveCommand.$(OBJEXT) DefaultPieceStorage.$(OBJEXT) \
UnknownLengthPieceStorage.$(OBJEXT) PieceStatMan.$(OBJEXT) \
@ -896,17 +895,18 @@ am__objects_32 = SocketCore.$(OBJEXT) Command.$(OBJEXT) \
ValueBase.$(OBJEXT) AdaptiveFileAllocationIterator.$(OBJEXT) \
StreamFilter.$(OBJEXT) SinkStreamFilter.$(OBJEXT) \
ChunkedDecodingStreamFilter.$(OBJEXT) \
NullSinkStreamFilter.$(OBJEXT) uri.$(OBJEXT) $(am__objects_1) \
$(am__objects_2) $(am__objects_3) $(am__objects_4) \
$(am__objects_5) $(am__objects_6) $(am__objects_7) \
$(am__objects_8) $(am__objects_9) $(am__objects_10) \
$(am__objects_11) $(am__objects_12) $(am__objects_13) \
$(am__objects_14) $(am__objects_15) $(am__objects_16) \
$(am__objects_17) $(am__objects_18) $(am__objects_19) \
$(am__objects_20) $(am__objects_21) $(am__objects_22) \
$(am__objects_23) $(am__objects_24) $(am__objects_25) \
$(am__objects_26) $(am__objects_27) $(am__objects_28) \
$(am__objects_29) $(am__objects_30) $(am__objects_31)
NullSinkStreamFilter.$(OBJEXT) uri.$(OBJEXT) \
cookie_helper.$(OBJEXT) $(am__objects_1) $(am__objects_2) \
$(am__objects_3) $(am__objects_4) $(am__objects_5) \
$(am__objects_6) $(am__objects_7) $(am__objects_8) \
$(am__objects_9) $(am__objects_10) $(am__objects_11) \
$(am__objects_12) $(am__objects_13) $(am__objects_14) \
$(am__objects_15) $(am__objects_16) $(am__objects_17) \
$(am__objects_18) $(am__objects_19) $(am__objects_20) \
$(am__objects_21) $(am__objects_22) $(am__objects_23) \
$(am__objects_24) $(am__objects_25) $(am__objects_26) \
$(am__objects_27) $(am__objects_28) $(am__objects_29) \
$(am__objects_30) $(am__objects_31)
am_libaria2c_a_OBJECTS = $(am__objects_32)
libaria2c_a_OBJECTS = $(am_libaria2c_a_OBJECTS)
am__installdirs = "$(DESTDIR)$(bindir)"
@ -1175,16 +1175,15 @@ SRCS = Socket.h SocketCore.cc SocketCore.h BinaryStream.h Command.cc \
MultiUrlRequestInfo.h UriListParser.cc UriListParser.h \
RealtimeCommand.cc RealtimeCommand.h ProgressAwareEntry.h \
RequestGroupEntry.cc RequestGroupEntry.h Cookie.cc Cookie.h \
CookieParser.cc CookieParser.h HttpHeaderProcessor.cc \
HttpHeaderProcessor.h FileEntry.cc FileEntry.h Platform.cc \
Platform.h PStringDatum.h PStringSegment.cc PStringSegment.h \
PStringNumLoop.h PStringSelect.h PStringVisitor.h \
PStringBuildVisitor.cc PStringBuildVisitor.h \
ParameterizedStringParser.cc ParameterizedStringParser.h \
FixedWidthNumberDecorator.h NumberDecorator.h \
AlphaNumberDecorator.h TimeBasedCommand.cc TimeBasedCommand.h \
AutoSaveCommand.cc AutoSaveCommand.h PieceStorage.h \
DefaultPieceStorage.cc DefaultPieceStorage.h \
HttpHeaderProcessor.cc HttpHeaderProcessor.h FileEntry.cc \
FileEntry.h Platform.cc Platform.h PStringDatum.h \
PStringSegment.cc PStringSegment.h PStringNumLoop.h \
PStringSelect.h PStringVisitor.h PStringBuildVisitor.cc \
PStringBuildVisitor.h ParameterizedStringParser.cc \
ParameterizedStringParser.h FixedWidthNumberDecorator.h \
NumberDecorator.h AlphaNumberDecorator.h TimeBasedCommand.cc \
TimeBasedCommand.h AutoSaveCommand.cc AutoSaveCommand.h \
PieceStorage.h DefaultPieceStorage.cc DefaultPieceStorage.h \
UnknownLengthPieceStorage.cc UnknownLengthPieceStorage.h \
PieceStatMan.cc PieceStatMan.h StatCalc.h ConsoleStatCalc.cc \
ConsoleStatCalc.h TransferStat.cc TransferStat.h Dependency.h \
@ -1244,17 +1243,17 @@ SRCS = Socket.h SocketCore.cc SocketCore.h BinaryStream.h Command.cc \
StreamFilter.h SinkStreamFilter.cc SinkStreamFilter.h \
ChunkedDecodingStreamFilter.cc ChunkedDecodingStreamFilter.h \
NullSinkStreamFilter.cc NullSinkStreamFilter.h uri.cc uri.h \
Triplet.h $(am__append_1) $(am__append_2) $(am__append_3) \
$(am__append_4) $(am__append_5) $(am__append_6) \
$(am__append_7) $(am__append_8) $(am__append_9) \
$(am__append_10) $(am__append_11) $(am__append_12) \
$(am__append_13) $(am__append_14) $(am__append_15) \
$(am__append_16) $(am__append_17) $(am__append_18) \
$(am__append_19) $(am__append_20) $(am__append_21) \
$(am__append_22) $(am__append_23) $(am__append_24) \
$(am__append_25) $(am__append_26) $(am__append_27) \
$(am__append_28) $(am__append_29) $(am__append_30) \
$(am__append_31)
Triplet.h cookie_helper.cc cookie_helper.h $(am__append_1) \
$(am__append_2) $(am__append_3) $(am__append_4) \
$(am__append_5) $(am__append_6) $(am__append_7) \
$(am__append_8) $(am__append_9) $(am__append_10) \
$(am__append_11) $(am__append_12) $(am__append_13) \
$(am__append_14) $(am__append_15) $(am__append_16) \
$(am__append_17) $(am__append_18) $(am__append_19) \
$(am__append_20) $(am__append_21) $(am__append_22) \
$(am__append_23) $(am__append_24) $(am__append_25) \
$(am__append_26) $(am__append_27) $(am__append_28) \
$(am__append_29) $(am__append_30) $(am__append_31)
noinst_LIBRARIES = libaria2c.a
libaria2c_a_SOURCES = $(SRCS)
aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\
@ -1417,7 +1416,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ConsoleStatCalc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ContentTypeRequestGroupCriteria.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Cookie.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CookieParser.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CookieStorage.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CreateRequestCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTAbstractMessage.Po@am__quote@
@ -1674,6 +1672,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bittorrent_helper.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clock_gettime_mingw.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clock_gettime_osx.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cookie_helper.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/daemon.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/download_helper.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gai_strerror.Po@am__quote@

View File

@ -59,6 +59,7 @@
#include "ServerStatMan.h"
#include "FileAllocationEntry.h"
#include "CheckIntegrityEntry.h"
#include "TimeA2.h"
#ifdef ENABLE_SSL
# include "SocketCore.h"
# include "TLSContext.h"
@ -128,7 +129,7 @@ downloadresultcode::RESULT MultiUrlRequestInfo::execute()
if(!option_->blank(PREF_LOAD_COOKIES)) {
File cookieFile(option_->get(PREF_LOAD_COOKIES));
if(cookieFile.isFile()) {
e->getCookieStorage()->load(cookieFile.getPath());
e->getCookieStorage()->load(cookieFile.getPath(), Time().getTime());
logger_->info("Loaded cookies from '%s'.",
cookieFile.getPath().c_str());
} else {

View File

@ -40,6 +40,8 @@
#include "A2STR.h"
#include "DlAbortEx.h"
#include "StringFormat.h"
#include "Cookie.h"
#include "cookie_helper.h"
namespace aria2 {
@ -47,35 +49,46 @@ NsCookieParser::NsCookieParser() {}
NsCookieParser::~NsCookieParser() {}
static const std::string C_TRUE("TRUE");
namespace {
const std::string C_TRUE("TRUE");
}
static Cookie parseNsCookie(const std::string& nsCookieStr)
namespace {
bool parseNsCookie
(Cookie& cookie, const std::string& nsCookieStr, time_t creationTime)
{
std::vector<std::string> vs;
util::split(nsCookieStr, std::back_inserter(vs), "\t", true);
if(vs.size() < 6 ) {
return Cookie();
if(vs.size() < 6) {
return false;
}
int64_t expireDate = util::parseLLInt(vs[4]);
// TODO assuming time_t is int32_t...
if(expireDate > INT32_MAX) {
expireDate = INT32_MAX;
std::string cookieDomain = cookie::removePrecedingDots(vs[0]);
if(vs[5].empty() || cookieDomain.empty() || !cookie::goodPath(vs[2])) {
return false;
}
Cookie c(vs[5], // name
vs.size() >= 7? vs[6]:A2STR::NIL, // value
expireDate, // expires
vs[2], // path
vs[0], // domain
vs[3] == C_TRUE ? true : false);
if(!util::startsWith(vs[0], A2STR::DOT_C)) {
c.markOriginServerOnly();
int64_t expiryTime;
if(!util::parseLLIntNoThrow(expiryTime, vs[4])) {
return false;
}
return c;
if(sizeof(time_t) == 4 && expiryTime > INT32_MAX) {
expiryTime = INT32_MAX;
}
cookie.setName(vs[5]);
cookie.setValue(vs.size() >= 7? vs[6]:A2STR::NIL);
cookie.setExpiryTime(expiryTime == 0?INT32_MAX:expiryTime);
// aria2 treats expiryTime == 0 means session cookie.
cookie.setPersistent(expiryTime != 0);
cookie.setDomain(cookieDomain);
cookie.setHostOnly(util::isNumericHost(cookieDomain) || vs[1] != C_TRUE);
cookie.setPath(vs[2]);
cookie.setSecure(vs[3] == C_TRUE);
cookie.setCreationTime(creationTime);
return true;
}
}
std::vector<Cookie> NsCookieParser::parse(const std::string& filename)
std::vector<Cookie> NsCookieParser::parse
(const std::string& filename, time_t creationTime)
{
std::ifstream s(filename.c_str(), std::ios::binary);
if(!s) {
@ -88,14 +101,9 @@ std::vector<Cookie> NsCookieParser::parse(const std::string& filename)
if(util::startsWith(line, A2STR::SHARP_C)) {
continue;
}
try {
Cookie c = parseNsCookie(line);
if(c.good()) {
cookies.push_back(c);
}
} catch(RecoverableException& e) {
// ignore malformed cookie entry
// TODO better to log it
Cookie c;
if(parseNsCookie(c, line, creationTime)) {
cookies.push_back(c);
}
}
return cookies;

View File

@ -40,17 +40,17 @@
#include <string>
#include <vector>
#include "Cookie.h"
namespace aria2 {
class Cookie;
class NsCookieParser {
public:
NsCookieParser();
~NsCookieParser();
std::vector<Cookie> parse(const std::string& filename);
std::vector<Cookie> parse(const std::string& filename, time_t creationTime);
};
} // namespace aria2

View File

@ -40,6 +40,7 @@
#include "util.h"
#include "StringFormat.h"
#include "A2STR.h"
#include "cookie_helper.h"
#ifndef HAVE_SQLITE3_OPEN_V2
# include "File.h"
#endif // !HAVE_SQLITE3_OPEN_V2
@ -80,34 +81,40 @@ static std::string toString(const char* str)
static int cookieRowMapper(void* data, int rowIndex,
char** values, char** names)
{
try {
std::vector<Cookie>& cookies =
*reinterpret_cast<std::vector<Cookie>*>(data);
int64_t expireDate = util::parseLLInt(toString(values[3]));
// TODO assuming time_t is int32_t...
if(expireDate > INT32_MAX) {
expireDate = INT32_MAX;
}
Cookie c(toString(values[4]), // name
toString(values[5]), // value
expireDate, // expires
toString(values[1]), // path
toString(values[0]), // domain
strcmp(toString(values[2]).c_str(), "1") == 0 ? true:false //secure
);
if(!util::startsWith(values[0], A2STR::DOT_C)) {
c.markOriginServerOnly();
}
if(c.good()) {
cookies.push_back(c);
}
} catch(RecoverableException& e) {
//failed to parse expiry.
std::vector<Cookie>& cookies =
*reinterpret_cast<std::vector<Cookie>*>(data);
std::string cookieDomain = cookie::removePrecedingDots(toString(values[0]));
std::string cookieName = toString(values[4]);
std::string cookiePath = toString(values[1]);
if(cookieName.empty() || cookieDomain.empty() ||
!cookie::goodPath(cookiePath)) {
return 0;
}
int64_t expiryTime;
if(!util::parseLLIntNoThrow(expiryTime, toString(values[3]))) {
return 0;
}
if(sizeof(time_t) == 4 && expiryTime > INT32_MAX) {
expiryTime = INT32_MAX;
}
// TODO get last access, creation date(chrome only)
Cookie c(cookieName,
toString(values[5]), // value
expiryTime,
true, // persistent
cookieDomain,
util::isNumericHost(cookieDomain) || values[0][0] != '.', // hostOnly
cookiePath,
strcmp(toString(values[2]).c_str(), "1") == 0, //secure
false,
0 // creation time. Set this later.
);
cookies.push_back(c);
return 0;
}
void Sqlite3CookieParser::parse(std::vector<Cookie>& cookies)
void Sqlite3CookieParser::parse
(std::vector<Cookie>& cookies, time_t creationTime)
{
if(!db_) {
throw DL_ABORT_EX(StringFormat("SQLite3 database is not opened.").str());
@ -116,6 +123,13 @@ void Sqlite3CookieParser::parse(std::vector<Cookie>& cookies)
char* sqlite3ErrMsg = 0;
int ret = sqlite3_exec(db_, getQuery().c_str(), cookieRowMapper,
&tcookies, &sqlite3ErrMsg);
// TODO If last access, creation date are retrieved from database,
// following for loop must be removed.
for(std::vector<Cookie>::iterator i = tcookies.begin(), eoi = tcookies.end();
i != eoi; ++i) {
(*i).setCreationTime(creationTime);
(*i).setLastAccessTime(creationTime);
}
std::string errMsg;
if(sqlite3ErrMsg) {
errMsg = sqlite3ErrMsg;

View File

@ -55,7 +55,7 @@ public:
// Loads cookies from sqlite3 database and stores them in cookies.
// When loading is successful, cookies stored in cookies initially
// are removed. Otherwise, the content of cookies is unchanged.
void parse(std::vector<Cookie>& cookies);
void parse(std::vector<Cookie>& cookies, time_t creationTime);
protected:
// Returns SQL select statement to get 1 record of cookie. The sql
// must return 6 columns in the following order: host, path,

View File

@ -421,10 +421,18 @@ class LeastRecentAccess:public std::binary_function<T, T, bool> {
public:
bool operator()(const T& lhs, const T& rhs) const
{
return lhs.getLastAccess() < rhs.getLastAccess();
return lhs.getLastAccessTime() < rhs.getLastAccessTime();
}
};
namespace {
template<typename T, typename S>
bool in(T x, S s, S t)
{
return s <= x && x <= t;
}
}
} // namespace aria2
#endif // _D_A2_FUNCTIONAL_H_

391
src/cookie_helper.cc Normal file
View File

@ -0,0 +1,391 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2010 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#include "cookie_helper.h"
#include <cstring>
#include <vector>
#include "util.h"
#include "array_fun.h"
#include "Cookie.h"
#include "a2functional.h"
namespace aria2 {
namespace cookie {
namespace {
bool isDelimiter(unsigned char c)
{
return c == 0x09U || in(c, 0x20U, 0x2fU) || in(c, 0x3bU, 0x40U) ||
in(c, 0x5bU, 0x60U) || in(c, 0x7bU, 0x7eU);
}
} // namespace
namespace {
std::string::const_iterator getNextDigit
(std::string::const_iterator first, std::string::const_iterator last)
{
for(; first != last && in(static_cast<unsigned char>(*first), 0x30U, 0x39U);
++first);
return first;
}
}
bool parseDate(time_t& time, const std::string& cookieDate)
{
std::vector<std::string> dateTokens;
for(std::string::const_iterator i = cookieDate.begin(),
eoi = cookieDate.end(); i != eoi;) {
unsigned char c = *i;
if(isDelimiter(c)) {
++i;
continue;
}
std::string::const_iterator s = i;
for(; s != eoi && !isDelimiter(static_cast<unsigned char>(*s)); ++s);
dateTokens.push_back(std::string(i, s));
i = s;
}
int dayOfMonth = 0;
bool foundDayOfMonth = false;
int month = 0;
bool foundMonth = false;
int year = 0;
bool foundYear = false;
int hour = 0;
int minute = 0;
int second = 0;
bool foundTime = false;
for(std::vector<std::string>::const_iterator i = dateTokens.begin(),
eoi = dateTokens.end(); i != eoi; ++i) {
if(!foundTime) {
std::string::const_iterator hEnd;
std::string::const_iterator mEnd;
std::string::const_iterator sEnd;
hEnd = getNextDigit((*i).begin(),(*i).end());
size_t len = std::distance((*i).begin(), hEnd);
if(len == 0 || 2 < len || hEnd == (*i).end() || *hEnd != ':') {
goto NOT_TIME;
}
mEnd = getNextDigit(hEnd+1, (*i).end());
len = std::distance(hEnd+1, mEnd);
if(len == 0 || 2 < len || mEnd == (*i).end() || *mEnd != ':') {
goto NOT_TIME;
}
sEnd = getNextDigit(mEnd+1, (*i).end());
len = std::distance(mEnd+1, sEnd);
if(len == 0 || 2 < len) {
goto NOT_TIME;
}
foundTime = true;
hour = util::parseInt(std::string((*i).begin(), hEnd));
minute = util::parseInt(std::string(hEnd+1, mEnd));
second = util::parseInt(std::string(mEnd+1, sEnd));
continue;
NOT_TIME:
;
}
if(!foundDayOfMonth) {
std::string::const_iterator j = getNextDigit((*i).begin(), (*i).end());
size_t len = std::distance((*i).begin(), j);
if(1 <= len && len <= 2) {
foundDayOfMonth = true;
dayOfMonth = util::parseInt(std::string((*i).begin(), j));
continue;
}
}
if(!foundMonth) {
static std::string MONTH[] = {
"jan", "feb", "mar", "apr",
"may", "jun", "jul", "aug",
"sep", "oct", "nov", "dec" };
if((*i).size() >= 3) {
std::string head = util::toLower((*i).substr(0, 3));
std::string* mptr = std::find(vbegin(MONTH), vend(MONTH), head);
if(mptr != vend(MONTH)) {
foundMonth = true;
month = std::distance(vbegin(MONTH), mptr)+1;
continue;
}
}
}
if(!foundYear) {
std::string::const_iterator j = getNextDigit((*i).begin(), (*i).end());
size_t len = std::distance((*i).begin(), j);
if(1 <= len && len <= 4) {
foundYear = true;
year = util::parseInt(std::string((*i).begin(), j));
continue;
}
}
}
if(in(year, 70, 99)) {
year += 1900;
} else if(in(year, 0, 69)) {
year += 2000;
}
if(!foundDayOfMonth || !foundMonth || !foundYear || !foundTime ||
!in(dayOfMonth, 1, 31) || year < 1601 || hour > 23 ||
minute > 59 || second > 59) {
return false;
}
if((month == 4 || month == 6 || month == 9 || month == 11) &&
dayOfMonth > 30) {
return false;
}
if(month == 2) {
if((year%4 == 0 && year%100 != 0) || year%400 == 0) {
if(dayOfMonth > 29) {
return false;
}
} else if(dayOfMonth > 28) {
return false;
}
}
tm timespec;
memset(&timespec, 0, sizeof(timespec));
timespec.tm_sec = second;
timespec.tm_min = minute;
timespec.tm_hour = hour;
timespec.tm_mday = dayOfMonth;
timespec.tm_mon = month-1;
timespec.tm_year = year-1900;
time = timegm(&timespec);
return time != -1;
}
bool parse
(Cookie& cookie,
const std::string& cookieStr,
const std::string& requestHost,
const std::string& defaultPath,
time_t creationTime)
{
std::string::const_iterator nvEnd = cookieStr.begin();
std::string::const_iterator end = cookieStr.end();
for(; nvEnd != end && *nvEnd != ';'; ++nvEnd);
std::string::const_iterator eq = cookieStr.begin();
for(; eq != nvEnd && *eq != '='; ++eq);
if(eq == nvEnd) {
return false;
}
std::string cookieName = util::trim(std::string(cookieStr.begin(), eq));
if(cookieName.empty()) {
return false;
}
std::string cookieValue = util::trim(std::string(eq+1, nvEnd));
time_t expiryTime = 0;
bool foundExpires = false;
bool persistent = false;
time_t maxAge = 0;
bool foundMaxAge = false;
std::string cookieDomain;
bool hostOnly = false;
std::string cookiePath;
bool secure = false;
bool httpOnly = false;
for(std::string::const_iterator i = nvEnd; i != end;) {
std::string::const_iterator j = i;
for(; j != end && *j != ';'; ++j);
std::string::const_iterator eq = i;
for(; eq != j && *eq != '='; ++eq);
std::string attrName = util::toLower(util::trim(std::string(i, eq)));
std::string attrValue;
if(eq != j) {
attrValue = util::trim(std::string(eq+1, j));
}
i = j;
if(j != end) {
++i;
}
if(attrName == "expires") {
if(parseDate(expiryTime, attrValue)) {
foundExpires = true;
} else {
return false;
}
} else if(attrName == "max-age") {
if(attrValue.empty() ||
(!in(static_cast<unsigned char>(attrValue[0]), 0x30u, 0x39u) &&
attrValue[0] != '-')) {
return false;
}
for(std::string::const_iterator s = attrValue.begin()+1,
eos = attrValue.end(); s != eos; ++s) {
if(!in(static_cast<unsigned char>(*s), 0x30u, 0x39u)) {
return false;
}
}
int64_t delta;
if(util::parseLLIntNoThrow(delta, attrValue)) {
foundMaxAge = true;
if(delta <= 0) {
maxAge = 0;
} else {
int64_t n = creationTime;
n += delta;
if(n < 0 || (sizeof(time_t) < 8 && n > INT32_MAX)) {
maxAge = INT32_MAX;
} else {
maxAge = n;
}
}
} else {
return false;
}
} else if(attrName == "domain") {
if(attrValue.empty()) {
return false;
}
std::string::const_iterator noDot = attrValue.begin();
std::string::const_iterator end = attrValue.end();
for(; noDot != end && *noDot == '.'; ++noDot);
if(noDot == end) {
return false;
}
cookieDomain = std::string(noDot, end);
} else if(attrName == "path") {
if(goodPath(attrValue)) {
cookiePath = attrValue;
} else {
cookiePath = defaultPath;
}
} else if(attrName == "secure") {
secure = true;
} else if(attrName == "httponly") {
httpOnly = true;
}
}
if(foundMaxAge) {
expiryTime = maxAge;
persistent = true;
} else if(foundExpires) {
persistent = true;
} else {
expiryTime = INT32_MAX;
persistent = false;
}
std::string canonicalizedHost = canonicalizeHost(requestHost);
if(cookieDomain.empty()) {
hostOnly = true;
cookieDomain = canonicalizedHost;
} else if(domainMatch(canonicalizedHost, cookieDomain)) {
hostOnly = util::isNumericHost(canonicalizedHost);
} else {
return false;
}
if(cookiePath.empty()) {
cookiePath = defaultPath;
}
cookie.setName(cookieName);
cookie.setValue(cookieValue);
cookie.setExpiryTime(expiryTime);
cookie.setPersistent(persistent);
cookie.setDomain(cookieDomain);
cookie.setHostOnly(hostOnly);
cookie.setPath(cookiePath);
cookie.setSecure(secure);
cookie.setHttpOnly(httpOnly);
cookie.setCreationTime(creationTime);
cookie.setLastAccessTime(creationTime);
return true;
}
std::string removePrecedingDots(const std::string& host)
{
std::string::const_iterator noDot = host.begin();
std::string::const_iterator end = host.end();
for(; noDot != end && *noDot == '.'; ++noDot);
return std::string(noDot, end);
}
bool goodPath(const std::string& cookiePath)
{
return !cookiePath.empty() && cookiePath[0] == '/';
}
std::string canonicalizeHost(const std::string& host)
{
std::string ch = util::toLower(host);
return ch;
}
bool domainMatch(const std::string& requestHost, const std::string& domain)
{
return requestHost == domain ||
(util::endsWith(requestHost, domain) &&
requestHost[requestHost.size()-domain.size()-1] == '.' &&
!util::isNumericHost(requestHost));
}
bool pathMatch(const std::string& requestPath, const std::string& path)
{
return requestPath == path ||
(util::startsWith(requestPath, path) &&
(path[path.size()-1] == '/' || requestPath[path.size()] == '/'));
}
std::string reverseDomainLevel(const std::string& domain)
{
std::string r;
for(std::string::const_iterator i = domain.begin(), eoi = domain.end();
i != eoi;) {
std::string::const_iterator j = i;
for(; j != eoi && *j != '.'; ++j);
r.insert(r.begin(), '.');
r.insert(r.begin(), i, j);
i = j;
if(j != eoi) {
++i;
}
}
if(!r.empty()) {
r.erase(r.size()-1, 1);
}
return r;
}
} // namespace cookie
} // namespace aria2

View File

@ -2,7 +2,7 @@
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
* Copyright (C) 2010 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -32,34 +32,44 @@
* files in the program, then also delete it here.
*/
/* copyright --> */
#ifndef _D_COOKIE_PARSER_H_
#define _D_COOKIE_PARSER_H_
#ifndef D_COOKIE_HELPER_H
#define D_COOKIE_HELPER_H
#include "common.h"
#include <string>
#include "SharedHandle.h"
#include "Cookie.h"
#include "a2time.h"
namespace aria2 {
class CookieParser {
public:
Cookie parse(const std::string& cookieStr, const std::string& defaultDomain,
const std::string& defaultPath) const;
private:
static const std::string C_SECURE;
static const std::string C_DOMAIN;
static const std::string C_PATH;
static const std::string C_EXPIRES;
};
class Cookie;
typedef SharedHandle<CookieParser> CookieParserHandle;
namespace cookie {
bool parseDate(time_t& time, const std::string& cookieDate);
bool parse
(Cookie& cookie,
const std::string& cookieStr,
const std::string& requestHost,
const std::string& defaultPath,
time_t creationTime);
std::string removePrecedingDots(const std::string& host);
bool goodPath(const std::string& cookiePath);
std::string canonicalizeHost(const std::string& host);
bool domainMatch(const std::string& requestHost, const std::string& domain);
bool pathMatch(const std::string& requestPath, const std::string& path);
std::string reverseDomainLevel(const std::string& domain);
} // namespace cookie
} // namespace aria2
#endif // _D_COOKIE_PARSER_H_
#endif // D_COOKIE_HELPER_H

View File

@ -74,7 +74,6 @@
#include "StringFormat.h"
#include "A2STR.h"
#include "array_fun.h"
#include "a2functional.h"
#include "bitfield.h"
#include "DownloadHandlerConstants.h"
#include "RequestGroup.h"
@ -291,17 +290,10 @@ bool inRFC2616HttpToken(const char c)
std::find(vbegin(chars), vend(chars), c) != vend(chars);
}
namespace {
bool in(unsigned char ch, unsigned char s, unsigned char t)
{
return s <= ch && ch <= t;
}
}
namespace {
bool isUtf8Tail(unsigned char ch)
{
return in(ch, 0x80, 0xbf);
return in(ch, 0x80u, 0xbfu);
}
}
@ -311,49 +303,49 @@ bool isUtf8(const std::string& str)
++s) {
unsigned char firstChar = *s;
// See ABNF in http://tools.ietf.org/search/rfc3629#section-4
if(in(firstChar, 0x20, 0x7e) ||
firstChar == 0x09 || firstChar == 0x0a ||firstChar == 0x0d) {
if(in(firstChar, 0x20u, 0x7eu) ||
firstChar == 0x09u || firstChar == 0x0au ||firstChar == 0x0du) {
// UTF8-1 (without ctrl chars)
} else if(in(firstChar, 0xc2, 0xdf)) {
} else if(in(firstChar, 0xc2u, 0xdfu)) {
// UTF8-2
if(++s == eos || !isUtf8Tail(*s)) {
return false;
}
} else if(0xe0 == firstChar) {
} else if(0xe0u == firstChar) {
// UTF8-3
if(++s == eos || !in(*s, 0xa0, 0xbf) ||
if(++s == eos || !in(static_cast<unsigned char>(*s), 0xa0u, 0xbfu) ||
++s == eos || !isUtf8Tail(*s)) {
return false;
}
} else if(in(firstChar, 0xe1, 0xec) || in(firstChar, 0xee, 0xef)) {
} else if(in(firstChar, 0xe1u, 0xecu) || in(firstChar, 0xeeu, 0xefu)) {
// UTF8-3
if(++s == eos || !isUtf8Tail(*s) ||
++s == eos || !isUtf8Tail(*s)) {
return false;
}
} else if(0xed == firstChar) {
} else if(0xedu == firstChar) {
// UTF8-3
if(++s == eos || !in(*s, 0x80, 0x9f) ||
if(++s == eos || !in(static_cast<unsigned char>(*s), 0x80u, 0x9fu) ||
++s == eos || !isUtf8Tail(*s)) {
return false;
}
} else if(0xf0 == firstChar) {
} else if(0xf0u == firstChar) {
// UTF8-4
if(++s == eos || !in(*s, 0x90, 0xbf) ||
if(++s == eos || !in(static_cast<unsigned char>(*s), 0x90u, 0xbfu) ||
++s == eos || !isUtf8Tail(*s) ||
++s == eos || !isUtf8Tail(*s)) {
return false;
}
} else if(in(firstChar, 0xf1, 0xf3)) {
} else if(in(firstChar, 0xf1u, 0xf3u)) {
// UTF8-4
if(++s == eos || !isUtf8Tail(*s) ||
++s == eos || !isUtf8Tail(*s) ||
++s == eos || !isUtf8Tail(*s)) {
return false;
}
} else if(0xf4 == firstChar) {
} else if(0xf4u == firstChar) {
// UTF8-4
if(++s == eos || !in(*s, 0x80, 0x8f) ||
if(++s == eos || !in(static_cast<unsigned char>(*s), 0x80u, 0x8fu) ||
++s == eos || !isUtf8Tail(*s) ||
++s == eos || !isUtf8Tail(*s)) {
return false;
@ -427,7 +419,7 @@ std::string toHex(const unsigned char* src, size_t len) {
const unsigned char* last = src+len;
for(const unsigned char* i = src; i != last; ++i) {
*o = (*i >> 4);
*(o+1) = (*i)&0x0f;
*(o+1) = (*i)&0x0fu;
for(int j = 0; j < 2; ++j) {
if(*o < 10) {
*o += '0';
@ -598,6 +590,24 @@ int64_t parseLLInt(const std::string& s, int32_t base)
return v;
}
bool parseLLIntNoThrow(int64_t& result, const std::string& s, int base)
{
std::string trimed = trim(s);
if(trimed.empty()) {
return false;
}
char* stop;
errno = 0;
int64_t v = strtoll(trimed.c_str(), &stop, base);
if(*stop != '\0') {
return false;
} else if(((v == INT64_MIN) || (v == INT64_MAX)) && (errno == ERANGE)) {
return false;
}
result = v;
return true;
}
uint64_t parseULLInt(const std::string& s, int base)
{
std::string trimed = trim(s);
@ -740,14 +750,14 @@ std::string iso8859ToUtf8(const std::string& src)
for(std::string::const_iterator itr = src.begin(), eoi = src.end();
itr != eoi; ++itr) {
unsigned char c = *itr;
if(0xa0 <= c) {
if(c <= 0xbf) {
dest += 0xc2;
if(0xa0u <= c) {
if(c <= 0xbfu) {
dest += 0xc2u;
} else {
dest += 0xc3;
dest += 0xc3u;
}
dest += c&(~0x40);
} else if(0x80 <= c && c <= 0x9f) {
dest += c&(~0x40u);
} else if(0x80u <= c && c <= 0x9fu) {
return A2STR::NIL;
} else {
dest += c;
@ -1000,10 +1010,10 @@ std::string abbrevSize(int64_t size)
char units[] = { 'K', 'M' };
size_t numUnit = sizeof(units)/sizeof(char);
size_t i = 0;
int r = size&0x3ff;
int r = size&0x3ffu;
size >>= 10;
for(; i < numUnit-1 && size >= 1024; ++i) {
r = size&0x3ff;
r = size&0x3ffu;
size >>= 10;
}
std::string result = itos(size, true);
@ -1332,7 +1342,7 @@ bool detectDirTraversal(const std::string& s)
{
for(std::string::const_iterator i = s.begin(), eoi = s.end(); i != eoi; ++i) {
unsigned char c = *i;
if(in(c, 0x00, 0x1f) || c == 0x7f) {
if(in(c, 0x00u, 0x1fu) || c == 0x7fu) {
return true;
}
}
@ -1367,7 +1377,7 @@ std::string escapePath(const std::string& s)
std::string d;
for(std::string::const_iterator i = s.begin(), eoi = s.end(); i != eoi; ++i) {
unsigned char c = *i;
if(in(c, 0x00, 0x1f) || c == 0x7f
if(in(c, 0x00u, 0x1fu) || c == 0x7fu
#ifdef __MINGW32__
|| std::find(vbegin(WIN_INVALID_PATH_CHARS),
vend(WIN_INVALID_PATH_CHARS),

View File

@ -181,6 +181,8 @@ bool parseUIntNoThrow(uint32_t& result, const std::string& s, int base = 10);
int64_t parseLLInt(const std::string& s, int32_t base = 10);
bool parseLLIntNoThrow(int64_t& result, const std::string& s, int base = 10);
uint64_t parseULLInt(const std::string& s, int base = 10);
IntSequence parseIntRange(const std::string& src);

View File

@ -1,89 +0,0 @@
#include "CookieBoxFactory.h"
#include "CookieBox.h"
#include <cppunit/extensions/HelperMacros.h>
namespace aria2 {
class CookieBoxFactoryTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(CookieBoxFactoryTest);
CPPUNIT_TEST(testLoadDefaultCookie);
CPPUNIT_TEST(testLoadDefaultCookie_sqlite3);
CPPUNIT_TEST(testCreateNewInstance);
CPPUNIT_TEST_SUITE_END();
private:
public:
void setUp() {
}
void testLoadDefaultCookie();
void testLoadDefaultCookie_sqlite3();
void testCreateNewInstance();
};
CPPUNIT_TEST_SUITE_REGISTRATION( CookieBoxFactoryTest );
void CookieBoxFactoryTest::testLoadDefaultCookie()
{
CookieBoxFactory factory;
factory.loadDefaultCookie("nscookietest.txt");
Cookies cookies = factory.getDefaultCookies();
CPPUNIT_ASSERT_EQUAL((int32_t)4, (int32_t)cookies.size());
Cookie c = cookies[0];
CPPUNIT_ASSERT_EQUAL(std::string("JSESSIONID"), c.name);
CPPUNIT_ASSERT_EQUAL(std::string("123456789"), c.value);
CPPUNIT_ASSERT_EQUAL((time_t)1181473200, c.expires);
CPPUNIT_ASSERT_EQUAL(std::string("/"), c.path);
CPPUNIT_ASSERT_EQUAL(std::string("localhost"), c.domain);
c = cookies[1];
CPPUNIT_ASSERT_EQUAL(std::string("user"), c.name);
CPPUNIT_ASSERT_EQUAL(std::string("me"), c.value);
CPPUNIT_ASSERT_EQUAL((time_t)1181473200, c.expires);
CPPUNIT_ASSERT_EQUAL(std::string("/"), c.path);
CPPUNIT_ASSERT_EQUAL(std::string("localhost"), c.domain);
c = cookies[2];
CPPUNIT_ASSERT_EQUAL(std::string("passwd"), c.name);
CPPUNIT_ASSERT_EQUAL(std::string("secret"), c.value);
CPPUNIT_ASSERT_EQUAL((time_t)2147483647, c.expires);
CPPUNIT_ASSERT_EQUAL(std::string("/cgi-bin"), c.path);
CPPUNIT_ASSERT_EQUAL(std::string("localhost"), c.domain);
c = cookies[3];
CPPUNIT_ASSERT_EQUAL(std::string("novalue"), c.name);
CPPUNIT_ASSERT_EQUAL(std::string(""), c.value);
CPPUNIT_ASSERT_EQUAL((time_t)2147483647, c.expires);
CPPUNIT_ASSERT_EQUAL(std::string("/"), c.path);
CPPUNIT_ASSERT_EQUAL(std::string("localhost"), c.domain);
}
void CookieBoxFactoryTest::testLoadDefaultCookie_sqlite3()
{
CookieBoxFactory factory;
factory.loadDefaultCookie("cookies.sqlite");
const std::deque<Cookie>& cookies = factory.getDefaultCookies();
#ifdef HAVE_SQLITE3
CPPUNIT_ASSERT_EQUAL((size_t)3, cookies.size());
#else // !HAVE_SQLITE3
CPPUNIT_ASSERT(cookies.empty());
#endif // !HAVE_SQLITE3
}
void CookieBoxFactoryTest::testCreateNewInstance()
{
CookieBoxFactory factory;
factory.loadDefaultCookie("nscookietest.txt");
SharedHandle<CookieBox> box = factory.createNewInstance();
std::deque<Cookie> cookies = box->criteriaFind("localhost", "/", 0, true);
CPPUNIT_ASSERT_EQUAL((int32_t)3, (int32_t)cookies.size());
}
} // namespace aria2

229
test/CookieHelperTest.cc Normal file
View File

@ -0,0 +1,229 @@
#include "cookie_helper.h"
#include <cppunit/extensions/HelperMacros.h>
#include "Exception.h"
#include "util.h"
#include "Cookie.h"
namespace aria2 {
class CookieHelperTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(CookieHelperTest);
CPPUNIT_TEST(testParseDate);
CPPUNIT_TEST(testDomainMatch);
CPPUNIT_TEST(testPathMatch);
CPPUNIT_TEST(testParse);
CPPUNIT_TEST(testReverseDomainLevel);
CPPUNIT_TEST_SUITE_END();
public:
void testParseDate();
void testDomainMatch();
void testPathMatch();
void testParse();
void testReverseDomainLevel();
};
CPPUNIT_TEST_SUITE_REGISTRATION(CookieHelperTest);
void CookieHelperTest::testParseDate()
{
// RFC1123
time_t time = 0;
CPPUNIT_ASSERT(cookie::parseDate(time, "Sat, 06 Sep 2008 15:26:33 GMT"));
CPPUNIT_ASSERT_EQUAL((time_t)1220714793, time);
// RFC850
CPPUNIT_ASSERT(cookie::parseDate(time, "Saturday, 06-Sep-08 15:26:33 GMT"));
CPPUNIT_ASSERT_EQUAL((time_t)1220714793, time);
// ANSI C's asctime()
CPPUNIT_ASSERT(cookie::parseDate(time, "Sun Sep 6 15:26:33 2008"));
CPPUNIT_ASSERT_EQUAL((time_t)1220714793, time);
CPPUNIT_ASSERT(cookie::parseDate(time, "Thu Jan 1 0:0:0 1970"));
CPPUNIT_ASSERT_EQUAL((time_t)0, time);
CPPUNIT_ASSERT(!cookie::parseDate(time, "Thu Jan 1 1970 0:"));
CPPUNIT_ASSERT(!cookie::parseDate(time, "Thu Jan 1 1970 0:0"));
CPPUNIT_ASSERT(!cookie::parseDate(time, "Thu Jan 1 1970 0:0:"));
// Leap year
CPPUNIT_ASSERT(cookie::parseDate(time, "Tue, 29 Feb 2000 00:00:00 GMT"));
CPPUNIT_ASSERT(!cookie::parseDate(time, "Thu, 29 Feb 2001 00:00:00 GMT"));
}
void CookieHelperTest::testDomainMatch()
{
CPPUNIT_ASSERT(cookie::domainMatch("localhost", "localhost"));
CPPUNIT_ASSERT(cookie::domainMatch("192.168.0.1", "192.168.0.1"));
CPPUNIT_ASSERT(cookie::domainMatch("www.example.org", "example.org"));
CPPUNIT_ASSERT(!cookie::domainMatch("192.168.0.1", "0.1"));
CPPUNIT_ASSERT(!cookie::domainMatch("example.org", "example.com"));
CPPUNIT_ASSERT(!cookie::domainMatch("example.org", "www.example.org"));
}
void CookieHelperTest::testPathMatch()
{
CPPUNIT_ASSERT(cookie::pathMatch("/", "/"));
CPPUNIT_ASSERT(cookie::pathMatch("/foo/", "/foo"));
CPPUNIT_ASSERT(!cookie::pathMatch("/bar/", "/foo"));
CPPUNIT_ASSERT(!cookie::pathMatch("/foo", "/bar/foo"));
CPPUNIT_ASSERT(cookie::pathMatch("/foo/bar", "/foo/"));
}
void CookieHelperTest::testParse()
{
time_t creationDate = 141;
{
std::string str = "ID=123456789; expires=Sun, 10-Jun-2007 11:00:00 GMT;"
"path=/foo; domain=localhost; secure;httpOnly ";
Cookie c;
CPPUNIT_ASSERT(cookie::parse(c, str, "localhost", "/", creationDate));
CPPUNIT_ASSERT_EQUAL(std::string("ID"), c.getName());
CPPUNIT_ASSERT_EQUAL(std::string("123456789"), c.getValue());
CPPUNIT_ASSERT_EQUAL((time_t)1181473200, c.getExpiryTime());
CPPUNIT_ASSERT(c.getPersistent());
CPPUNIT_ASSERT_EQUAL(std::string("localhost"), c.getDomain());
CPPUNIT_ASSERT(!c.getHostOnly());
CPPUNIT_ASSERT_EQUAL(std::string("/foo"), c.getPath());
CPPUNIT_ASSERT(c.getSecure());
CPPUNIT_ASSERT(c.getHttpOnly());
CPPUNIT_ASSERT_EQUAL((time_t)141, c.getCreationTime());
CPPUNIT_ASSERT_EQUAL((time_t)141, c.getLastAccessTime());
}
{
std::string str = "id=; Max-Age=0;";
Cookie c;
CPPUNIT_ASSERT(cookie::parse(c, str, "localhost", "/", creationDate));
CPPUNIT_ASSERT_EQUAL(std::string("id"), c.getName());
CPPUNIT_ASSERT_EQUAL((time_t)0, c.getExpiryTime());
CPPUNIT_ASSERT(c.getPersistent());
CPPUNIT_ASSERT_EQUAL(std::string("localhost"), c.getDomain());
CPPUNIT_ASSERT(c.getHostOnly());
CPPUNIT_ASSERT_EQUAL(std::string("/"), c.getPath());
CPPUNIT_ASSERT(!c.getSecure());
CPPUNIT_ASSERT(!c.getHttpOnly());
}
{
std::string str = "id=; Max-Age=-100;";
Cookie c;
CPPUNIT_ASSERT(cookie::parse(c, str, "localhost", "/", creationDate));
CPPUNIT_ASSERT_EQUAL((time_t)0, c.getExpiryTime());
CPPUNIT_ASSERT(c.getPersistent());
}
{
std::string str = "id=; Max-Age=100;";
Cookie c;
CPPUNIT_ASSERT(cookie::parse(c, str, "localhost", "/", creationDate));
CPPUNIT_ASSERT_EQUAL((time_t)creationDate+100, c.getExpiryTime());
CPPUNIT_ASSERT(c.getPersistent());
}
{
std::string str = "id=; Max-Age=9223372036854775807;";
Cookie c;
CPPUNIT_ASSERT(cookie::parse(c, str, "localhost", "/", creationDate));
CPPUNIT_ASSERT_EQUAL((time_t)INT32_MAX, c.getExpiryTime());
CPPUNIT_ASSERT(c.getPersistent());
}
{
std::string str = "id=; Max-Age=X;";
Cookie c;
CPPUNIT_ASSERT(!cookie::parse(c, str, "localhost", "/", creationDate));
}
{
std::string str = "id=; Max-Age=100garbage;";
Cookie c;
CPPUNIT_ASSERT(!cookie::parse(c, str, "localhost", "/", creationDate));
}
{
std::string str = "id=; Max-Age=100;expires=Sun, 10-Jun-2007 11:00:00 GMT;";
Cookie c;
CPPUNIT_ASSERT(cookie::parse(c, str, "localhost", "/", creationDate));
CPPUNIT_ASSERT_EQUAL((time_t)creationDate+100, c.getExpiryTime());
CPPUNIT_ASSERT(c.getPersistent());
}
{
// Cookie data cannot be parsed.
std::string str = "id=; expires=2007-10-01 11:00:00 GMT;";
Cookie c;
CPPUNIT_ASSERT(!cookie::parse(c, str, "localhost", "/", creationDate));
}
{
std::string str = "id=;";
Cookie c;
CPPUNIT_ASSERT(cookie::parse(c, str, "localhost", "/", creationDate));
CPPUNIT_ASSERT(!c.getPersistent());
}
{
std::string str = "id=; path=abc";
Cookie c;
CPPUNIT_ASSERT(cookie::parse(c, str, "localhost", "/", creationDate));
CPPUNIT_ASSERT_EQUAL(std::string("/"), c.getPath());
}
{
std::string str = "id=; domain=.example.org";
Cookie c;
CPPUNIT_ASSERT(cookie::parse(c, str, "www.example.org", "/",creationDate));
}
{
// Fails because request host does not domain-match with cookie
// domain.
std::string str = "id=; domain=www.example.org";
Cookie c;
CPPUNIT_ASSERT(!cookie::parse(c, str, "example.org", "/", creationDate));
}
{
std::string str = "id=; domain=.";
Cookie c;
CPPUNIT_ASSERT(!cookie::parse(c, str, "localhost", "/",creationDate));
}
{
std::string str = "";
Cookie c;
CPPUNIT_ASSERT(!cookie::parse(c, str, "localhost", "/",creationDate));
}
{
std::string str = "=";
Cookie c;
CPPUNIT_ASSERT(!cookie::parse(c, str, "localhost", "/",creationDate));
}
{
// Use domain last time seen.
std::string str = "id=;domain=a.example.org;domain=.example.org";
Cookie c;
CPPUNIT_ASSERT(cookie::parse(c, str, "b.example.org", "/",creationDate));
CPPUNIT_ASSERT_EQUAL(std::string("example.org"), c.getDomain());
}
{
// numeric host
std::string str = "id=;";
Cookie c;
CPPUNIT_ASSERT(cookie::parse(c, str, "192.168.0.1", "/",creationDate));
CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), c.getDomain());
CPPUNIT_ASSERT(c.getHostOnly());
}
{
// numeric host
std::string str = "id=; domain=192.168.0.1";
Cookie c;
CPPUNIT_ASSERT(cookie::parse(c, str, "192.168.0.1", "/",creationDate));
CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), c.getDomain());
CPPUNIT_ASSERT(c.getHostOnly());
}
}
void CookieHelperTest::testReverseDomainLevel()
{
CPPUNIT_ASSERT_EQUAL(std::string("net.sourceforge.aria2"),
cookie::reverseDomainLevel("aria2.sourceforge.net"));
CPPUNIT_ASSERT_EQUAL(std::string("localhost"),
cookie::reverseDomainLevel("localhost"));
// Behavior check
CPPUNIT_ASSERT_EQUAL(std::string(""), cookie::reverseDomainLevel(""));
CPPUNIT_ASSERT_EQUAL(std::string(""), cookie::reverseDomainLevel("."));
CPPUNIT_ASSERT_EQUAL(std::string("foo."), cookie::reverseDomainLevel(".foo"));
CPPUNIT_ASSERT_EQUAL(std::string("foo"), cookie::reverseDomainLevel("foo."));
}
} // namespace aria2

View File

@ -1,70 +0,0 @@
#include "CookieParser.h"
#include <cppunit/extensions/HelperMacros.h>
namespace aria2 {
class CookieParserTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(CookieParserTest);
CPPUNIT_TEST(testParse);
CPPUNIT_TEST_SUITE_END();
public:
void testParse();
};
CPPUNIT_TEST_SUITE_REGISTRATION( CookieParserTest );
void CookieParserTest::testParse()
{
std::string str = "JSESSIONID=123456789; expires=Sun, 10-Jun-2007 11:00:00 GMT; path=/; domain=localhost; secure";
Cookie c = CookieParser().parse(str, "", "");
CPPUNIT_ASSERT(c.good());
CPPUNIT_ASSERT_EQUAL(std::string("JSESSIONID"), c.getName());
CPPUNIT_ASSERT_EQUAL(std::string("123456789"), c.getValue());
CPPUNIT_ASSERT_EQUAL((time_t)1181473200, c.getExpiry());
CPPUNIT_ASSERT_EQUAL(std::string("/"), c.getPath());
CPPUNIT_ASSERT_EQUAL(std::string(".localhost.local"), c.getDomain());
CPPUNIT_ASSERT_EQUAL(true, c.isSecureCookie());
CPPUNIT_ASSERT_EQUAL(false, c.isSessionCookie());
std::string str2 = "JSESSIONID=123456789";
c = CookieParser().parse(str2, "default.domain", "/default/path");
CPPUNIT_ASSERT(c.good());
CPPUNIT_ASSERT_EQUAL(std::string("JSESSIONID"), c.getName());
CPPUNIT_ASSERT_EQUAL(std::string("123456789"), c.getValue());
CPPUNIT_ASSERT_EQUAL((time_t)0, c.getExpiry());
CPPUNIT_ASSERT_EQUAL(std::string("default.domain"), c.getDomain());
CPPUNIT_ASSERT_EQUAL(std::string("/default/path"), c.getPath());
CPPUNIT_ASSERT_EQUAL(false, c.isSecureCookie());
CPPUNIT_ASSERT_EQUAL(true, c.isSessionCookie());
std::string str3 = "";
c = CookieParser().parse(str3, "", "");
CPPUNIT_ASSERT(!c.good());
#ifndef __MINGW32__
std::string str4 = "UID=300; expires=Wed, 01-Jan-1960 00:00:00 GMT";
time_t expire_time = (time_t) -315619200;
#else
std::string str4 = "UID=300; expires=Wed, 01-Jan-1970 00:00:01 GMT";
time_t expire_time = (time_t) 1;
#endif
c = CookieParser().parse(str4, "localhost", "/");
CPPUNIT_ASSERT(c.good());
CPPUNIT_ASSERT(!c.isSessionCookie());
CPPUNIT_ASSERT_EQUAL(expire_time, c.getExpiry());
std::string str5 = "k=v; expires=Sun, 10-Jun-07 11:00:00 GMT";
c = CookieParser().parse(str5, "", "");
CPPUNIT_ASSERT(c.good());
CPPUNIT_ASSERT_EQUAL(std::string("k"), c.getName());
CPPUNIT_ASSERT_EQUAL(std::string("v"), c.getValue());
CPPUNIT_ASSERT_EQUAL((time_t)1181473200, c.getExpiry());
CPPUNIT_ASSERT_EQUAL(std::string(""), c.getDomain());
CPPUNIT_ASSERT_EQUAL(std::string(""), c.getPath());
CPPUNIT_ASSERT(!c.isSecureCookie());
CPPUNIT_ASSERT(!c.isSessionCookie());
}
} // namespace aria2

View File

@ -8,7 +8,6 @@
#include "Exception.h"
#include "util.h"
#include "TimeA2.h"
#include "CookieParser.h"
#include "RecoverableException.h"
#include "File.h"
#include "TestUtil.h"
@ -21,6 +20,7 @@ class CookieStorageTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testStore);
CPPUNIT_TEST(testParseAndStore);
CPPUNIT_TEST(testCriteriaFind);
CPPUNIT_TEST(testCriteriaFind_cookieOrder);
CPPUNIT_TEST(testLoad);
CPPUNIT_TEST(testLoad_sqlite3);
CPPUNIT_TEST(testLoad_fileNotfound);
@ -39,6 +39,7 @@ public:
void testStore();
void testParseAndStore();
void testCriteriaFind();
void testCriteriaFind_cookieOrder();
void testLoad();
void testLoad_sqlite3();
void testLoad_fileNotfound();
@ -60,113 +61,111 @@ void CookieStorageTest::dumpCookie
void CookieStorageTest::testStore()
{
time_t now = 1000;
CookieStorage st;
Cookie goodCookie("k", "v", "/", "localhost", false);
CPPUNIT_ASSERT(st.store(goodCookie));
Cookie goodCookie(createCookie("k", "v", "localhost", true, "/", false));
CPPUNIT_ASSERT(st.store(goodCookie, now));
CPPUNIT_ASSERT_EQUAL((size_t)1, st.size());
CPPUNIT_ASSERT(st.contains(goodCookie));
Cookie anotherCookie("k", "v", "/", "mirror", true);
CPPUNIT_ASSERT(st.store(anotherCookie));
Cookie anotherCookie(createCookie("k", "v", "mirror", true, "/", true));
CPPUNIT_ASSERT(st.store(anotherCookie, now));
CPPUNIT_ASSERT_EQUAL((size_t)2, st.size());
CPPUNIT_ASSERT(st.contains(anotherCookie));
CPPUNIT_ASSERT(st.contains(goodCookie));
Cookie updateGoodCookie("k", "v2", "/", "localhost", false);
CPPUNIT_ASSERT(st.store(goodCookie));
Cookie updateGoodCookie(createCookie("k", "v2", "localhost", true,
"/", false));
CPPUNIT_ASSERT(st.store(updateGoodCookie, now));
CPPUNIT_ASSERT_EQUAL((size_t)2, st.size());
CPPUNIT_ASSERT(st.contains(updateGoodCookie));
CPPUNIT_ASSERT(st.contains(anotherCookie));
Cookie expireGoodCookie("k", "v3", 1, "/", "localhost", false);
CPPUNIT_ASSERT(!st.store(expireGoodCookie));
Cookie expireGoodCookie(createCookie("k", "v3", 0, "localhost", true,
"/", false));
CPPUNIT_ASSERT(!st.store(expireGoodCookie, now));
CPPUNIT_ASSERT_EQUAL((size_t)1, st.size());
CPPUNIT_ASSERT(st.contains(anotherCookie));
Cookie badCookie("", "", "/", "localhost", false);
CPPUNIT_ASSERT(!st.store(badCookie));
CPPUNIT_ASSERT_EQUAL((size_t)1, st.size());
CPPUNIT_ASSERT(st.contains(anotherCookie));
Cookie fromNumericHost("k", "v", "/", "192.168.1.1", false);
CPPUNIT_ASSERT(st.store(fromNumericHost));
Cookie fromNumericHost(createCookie("k", "v", "192.168.1.1", true,
"/", false));
CPPUNIT_ASSERT(st.store(fromNumericHost, now));
CPPUNIT_ASSERT_EQUAL((size_t)2, st.size());
CPPUNIT_ASSERT(st.contains(fromNumericHost));
Cookie sessionScopedGoodCookie("k", "v3", 0, "/", "localhost", false);
CPPUNIT_ASSERT(st.store(sessionScopedGoodCookie));
CPPUNIT_ASSERT_EQUAL((size_t)3, st.size());
CPPUNIT_ASSERT(st.contains(sessionScopedGoodCookie));
Cookie sessionScopedGoodCookie2("k2", "v3", "/", "localhost", false);
CPPUNIT_ASSERT(st.store(sessionScopedGoodCookie2));
CPPUNIT_ASSERT_EQUAL((size_t)4, st.size());
CPPUNIT_ASSERT(st.contains(sessionScopedGoodCookie2));
}
void CookieStorageTest::testParseAndStore()
{
CookieStorage st;
time_t now = 1000;
std::string localhostCookieStr = "k=v;"
" expires=Fri, 2038-01-01 00:00:00 GMT; path=/; domain=localhost;";
CPPUNIT_ASSERT(st.parseAndStore(localhostCookieStr,
"localhost", "/downloads"));
CPPUNIT_ASSERT(!st.parseAndStore(localhostCookieStr,
"mirror", "/downloads"));
CPPUNIT_ASSERT(!st.parseAndStore(localhostCookieStr,
"127.0.0.1", "/downloads"));
" expires=Fri, 01 Jan 2038 00:00:00 GMT; path=/; domain=localhost;";
CPPUNIT_ASSERT
(st.parseAndStore(localhostCookieStr, "localhost", "/downloads", now));
CPPUNIT_ASSERT
(!st.parseAndStore(localhostCookieStr, "mirror", "/downloads", now));
CPPUNIT_ASSERT
(!st.parseAndStore(localhostCookieStr, "127.0.0.1", "/downloads", now));
std::string numericHostCookieStr = "k=v;"
" expires=Fri, 2038-01-01 00:00:00 GMT; path=/; domain=192.168.1.1;";
CPPUNIT_ASSERT(st.parseAndStore(numericHostCookieStr, "192.168.1.1", "/"));
" expires=Fri, 01 Jan 2038 00:00:00 GMT; path=/; domain=192.168.1.1;";
CPPUNIT_ASSERT
(st.parseAndStore(numericHostCookieStr, "192.168.1.1", "/", now));
// No domain and no path are specified.
std::string noDomainPathCookieStr = "k=v";
CPPUNIT_ASSERT
(st.parseAndStore(noDomainPathCookieStr, "aria2.sf.net", "/downloads"));
(st.parseAndStore(noDomainPathCookieStr,
"aria2.sf.net", "/downloads", now));
}
void CookieStorageTest::testCriteriaFind()
{
CookieStorage st;
time_t now = 1000;
Cookie alpha("alpha", "ALPHA", "/", ".aria2.org", false);
Cookie bravo("bravo", "BRAVO", Time().getTime()+60, "/foo", ".aria2.org",
false);
Cookie charlie("charlie", "CHARLIE", "/", ".aria2.org", true);
Cookie delta("delta", "DELTA", "/foo/bar", ".aria2.org", false);
Cookie echo("echo", "ECHO", "/", "www.dl.aria2.org", false);
Cookie foxtrot("foxtrot", "FOXTROT", "/", ".sf.net", false);
Cookie golf("golf", "GOLF", "/", "192.168.1.1", false);
Cookie hotel1("hotel", "HOTEL1", "/", "samename.x", false);
Cookie hotel2("hotel", "HOTEL2", "/hotel", "samename.x", false);
Cookie hotel3("hotel", "HOTEL3", "/bar/wine", "samename.x", false);
Cookie hotel4("hotel", "HOTEL4", "/bar/", "samename.x", false);
Cookie india1("india", "INDIA1", "/foo", "default.domain", false);
india1.markOriginServerOnly();
Cookie india2("india", "INDIA2", "/", "default.domain", false);
Cookie juliet1("juliet", "JULIET1", "/foo", "localhost", false);
juliet1.markOriginServerOnly();
Cookie juliet2("juliet", "JULIET2", "/", "localhost", false);
Cookie alpha(createCookie("alpha", "ALPHA", "aria2.org", false, "/", false));
Cookie bravo(createCookie("bravo", "BRAVO", 1060, "aria2.org", false,
"/foo", false));
Cookie charlie(createCookie("charlie", "CHARLIE", "aria2.org", false,
"/", true));
Cookie delta(createCookie("delta", "DELTA", "aria2.org", false,
"/foo/bar", false));
Cookie echo(createCookie("echo", "ECHO", "www.dl.aria2.org", false,
"/", false));
Cookie foxtrot(createCookie("foxtrot", "FOXTROT", "sf.net", false,
"/", false));
Cookie golf(createCookie("golf", "GOLF", "192.168.1.1", true,
"/", false));
Cookie hotel1(createCookie("hotel", "HOTEL1", "samename.x", false,
"/", false));
Cookie hotel2(createCookie("hotel", "HOTEL2", "samename.x", false,
"/hotel", false));
Cookie hotel3(createCookie("hotel", "HOTEL3", "samename.x", false,
"/bar/wine", false));
Cookie hotel4(createCookie("hotel", "HOTEL4", "samename.x", false,
"/bar/", false));
Cookie india1(createCookie("india", "INDIA1", "default.domain", true,
"/foo", false));
Cookie india2(createCookie("india", "INDIA2", "default.domain", false,
"/", false));
Cookie juliet1(createCookie("juliet", "JULIET1", "localhost", true,
"/foo", false));
CPPUNIT_ASSERT(st.store(alpha));
CPPUNIT_ASSERT(st.store(bravo));
CPPUNIT_ASSERT(st.store(charlie));
CPPUNIT_ASSERT(st.store(delta));
CPPUNIT_ASSERT(st.store(echo));
CPPUNIT_ASSERT(st.store(foxtrot));
CPPUNIT_ASSERT(st.store(golf));
CPPUNIT_ASSERT(st.store(hotel1));
CPPUNIT_ASSERT(st.store(hotel2));
CPPUNIT_ASSERT(st.store(hotel3));
CPPUNIT_ASSERT(st.store(hotel4));
CPPUNIT_ASSERT(st.store(india1));
CPPUNIT_ASSERT(st.store(india2));
CPPUNIT_ASSERT(st.store(juliet1));
CPPUNIT_ASSERT(st.store(juliet2));
CPPUNIT_ASSERT(st.store(alpha, now));
CPPUNIT_ASSERT(st.store(bravo, now));
CPPUNIT_ASSERT(st.store(charlie, now));
CPPUNIT_ASSERT(st.store(delta, now));
CPPUNIT_ASSERT(st.store(echo, now));
CPPUNIT_ASSERT(st.store(foxtrot, now));
CPPUNIT_ASSERT(st.store(golf, now));
CPPUNIT_ASSERT(st.store(hotel1, now));
CPPUNIT_ASSERT(st.store(hotel2, now));
CPPUNIT_ASSERT(st.store(hotel3, now));
CPPUNIT_ASSERT(st.store(hotel4, now));
CPPUNIT_ASSERT(st.store(india1, now));
CPPUNIT_ASSERT(st.store(india2, now));
CPPUNIT_ASSERT(st.store(juliet1, now));
std::vector<Cookie> aria2Slash = st.criteriaFind("www.dl.aria2.org", "/",
0, false);
@ -186,7 +185,7 @@ void CookieStorageTest::testCriteriaFind()
!= aria2SlashFoo.end());
std::vector<Cookie> aria2Expires = st.criteriaFind("www.dl.aria2.org", "/foo",
Time().getTime()+120,
1120,
false);
CPPUNIT_ASSERT_EQUAL((size_t)2, aria2Expires.size());
CPPUNIT_ASSERT(std::find(aria2Expires.begin(), aria2Expires.end(), alpha)
@ -220,23 +219,47 @@ void CookieStorageTest::testCriteriaFind()
defaultDomainCookies =
st.criteriaFind("sub.default.domain", "/foo", 0, false);
CPPUNIT_ASSERT_EQUAL((size_t)1, defaultDomainCookies.size());
CPPUNIT_ASSERT_EQUAL(std::string("INDIA2"),
defaultDomainCookies[0].getValue());
// localhost.local case
std::vector<Cookie> localDomainCookies =
st.criteriaFind("localhost", "/foo", 0, false);
CPPUNIT_ASSERT_EQUAL((size_t)2, localDomainCookies.size());
CPPUNIT_ASSERT_EQUAL((size_t)1, localDomainCookies.size());
CPPUNIT_ASSERT_EQUAL(std::string("JULIET1"),
localDomainCookies[0].getValue());
CPPUNIT_ASSERT_EQUAL(std::string("JULIET2"),
localDomainCookies[1].getValue());
}
void CookieStorageTest::testCriteriaFind_cookieOrder()
{
CookieStorage st;
Cookie a(createCookie("a", "0", "host", true, "/", false));
a.setCreationTime(1000);
Cookie b(createCookie("b", "0", "host", true, "/foo", false));
b.setCreationTime(5000);
Cookie c(createCookie("c", "0", "host", true, "/foo", false));
c.setCreationTime(4000);
Cookie d(createCookie("d", "0", "host", true, "/foo/bar", false));
d.setCreationTime(6000);
st.store(a, 0);
st.store(b, 0);
st.store(c, 0);
st.store(d, 0);
std::vector<Cookie> cookies = st.criteriaFind("host", "/foo/bar", 0, false);
CPPUNIT_ASSERT_EQUAL((size_t)4, cookies.size());
CPPUNIT_ASSERT_EQUAL(std::string("d"), cookies[0].getName());
CPPUNIT_ASSERT_EQUAL(std::string("c"), cookies[1].getName());
CPPUNIT_ASSERT_EQUAL(std::string("b"), cookies[2].getName());
CPPUNIT_ASSERT_EQUAL(std::string("a"), cookies[3].getName());
}
void CookieStorageTest::testLoad()
{
CookieStorage st;
st.load("nscookietest.txt");
st.load("nscookietest.txt", 1001);
CPPUNIT_ASSERT_EQUAL((size_t)4, st.size());
@ -244,72 +267,71 @@ void CookieStorageTest::testLoad()
dumpCookie(cookies, st);
Cookie c = cookies[0];
CPPUNIT_ASSERT_EQUAL(std::string("novalue"), c.getName());
CPPUNIT_ASSERT_EQUAL(std::string(""), c.getValue());
CPPUNIT_ASSERT_EQUAL((time_t)2147483647, c.getExpiry());
CPPUNIT_ASSERT_EQUAL(std::string("/"), c.getPath());
CPPUNIT_ASSERT_EQUAL(std::string(".example.org"), c.getDomain());
CPPUNIT_ASSERT(!c.isSecureCookie());
c = cookies[1];
CPPUNIT_ASSERT_EQUAL(std::string("JSESSIONID"), c.getName());
CPPUNIT_ASSERT_EQUAL(std::string("123456789"), c.getValue());
CPPUNIT_ASSERT_EQUAL((time_t)2147483647, c.getExpiry());
CPPUNIT_ASSERT_EQUAL(std::string("/"), c.getPath());
CPPUNIT_ASSERT_EQUAL(std::string("localhost.local"), c.getDomain());
CPPUNIT_ASSERT(c.isSecureCookie());
c = cookies[2];
CPPUNIT_ASSERT_EQUAL(std::string("passwd"), c.getName());
CPPUNIT_ASSERT_EQUAL(std::string("secret"), c.getValue());
CPPUNIT_ASSERT_EQUAL((time_t)2147483647, c.getExpiry());
CPPUNIT_ASSERT_EQUAL((time_t)INT32_MAX, c.getExpiryTime());
CPPUNIT_ASSERT(!c.getPersistent());
CPPUNIT_ASSERT_EQUAL(std::string("/cgi-bin"), c.getPath());
CPPUNIT_ASSERT_EQUAL(std::string("localhost.local"), c.getDomain());
CPPUNIT_ASSERT(!c.isSecureCookie());
CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), c.getDomain());
CPPUNIT_ASSERT(c.getHostOnly());
CPPUNIT_ASSERT(!c.getSecure());
c = cookies[1];
CPPUNIT_ASSERT_EQUAL(std::string("novalue"), c.getName());
CPPUNIT_ASSERT_EQUAL(std::string(""), c.getValue());
CPPUNIT_ASSERT_EQUAL((time_t)2147483647, c.getExpiryTime());
CPPUNIT_ASSERT(c.getPersistent());
CPPUNIT_ASSERT_EQUAL(std::string("/"), c.getPath());
CPPUNIT_ASSERT_EQUAL(std::string("example.org"), c.getDomain());
CPPUNIT_ASSERT(!c.getHostOnly());
CPPUNIT_ASSERT(!c.getSecure());
c = cookies[2];
CPPUNIT_ASSERT_EQUAL(std::string("JSESSIONID"), c.getName());
CPPUNIT_ASSERT_EQUAL(std::string("123456789"), c.getValue());
CPPUNIT_ASSERT_EQUAL((time_t)2147483647, c.getExpiryTime());
CPPUNIT_ASSERT_EQUAL(std::string("/"), c.getPath());
CPPUNIT_ASSERT_EQUAL(std::string("localhost"), c.getDomain());
CPPUNIT_ASSERT(c.getHostOnly());
CPPUNIT_ASSERT(c.getSecure());
c = cookies[3];
CPPUNIT_ASSERT_EQUAL(std::string("TAX"), c.getName());
CPPUNIT_ASSERT_EQUAL(std::string("1000"), c.getValue());
CPPUNIT_ASSERT_EQUAL((time_t)2147483647, c.getExpiry());
CPPUNIT_ASSERT((time_t)INT32_MAX <= c.getExpiryTime());
CPPUNIT_ASSERT(c.getPersistent());
CPPUNIT_ASSERT_EQUAL(std::string("/"), c.getPath());
CPPUNIT_ASSERT_EQUAL(std::string("overflow.local"), c.getDomain());
CPPUNIT_ASSERT(!c.isSecureCookie());
CPPUNIT_ASSERT_EQUAL(std::string("overflow"), c.getDomain());
CPPUNIT_ASSERT(!c.getSecure());
}
void CookieStorageTest::testLoad_sqlite3()
{
CookieStorage st;
#ifdef HAVE_SQLITE3
st.load("cookies.sqlite");
CPPUNIT_ASSERT_EQUAL((size_t)3, st.size());
st.load("cookies.sqlite", 1000);
CPPUNIT_ASSERT_EQUAL((size_t)2, st.size());
std::vector<Cookie> cookies;
dumpCookie(cookies, st);
Cookie c = cookies[0];
CPPUNIT_ASSERT_EQUAL(std::string("uid"), c.getName());
CPPUNIT_ASSERT_EQUAL(std::string(""), c.getValue());
CPPUNIT_ASSERT_EQUAL((time_t)0, c.getExpiry());
CPPUNIT_ASSERT_EQUAL(std::string("/path/to"), c.getPath());
CPPUNIT_ASSERT_EQUAL(std::string(".null_value.com"), c.getDomain());
CPPUNIT_ASSERT(!c.isSecureCookie());
CPPUNIT_ASSERT(c.isSessionCookie());
CPPUNIT_ASSERT_EQUAL(std::string("JSESSIONID"), c.getName());
CPPUNIT_ASSERT_EQUAL(std::string("123456789"), c.getValue());
CPPUNIT_ASSERT_EQUAL((time_t)INT32_MAX, c.getExpiryTime());
CPPUNIT_ASSERT(c.getPersistent());
CPPUNIT_ASSERT_EQUAL(std::string("localhost"), c.getDomain());
CPPUNIT_ASSERT(c.getHostOnly());
CPPUNIT_ASSERT_EQUAL(std::string("/"), c.getPath());
CPPUNIT_ASSERT(c.getSecure());
c = cookies[1];
CPPUNIT_ASSERT_EQUAL(std::string("foo"), c.getName());
CPPUNIT_ASSERT_EQUAL(std::string("bar"), c.getValue());
CPPUNIT_ASSERT_EQUAL((time_t)2147483647, c.getExpiry());
CPPUNIT_ASSERT((time_t)INT32_MAX <= c.getExpiryTime());
CPPUNIT_ASSERT(c.getPersistent());
CPPUNIT_ASSERT_EQUAL(std::string("overflow.time_t.org"), c.getDomain());
CPPUNIT_ASSERT(!c.getHostOnly());
CPPUNIT_ASSERT_EQUAL(std::string("/path/to"), c.getPath());
CPPUNIT_ASSERT_EQUAL(std::string(".overflow.time_t.org"), c.getDomain());
CPPUNIT_ASSERT(!c.isSecureCookie());
CPPUNIT_ASSERT(!c.isSessionCookie());
c = cookies[2];
CPPUNIT_ASSERT_EQUAL(std::string("JSESSIONID"), c.getName());
CPPUNIT_ASSERT_EQUAL(std::string("123456789"), c.getValue());
CPPUNIT_ASSERT_EQUAL((time_t)2147483647, c.getExpiry());
CPPUNIT_ASSERT_EQUAL(std::string("/"), c.getPath());
CPPUNIT_ASSERT_EQUAL(std::string("localhost.local"), c.getDomain());
CPPUNIT_ASSERT(c.isSecureCookie());
CPPUNIT_ASSERT(!c.isSessionCookie());
CPPUNIT_ASSERT(!c.getSecure());
#else // !HAVE_SQLITE3
CPPUNIT_ASSERT(!st.load("cookies.sqlite"));
@ -319,7 +341,7 @@ void CookieStorageTest::testLoad_sqlite3()
void CookieStorageTest::testLoad_fileNotfound()
{
CookieStorage st;
CPPUNIT_ASSERT(!st.load("./aria2_CookieStorageTest_testLoad_fileNotfound"));
CPPUNIT_ASSERT(!st.load("./aria2_CookieStorageTest_testLoad_fileNotfound",0));
}
void CookieStorageTest::testSaveNsFormat()
@ -328,19 +350,20 @@ void CookieStorageTest::testSaveNsFormat()
std::string filename = "./aria2_CookieStorageTest_testSaveNsFormat";
File(filename).remove();
CookieStorage st;
st.store(Cookie("favorite","classic","/config",".domain.org",true));
st.store(Cookie("uid","tujikawa","/",".domain.org",false));
time_t now = 1000;
st.store(Cookie(createCookie("favorite", "classic", "domain.org", false,
"/config",true)), now);
st.store(Cookie(createCookie("uid", "tujikawa", now, "domain.org", true,
"/",false)), now);
st.saveNsFormat(filename);
CookieStorage loadst;
loadst.load(filename);
loadst.load(filename, now);
CPPUNIT_ASSERT_EQUAL((size_t)2, loadst.size());
std::vector<Cookie> cookies;
dumpCookie(cookies, loadst);
CPPUNIT_ASSERT_EQUAL(std::string("favorite"), cookies[0].getName());
CPPUNIT_ASSERT_EQUAL((time_t)0, cookies[0].getExpiry());
CPPUNIT_ASSERT(cookies[0].isSessionCookie());
CPPUNIT_ASSERT_EQUAL(std::string("uid"), cookies[1].getName());
}
@ -359,8 +382,9 @@ void CookieStorageTest::testCookieIsFull()
{
CookieStorage st;
for(size_t i = 0; i < CookieStorage::MAX_COOKIE_PER_DOMAIN+1; ++i) {
Cookie c("k"+util::itos(i), "v", "/", ".aria2.org", false);
st.store(c);
Cookie c(createCookie("k"+util::itos(i), "v", "aria2.org", false,
"/", false));
st.store(c, 0);
}
CPPUNIT_ASSERT_EQUAL((size_t)CookieStorage::MAX_COOKIE_PER_DOMAIN, st.size());
}
@ -371,8 +395,9 @@ void CookieStorageTest::testDomainIsFull()
// CookieStorage.cc
CookieStorage st;
for(size_t i = 0; i < 2001; ++i) {
Cookie c("k", "v", "/", "domain"+util::itos(i), false);
st.store(c);
Cookie c(createCookie("k", "v", "domain"+util::itos(i), true,
"/", false));
st.store(c, 0);
}
CPPUNIT_ASSERT_EQUAL((size_t)1801, st.size());
}

View File

@ -7,200 +7,108 @@
#include "Exception.h"
#include "util.h"
#include "TimeA2.h"
#include "TestUtil.h"
namespace aria2 {
class CookieTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(CookieTest);
CPPUNIT_TEST(testValidate);
CPPUNIT_TEST(testOperatorEqual);
CPPUNIT_TEST(testMatch);
CPPUNIT_TEST(testIsExpired);
CPPUNIT_TEST(testNormalizeDomain);
CPPUNIT_TEST(testToNsCookieFormat);
CPPUNIT_TEST(testMarkOriginServerOnly);
CPPUNIT_TEST_SUITE_END();
public:
void setUp() {}
void tearDown() {}
void testValidate();
void testOperatorEqual();
void testMatch();
void testIsExpired();
void testNormalizeDomain();
void testToNsCookieFormat();
void testMarkOriginServerOnly();
};
CPPUNIT_TEST_SUITE_REGISTRATION(CookieTest);
void CookieTest::testValidate()
{
{
Cookie defaultDomainPath("k", "v", "/", "localhost", false);
CPPUNIT_ASSERT(defaultDomainPath.validate("localhost", "/"));
}
{
Cookie domainStartsWithoutDot("k", "v", "/", "aria2.org", false);
CPPUNIT_ASSERT(domainStartsWithoutDot.validate("www.aria2.org", "/"));
Cookie domainStartsWithDot("k", "v", "/", ".aria2.org", false);
CPPUNIT_ASSERT(domainStartsWithDot.validate("www.aria2.org", "/"));
}
{
Cookie domainWithoutEmbeddedDot("k", "v", "/", ".org", false);
CPPUNIT_ASSERT(!domainWithoutEmbeddedDot.validate("aria2.org", "/"));
}
{
Cookie domainEndsWithDot("k", "v", "/", ".aria2.org.", false);
CPPUNIT_ASSERT(!domainEndsWithDot.validate("www.aria2.org", "/"));
}
{
Cookie domainHD("k", "v", "/", ".aria2.org", false);
CPPUNIT_ASSERT(!domainHD.validate("aria2.www.aria2.org", "/"));
}
{
Cookie pathNotStartsWith("k", "v", "/downloads", "localhost", false);
CPPUNIT_ASSERT(!pathNotStartsWith.validate("localhost", "/examples"));
}
{
Cookie pathStartsWith("k", "v", "/downloads", "localhost", false);
CPPUNIT_ASSERT(pathStartsWith.validate("localhost", "/downloads/latest/"));
}
{
Cookie pathSlash("k", "v", "/downloads", "localhost", false);
CPPUNIT_ASSERT(pathSlash.validate("localhost", "/downloads/"));
}
{
Cookie pathSlash("k", "v", "/downloads/", "localhost", false);
CPPUNIT_ASSERT(pathSlash.validate("localhost", "/downloads"));
}
{
Cookie pathNotMatch("k", "v", "/downloads", "localhost", false);
CPPUNIT_ASSERT(!pathNotMatch.validate("localhost", "/downloadss"));
}
{
Cookie pathNotMatch("k", "v", "/downloads/", "localhost", false);
CPPUNIT_ASSERT(!pathNotMatch.validate("localhost", "/downloadss"));
}
{
Cookie pathNotMatch("k", "v", "/downloads", "localhost", false);
CPPUNIT_ASSERT(!pathNotMatch.validate("localhost", "/downloadss/"));
}
{
Cookie nameEmpty("", "v", "/", "localhost", false);
CPPUNIT_ASSERT(!nameEmpty.validate("localhost", "/"));
}
{
Cookie fromNumericHost("k", "v", "/", "192.168.1.1", false);
CPPUNIT_ASSERT(fromNumericHost.validate("192.168.1.1", "/"));
CPPUNIT_ASSERT(!fromNumericHost.validate("www.aria2.org", "/"));
}
}
void CookieTest::testOperatorEqual()
{
Cookie a("k", "v", "/", "localhost", false);
Cookie b("k", "v", "/", "LOCALHOST", true);
Cookie wrongPath("k", "v", "/a", "localhost", false);
Cookie wrongDomain("k", "v", "/", "mydomain", false);
Cookie wrongName("h", "v", "/a", "localhost", false);
Cookie caseSensitiveName("K", "v", "/a", "localhost", false);
Cookie a(createCookie("k", "v", "localhost", true, "/", false));
Cookie b(createCookie("k", "v", "localhost", true, "/", true));
Cookie wrongPath(createCookie("k", "v", "localhost", true, "/a", false));
Cookie wrongDomain(createCookie("k", "v", "mydomain", true, "/", false));
Cookie wrongName(createCookie("h", "v", "localhost", true, "/a", false));
Cookie caseSensitiveName(createCookie("K", "v", "localhost", true,
"/a", false));
CPPUNIT_ASSERT(a == b);
CPPUNIT_ASSERT(!(a == wrongPath));
CPPUNIT_ASSERT(!(a == wrongDomain));
CPPUNIT_ASSERT(!(a == wrongName));
CPPUNIT_ASSERT(!(a == caseSensitiveName));
// normalize
Cookie n1("k", "v", "/", "localhost", false);
Cookie n2("k", "v", "/", ".localhost", false);
Cookie n3("k", "v", "/", "localhost.local", false);
Cookie n4("k", "v", "/", ".localhost.local", false);
CPPUNIT_ASSERT(n1 == n2);
CPPUNIT_ASSERT(n1 == n3);
CPPUNIT_ASSERT(n1 == n4);
}
void CookieTest::testMatch()
{
Cookie c("k", "v", "/downloads", ".aria2.org", false);
Cookie c2("k", "v", "/downloads/", ".aria2.org", false);
Cookie c3("k", "v", "/downloads/", "aria2.org", false);
Cookie c4("k", "v", "/downloads/", "localhost", false);
Cookie c(createCookie("k", "v", "aria2.org", false, "/downloads", false));
Cookie c2(createCookie("k", "v", "aria2.org", false, "/downloads", false));
Cookie c3(createCookie("k", "v", "aria2.org", true, "/downloads", false));
Cookie c4(createCookie("k", "v", "localhost", true, "/downloads", false));
CPPUNIT_ASSERT(c.match("www.aria2.org", "/downloads", 0, false));
CPPUNIT_ASSERT(c.match("www.aria2.org", "/downloads/", 0, false));
CPPUNIT_ASSERT(c2.match("www.aria2.org", "/downloads", 0, false));
CPPUNIT_ASSERT(c.match("WWW.ARIA2.ORG", "/downloads", 0, false));
CPPUNIT_ASSERT(!c.match("www.aria.org", "/downloads", 0, false));
CPPUNIT_ASSERT(!c.match("www.aria2.org", "/examples", 0, false));
CPPUNIT_ASSERT(c.match("www.aria2.org", "/downloads", 0, true));
CPPUNIT_ASSERT(c.match("www.aria2.org", "/downloads/latest", 0, false));
CPPUNIT_ASSERT(!c.match("www.aria2.org", "/downloadss/latest", 0, false));
CPPUNIT_ASSERT(!c.match("www.aria2.org", "/DOWNLOADS", 0, false));
CPPUNIT_ASSERT(c3.match("www.aria2.org", "/downloads", 0, false));
CPPUNIT_ASSERT(!c3.match("www.aria2.org", "/downloads", 0, false));
CPPUNIT_ASSERT(c4.match("localhost", "/downloads", 0, false));
Cookie secureCookie("k", "v", "/", "secure.aria2.org", true);
Cookie secureCookie(createCookie("k", "v", "secure.aria2.org", false,
"/", true));
CPPUNIT_ASSERT(secureCookie.match("secure.aria2.org", "/", 0, true));
CPPUNIT_ASSERT(!secureCookie.match("secure.aria2.org", "/", 0, false));
CPPUNIT_ASSERT(!secureCookie.match("ssecure.aria2.org", "/", 0, true));
CPPUNIT_ASSERT(secureCookie.match("www.secure.aria2.org", "/", 0, true));
Cookie expireTest("k", "v", 1000, "/", ".aria2.org", false);
Cookie expireTest(createCookie("k", "v", 1000, "aria2.org", false,
"/", false));
CPPUNIT_ASSERT(expireTest.match("www.aria2.org", "/", 999, false));
CPPUNIT_ASSERT(!expireTest.match("www.aria2.org", "/", 1000, false));
CPPUNIT_ASSERT(expireTest.match("www.aria2.org", "/", 1000, false));
CPPUNIT_ASSERT(!expireTest.match("www.aria2.org", "/", 1001, false));
Cookie fromNumericHost("k", "v", "/", "192.168.1.1", false);
CPPUNIT_ASSERT(fromNumericHost.match("192.168.1.1", "/", 0, false));
CPPUNIT_ASSERT(!fromNumericHost.match("www.aria2.org", "/", 0, false));
Cookie fromNumericHost(createCookie("k", "v", "192.168.1.1", true,
"/foo", false));
CPPUNIT_ASSERT(fromNumericHost.match("192.168.1.1", "/foo", 0, false));
CPPUNIT_ASSERT(!fromNumericHost.match("www.aria2.org", "/foo", 0, false));
CPPUNIT_ASSERT(!fromNumericHost.match("1.192.168.1.1", "/foo", 0, false));
CPPUNIT_ASSERT(!fromNumericHost.match("192.168.1.1", "/", 0, false));
}
void CookieTest::testIsExpired()
{
Cookie expiredCookie("k", "v", 1000, "/", "localhost", false);
CPPUNIT_ASSERT(expiredCookie.isExpired());
Cookie validCookie("k", "v", Time().getTime()+60, "/", "localhost", false);
CPPUNIT_ASSERT(!validCookie.isExpired());
Cookie sessionCookie("k", "v", "/", "localhost", false);
CPPUNIT_ASSERT(!sessionCookie.isExpired());
Cookie sessionCookie2("k", "v", 0, "/", "localhost", false);
CPPUNIT_ASSERT(!sessionCookie2.isExpired());
}
void CookieTest::testNormalizeDomain()
{
Cookie dot("k", "v", "/", ".", false);
CPPUNIT_ASSERT_EQUAL(std::string("..local"), dot.getDomain());
Cookie ip("k", "v", "/", "192.168.1.1", false);
CPPUNIT_ASSERT_EQUAL(std::string("192.168.1.1"), ip.getDomain());
Cookie ipv6("k", "v", "/", "::1", false);
CPPUNIT_ASSERT_EQUAL(std::string("::1"), ipv6.getDomain());
Cookie cookie(createCookie("k", "v", 1000, "localhost", true,
"/", false));
CPPUNIT_ASSERT(cookie.isExpired(1001));
CPPUNIT_ASSERT(!cookie.isExpired(1000));
CPPUNIT_ASSERT(!cookie.isExpired(999));
Cookie sessionCookie(createCookie("k", "v", "localhost", true, "/", false));
CPPUNIT_ASSERT(!sessionCookie.isExpired(INT32_MAX));
}
void CookieTest::testToNsCookieFormat()
{
CPPUNIT_ASSERT_EQUAL
(std::string(".domain.org\tTRUE\t/\tFALSE\t12345678\thello\tworld"),
Cookie("hello","world",12345678,"/",".domain.org",false).toNsCookieFormat());
// Session cookie's expiry is 0
createCookie("hello", "world", 12345678, "domain.org", false, "/",false)
.toNsCookieFormat());
// Session cookie
CPPUNIT_ASSERT_EQUAL
(std::string(".domain.org\tTRUE\t/\tTRUE\t0\thello\tworld"),
Cookie("hello","world","/","domain.org",true).toNsCookieFormat());
}
void CookieTest::testMarkOriginServerOnly()
{
Cookie c("k", "v", "/", "aria2.sf.net", false);
c.markOriginServerOnly();
CPPUNIT_ASSERT_EQUAL(std::string("aria2.sf.net"), c.getDomain());
Cookie ip("k", "v", "/", "192.168.0.1", false);
ip.markOriginServerOnly();
CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), ip.getDomain());
(std::string("domain.org\tFALSE\t/\tTRUE\t0\thello\tworld"),
createCookie("hello", "world", "domain.org", true, "/", true)
.toNsCookieFormat());
}
} // namespace aria2

View File

@ -15,6 +15,7 @@
#include "CookieStorage.h"
#include "util.h"
#include "AuthConfig.h"
#include "TestUtil.h"
namespace aria2 {
@ -380,16 +381,21 @@ void HttpRequestTest::testCreateRequest_with_cookie()
(new PiecedSegment(1024*1024, p));
SharedHandle<FileEntry> fileEntry(new FileEntry("file", 1024*1024*10, 0));
Cookie cookie1("name1", "value1", "/archives", "localhost", false);
Cookie cookie2("name2", "value2", "/archives/download", "localhost", false);
Cookie cookie3("name3", "value3", "/archives/download", ".aria2.org", false);
Cookie cookie4("name4", "value4", "/archives/", ".aria2.org", true);
Cookie cookie1(createCookie("name1", "value1", "localhost", true,
"/archives", false));
Cookie cookie2(createCookie("name2", "value2", "localhost", true,
"/archives/download", false));
Cookie cookie3(createCookie("name3", "value3", "aria2.org", false,
"/archives/download", false));
Cookie cookie4(createCookie("name4", "value4", "aria2.org", false,
"/archives/", true));
time_t now = time(0);
SharedHandle<CookieStorage> st(new CookieStorage());
CPPUNIT_ASSERT(st->store(cookie1));
CPPUNIT_ASSERT(st->store(cookie2));
CPPUNIT_ASSERT(st->store(cookie3));
CPPUNIT_ASSERT(st->store(cookie4));
CPPUNIT_ASSERT(st->store(cookie1, now));
CPPUNIT_ASSERT(st->store(cookie2, now));
CPPUNIT_ASSERT(st->store(cookie3, now));
CPPUNIT_ASSERT(st->store(cookie4, now));
HttpRequest httpRequest;

View File

@ -22,7 +22,6 @@ aria2c_SOURCES = AllTest.cc\
UriListParserTest.cc\
HttpHeaderProcessorTest.cc\
RequestTest.cc\
CookieParserTest.cc\
HttpRequestTest.cc\
RequestGroupManTest.cc\
AuthConfigFactoryTest.cc\
@ -75,7 +74,8 @@ aria2c_SOURCES = AllTest.cc\
ChunkedDecodingStreamFilterTest.cc\
UriTest.cc\
MockSegment.h\
TripletTest.cc
TripletTest.cc\
CookieHelperTest.cc
if ENABLE_XML_RPC
aria2c_SOURCES += XmlRpcRequestParserControllerTest.cc\

View File

@ -193,17 +193,16 @@ am__aria2c_SOURCES_DIST = AllTest.cc TestUtil.cc TestUtil.h \
DefaultBtProgressInfoFileTest.cc RequestGroupTest.cc \
PStringBuildVisitorTest.cc ParameterizedStringParserTest.cc \
UtilTest.cc AlphaNumberDecoratorTest.cc UriListParserTest.cc \
HttpHeaderProcessorTest.cc RequestTest.cc CookieParserTest.cc \
HttpRequestTest.cc RequestGroupManTest.cc \
AuthConfigFactoryTest.cc NetrcAuthResolverTest.cc \
DefaultAuthResolverTest.cc OptionHandlerTest.cc \
SegmentManTest.cc BitfieldManTest.cc NetrcTest.cc \
SingletonHolderTest.cc HttpHeaderTest.cc HttpResponseTest.cc \
SharedHandleTest.cc FileTest.cc OptionTest.cc \
DefaultDiskWriterTest.cc FeatureConfigTest.cc SpeedCalcTest.cc \
MultiDiskAdaptorTest.cc MultiFileAllocationIteratorTest.cc \
FixedNumberRandomizer.h ProtocolDetectorTest.cc \
StringFormatTest.cc ExceptionTest.cc \
HttpHeaderProcessorTest.cc RequestTest.cc HttpRequestTest.cc \
RequestGroupManTest.cc AuthConfigFactoryTest.cc \
NetrcAuthResolverTest.cc DefaultAuthResolverTest.cc \
OptionHandlerTest.cc SegmentManTest.cc BitfieldManTest.cc \
NetrcTest.cc SingletonHolderTest.cc HttpHeaderTest.cc \
HttpResponseTest.cc SharedHandleTest.cc FileTest.cc \
OptionTest.cc DefaultDiskWriterTest.cc FeatureConfigTest.cc \
SpeedCalcTest.cc MultiDiskAdaptorTest.cc \
MultiFileAllocationIteratorTest.cc FixedNumberRandomizer.h \
ProtocolDetectorTest.cc StringFormatTest.cc ExceptionTest.cc \
DownloadHandlerFactoryTest.cc SignatureTest.cc \
ServerStatManTest.cc FeedbackURISelectorTest.cc \
InOrderURISelectorTest.cc ServerStatTest.cc \
@ -216,7 +215,8 @@ am__aria2c_SOURCES_DIST = AllTest.cc TestUtil.cc TestUtil.h \
bitfieldTest.cc DownloadContextTest.cc \
SessionSerializerTest.cc ValueBaseTest.cc \
ChunkedDecodingStreamFilterTest.cc UriTest.cc MockSegment.h \
TripletTest.cc XmlRpcRequestParserControllerTest.cc \
TripletTest.cc CookieHelperTest.cc \
XmlRpcRequestParserControllerTest.cc \
XmlRpcRequestProcessorTest.cc XmlRpcMethodTest.cc \
FallocFileAllocationIteratorTest.cc GZipDecoderTest.cc \
GZipEncoderTest.cc GZipDecodingStreamFilterTest.cc \
@ -384,8 +384,8 @@ am_aria2c_OBJECTS = AllTest.$(OBJEXT) TestUtil.$(OBJEXT) \
ParameterizedStringParserTest.$(OBJEXT) UtilTest.$(OBJEXT) \
AlphaNumberDecoratorTest.$(OBJEXT) UriListParserTest.$(OBJEXT) \
HttpHeaderProcessorTest.$(OBJEXT) RequestTest.$(OBJEXT) \
CookieParserTest.$(OBJEXT) HttpRequestTest.$(OBJEXT) \
RequestGroupManTest.$(OBJEXT) AuthConfigFactoryTest.$(OBJEXT) \
HttpRequestTest.$(OBJEXT) RequestGroupManTest.$(OBJEXT) \
AuthConfigFactoryTest.$(OBJEXT) \
NetrcAuthResolverTest.$(OBJEXT) \
DefaultAuthResolverTest.$(OBJEXT) OptionHandlerTest.$(OBJEXT) \
SegmentManTest.$(OBJEXT) BitfieldManTest.$(OBJEXT) \
@ -412,9 +412,10 @@ am_aria2c_OBJECTS = AllTest.$(OBJEXT) TestUtil.$(OBJEXT) \
DownloadContextTest.$(OBJEXT) SessionSerializerTest.$(OBJEXT) \
ValueBaseTest.$(OBJEXT) \
ChunkedDecodingStreamFilterTest.$(OBJEXT) UriTest.$(OBJEXT) \
TripletTest.$(OBJEXT) $(am__objects_1) $(am__objects_2) \
$(am__objects_3) $(am__objects_4) $(am__objects_5) \
$(am__objects_6) $(am__objects_7)
TripletTest.$(OBJEXT) CookieHelperTest.$(OBJEXT) \
$(am__objects_1) $(am__objects_2) $(am__objects_3) \
$(am__objects_4) $(am__objects_5) $(am__objects_6) \
$(am__objects_7)
aria2c_OBJECTS = $(am_aria2c_OBJECTS)
am__DEPENDENCIES_1 =
aria2c_DEPENDENCIES = ../src/libaria2c.a $(am__DEPENDENCIES_1)
@ -626,17 +627,16 @@ aria2c_SOURCES = AllTest.cc TestUtil.cc TestUtil.h SocketCoreTest.cc \
DefaultBtProgressInfoFileTest.cc RequestGroupTest.cc \
PStringBuildVisitorTest.cc ParameterizedStringParserTest.cc \
UtilTest.cc AlphaNumberDecoratorTest.cc UriListParserTest.cc \
HttpHeaderProcessorTest.cc RequestTest.cc CookieParserTest.cc \
HttpRequestTest.cc RequestGroupManTest.cc \
AuthConfigFactoryTest.cc NetrcAuthResolverTest.cc \
DefaultAuthResolverTest.cc OptionHandlerTest.cc \
SegmentManTest.cc BitfieldManTest.cc NetrcTest.cc \
SingletonHolderTest.cc HttpHeaderTest.cc HttpResponseTest.cc \
SharedHandleTest.cc FileTest.cc OptionTest.cc \
DefaultDiskWriterTest.cc FeatureConfigTest.cc SpeedCalcTest.cc \
MultiDiskAdaptorTest.cc MultiFileAllocationIteratorTest.cc \
FixedNumberRandomizer.h ProtocolDetectorTest.cc \
StringFormatTest.cc ExceptionTest.cc \
HttpHeaderProcessorTest.cc RequestTest.cc HttpRequestTest.cc \
RequestGroupManTest.cc AuthConfigFactoryTest.cc \
NetrcAuthResolverTest.cc DefaultAuthResolverTest.cc \
OptionHandlerTest.cc SegmentManTest.cc BitfieldManTest.cc \
NetrcTest.cc SingletonHolderTest.cc HttpHeaderTest.cc \
HttpResponseTest.cc SharedHandleTest.cc FileTest.cc \
OptionTest.cc DefaultDiskWriterTest.cc FeatureConfigTest.cc \
SpeedCalcTest.cc MultiDiskAdaptorTest.cc \
MultiFileAllocationIteratorTest.cc FixedNumberRandomizer.h \
ProtocolDetectorTest.cc StringFormatTest.cc ExceptionTest.cc \
DownloadHandlerFactoryTest.cc SignatureTest.cc \
ServerStatManTest.cc FeedbackURISelectorTest.cc \
InOrderURISelectorTest.cc ServerStatTest.cc \
@ -649,9 +649,9 @@ aria2c_SOURCES = AllTest.cc TestUtil.cc TestUtil.h SocketCoreTest.cc \
bitfieldTest.cc DownloadContextTest.cc \
SessionSerializerTest.cc ValueBaseTest.cc \
ChunkedDecodingStreamFilterTest.cc UriTest.cc MockSegment.h \
TripletTest.cc $(am__append_1) $(am__append_2) $(am__append_3) \
$(am__append_4) $(am__append_5) $(am__append_6) \
$(am__append_7)
TripletTest.cc CookieHelperTest.cc $(am__append_1) \
$(am__append_2) $(am__append_3) $(am__append_4) \
$(am__append_5) $(am__append_6) $(am__append_7)
#aria2c_CXXFLAGS = ${CPPUNIT_CFLAGS} -I../src -I../lib -Wall -D_FILE_OFFSET_BITS=64
#aria2c_LDFLAGS = ${CPPUNIT_LIBS}
@ -783,7 +783,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtUnchokeMessageTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ByteArrayDiskWriterTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ChunkedDecodingStreamFilterTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CookieParserTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CookieHelperTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CookieStorageTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CookieTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHKeyExchangeTest.Po@am__quote@

View File

@ -6,6 +6,7 @@
#include "RecoverableException.h"
#include "util.h"
#include "Cookie.h"
namespace aria2 {
@ -30,50 +31,67 @@ CPPUNIT_TEST_SUITE_REGISTRATION(NsCookieParserTest);
void NsCookieParserTest::testParse()
{
NsCookieParser parser;
std::vector<Cookie> cookies = parser.parse("nscookietest.txt");
time_t now = 0;
std::vector<Cookie> cookies = parser.parse("nscookietest.txt", now);
CPPUNIT_ASSERT_EQUAL((size_t)5, cookies.size());
Cookie c = cookies[0];
CPPUNIT_ASSERT_EQUAL(std::string("JSESSIONID"), c.getName());
CPPUNIT_ASSERT_EQUAL(std::string("123456789"), c.getValue());
CPPUNIT_ASSERT_EQUAL((time_t)2147483647, c.getExpiry());
CPPUNIT_ASSERT_EQUAL((time_t)INT32_MAX, c.getExpiryTime());
CPPUNIT_ASSERT(c.getPersistent());
CPPUNIT_ASSERT_EQUAL(std::string("localhost"), c.getDomain());
CPPUNIT_ASSERT(c.getHostOnly());
CPPUNIT_ASSERT_EQUAL(std::string("/"), c.getPath());
CPPUNIT_ASSERT_EQUAL(std::string("localhost.local"), c.getDomain());
CPPUNIT_ASSERT(c.getSecure());
c = cookies[1];
CPPUNIT_ASSERT_EQUAL(std::string("user"), c.getName());
CPPUNIT_ASSERT_EQUAL(std::string("me"), c.getValue());
CPPUNIT_ASSERT_EQUAL((time_t)1181473200, c.getExpiry());
CPPUNIT_ASSERT_EQUAL((time_t)1000, c.getExpiryTime());
CPPUNIT_ASSERT(c.getPersistent());
CPPUNIT_ASSERT_EQUAL(std::string("expired"), c.getDomain());
CPPUNIT_ASSERT(c.getHostOnly());
CPPUNIT_ASSERT_EQUAL(std::string("/"), c.getPath());
CPPUNIT_ASSERT_EQUAL(std::string("expired.local"), c.getDomain());
CPPUNIT_ASSERT(!c.getSecure());
c = cookies[2];
CPPUNIT_ASSERT_EQUAL(std::string("passwd"), c.getName());
CPPUNIT_ASSERT_EQUAL(std::string("secret"), c.getValue());
CPPUNIT_ASSERT_EQUAL((time_t)2147483647, c.getExpiry());
CPPUNIT_ASSERT_EQUAL((time_t)INT32_MAX, c.getExpiryTime());
CPPUNIT_ASSERT(!c.getPersistent());
CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), c.getDomain());
CPPUNIT_ASSERT(c.getHostOnly());
CPPUNIT_ASSERT_EQUAL(std::string("/cgi-bin"), c.getPath());
CPPUNIT_ASSERT_EQUAL(std::string("localhost.local"), c.getDomain());
CPPUNIT_ASSERT(!c.getSecure());
c = cookies[3];
CPPUNIT_ASSERT_EQUAL(std::string("TAX"), c.getName());
CPPUNIT_ASSERT_EQUAL(std::string("1000"), c.getValue());
CPPUNIT_ASSERT_EQUAL((time_t)2147483647, c.getExpiry());
CPPUNIT_ASSERT((time_t)INT32_MAX <= c.getExpiryTime());
CPPUNIT_ASSERT(c.getPersistent());
CPPUNIT_ASSERT_EQUAL(std::string("overflow"), c.getDomain());
CPPUNIT_ASSERT(c.getHostOnly());
CPPUNIT_ASSERT_EQUAL(std::string("/"), c.getPath());
CPPUNIT_ASSERT_EQUAL(std::string("overflow.local"), c.getDomain());
CPPUNIT_ASSERT(!c.getSecure());
c = cookies[4];
CPPUNIT_ASSERT_EQUAL(std::string("novalue"), c.getName());
CPPUNIT_ASSERT_EQUAL(std::string(""), c.getValue());
CPPUNIT_ASSERT_EQUAL((time_t)2147483647, c.getExpiry());
CPPUNIT_ASSERT_EQUAL((time_t)INT32_MAX, c.getExpiryTime());
CPPUNIT_ASSERT(c.getPersistent());
CPPUNIT_ASSERT_EQUAL(std::string("example.org"), c.getDomain());
CPPUNIT_ASSERT(!c.getHostOnly());
CPPUNIT_ASSERT_EQUAL(std::string("/"), c.getPath());
CPPUNIT_ASSERT_EQUAL(std::string(".example.org"), c.getDomain());
CPPUNIT_ASSERT(!c.getSecure());
}
void NsCookieParserTest::testParse_fileNotFound()
{
NsCookieParser parser;
try {
parser.parse("fileNotFound");
time_t now = 0;
parser.parse("fileNotFound", now);
CPPUNIT_FAIL("exception must be thrown.");
} catch(RecoverableException& e) {
// SUCCESS

View File

@ -35,35 +35,43 @@ void Sqlite3CookieParserTest::testMozParse()
{
Sqlite3MozCookieParser parser("cookies.sqlite");
std::vector<Cookie> cookies;
parser.parse(cookies);
parser.parse(cookies, 0);
CPPUNIT_ASSERT_EQUAL((size_t)3, cookies.size());
const Cookie& localhost = cookies[0];
CPPUNIT_ASSERT_EQUAL(std::string("localhost.local"), localhost.getDomain());
CPPUNIT_ASSERT_EQUAL(std::string("/"), localhost.getPath());
CPPUNIT_ASSERT_EQUAL(std::string("JSESSIONID"), localhost.getName());
CPPUNIT_ASSERT_EQUAL(std::string("123456789"), localhost.getValue());
CPPUNIT_ASSERT_EQUAL((time_t)INT32_MAX, localhost.getExpiry());
CPPUNIT_ASSERT_EQUAL(true, localhost.isSecureCookie());
CPPUNIT_ASSERT_EQUAL((time_t)INT32_MAX, localhost.getExpiryTime());
CPPUNIT_ASSERT(localhost.getPersistent());
CPPUNIT_ASSERT_EQUAL(std::string("localhost"), localhost.getDomain());
CPPUNIT_ASSERT(localhost.getHostOnly());
CPPUNIT_ASSERT_EQUAL(std::string("/"), localhost.getPath());
CPPUNIT_ASSERT(localhost.getSecure());
const Cookie& nullValue = cookies[1];
CPPUNIT_ASSERT_EQUAL(std::string(".null_value.com"), nullValue.getDomain());
CPPUNIT_ASSERT_EQUAL(std::string("/path/to"), nullValue.getPath());
CPPUNIT_ASSERT_EQUAL(std::string("uid"), nullValue.getName());
CPPUNIT_ASSERT_EQUAL(std::string(""), nullValue.getValue());
CPPUNIT_ASSERT_EQUAL((time_t)0, nullValue.getExpiry());
CPPUNIT_ASSERT_EQUAL(false, nullValue.isSecureCookie());
CPPUNIT_ASSERT_EQUAL((time_t)0, nullValue.getExpiryTime());
CPPUNIT_ASSERT(nullValue.getPersistent());
CPPUNIT_ASSERT_EQUAL(std::string("null_value.com"), nullValue.getDomain());
CPPUNIT_ASSERT(!nullValue.getHostOnly());
CPPUNIT_ASSERT_EQUAL(std::string("/path/to"), nullValue.getPath());
CPPUNIT_ASSERT(!nullValue.getSecure());
// See row id=3 has no name, so it is skipped.
const Cookie& overflowTime = cookies[2];
CPPUNIT_ASSERT_EQUAL(std::string(".overflow.time_t.org"),
overflowTime.getDomain());
CPPUNIT_ASSERT_EQUAL(std::string("/path/to"), overflowTime.getPath());
CPPUNIT_ASSERT_EQUAL(std::string("foo"), overflowTime.getName());
CPPUNIT_ASSERT_EQUAL(std::string("bar"), overflowTime.getValue());
CPPUNIT_ASSERT_EQUAL((time_t)INT32_MAX, overflowTime.getExpiry());
CPPUNIT_ASSERT_EQUAL(false, overflowTime.isSecureCookie());
CPPUNIT_ASSERT((time_t)INT32_MAX <= overflowTime.getExpiryTime());
CPPUNIT_ASSERT(overflowTime.getPersistent());
CPPUNIT_ASSERT_EQUAL(std::string("overflow.time_t.org"),
overflowTime.getDomain());
CPPUNIT_ASSERT(!overflowTime.getHostOnly());
CPPUNIT_ASSERT_EQUAL(std::string("/path/to"), overflowTime.getPath());
CPPUNIT_ASSERT(!overflowTime.getSecure());
// See row id=5 has bad path, so it is skipped.
}
void Sqlite3CookieParserTest::testMozParse_fileNotFound()
@ -71,7 +79,7 @@ void Sqlite3CookieParserTest::testMozParse_fileNotFound()
Sqlite3MozCookieParser parser("fileNotFound");
try {
std::vector<Cookie> cookies;
parser.parse(cookies);
parser.parse(cookies, 0);
CPPUNIT_FAIL("exception must be thrown.");
} catch(RecoverableException& e) {
// SUCCESS
@ -85,7 +93,7 @@ void Sqlite3CookieParserTest::testMozParse_badfile()
Sqlite3MozCookieParser parser("badcookies.sqlite");
try {
std::vector<Cookie> cookies;
parser.parse(cookies);
parser.parse(cookies, 0);
CPPUNIT_FAIL("exception must be thrown.");
} catch(RecoverableException& e) {
// SUCCESS
@ -96,23 +104,33 @@ void Sqlite3CookieParserTest::testChromumParse()
{
Sqlite3ChromiumCookieParser parser("chromium_cookies.sqlite");
std::vector<Cookie> cookies;
parser.parse(cookies);
parser.parse(cookies, 0);
CPPUNIT_ASSERT_EQUAL((size_t)3, cookies.size());
const Cookie& sfnet = cookies[0];
CPPUNIT_ASSERT_EQUAL(std::string(".aria2.sourceforge.net"),
sfnet.getDomain());
CPPUNIT_ASSERT_EQUAL(std::string("/"), sfnet.getPath());
CPPUNIT_ASSERT_EQUAL(std::string("mykey"), sfnet.getName());
CPPUNIT_ASSERT_EQUAL(std::string("pass"), sfnet.getValue());
CPPUNIT_ASSERT_EQUAL((time_t)12345679, sfnet.getExpiry());
CPPUNIT_ASSERT_EQUAL(false, sfnet.isSecureCookie());
CPPUNIT_ASSERT_EQUAL((time_t)12345679, sfnet.getExpiryTime());
CPPUNIT_ASSERT(sfnet.getPersistent());
CPPUNIT_ASSERT_EQUAL(std::string("aria2.sourceforge.net"),
sfnet.getDomain());
CPPUNIT_ASSERT(!sfnet.getHostOnly());
CPPUNIT_ASSERT_EQUAL(std::string("/"), sfnet.getPath());
CPPUNIT_ASSERT(!sfnet.getSecure());
const Cookie& sfjp = cookies[1];
CPPUNIT_ASSERT_EQUAL(std::string(".aria2.sourceforge.jp"), sfjp.getDomain());
CPPUNIT_ASSERT_EQUAL(std::string("/profile"), sfjp.getPath());
CPPUNIT_ASSERT_EQUAL(std::string("myseckey"), sfjp.getName());
CPPUNIT_ASSERT_EQUAL(std::string("pass2"), sfjp.getValue());
CPPUNIT_ASSERT_EQUAL((time_t)0, sfjp.getExpiry());
CPPUNIT_ASSERT_EQUAL(true, sfjp.isSecureCookie());
CPPUNIT_ASSERT_EQUAL((time_t)0, sfjp.getExpiryTime());
CPPUNIT_ASSERT(sfjp.getPersistent());
CPPUNIT_ASSERT_EQUAL(std::string("aria2.sourceforge.jp"), sfjp.getDomain());
CPPUNIT_ASSERT(sfjp.getHostOnly());
CPPUNIT_ASSERT_EQUAL(std::string("/profile"), sfjp.getPath());
CPPUNIT_ASSERT(sfjp.getSecure());
const Cookie& localnet = cookies[2];
CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), localnet.getDomain());
CPPUNIT_ASSERT(sfjp.getHostOnly());
}
} // namespace aria2

View File

@ -12,6 +12,7 @@
#include "File.h"
#include "StringFormat.h"
#include "FatalException.h"
#include "Cookie.h"
namespace aria2 {
@ -45,4 +46,29 @@ std::string readFile(const std::string& path)
return ss.str();
}
};
Cookie createCookie
(const std::string& name,
const std::string& value,
const std::string& domain,
bool hostOnly,
const std::string& path,
bool secure)
{
return Cookie
(name, value, 0, false, domain, hostOnly, path, secure, false, 0);
}
Cookie createCookie
(const std::string& name,
const std::string& value,
time_t expiryTime,
const std::string& domain,
bool hostOnly,
const std::string& path,
bool secure)
{
return Cookie
(name, value, expiryTime, true, domain, hostOnly, path, secure, false, 0);
}
} // namespace aria2

View File

@ -22,4 +22,21 @@ public:
}
};
Cookie createCookie
(const std::string& name,
const std::string& value,
const std::string& domain,
bool hostOnly,
const std::string& path,
bool secure);
Cookie createCookie
(const std::string& name,
const std::string& value,
time_t expiryTime,
const std::string& domain,
bool hostOnly,
const std::string& path,
bool secure);
} // namespace aria2

View File

@ -55,7 +55,7 @@ public:
time_t lastAccess_;
LastAccess(time_t lastAccess):lastAccess_(lastAccess) {}
time_t getLastAccess() const
time_t getLastAccessTime() const
{
return lastAccess_;
}

Binary file not shown.

Binary file not shown.

View File

@ -1,9 +1,9 @@
# name=this is a omment line;
localhost FALSE / TRUE 2147483647 JSESSIONID 123456789
expired FALSE / FALSE 1181473200 user me
expired FALSE / FALSE 1000 user me
localhost FALSE /cgi-bin FALSE 2147483647 passwd secret
192.168.0.1 TRUE /cgi-bin FALSE 0 passwd secret
badformat
overflow FALSE / FALSE 9223372036854775807 TAX 1000
.example.org TRUE / FALSE 2147483648 novalue
.example.org TRUE / FALSE 2147483647 novalue