mirror of https://github.com/aria2/aria2
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.txtpull/1/head
parent
9b1280f7a3
commit
8b17d4b276
44
ChangeLog
44
ChangeLog
|
@ -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().
|
||||
|
|
214
src/Cookie.cc
214
src/Cookie.cc
|
@ -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
|
||||
|
|
159
src/Cookie.h
159
src/Cookie.h
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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\
|
||||
|
|
|
@ -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@
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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(×pec, 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(×pec);
|
||||
|
||||
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
|
|
@ -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
|
76
src/util.cc
76
src/util.cc
|
@ -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),
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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\
|
||||
|
|
|
@ -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@
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue