mirror of https://github.com/aria2/aria2
Rewrite CookieStorage
parent
0b1e05b13b
commit
5a223115e0
|
@ -43,23 +43,23 @@
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
Cookie::Cookie
|
Cookie::Cookie
|
||||||
(const std::string& name,
|
(std::string name,
|
||||||
const std::string& value,
|
std::string value,
|
||||||
time_t expiryTime,
|
time_t expiryTime,
|
||||||
bool persistent,
|
bool persistent,
|
||||||
const std::string& domain,
|
std::string domain,
|
||||||
bool hostOnly,
|
bool hostOnly,
|
||||||
const std::string& path,
|
std::string path,
|
||||||
bool secure,
|
bool secure,
|
||||||
bool httpOnly,
|
bool httpOnly,
|
||||||
time_t creationTime):
|
time_t creationTime):
|
||||||
name_(name),
|
name_(std::move(name)),
|
||||||
value_(value),
|
value_(std::move(value)),
|
||||||
expiryTime_(expiryTime),
|
expiryTime_(expiryTime),
|
||||||
persistent_(persistent),
|
persistent_(persistent),
|
||||||
domain_(domain),
|
domain_(std::move(domain)),
|
||||||
hostOnly_(hostOnly),
|
hostOnly_(hostOnly),
|
||||||
path_(path),
|
path_(std::move(path)),
|
||||||
secure_(secure),
|
secure_(secure),
|
||||||
httpOnly_(httpOnly),
|
httpOnly_(httpOnly),
|
||||||
creationTime_(creationTime),
|
creationTime_(creationTime),
|
||||||
|
@ -74,40 +74,6 @@ Cookie::Cookie():
|
||||||
creationTime_(0),
|
creationTime_(0),
|
||||||
lastAccessTime_(0) {}
|
lastAccessTime_(0) {}
|
||||||
|
|
||||||
Cookie::Cookie(const Cookie& c)
|
|
||||||
: name_(c.name_),
|
|
||||||
value_(c.value_),
|
|
||||||
expiryTime_(c.expiryTime_),
|
|
||||||
persistent_(c.persistent_),
|
|
||||||
domain_(c.domain_),
|
|
||||||
hostOnly_(c.hostOnly_),
|
|
||||||
path_(c.path_),
|
|
||||||
secure_(c.secure_),
|
|
||||||
httpOnly_(c.httpOnly_),
|
|
||||||
creationTime_(c.creationTime_),
|
|
||||||
lastAccessTime_(c.lastAccessTime_)
|
|
||||||
{}
|
|
||||||
|
|
||||||
Cookie::~Cookie() {}
|
|
||||||
|
|
||||||
Cookie& Cookie::operator=(const Cookie& c)
|
|
||||||
{
|
|
||||||
if(this != &c) {
|
|
||||||
name_ = c.name_;
|
|
||||||
value_ = c.value_;
|
|
||||||
expiryTime_ = c.expiryTime_;
|
|
||||||
persistent_ = c.persistent_;
|
|
||||||
domain_ = c.domain_;
|
|
||||||
hostOnly_ = c.hostOnly_;
|
|
||||||
path_ = c.path_;
|
|
||||||
secure_ = c.secure_;
|
|
||||||
httpOnly_ = c.httpOnly_;
|
|
||||||
creationTime_ = c.creationTime_;
|
|
||||||
lastAccessTime_ = c.lastAccessTime_;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Cookie::toString() const
|
std::string Cookie::toString() const
|
||||||
{
|
{
|
||||||
std::string s = name_;
|
std::string s = name_;
|
||||||
|
@ -138,6 +104,11 @@ bool Cookie::operator==(const Cookie& cookie) const
|
||||||
name_ == cookie.name_;
|
name_ == cookie.name_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Cookie::operator!=(const Cookie& cookie) const
|
||||||
|
{
|
||||||
|
return !(*this == cookie);
|
||||||
|
}
|
||||||
|
|
||||||
bool Cookie::isExpired(time_t base) const
|
bool Cookie::isExpired(time_t base) const
|
||||||
{
|
{
|
||||||
return persistent_ && base > expiryTime_;
|
return persistent_ && base > expiryTime_;
|
||||||
|
@ -174,24 +145,24 @@ std::string Cookie::toNsCookieFormat() const
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cookie::setName(const std::string& name)
|
void Cookie::setName(std::string name)
|
||||||
{
|
{
|
||||||
name_ = name;
|
name_ = std::move(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cookie::setValue(const std::string& value)
|
void Cookie::setValue(std::string value)
|
||||||
{
|
{
|
||||||
value_ = value;
|
value_ = std::move(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cookie::setDomain(const std::string& domain)
|
void Cookie::setDomain(std::string domain)
|
||||||
{
|
{
|
||||||
domain_ = domain;
|
domain_ = std::move(domain);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cookie::setPath(const std::string& path)
|
void Cookie::setPath(std::string path)
|
||||||
{
|
{
|
||||||
path_ = path;
|
path_ = std::move(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
24
src/Cookie.h
24
src/Cookie.h
|
@ -63,23 +63,17 @@ public:
|
||||||
Cookie();
|
Cookie();
|
||||||
|
|
||||||
Cookie
|
Cookie
|
||||||
(const std::string& name,
|
(std::string name,
|
||||||
const std::string& value,
|
std::string value,
|
||||||
time_t expiryTime,
|
time_t expiryTime,
|
||||||
bool persistent,
|
bool persistent,
|
||||||
const std::string& domain,
|
std::string domain,
|
||||||
bool hostOnly,
|
bool hostOnly,
|
||||||
const std::string& path,
|
std::string path,
|
||||||
bool secure,
|
bool secure,
|
||||||
bool httpOnly,
|
bool httpOnly,
|
||||||
time_t creationTime);
|
time_t creationTime);
|
||||||
|
|
||||||
Cookie(const Cookie& c);
|
|
||||||
|
|
||||||
~Cookie();
|
|
||||||
|
|
||||||
Cookie& operator=(const Cookie& c);
|
|
||||||
|
|
||||||
std::string toString() const;
|
std::string toString() const;
|
||||||
|
|
||||||
bool match
|
bool match
|
||||||
|
@ -88,6 +82,8 @@ public:
|
||||||
|
|
||||||
bool operator==(const Cookie& cookie) const;
|
bool operator==(const Cookie& cookie) const;
|
||||||
|
|
||||||
|
bool operator!=(const Cookie& cookie) const;
|
||||||
|
|
||||||
bool isExpired(time_t base) const;
|
bool isExpired(time_t base) const;
|
||||||
|
|
||||||
const std::string& getName() const
|
const std::string& getName() const
|
||||||
|
@ -95,7 +91,7 @@ public:
|
||||||
return name_;
|
return name_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setName(const std::string& name);
|
void setName(std::string name);
|
||||||
|
|
||||||
template<typename InputIterator>
|
template<typename InputIterator>
|
||||||
void setName(InputIterator first, InputIterator last)
|
void setName(InputIterator first, InputIterator last)
|
||||||
|
@ -108,7 +104,7 @@ public:
|
||||||
return value_;
|
return value_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setValue(const std::string& value);
|
void setValue(std::string value);
|
||||||
|
|
||||||
template<typename InputIterator>
|
template<typename InputIterator>
|
||||||
void setValue(InputIterator first, InputIterator last)
|
void setValue(InputIterator first, InputIterator last)
|
||||||
|
@ -141,7 +137,7 @@ public:
|
||||||
return domain_;
|
return domain_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setDomain(const std::string& domain);
|
void setDomain(std::string domain);
|
||||||
|
|
||||||
template<typename InputIterator>
|
template<typename InputIterator>
|
||||||
void setDomain(InputIterator first, InputIterator last)
|
void setDomain(InputIterator first, InputIterator last)
|
||||||
|
@ -164,7 +160,7 @@ public:
|
||||||
return path_;
|
return path_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setPath(const std::string& path);
|
void setPath(std::string path);
|
||||||
|
|
||||||
template<typename InputIterator>
|
template<typename InputIterator>
|
||||||
void setPath(InputIterator first, InputIterator last)
|
void setPath(InputIterator first, InputIterator last)
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/*
|
/*
|
||||||
* aria2 - The high speed download utility
|
* aria2 - The high speed download utility
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006 Tatsuhiro Tsujikawa
|
* Copyright (C) 2013 Tatsuhiro Tsujikawa
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -56,131 +56,196 @@
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
CookieStorage::DomainEntry::DomainEntry(const std::string& domain)
|
DomainNode::DomainNode(std::string label, DomainNode* parent)
|
||||||
: key_(util::isNumericHost(domain)?domain:cookie::reverseDomainLevel(domain)),
|
: label_{std::move(label)}, parent_{parent}, lastAccessTime_{0},
|
||||||
lastAccessTime_(0)
|
lruAccessTime_{0}, inLru_{false}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
CookieStorage::DomainEntry::DomainEntry
|
void DomainNode::findCookie
|
||||||
(const DomainEntry& c)
|
(std::vector<const Cookie*>& out,
|
||||||
: key_(c.key_),
|
|
||||||
lastAccessTime_(c.lastAccessTime_),
|
|
||||||
cookies_(c.cookies_)
|
|
||||||
{}
|
|
||||||
|
|
||||||
CookieStorage::DomainEntry::~DomainEntry() {}
|
|
||||||
|
|
||||||
CookieStorage::DomainEntry& CookieStorage::DomainEntry::operator=
|
|
||||||
(const DomainEntry& c)
|
|
||||||
{
|
|
||||||
if(this != &c) {
|
|
||||||
key_ = c.key_;
|
|
||||||
lastAccessTime_ = c.lastAccessTime_;
|
|
||||||
cookies_ = c.cookies_;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CookieStorage::DomainEntry::swap(CookieStorage::DomainEntry& c)
|
|
||||||
{
|
|
||||||
using std::swap;
|
|
||||||
swap(key_, c.key_);
|
|
||||||
swap(lastAccessTime_, c.lastAccessTime_);
|
|
||||||
swap(cookies_, c.cookies_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void swap(CookieStorage::DomainEntry& a, CookieStorage::DomainEntry& b)
|
|
||||||
{
|
|
||||||
a.swap(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CookieStorage::DomainEntry::findCookie
|
|
||||||
(std::vector<Cookie>& out,
|
|
||||||
const std::string& requestHost,
|
const std::string& requestHost,
|
||||||
const std::string& requestPath,
|
const std::string& requestPath,
|
||||||
time_t now, bool secure)
|
time_t now, bool secure)
|
||||||
{
|
{
|
||||||
for(std::deque<Cookie>::iterator i = cookies_.begin(),
|
if(cookies_) {
|
||||||
eoi = cookies_.end(); i != eoi; ++i) {
|
for(auto& c : *cookies_) {
|
||||||
if((*i).match(requestHost, requestPath, now, secure)) {
|
if(c->match(requestHost, requestPath, now, secure)) {
|
||||||
(*i).setLastAccessTime(now);
|
c->setLastAccessTime(now);
|
||||||
out.push_back(*i);
|
out.push_back(c.get());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CookieStorage::DomainEntry::addCookie(const Cookie& cookie, time_t now)
|
bool DomainNode::addCookie(std::unique_ptr<Cookie> cookie, time_t now)
|
||||||
{
|
{
|
||||||
using namespace std::placeholders;
|
using namespace std::placeholders;
|
||||||
setLastAccessTime(now);
|
setLastAccessTime(now);
|
||||||
std::deque<Cookie>::iterator i =
|
if(!cookies_) {
|
||||||
std::find(cookies_.begin(), cookies_.end(), cookie);
|
if(cookie->isExpired(now)) {
|
||||||
if(i == cookies_.end()) {
|
|
||||||
if(cookie.isExpired(now)) {
|
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
if(cookies_.size() >= CookieStorage::MAX_COOKIE_PER_DOMAIN) {
|
cookies_ = make_unique<std::deque<std::unique_ptr<Cookie>>>();
|
||||||
cookies_.erase
|
cookies_->push_back(std::move(cookie));
|
||||||
(std::remove_if(cookies_.begin(), cookies_.end(),
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto i = std::find_if(std::begin(*cookies_), std::end(*cookies_),
|
||||||
|
[&](const std::unique_ptr<Cookie>& c)
|
||||||
|
{
|
||||||
|
return *c == *cookie;
|
||||||
|
});
|
||||||
|
if(i == std::end(*cookies_)) {
|
||||||
|
if(cookie->isExpired(now)) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
if(cookies_->size() >= CookieStorage::MAX_COOKIE_PER_DOMAIN) {
|
||||||
|
cookies_->erase
|
||||||
|
(std::remove_if(std::begin(*cookies_), std::end(*cookies_),
|
||||||
std::bind(&Cookie::isExpired, _1, now)),
|
std::bind(&Cookie::isExpired, _1, now)),
|
||||||
cookies_.end());
|
std::end(*cookies_));
|
||||||
if(cookies_.size() >= CookieStorage::MAX_COOKIE_PER_DOMAIN) {
|
if(cookies_->size() >= CookieStorage::MAX_COOKIE_PER_DOMAIN) {
|
||||||
std::deque<Cookie>::iterator m = std::min_element
|
auto m = std::min_element(std::begin(*cookies_), std::end(*cookies_),
|
||||||
(cookies_.begin(), cookies_.end(), LeastRecentAccess<Cookie>());
|
[](const std::unique_ptr<Cookie>& lhs,
|
||||||
*m = cookie;
|
const std::unique_ptr<Cookie>& rhs)
|
||||||
|
{
|
||||||
|
return lhs->getLastAccessTime() <
|
||||||
|
rhs->getLastAccessTime();
|
||||||
|
});
|
||||||
|
*m = std::move(cookie);
|
||||||
} else {
|
} else {
|
||||||
cookies_.push_back(cookie);
|
cookies_->push_back(std::move(cookie));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cookies_.push_back(cookie);
|
cookies_->push_back(std::move(cookie));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if(cookie.isExpired(now)) {
|
} else if(cookie->isExpired(now)) {
|
||||||
cookies_.erase(i);
|
cookies_->erase(i);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
*i = cookie;
|
*i = std::move(cookie);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CookieStorage::DomainEntry::contains(const Cookie& cookie) const
|
bool DomainNode::contains(const Cookie& cookie) const
|
||||||
{
|
{
|
||||||
return std::find(cookies_.begin(), cookies_.end(), cookie) != cookies_.end();
|
if(cookies_) {
|
||||||
|
for(auto& i : *cookies_) {
|
||||||
|
if(*i == cookie) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CookieStorage::DomainEntry::writeCookie(BufferedFile& fp) const
|
bool DomainNode::writeCookie(BufferedFile& fp) const
|
||||||
{
|
{
|
||||||
for(std::deque<Cookie>::const_iterator i = cookies_.begin(),
|
if(cookies_) {
|
||||||
eoi = cookies_.end(); i != eoi; ++i) {
|
for(const auto& c : *cookies_) {
|
||||||
std::string data = (*i).toNsCookieFormat();
|
std::string data = c->toNsCookieFormat();
|
||||||
data += "\n";
|
data += "\n";
|
||||||
if(fp.write(data.data(), data.size()) != data.size()) {
|
if(fp.write(data.data(), data.size()) != data.size()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t CookieStorage::DomainEntry::countCookie() const
|
size_t DomainNode::countCookie() const
|
||||||
{
|
{
|
||||||
return cookies_.size();
|
if(cookies_) {
|
||||||
|
return cookies_->size();
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CookieStorage::DomainEntry::operator==(const DomainEntry& de) const
|
void DomainNode::clearCookie()
|
||||||
{
|
{
|
||||||
return key_ == de.key_;
|
cookies_->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CookieStorage::DomainEntry::operator<(const DomainEntry& de) const
|
void DomainNode::setLastAccessTime(time_t lastAccessTime)
|
||||||
{
|
{
|
||||||
return key_ < de.key_;
|
lastAccessTime_ = lastAccessTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
CookieStorage::CookieStorage() {}
|
time_t DomainNode::getLastAccessTime() const
|
||||||
|
{
|
||||||
|
return lastAccessTime_;
|
||||||
|
}
|
||||||
|
|
||||||
CookieStorage::~CookieStorage() {}
|
void DomainNode::setLruAccessTime(time_t t)
|
||||||
|
{
|
||||||
|
lruAccessTime_ = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
time_t DomainNode::getLruAccessTime() const
|
||||||
|
{
|
||||||
|
return lruAccessTime_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DomainNode::empty() const
|
||||||
|
{
|
||||||
|
return !cookies_ || cookies_->empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DomainNode::hasNext() const
|
||||||
|
{
|
||||||
|
return !next_.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
DomainNode* DomainNode::getParent() const
|
||||||
|
{
|
||||||
|
return parent_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DomainNode::removeNode(DomainNode* node)
|
||||||
|
{
|
||||||
|
next_.erase(node->getLabel());
|
||||||
|
}
|
||||||
|
|
||||||
|
DomainNode* DomainNode::findNext(const std::string& label) const
|
||||||
|
{
|
||||||
|
auto i = next_.find(label);
|
||||||
|
if(i == std::end(next_)) {
|
||||||
|
return nullptr;
|
||||||
|
} else {
|
||||||
|
return (*i).second.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DomainNode* DomainNode::addNext(std::string label,
|
||||||
|
std::unique_ptr<DomainNode> node)
|
||||||
|
{
|
||||||
|
auto& res = next_[std::move(label)] = std::move(node);
|
||||||
|
return res.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& DomainNode::getLabel() const
|
||||||
|
{
|
||||||
|
return label_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DomainNode::getInLru() const
|
||||||
|
{
|
||||||
|
return inLru_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DomainNode::setInLru(bool f)
|
||||||
|
{
|
||||||
|
inLru_ = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
CookieStorage::CookieStorage()
|
||||||
|
: rootNode_{make_unique<DomainNode>("", nullptr)}
|
||||||
|
{}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
// See CookieStorageTest::testDomainIsFull() in CookieStorageTest.cc
|
// See CookieStorageTest::testDomainIsFull() in CookieStorageTest.cc
|
||||||
|
@ -189,29 +254,86 @@ const size_t DOMAIN_EVICTION_TRIGGER = 2000;
|
||||||
const double DOMAIN_EVICTION_RATE = 0.1;
|
const double DOMAIN_EVICTION_RATE = 0.1;
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
bool CookieStorage::store(const Cookie& cookie, time_t now)
|
namespace {
|
||||||
|
std::vector<std::string> splitDomainLabel(const std::string& domain)
|
||||||
{
|
{
|
||||||
if(domains_.size() >= DOMAIN_EVICTION_TRIGGER) {
|
auto labels = std::vector<std::string>{};
|
||||||
std::vector<std::shared_ptr<DomainEntry> > evictions(domains_.begin(),
|
if(util::isNumericHost(domain)) {
|
||||||
domains_.end());
|
labels.push_back(domain);
|
||||||
std::sort(evictions.begin(), evictions.end(),
|
|
||||||
LeastRecentAccess<DomainEntry>());
|
|
||||||
size_t delnum = (size_t)(evictions.size()*DOMAIN_EVICTION_RATE);
|
|
||||||
domains_.clear();
|
|
||||||
domains_.insert(evictions.begin()+delnum, evictions.end());
|
|
||||||
}
|
|
||||||
std::shared_ptr<DomainEntry> v(new DomainEntry(cookie.getDomain()));
|
|
||||||
DomainEntrySet::iterator i = domains_.lower_bound(v);
|
|
||||||
bool added = false;
|
|
||||||
if(i != domains_.end() && *(*i) == *v) {
|
|
||||||
added = (*i)->addCookie(cookie, now);
|
|
||||||
} else {
|
} else {
|
||||||
added = v->addCookie(cookie, now);
|
util::split(std::begin(domain), std::end(domain),
|
||||||
if(added) {
|
std::back_inserter(labels), '.');
|
||||||
domains_.insert(i, v);
|
}
|
||||||
|
return labels;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
|
size_t CookieStorage::getLruTrackerSize() const
|
||||||
|
{
|
||||||
|
return lruTracker_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CookieStorage::evictNode(size_t delnum)
|
||||||
|
{
|
||||||
|
for(; delnum > 0 && !lruTracker_.empty(); --delnum) {
|
||||||
|
auto node = (*lruTracker_.begin()).second;
|
||||||
|
lruTracker_.erase(lruTracker_.begin());
|
||||||
|
node->setInLru(false);
|
||||||
|
node->clearCookie();
|
||||||
|
while(node->empty() && !node->hasNext()) {
|
||||||
|
auto parent = node->getParent();
|
||||||
|
parent->removeNode(node);
|
||||||
|
if(!parent->empty() || parent->hasNext() ||
|
||||||
|
parent == rootNode_.get()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
node = parent;
|
||||||
|
if(node->getInLru()) {
|
||||||
|
lruTracker_.erase({node->getLruAccessTime(), node});
|
||||||
|
node->setInLru(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return added;
|
}
|
||||||
|
|
||||||
|
const DomainNode* CookieStorage::getRootNode() const
|
||||||
|
{
|
||||||
|
return rootNode_.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CookieStorage::store(std::unique_ptr<Cookie> cookie, time_t now)
|
||||||
|
{
|
||||||
|
if(lruTracker_.size() >= DOMAIN_EVICTION_TRIGGER) {
|
||||||
|
auto delnum = size_t(lruTracker_.size()*DOMAIN_EVICTION_RATE);
|
||||||
|
evictNode(delnum);
|
||||||
|
}
|
||||||
|
auto labels = splitDomainLabel(cookie->getDomain());
|
||||||
|
auto node = rootNode_.get();
|
||||||
|
for(auto i = labels.rbegin(), eoi = labels.rend(); i != eoi; ++i) {
|
||||||
|
auto nextNode = node->findNext(*i);
|
||||||
|
if(nextNode) {
|
||||||
|
node = nextNode;
|
||||||
|
} else {
|
||||||
|
node = node->addNext(*i, make_unique<DomainNode>(*i, node));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool ok = node->addCookie(std::move(cookie), now);
|
||||||
|
if(ok) {
|
||||||
|
updateLru(node, now);
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CookieStorage::updateLru(DomainNode* node, time_t now)
|
||||||
|
{
|
||||||
|
if(node->getInLru()) {
|
||||||
|
lruTracker_.erase({node->getLruAccessTime(), node});
|
||||||
|
} else {
|
||||||
|
node->setInLru(true);
|
||||||
|
}
|
||||||
|
node->setLruAccessTime(now);
|
||||||
|
lruTracker_.insert({node->getLruAccessTime(), node});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CookieStorage::parseAndStore
|
bool CookieStorage::parseAndStore
|
||||||
|
@ -220,20 +342,17 @@ bool CookieStorage::parseAndStore
|
||||||
const std::string& defaultPath,
|
const std::string& defaultPath,
|
||||||
time_t now)
|
time_t now)
|
||||||
{
|
{
|
||||||
Cookie cookie;
|
auto cookie = cookie::parse(setCookieString, requestHost, defaultPath, now);
|
||||||
if(cookie::parse(cookie, setCookieString, requestHost, defaultPath, now)) {
|
return cookie && store(std::move(cookie), now);
|
||||||
return store(cookie, now);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
struct CookiePathDivider {
|
struct CookiePathDivider {
|
||||||
Cookie cookie_;
|
const Cookie* cookie_;
|
||||||
int pathDepth_;
|
int pathDepth_;
|
||||||
CookiePathDivider(const Cookie& cookie):cookie_(cookie), pathDepth_(0)
|
CookiePathDivider(const Cookie* cookie):cookie_(cookie), pathDepth_(0)
|
||||||
{
|
{
|
||||||
const std::string& path = cookie_.getPath();
|
const std::string& path = cookie_->getPath();
|
||||||
if(!path.empty()) {
|
if(!path.empty()) {
|
||||||
for(size_t i = 1, len = path.size(); i < len; ++i) {
|
for(size_t i = 1, len = path.size(); i < len; ++i) {
|
||||||
if(path[i] == '/' && path[i-1] != '/') {
|
if(path[i] == '/' && path[i-1] != '/') {
|
||||||
|
@ -246,16 +365,17 @@ struct CookiePathDivider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
class CookiePathDividerConverter {
|
class CookiePathDividerConverter {
|
||||||
public:
|
public:
|
||||||
CookiePathDivider operator()(const Cookie& cookie) const
|
CookiePathDivider operator()(const Cookie* cookie) const
|
||||||
{
|
{
|
||||||
return CookiePathDivider(cookie);
|
return CookiePathDivider(cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
Cookie operator()(const CookiePathDivider& cookiePathDivider) const
|
const Cookie* operator()(const CookiePathDivider& cookiePathDivider) const
|
||||||
{
|
{
|
||||||
return cookiePathDivider.cookie_;
|
return cookiePathDivider.cookie_;
|
||||||
}
|
}
|
||||||
|
@ -280,80 +400,69 @@ public:
|
||||||
// creation-times.
|
// creation-times.
|
||||||
return lhs.pathDepth_ > rhs.pathDepth_ ||
|
return lhs.pathDepth_ > rhs.pathDepth_ ||
|
||||||
(!(rhs.pathDepth_ > lhs.pathDepth_) &&
|
(!(rhs.pathDepth_ > lhs.pathDepth_) &&
|
||||||
lhs.cookie_.getCreationTime() < rhs.cookie_.getCreationTime());
|
lhs.cookie_->getCreationTime() < rhs.cookie_->getCreationTime());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void CookieStorage::searchCookieByDomainSuffix
|
namespace {
|
||||||
(std::vector<Cookie>& out,
|
DomainNode* findNode(const std::string& domain, DomainNode* node)
|
||||||
const std::string& domain,
|
|
||||||
const std::string& requestHost,
|
|
||||||
const std::string& requestPath,
|
|
||||||
time_t now, bool secure)
|
|
||||||
{
|
{
|
||||||
std::shared_ptr<DomainEntry> v(new DomainEntry(domain));
|
auto labels = splitDomainLabel(domain);
|
||||||
DomainEntrySet::iterator i = domains_.lower_bound(v);
|
for(auto i = labels.rbegin(), eoi = labels.rend(); i != eoi && node; ++i) {
|
||||||
if(i != domains_.end() && *(*i) == *v) {
|
node = node->findNext(*i);
|
||||||
(*i)->setLastAccessTime(now);
|
|
||||||
(*i)->findCookie(out, requestHost, requestPath, now, secure);
|
|
||||||
}
|
}
|
||||||
|
return node;
|
||||||
}
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
bool CookieStorage::contains(const Cookie& cookie) const
|
bool CookieStorage::contains(const Cookie& cookie) const
|
||||||
{
|
{
|
||||||
std::shared_ptr<DomainEntry> v(new DomainEntry(cookie.getDomain()));
|
auto node = findNode(cookie.getDomain(), rootNode_.get());
|
||||||
DomainEntrySet::iterator i = domains_.find(v);
|
return node && node->contains(cookie);
|
||||||
if(i != domains_.end()) {
|
|
||||||
return (*i)->contains(cookie);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Cookie> CookieStorage::criteriaFind
|
std::vector<const Cookie*> CookieStorage::criteriaFind
|
||||||
(const std::string& requestHost,
|
(const std::string& requestHost,
|
||||||
const std::string& requestPath,
|
const std::string& requestPath,
|
||||||
time_t now,
|
time_t now,
|
||||||
bool secure)
|
bool secure)
|
||||||
{
|
{
|
||||||
std::vector<Cookie> res;
|
auto res = std::vector<const Cookie*>{};
|
||||||
if(requestPath.empty()) {
|
if(requestPath.empty()) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
if(util::isNumericHost(requestHost)) {
|
auto labels = splitDomainLabel(requestHost);
|
||||||
searchCookieByDomainSuffix
|
auto node = rootNode_.get();
|
||||||
(res, requestHost, requestHost, requestPath, now, secure);
|
for(auto i = labels.rbegin(), eoi = labels.rend(); i != eoi; ++i) {
|
||||||
} else {
|
auto nextNode = node->findNext(*i);
|
||||||
std::vector<Scip> levels;
|
if(nextNode) {
|
||||||
util::splitIter(requestHost.begin(), requestHost.end(),
|
nextNode->setLastAccessTime(now);
|
||||||
std::back_inserter(levels), '.');
|
if(nextNode->getInLru()) {
|
||||||
std::string domain;
|
updateLru(nextNode, now);
|
||||||
for(std::vector<Scip>::const_reverse_iterator i =
|
}
|
||||||
levels.rbegin(), eoi = levels.rend();
|
nextNode->findCookie(res, requestHost, requestPath, now, secure);
|
||||||
i != eoi; ++i, domain.insert(domain.begin(), '.')) {
|
node = nextNode;
|
||||||
domain.insert(domain.begin(), (*i).first, (*i).second);
|
} else {
|
||||||
searchCookieByDomainSuffix
|
break;
|
||||||
(res, domain, requestHost, requestPath, now, secure);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::vector<CookiePathDivider> divs;
|
auto divs = std::vector<CookiePathDivider>{};
|
||||||
std::transform(res.begin(), res.end(), std::back_inserter(divs),
|
std::transform(std::begin(res), std::end(res), std::back_inserter(divs),
|
||||||
CookiePathDividerConverter());
|
CookiePathDividerConverter{});
|
||||||
std::sort(divs.begin(), divs.end(), OrderByPathDepthDesc());
|
std::sort(std::begin(divs), std::end(divs), OrderByPathDepthDesc{});
|
||||||
std::transform(divs.begin(), divs.end(), res.begin(),
|
std::transform(std::begin(divs), std::end(divs), std::begin(res),
|
||||||
CookiePathDividerConverter());
|
CookiePathDividerConverter{});
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t CookieStorage::size() const
|
size_t CookieStorage::size() const
|
||||||
{
|
{
|
||||||
size_t numCookie = 0;
|
size_t n = 0;
|
||||||
for(DomainEntrySet::iterator i = domains_.begin(), eoi = domains_.end();
|
for(auto& p : lruTracker_) {
|
||||||
i != eoi; ++i) {
|
n += p.second->countCookie();
|
||||||
numCookie += (*i)->countCookie();
|
|
||||||
}
|
}
|
||||||
return numCookie;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CookieStorage::load(const std::string& filename, time_t now)
|
bool CookieStorage::load(const std::string& filename, time_t now)
|
||||||
|
@ -361,7 +470,7 @@ bool CookieStorage::load(const std::string& filename, time_t now)
|
||||||
char header[16]; // "SQLite format 3" plus \0
|
char header[16]; // "SQLite format 3" plus \0
|
||||||
size_t headlen;
|
size_t headlen;
|
||||||
{
|
{
|
||||||
BufferedFile fp(filename.c_str(), BufferedFile::READ);
|
BufferedFile fp{filename.c_str(), BufferedFile::READ};
|
||||||
if(!fp) {
|
if(!fp) {
|
||||||
A2_LOG_ERROR(fmt("Failed to open cookie file %s", filename.c_str()));
|
A2_LOG_ERROR(fmt("Failed to open cookie file %s", filename.c_str()));
|
||||||
return false;
|
return false;
|
||||||
|
@ -371,25 +480,28 @@ bool CookieStorage::load(const std::string& filename, time_t now)
|
||||||
try {
|
try {
|
||||||
if(headlen == 16 && memcmp(header, "SQLite format 3\0", 16) == 0) {
|
if(headlen == 16 && memcmp(header, "SQLite format 3\0", 16) == 0) {
|
||||||
#ifdef HAVE_SQLITE3
|
#ifdef HAVE_SQLITE3
|
||||||
std::vector<Cookie> cookies;
|
|
||||||
try {
|
try {
|
||||||
Sqlite3MozCookieParser(filename).parse(cookies);
|
auto cookies = Sqlite3MozCookieParser(filename).parse();
|
||||||
|
storeCookies(std::make_move_iterator(std::begin(cookies)),
|
||||||
|
std::make_move_iterator(std::end(cookies)), now);
|
||||||
} catch(RecoverableException& e) {
|
} catch(RecoverableException& e) {
|
||||||
A2_LOG_INFO_EX(EX_EXCEPTION_CAUGHT, e);
|
A2_LOG_INFO_EX(EX_EXCEPTION_CAUGHT, e);
|
||||||
A2_LOG_INFO("This does not look like Firefox3 cookie file."
|
A2_LOG_INFO("This does not look like Firefox3 cookie file."
|
||||||
" Retrying, assuming it is Chromium cookie file.");
|
" Retrying, assuming it is Chromium cookie file.");
|
||||||
// Try chrome cookie format
|
// Try chrome cookie format
|
||||||
Sqlite3ChromiumCookieParser(filename).parse(cookies);
|
auto cookies = Sqlite3ChromiumCookieParser(filename).parse();
|
||||||
|
storeCookies(std::make_move_iterator(std::begin(cookies)),
|
||||||
|
std::make_move_iterator(std::end(cookies)), now);
|
||||||
}
|
}
|
||||||
storeCookies(cookies.begin(), cookies.end(), now);
|
|
||||||
#else // !HAVE_SQLITE3
|
#else // !HAVE_SQLITE3
|
||||||
throw DL_ABORT_EX
|
throw DL_ABORT_EX
|
||||||
("Cannot read SQLite3 database because SQLite3 support is disabled by"
|
("Cannot read SQLite3 database because SQLite3 support is disabled by"
|
||||||
" configuration.");
|
" configuration.");
|
||||||
#endif // !HAVE_SQLITE3
|
#endif // !HAVE_SQLITE3
|
||||||
} else {
|
} else {
|
||||||
std::vector<Cookie> cookies = NsCookieParser().parse(filename, now);
|
auto cookies = NsCookieParser().parse(filename, now);
|
||||||
storeCookies(cookies.begin(), cookies.end(), now);
|
storeCookies(std::make_move_iterator(std::begin(cookies)),
|
||||||
|
std::make_move_iterator(std::end(cookies)), now);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} catch(RecoverableException& e) {
|
} catch(RecoverableException& e) {
|
||||||
|
@ -400,17 +512,16 @@ bool CookieStorage::load(const std::string& filename, time_t now)
|
||||||
|
|
||||||
bool CookieStorage::saveNsFormat(const std::string& filename)
|
bool CookieStorage::saveNsFormat(const std::string& filename)
|
||||||
{
|
{
|
||||||
std::string tempfilename = filename;
|
auto tempfilename = filename;
|
||||||
tempfilename += "__temp";
|
tempfilename += "__temp";
|
||||||
{
|
{
|
||||||
BufferedFile fp(tempfilename.c_str(), BufferedFile::WRITE);
|
BufferedFile fp{tempfilename.c_str(), BufferedFile::WRITE};
|
||||||
if(!fp) {
|
if(!fp) {
|
||||||
A2_LOG_ERROR(fmt("Cannot create cookie file %s", filename.c_str()));
|
A2_LOG_ERROR(fmt("Cannot create cookie file %s", filename.c_str()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for(DomainEntrySet::iterator i = domains_.begin(), eoi = domains_.end();
|
for(auto& p : lruTracker_) {
|
||||||
i != eoi; ++i) {
|
if(!p.second->writeCookie(fp)) {
|
||||||
if(!(*i)->writeCookie(fp)) {
|
|
||||||
A2_LOG_ERROR(fmt("Failed to save cookies to %s", filename.c_str()));
|
A2_LOG_ERROR(fmt("Failed to save cookies to %s", filename.c_str()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -431,14 +542,3 @@ bool CookieStorage::saveNsFormat(const std::string& filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
||||||
namespace std {
|
|
||||||
template<>
|
|
||||||
void swap<aria2::CookieStorage::DomainEntry>
|
|
||||||
(aria2::CookieStorage::DomainEntry& a,
|
|
||||||
aria2::CookieStorage::DomainEntry& b)
|
|
||||||
{
|
|
||||||
a.swap(b);
|
|
||||||
}
|
|
||||||
} // namespace std
|
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/*
|
/*
|
||||||
* aria2 - The high speed download utility
|
* aria2 - The high speed download utility
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006 Tatsuhiro Tsujikawa
|
* Copyright (C) 2013 Tatsuhiro Tsujikawa
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -42,6 +42,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "a2time.h"
|
#include "a2time.h"
|
||||||
#include "Cookie.h"
|
#include "Cookie.h"
|
||||||
|
@ -51,89 +52,97 @@ namespace aria2 {
|
||||||
|
|
||||||
class BufferedFile;
|
class BufferedFile;
|
||||||
|
|
||||||
|
// This object represents one domain label.
|
||||||
|
class DomainNode {
|
||||||
|
public:
|
||||||
|
DomainNode(std::string label, DomainNode* parent);
|
||||||
|
// Stores the matching cookies in |out|. The |now| is used to update
|
||||||
|
// the last access time of this node.
|
||||||
|
void findCookie
|
||||||
|
(std::vector<const Cookie*>& out,
|
||||||
|
const std::string& requestHost,
|
||||||
|
const std::string& requestPath,
|
||||||
|
time_t now, bool secure);
|
||||||
|
// Returns the number of cookies this node has.
|
||||||
|
size_t countCookie() const;
|
||||||
|
// Add |cookie| using update time |now|. Returns true if the
|
||||||
|
// function succeeds.
|
||||||
|
bool addCookie(std::unique_ptr<Cookie> cookie, time_t now);
|
||||||
|
// Sets the last access time of this node.
|
||||||
|
void setLastAccessTime(time_t lastAccessTime);
|
||||||
|
// Returns the last access time of this node.
|
||||||
|
time_t getLastAccessTime() const;
|
||||||
|
// Sets the time |t| as a time used as key in LRU tracker.
|
||||||
|
void setLruAccessTime(time_t t);
|
||||||
|
time_t getLruAccessTime() const;
|
||||||
|
|
||||||
|
bool writeCookie(BufferedFile& fp) const;
|
||||||
|
// Returns true if this node contains the |cookie|.
|
||||||
|
bool contains(const Cookie& cookie) const;
|
||||||
|
// Returns true if this node contains no cookie.
|
||||||
|
bool empty() const;
|
||||||
|
// Returns true if this node has any next nodes.
|
||||||
|
bool hasNext() const;
|
||||||
|
// Returns the parent node. If this is the root node, returns
|
||||||
|
// nullptr.
|
||||||
|
DomainNode* getParent() const;
|
||||||
|
// Removes the child node |node|. Nothing happens if |node| is not a
|
||||||
|
// child of this node.
|
||||||
|
void removeNode(DomainNode* node);
|
||||||
|
// Returns the child node having label |label. Returns nullptr if
|
||||||
|
// there is no such node.
|
||||||
|
DomainNode* findNext(const std::string& label) const;
|
||||||
|
// Add the |node| as a child using label |label and returns the raw
|
||||||
|
// pointer of |node|.
|
||||||
|
DomainNode* addNext(std::string label, std::unique_ptr<DomainNode> node);
|
||||||
|
// Returns the |label|.
|
||||||
|
const std::string& getLabel() const;
|
||||||
|
// Deletes all cookies this node has.
|
||||||
|
void clearCookie();
|
||||||
|
// Returns value set by setInLru(). This is typically used to know
|
||||||
|
// this node is tracked by LRU tracker or not.
|
||||||
|
bool getInLru() const;
|
||||||
|
void setInLru(bool f);
|
||||||
|
|
||||||
|
template<typename OutputIterator>
|
||||||
|
OutputIterator dumpCookie(OutputIterator out) const
|
||||||
|
{
|
||||||
|
if(cookies_) {
|
||||||
|
for(auto& c : *cookies_) {
|
||||||
|
out++ = c.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::string label_;
|
||||||
|
DomainNode* parent_;
|
||||||
|
time_t lastAccessTime_;
|
||||||
|
time_t lruAccessTime_;
|
||||||
|
bool inLru_;
|
||||||
|
std::unique_ptr<std::deque<std::unique_ptr<Cookie>>> cookies_;
|
||||||
|
// domain label string to DomainNode
|
||||||
|
// e.g. net, sourceforge
|
||||||
|
// For numerical addresses, this is address itself.
|
||||||
|
// e.g. 192.168.0.1
|
||||||
|
std::unordered_map<std::string, std::unique_ptr<DomainNode>> next_;
|
||||||
|
};
|
||||||
|
|
||||||
class CookieStorage {
|
class CookieStorage {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static const size_t MAX_COOKIE_PER_DOMAIN = 50;
|
static const size_t MAX_COOKIE_PER_DOMAIN = 50;
|
||||||
|
|
||||||
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 lastAccessTime_;
|
|
||||||
|
|
||||||
std::deque<Cookie> cookies_;
|
|
||||||
public:
|
|
||||||
DomainEntry(const std::string& domain);
|
|
||||||
DomainEntry(const DomainEntry& c);
|
|
||||||
~DomainEntry();
|
|
||||||
|
|
||||||
void swap(DomainEntry& c);
|
|
||||||
|
|
||||||
DomainEntry& operator=(const DomainEntry& c);
|
|
||||||
|
|
||||||
const std::string& getKey() const
|
|
||||||
{
|
|
||||||
return key_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void findCookie
|
|
||||||
(std::vector<Cookie>& out,
|
|
||||||
const std::string& requestHost,
|
|
||||||
const std::string& requestPath,
|
|
||||||
time_t now, bool secure);
|
|
||||||
|
|
||||||
size_t countCookie() const;
|
|
||||||
|
|
||||||
bool addCookie(const Cookie& cookie, time_t now);
|
|
||||||
|
|
||||||
void setLastAccessTime(time_t lastAccessTime)
|
|
||||||
{
|
|
||||||
lastAccessTime_ = lastAccessTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
time_t getLastAccessTime() const
|
|
||||||
{
|
|
||||||
return lastAccessTime_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool writeCookie(BufferedFile& fp) const;
|
|
||||||
|
|
||||||
bool contains(const Cookie& cookie) const;
|
|
||||||
|
|
||||||
template<typename OutputIterator>
|
|
||||||
OutputIterator dumpCookie(OutputIterator out) const
|
|
||||||
{
|
|
||||||
return std::copy(cookies_.begin(), cookies_.end(), out);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const DomainEntry& de) const;
|
|
||||||
bool operator<(const DomainEntry& de) const;
|
|
||||||
};
|
|
||||||
private:
|
private:
|
||||||
typedef std::set<std::shared_ptr<DomainEntry>,
|
// typedef std::set<std::shared_ptr<DomainEntry>,
|
||||||
DerefLess<std::shared_ptr<DomainEntry> > > DomainEntrySet;
|
// DerefLess<std::shared_ptr<DomainEntry> > > DomainEntrySet;
|
||||||
DomainEntrySet domains_;
|
// DomainEntrySet domains_;
|
||||||
|
|
||||||
template<typename InputIterator>
|
|
||||||
void storeCookies(InputIterator first, InputIterator last, time_t now)
|
|
||||||
{
|
|
||||||
for(; first != last; ++first) {
|
|
||||||
store(*first, now);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public:
|
public:
|
||||||
CookieStorage();
|
CookieStorage();
|
||||||
|
|
||||||
~CookieStorage();
|
|
||||||
|
|
||||||
// Returns true if cookie is stored or updated existing cookie.
|
// Returns true if cookie is stored or updated existing cookie.
|
||||||
// Returns false if cookie is expired. now is used as last access
|
// Returns false if cookie is expired. now is used as last access
|
||||||
// time.
|
// time.
|
||||||
bool store(const Cookie& cookie, time_t now);
|
bool store(std::unique_ptr<Cookie> cookie, time_t now);
|
||||||
|
|
||||||
// Returns true if cookie is stored or updated existing cookie.
|
// Returns true if cookie is stored or updated existing cookie.
|
||||||
// Otherwise, returns false. now is used as creation time and last
|
// Otherwise, returns false. now is used as creation time and last
|
||||||
|
@ -146,9 +155,10 @@ public:
|
||||||
|
|
||||||
// Finds cookies matched with given criteria and returns them.
|
// Finds cookies matched with given criteria and returns them.
|
||||||
// Matched cookies' lastAccess_ property is updated.
|
// Matched cookies' lastAccess_ property is updated.
|
||||||
std::vector<Cookie> criteriaFind(const std::string& requestHost,
|
std::vector<const Cookie*>
|
||||||
const std::string& requestPath,
|
criteriaFind(const std::string& requestHost,
|
||||||
time_t now, bool secure);
|
const std::string& requestPath,
|
||||||
|
time_t now, bool secure);
|
||||||
|
|
||||||
// Loads Cookies from file denoted by filename. If compiled with
|
// Loads Cookies from file denoted by filename. If compiled with
|
||||||
// libsqlite3, this method automatically detects the specified file
|
// libsqlite3, this method automatically detects the specified file
|
||||||
|
@ -170,36 +180,51 @@ public:
|
||||||
// satisfies.
|
// satisfies.
|
||||||
bool contains(const Cookie& cookie) const;
|
bool contains(const Cookie& cookie) const;
|
||||||
|
|
||||||
// Searches Cookie using given domain, requestHost, requestPath,
|
|
||||||
// current time and secure flag. The found Cookies are stored in
|
|
||||||
// out.
|
|
||||||
void searchCookieByDomainSuffix
|
|
||||||
(std::vector<Cookie>& out,
|
|
||||||
const std::string& domain,
|
|
||||||
const std::string& requestHost,
|
|
||||||
const std::string& requestPath,
|
|
||||||
time_t now, bool secure);
|
|
||||||
|
|
||||||
template<typename OutputIterator>
|
template<typename OutputIterator>
|
||||||
OutputIterator dumpCookie(OutputIterator out) const
|
OutputIterator dumpCookie(OutputIterator out) const
|
||||||
{
|
{
|
||||||
for(DomainEntrySet::iterator i = domains_.begin(), eoi = domains_.end();
|
for(auto& i : lruTracker_) {
|
||||||
i != eoi; ++i) {
|
out = i.second->dumpCookie(out);
|
||||||
out = (*i)->dumpCookie(out);
|
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
void swap(CookieStorage::DomainEntry& a, CookieStorage::DomainEntry& b);
|
// Force eviction of delnum nodes. Exposed for unittest
|
||||||
|
void evictNode(size_t delnum);
|
||||||
|
// Returns size of LRU tracker. Exposed for unittest
|
||||||
|
size_t getLruTrackerSize() const;
|
||||||
|
// Returns root node. Exposed for unittest
|
||||||
|
const DomainNode* getRootNode() const;
|
||||||
|
private:
|
||||||
|
template<typename InputIterator>
|
||||||
|
void storeCookies(InputIterator first, InputIterator last, time_t now)
|
||||||
|
{
|
||||||
|
for(; first != last; ++first) {
|
||||||
|
store(*first, now);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateLru(DomainNode* node, time_t now);
|
||||||
|
|
||||||
|
// rootNode_ is a root node of tree structure of reversed domain
|
||||||
|
// labels. rootNode_ always contans no cookie. It has the child
|
||||||
|
// nodes of the top level domain label (e.g., net, com and org). And
|
||||||
|
// those top level domain nodes have 2nd doman label (e.g.,
|
||||||
|
// sourcforge, github), and so on. The numeric host name are always
|
||||||
|
// stored as a child node of rootNode_. So the domain name of a
|
||||||
|
// paricular node is constructed as follows. First traverse the
|
||||||
|
// target node from root node. The concatenation of the visited
|
||||||
|
// node's label in the reverse order, delimited by ".", is the
|
||||||
|
std::unique_ptr<DomainNode> rootNode_;
|
||||||
|
// This object tracks the node which has cookies or it once had. The
|
||||||
|
// order is sorted by the least recent updated node first. This
|
||||||
|
// object does not track the node which has not contan cookie. For
|
||||||
|
// example, adding cookies in aria2.sourceforge.net, and no node
|
||||||
|
// labeled "sourceforge" is present, only node labelded "aria2" is
|
||||||
|
// tracked and node labeled "sourceforge" and "net" are not.
|
||||||
|
std::set<std::pair<time_t, DomainNode*>> lruTracker_;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
||||||
namespace std {
|
|
||||||
template<>
|
|
||||||
void swap<aria2::CookieStorage::DomainEntry>
|
|
||||||
(aria2::CookieStorage::DomainEntry& a,
|
|
||||||
aria2::CookieStorage::DomainEntry& b);
|
|
||||||
} // namespace std
|
|
||||||
|
|
||||||
#endif // D_COOKIE_STORAGE_H
|
#endif // D_COOKIE_STORAGE_H
|
||||||
|
|
|
@ -234,13 +234,11 @@ std::string HttpRequest::createRequest()
|
||||||
std::string cookiesValue;
|
std::string cookiesValue;
|
||||||
std::string path = getDir();
|
std::string path = getDir();
|
||||||
path += getFile();
|
path += getFile();
|
||||||
std::vector<Cookie> cookies =
|
auto cookies = cookieStorage_->criteriaFind(getHost(), path,
|
||||||
cookieStorage_->criteriaFind(getHost(), path,
|
Time().getTime(),
|
||||||
Time().getTime(),
|
getProtocol() == "https");
|
||||||
getProtocol() == "https");
|
for(auto c : cookies) {
|
||||||
for(std::vector<Cookie>::const_iterator itr = cookies.begin(),
|
cookiesValue += c->toString();
|
||||||
eoi = cookies.end(); itr != eoi; ++itr) {
|
|
||||||
cookiesValue += (*itr).toString();
|
|
||||||
cookiesValue += ";";
|
cookiesValue += ";";
|
||||||
}
|
}
|
||||||
if(!cookiesValue.empty()) {
|
if(!cookiesValue.empty()) {
|
||||||
|
|
|
@ -54,58 +54,59 @@ NsCookieParser::NsCookieParser() {}
|
||||||
NsCookieParser::~NsCookieParser() {}
|
NsCookieParser::~NsCookieParser() {}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
bool parseNsCookie
|
std::unique_ptr<Cookie> parseNsCookie
|
||||||
(Cookie& cookie, const std::string& cookieStr, time_t creationTime)
|
(const std::string& cookieStr, time_t creationTime)
|
||||||
{
|
{
|
||||||
std::vector<Scip> vs;
|
std::vector<Scip> vs;
|
||||||
util::splitIter(cookieStr.begin(), cookieStr.end(), std::back_inserter(vs),
|
util::splitIter(cookieStr.begin(), cookieStr.end(), std::back_inserter(vs),
|
||||||
'\t', true);
|
'\t', true);
|
||||||
if(vs.size() < 6) {
|
if(vs.size() < 6) {
|
||||||
return false;
|
return std::unique_ptr<Cookie>{};
|
||||||
}
|
}
|
||||||
vs[0].first = util::lstripIter(vs[0].first, vs[0].second, '.');
|
vs[0].first = util::lstripIter(vs[0].first, vs[0].second, '.');
|
||||||
if(vs[5].first == vs[5].second || vs[0].first == vs[0].second ||
|
if(vs[5].first == vs[5].second || vs[0].first == vs[0].second ||
|
||||||
!cookie::goodPath(vs[2].first, vs[2].second)) {
|
!cookie::goodPath(vs[2].first, vs[2].second)) {
|
||||||
return false;
|
return std::unique_ptr<Cookie>{};
|
||||||
}
|
}
|
||||||
int64_t expiryTime;
|
int64_t expiryTime;
|
||||||
if(!util::parseLLIntNoThrow(expiryTime,
|
if(!util::parseLLIntNoThrow(expiryTime,
|
||||||
std::string(vs[4].first, vs[4].second))) {
|
std::string(vs[4].first, vs[4].second))) {
|
||||||
return false;
|
return std::unique_ptr<Cookie>{};
|
||||||
}
|
}
|
||||||
if(std::numeric_limits<time_t>::max() < expiryTime) {
|
if(std::numeric_limits<time_t>::max() < expiryTime) {
|
||||||
expiryTime = std::numeric_limits<time_t>::max();
|
expiryTime = std::numeric_limits<time_t>::max();
|
||||||
} else if(std::numeric_limits<time_t>::min() > expiryTime) {
|
} else if(std::numeric_limits<time_t>::min() > expiryTime) {
|
||||||
expiryTime = std::numeric_limits<time_t>::min();
|
expiryTime = std::numeric_limits<time_t>::min();
|
||||||
}
|
}
|
||||||
cookie.setName(vs[5].first, vs[5].second);
|
auto cookie = make_unique<Cookie>();
|
||||||
|
cookie->setName(vs[5].first, vs[5].second);
|
||||||
if(vs.size() >= 7) {
|
if(vs.size() >= 7) {
|
||||||
cookie.setValue(vs[6].first, vs[6].second);
|
cookie->setValue(vs[6].first, vs[6].second);
|
||||||
} else {
|
} else {
|
||||||
cookie.setValue(A2STR::NIL.begin(), A2STR::NIL.end());
|
cookie->setValue("");
|
||||||
}
|
}
|
||||||
cookie.setExpiryTime(expiryTime == 0?
|
cookie->setExpiryTime(expiryTime == 0?
|
||||||
std::numeric_limits<time_t>::max():expiryTime);
|
std::numeric_limits<time_t>::max():expiryTime);
|
||||||
// aria2 treats expiryTime == 0 means session cookie.
|
// aria2 treats expiryTime == 0 means session cookie->
|
||||||
cookie.setPersistent(expiryTime != 0);
|
cookie->setPersistent(expiryTime != 0);
|
||||||
cookie.setDomain(vs[0].first, vs[0].second);
|
cookie->setDomain(vs[0].first, vs[0].second);
|
||||||
cookie.setHostOnly(util::isNumericHost(cookie.getDomain()) ||
|
cookie->setHostOnly(util::isNumericHost(cookie->getDomain()) ||
|
||||||
!util::streq(vs[1].first, vs[1].second, "TRUE"));
|
!util::streq(vs[1].first, vs[1].second, "TRUE"));
|
||||||
cookie.setPath(vs[2].first, vs[2].second);
|
cookie->setPath(vs[2].first, vs[2].second);
|
||||||
cookie.setSecure(util::streq(vs[3].first, vs[3].second, "TRUE"));
|
cookie->setSecure(util::streq(vs[3].first, vs[3].second, "TRUE"));
|
||||||
cookie.setCreationTime(creationTime);
|
cookie->setCreationTime(creationTime);
|
||||||
return true;
|
return cookie;
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
std::vector<Cookie> NsCookieParser::parse
|
std::vector<std::unique_ptr<Cookie>> NsCookieParser::parse
|
||||||
(const std::string& filename, time_t creationTime)
|
(const std::string& filename, time_t creationTime)
|
||||||
{
|
{
|
||||||
BufferedFile fp(filename.c_str(), BufferedFile::READ);
|
BufferedFile fp{filename.c_str(), BufferedFile::READ};
|
||||||
if(!fp) {
|
if(!fp) {
|
||||||
throw DL_ABORT_EX(fmt("Failed to open file %s", filename.c_str()));
|
throw DL_ABORT_EX(fmt("Failed to open file %s", filename.c_str()));
|
||||||
}
|
}
|
||||||
std::vector<Cookie> cookies;
|
std::vector<std::unique_ptr<Cookie>> cookies;
|
||||||
while(1) {
|
while(1) {
|
||||||
std::string line = fp.getLine();
|
std::string line = fp.getLine();
|
||||||
if(line.empty()) {
|
if(line.empty()) {
|
||||||
|
@ -120,9 +121,9 @@ std::vector<Cookie> NsCookieParser::parse
|
||||||
if(line[0] == '#') {
|
if(line[0] == '#') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Cookie c;
|
auto c = parseNsCookie(line, creationTime);
|
||||||
if(parseNsCookie(c, line, creationTime)) {
|
if(c) {
|
||||||
cookies.push_back(c);
|
cookies.push_back(std::move(c));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return cookies;
|
return cookies;
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
@ -50,7 +51,8 @@ public:
|
||||||
|
|
||||||
~NsCookieParser();
|
~NsCookieParser();
|
||||||
|
|
||||||
std::vector<Cookie> parse(const std::string& filename, time_t creationTime);
|
std::vector<std::unique_ptr<Cookie>> parse
|
||||||
|
(const std::string& filename, time_t creationTime);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -102,8 +102,8 @@ int cookieRowMapper(void* data, int columns, char** values, char** names)
|
||||||
if(columns != 7 || !values[0] || !values[1] || !values[4]) {
|
if(columns != 7 || !values[0] || !values[1] || !values[4]) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
std::vector<Cookie>& cookies =
|
std::vector<std::unique_ptr<Cookie>>& cookies =
|
||||||
*reinterpret_cast<std::vector<Cookie>*>(data);
|
*reinterpret_cast<std::vector<std::unique_ptr<Cookie>>*>(data);
|
||||||
size_t val0len = strlen(values[0]);
|
size_t val0len = strlen(values[0]);
|
||||||
std::string cookieDomain
|
std::string cookieDomain
|
||||||
(util::lstripIter(&values[0][0], &values[0][val0len], '.'),
|
(util::lstripIter(&values[0][0], &values[0][val0len], '.'),
|
||||||
|
@ -122,29 +122,29 @@ int cookieRowMapper(void* data, int columns, char** values, char** names)
|
||||||
if(!values[6] || !parseTime(lastAccessTime, values[6])) {
|
if(!values[6] || !parseTime(lastAccessTime, values[6])) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Cookie c(cookieName,
|
cookies.push_back(make_unique<Cookie>
|
||||||
toString(values[5]), // value
|
(std::move(cookieName),
|
||||||
expiryTime,
|
toString(values[5]), // value
|
||||||
true, // persistent
|
expiryTime,
|
||||||
cookieDomain,
|
true, // persistent
|
||||||
util::isNumericHost(cookieDomain) ||
|
std::move(cookieDomain),
|
||||||
(values[0] && values[0][0] != '.'), // hostOnly
|
util::isNumericHost(cookieDomain) ||
|
||||||
cookiePath,
|
(values[0] && values[0][0] != '.'), // hostOnly
|
||||||
values[2] && strcmp(values[2], "1") == 0, //secure
|
std::move(cookiePath),
|
||||||
false,
|
values[2] && strcmp(values[2], "1") == 0, //secure
|
||||||
lastAccessTime // creation time. Set this later.
|
false,
|
||||||
);
|
lastAccessTime // creation time. Set this later.
|
||||||
cookies.push_back(c);
|
));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void Sqlite3CookieParser::parse(std::vector<Cookie>& cookies)
|
std::vector<std::unique_ptr<Cookie>> Sqlite3CookieParser::parse()
|
||||||
{
|
{
|
||||||
if(!db_) {
|
if(!db_) {
|
||||||
throw DL_ABORT_EX(fmt("SQLite3 database is not opened."));
|
throw DL_ABORT_EX(fmt("SQLite3 database is not opened."));
|
||||||
}
|
}
|
||||||
std::vector<Cookie> tcookies;
|
auto tcookies = std::vector<std::unique_ptr<Cookie>>{};
|
||||||
char* sqlite3ErrMsg = 0;
|
char* sqlite3ErrMsg = 0;
|
||||||
int ret = sqlite3_exec(db_, getQuery(), cookieRowMapper,
|
int ret = sqlite3_exec(db_, getQuery(), cookieRowMapper,
|
||||||
&tcookies, &sqlite3ErrMsg);
|
&tcookies, &sqlite3ErrMsg);
|
||||||
|
@ -157,7 +157,7 @@ void Sqlite3CookieParser::parse(std::vector<Cookie>& cookies)
|
||||||
throw DL_ABORT_EX
|
throw DL_ABORT_EX
|
||||||
(fmt("Failed to read SQLite3 database: %s", errMsg.c_str()));
|
(fmt("Failed to read SQLite3 database: %s", errMsg.c_str()));
|
||||||
}
|
}
|
||||||
cookies.swap(tcookies);
|
return tcookies;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include <sqlite3.h>
|
#include <sqlite3.h>
|
||||||
|
|
||||||
|
@ -55,7 +56,7 @@ public:
|
||||||
// Loads cookies from sqlite3 database and stores them in cookies.
|
// Loads cookies from sqlite3 database and stores them in cookies.
|
||||||
// When loading is successful, cookies stored in cookies initially
|
// When loading is successful, cookies stored in cookies initially
|
||||||
// are removed. Otherwise, the content of cookies is unchanged.
|
// are removed. Otherwise, the content of cookies is unchanged.
|
||||||
void parse(std::vector<Cookie>& cookies);
|
std::vector<std::unique_ptr<Cookie>> parse();
|
||||||
protected:
|
protected:
|
||||||
// Returns SQL select statement to get 1 record of cookie. The sql
|
// Returns SQL select statement to get 1 record of cookie. The sql
|
||||||
// must return 6 columns in the following order: host, path,
|
// must return 6 columns in the following order: host, path,
|
||||||
|
|
|
@ -216,9 +216,8 @@ bool parseDate
|
||||||
return time != -1;
|
return time != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parse
|
std::unique_ptr<Cookie> parse
|
||||||
(Cookie& cookie,
|
(const std::string& cookieStr,
|
||||||
const std::string& cookieStr,
|
|
||||||
const std::string& requestHost,
|
const std::string& requestHost,
|
||||||
const std::string& defaultPath,
|
const std::string& defaultPath,
|
||||||
time_t creationTime)
|
time_t creationTime)
|
||||||
|
@ -231,13 +230,13 @@ bool parse
|
||||||
std::string::const_iterator eq = cookieStr.begin();
|
std::string::const_iterator eq = cookieStr.begin();
|
||||||
for(; eq != nvEnd && *eq != '='; ++eq);
|
for(; eq != nvEnd && *eq != '='; ++eq);
|
||||||
if(eq == nvEnd) {
|
if(eq == nvEnd) {
|
||||||
return false;
|
return std::unique_ptr<Cookie>{};
|
||||||
}
|
}
|
||||||
std::pair<std::string::const_iterator,
|
std::pair<std::string::const_iterator,
|
||||||
std::string::const_iterator> p =
|
std::string::const_iterator> p =
|
||||||
util::stripIter(cookieStr.begin(), eq);
|
util::stripIter(cookieStr.begin(), eq);
|
||||||
if(p.first == p.second) {
|
if(p.first == p.second) {
|
||||||
return false;
|
return std::unique_ptr<Cookie>{};
|
||||||
}
|
}
|
||||||
Scip cookieName(p.first, p.second);
|
Scip cookieName(p.first, p.second);
|
||||||
p = util::stripIter(eq+1, nvEnd);
|
p = util::stripIter(eq+1, nvEnd);
|
||||||
|
@ -276,18 +275,18 @@ bool parse
|
||||||
if(parseDate(expiryTime, attrp.first, attrp.second)) {
|
if(parseDate(expiryTime, attrp.first, attrp.second)) {
|
||||||
foundExpires = true;
|
foundExpires = true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return std::unique_ptr<Cookie>{};
|
||||||
}
|
}
|
||||||
} else if(util::strieq(p.first, p.second, "max-age")) {
|
} else if(util::strieq(p.first, p.second, "max-age")) {
|
||||||
if(attrp.first == attrp.second ||
|
if(attrp.first == attrp.second ||
|
||||||
(!in(static_cast<unsigned char>(*attrp.first), 0x30u, 0x39u) &&
|
(!in(static_cast<unsigned char>(*attrp.first), 0x30u, 0x39u) &&
|
||||||
*attrp.first != '-')) {
|
*attrp.first != '-')) {
|
||||||
return false;
|
return std::unique_ptr<Cookie>{};
|
||||||
}
|
}
|
||||||
for(std::string::const_iterator s = attrp.first+1,
|
for(std::string::const_iterator s = attrp.first+1,
|
||||||
eos = attrp.second; s != eos; ++s) {
|
eos = attrp.second; s != eos; ++s) {
|
||||||
if(!in(static_cast<unsigned char>(*s), 0x30u, 0x39u)) {
|
if(!in(static_cast<unsigned char>(*s), 0x30u, 0x39u)) {
|
||||||
return false;
|
return std::unique_ptr<Cookie>{};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int64_t delta;
|
int64_t delta;
|
||||||
|
@ -306,17 +305,17 @@ bool parse
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return std::unique_ptr<Cookie>{};
|
||||||
}
|
}
|
||||||
} else if(util::strieq(p.first, p.second, "domain")) {
|
} else if(util::strieq(p.first, p.second, "domain")) {
|
||||||
if(attrp.first == attrp.second) {
|
if(attrp.first == attrp.second) {
|
||||||
return false;
|
return std::unique_ptr<Cookie>{};
|
||||||
}
|
}
|
||||||
std::string::const_iterator noDot = attrp.first;
|
std::string::const_iterator noDot = attrp.first;
|
||||||
std::string::const_iterator end = attrp.second;
|
std::string::const_iterator end = attrp.second;
|
||||||
for(; noDot != end && *noDot == '.'; ++noDot);
|
for(; noDot != end && *noDot == '.'; ++noDot);
|
||||||
if(noDot == end) {
|
if(noDot == end) {
|
||||||
return false;
|
return std::unique_ptr<Cookie>{};
|
||||||
}
|
}
|
||||||
cookieDomain.assign(noDot, end);
|
cookieDomain.assign(noDot, end);
|
||||||
} else if(util::strieq(p.first, p.second, "path")) {
|
} else if(util::strieq(p.first, p.second, "path")) {
|
||||||
|
@ -349,26 +348,27 @@ bool parse
|
||||||
} else if(domainMatch(canonicalizedHost, cookieDomain)) {
|
} else if(domainMatch(canonicalizedHost, cookieDomain)) {
|
||||||
hostOnly = util::isNumericHost(canonicalizedHost);
|
hostOnly = util::isNumericHost(canonicalizedHost);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return std::unique_ptr<Cookie>{};
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cookiePath.empty()) {
|
if(cookiePath.empty()) {
|
||||||
cookiePath = defaultPath;
|
cookiePath = defaultPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
cookie.setName(cookieName.first, cookieName.second);
|
auto cookie = make_unique<Cookie>();
|
||||||
cookie.setValue(cookieValue.first, cookieValue.second);
|
cookie->setName(cookieName.first, cookieName.second);
|
||||||
cookie.setExpiryTime(expiryTime);
|
cookie->setValue(cookieValue.first, cookieValue.second);
|
||||||
cookie.setPersistent(persistent);
|
cookie->setExpiryTime(expiryTime);
|
||||||
cookie.setDomain(cookieDomain);
|
cookie->setPersistent(persistent);
|
||||||
cookie.setHostOnly(hostOnly);
|
cookie->setDomain(std::move(cookieDomain));
|
||||||
cookie.setPath(cookiePath);
|
cookie->setHostOnly(hostOnly);
|
||||||
cookie.setSecure(secure);
|
cookie->setPath(std::move(cookiePath));
|
||||||
cookie.setHttpOnly(httpOnly);
|
cookie->setSecure(secure);
|
||||||
cookie.setCreationTime(creationTime);
|
cookie->setHttpOnly(httpOnly);
|
||||||
cookie.setLastAccessTime(creationTime);
|
cookie->setCreationTime(creationTime);
|
||||||
|
cookie->setLastAccessTime(creationTime);
|
||||||
|
|
||||||
return true;
|
return cookie;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool goodPath
|
bool goodPath
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "a2time.h"
|
#include "a2time.h"
|
||||||
|
|
||||||
|
@ -52,9 +53,8 @@ bool parseDate
|
||||||
std::string::const_iterator first,
|
std::string::const_iterator first,
|
||||||
std::string::const_iterator last);
|
std::string::const_iterator last);
|
||||||
|
|
||||||
bool parse
|
std::unique_ptr<Cookie> parse
|
||||||
(Cookie& cookie,
|
(const std::string& cookieStr,
|
||||||
const std::string& cookieStr,
|
|
||||||
const std::string& requestHost,
|
const std::string& requestHost,
|
||||||
const std::string& defaultPath,
|
const std::string& defaultPath,
|
||||||
time_t creationTime);
|
time_t creationTime);
|
||||||
|
|
|
@ -88,145 +88,145 @@ void CookieHelperTest::testParse()
|
||||||
{
|
{
|
||||||
std::string str = "ID=123456789; expires=Sun, 10-Jun-2007 11:00:00 GMT;"
|
std::string str = "ID=123456789; expires=Sun, 10-Jun-2007 11:00:00 GMT;"
|
||||||
"path=/foo; domain=localhost; secure;httpOnly ";
|
"path=/foo; domain=localhost; secure;httpOnly ";
|
||||||
Cookie c;
|
auto c = cookie::parse(str, "localhost", "/", creationDate);
|
||||||
CPPUNIT_ASSERT(cookie::parse(c, str, "localhost", "/", creationDate));
|
CPPUNIT_ASSERT(c);
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("ID"), c.getName());
|
CPPUNIT_ASSERT_EQUAL(std::string("ID"), c->getName());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("123456789"), c.getValue());
|
CPPUNIT_ASSERT_EQUAL(std::string("123456789"), c->getValue());
|
||||||
CPPUNIT_ASSERT_EQUAL((time_t)1181473200, c.getExpiryTime());
|
CPPUNIT_ASSERT_EQUAL((time_t)1181473200, c->getExpiryTime());
|
||||||
CPPUNIT_ASSERT(c.getPersistent());
|
CPPUNIT_ASSERT(c->getPersistent());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("localhost"), c.getDomain());
|
CPPUNIT_ASSERT_EQUAL(std::string("localhost"), c->getDomain());
|
||||||
CPPUNIT_ASSERT(!c.getHostOnly());
|
CPPUNIT_ASSERT(!c->getHostOnly());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("/foo"), c.getPath());
|
CPPUNIT_ASSERT_EQUAL(std::string("/foo"), c->getPath());
|
||||||
CPPUNIT_ASSERT(c.getSecure());
|
CPPUNIT_ASSERT(c->getSecure());
|
||||||
CPPUNIT_ASSERT(c.getHttpOnly());
|
CPPUNIT_ASSERT(c->getHttpOnly());
|
||||||
CPPUNIT_ASSERT_EQUAL((time_t)141, c.getCreationTime());
|
CPPUNIT_ASSERT_EQUAL((time_t)141, c->getCreationTime());
|
||||||
CPPUNIT_ASSERT_EQUAL((time_t)141, c.getLastAccessTime());
|
CPPUNIT_ASSERT_EQUAL((time_t)141, c->getLastAccessTime());
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::string str = "id=; Max-Age=0;";
|
std::string str = "id=; Max-Age=0;";
|
||||||
Cookie c;
|
auto c = cookie::parse(str, "localhost", "/", creationDate);
|
||||||
CPPUNIT_ASSERT(cookie::parse(c, str, "localhost", "/", creationDate));
|
CPPUNIT_ASSERT(c);
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("id"), c.getName());
|
CPPUNIT_ASSERT_EQUAL(std::string("id"), c->getName());
|
||||||
CPPUNIT_ASSERT_EQUAL((time_t)0, c.getExpiryTime());
|
CPPUNIT_ASSERT_EQUAL((time_t)0, c->getExpiryTime());
|
||||||
CPPUNIT_ASSERT(c.getPersistent());
|
CPPUNIT_ASSERT(c->getPersistent());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("localhost"), c.getDomain());
|
CPPUNIT_ASSERT_EQUAL(std::string("localhost"), c->getDomain());
|
||||||
CPPUNIT_ASSERT(c.getHostOnly());
|
CPPUNIT_ASSERT(c->getHostOnly());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("/"), c.getPath());
|
CPPUNIT_ASSERT_EQUAL(std::string("/"), c->getPath());
|
||||||
CPPUNIT_ASSERT(!c.getSecure());
|
CPPUNIT_ASSERT(!c->getSecure());
|
||||||
CPPUNIT_ASSERT(!c.getHttpOnly());
|
CPPUNIT_ASSERT(!c->getHttpOnly());
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::string str = "id=; Max-Age=-100;";
|
std::string str = "id=; Max-Age=-100;";
|
||||||
Cookie c;
|
auto c = cookie::parse(str, "localhost", "/", creationDate);
|
||||||
CPPUNIT_ASSERT(cookie::parse(c, str, "localhost", "/", creationDate));
|
CPPUNIT_ASSERT(c);
|
||||||
CPPUNIT_ASSERT_EQUAL((time_t)0, c.getExpiryTime());
|
CPPUNIT_ASSERT_EQUAL((time_t)0, c->getExpiryTime());
|
||||||
CPPUNIT_ASSERT(c.getPersistent());
|
CPPUNIT_ASSERT(c->getPersistent());
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::string str = "id=; Max-Age=100;";
|
std::string str = "id=; Max-Age=100;";
|
||||||
Cookie c;
|
auto c = cookie::parse(str, "localhost", "/", creationDate);
|
||||||
CPPUNIT_ASSERT(cookie::parse(c, str, "localhost", "/", creationDate));
|
CPPUNIT_ASSERT(c);
|
||||||
CPPUNIT_ASSERT_EQUAL((time_t)creationDate+100, c.getExpiryTime());
|
CPPUNIT_ASSERT_EQUAL((time_t)creationDate+100, c->getExpiryTime());
|
||||||
CPPUNIT_ASSERT(c.getPersistent());
|
CPPUNIT_ASSERT(c->getPersistent());
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::string str = "id=; Max-Age=9223372036854775807;";
|
std::string str = "id=; Max-Age=9223372036854775807;";
|
||||||
Cookie c;
|
auto c = cookie::parse(str, "localhost", "/", creationDate);
|
||||||
CPPUNIT_ASSERT(cookie::parse(c, str, "localhost", "/", creationDate));
|
CPPUNIT_ASSERT(c);
|
||||||
CPPUNIT_ASSERT_EQUAL(std::numeric_limits<time_t>::max(), c.getExpiryTime());
|
CPPUNIT_ASSERT_EQUAL(std::numeric_limits<time_t>::max(),
|
||||||
CPPUNIT_ASSERT(c.getPersistent());
|
c->getExpiryTime());
|
||||||
|
CPPUNIT_ASSERT(c->getPersistent());
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::string str = "id=; Max-Age=X;";
|
std::string str = "id=; Max-Age=X;";
|
||||||
Cookie c;
|
CPPUNIT_ASSERT(!cookie::parse(str, "localhost", "/", creationDate));
|
||||||
CPPUNIT_ASSERT(!cookie::parse(c, str, "localhost", "/", creationDate));
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::string str = "id=; Max-Age=100garbage;";
|
std::string str = "id=; Max-Age=100garbage;";
|
||||||
Cookie c;
|
CPPUNIT_ASSERT(!cookie::parse(str, "localhost", "/", creationDate));
|
||||||
CPPUNIT_ASSERT(!cookie::parse(c, str, "localhost", "/", creationDate));
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::string str = "id=; Max-Age=100;expires=Sun, 10-Jun-2007 11:00:00 GMT;";
|
std::string str = "id=; Max-Age=100;expires=Sun, 10-Jun-2007 11:00:00 GMT;";
|
||||||
Cookie c;
|
auto c = cookie::parse(str, "localhost", "/", creationDate);
|
||||||
CPPUNIT_ASSERT(cookie::parse(c, str, "localhost", "/", creationDate));
|
CPPUNIT_ASSERT(c);
|
||||||
CPPUNIT_ASSERT_EQUAL((time_t)creationDate+100, c.getExpiryTime());
|
CPPUNIT_ASSERT_EQUAL((time_t)creationDate+100, c->getExpiryTime());
|
||||||
CPPUNIT_ASSERT(c.getPersistent());
|
CPPUNIT_ASSERT(c->getPersistent());
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Cookie data cannot be parsed.
|
// Cookie data cannot be parsed.
|
||||||
std::string str = "id=; expires=2007-10-01 11:00:00 GMT;";
|
std::string str = "id=; expires=2007-10-01 11:00:00 GMT;";
|
||||||
Cookie c;
|
CPPUNIT_ASSERT(!cookie::parse(str, "localhost", "/", creationDate));
|
||||||
CPPUNIT_ASSERT(!cookie::parse(c, str, "localhost", "/", creationDate));
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::string str = "id=;";
|
std::string str = "id=;";
|
||||||
Cookie c;
|
auto c = cookie::parse(str, "localhost", "/", creationDate);
|
||||||
CPPUNIT_ASSERT(cookie::parse(c, str, "localhost", "/", creationDate));
|
CPPUNIT_ASSERT(c);
|
||||||
CPPUNIT_ASSERT(!c.getPersistent());
|
CPPUNIT_ASSERT(!c->getPersistent());
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::string str = "id=; path=abc";
|
std::string str = "id=; path=abc";
|
||||||
Cookie c;
|
auto c = cookie::parse(str, "localhost", "/", creationDate);
|
||||||
CPPUNIT_ASSERT(cookie::parse(c, str, "localhost", "/", creationDate));
|
CPPUNIT_ASSERT(c);
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("/"), c.getPath());
|
CPPUNIT_ASSERT_EQUAL(std::string("/"), c->getPath());
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::string str = "id=; domain=.example.org";
|
std::string str = "id=; domain=.example.org";
|
||||||
Cookie c;
|
CPPUNIT_ASSERT(cookie::parse(str, "www.example.org", "/",creationDate));
|
||||||
CPPUNIT_ASSERT(cookie::parse(c, str, "www.example.org", "/",creationDate));
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Fails because request host does not domain-match with cookie
|
// Fails because request host does not domain-match with cookie
|
||||||
// domain.
|
// domain.
|
||||||
std::string str = "id=; domain=www.example.org";
|
std::string str = "id=; domain=www.example.org";
|
||||||
Cookie c;
|
CPPUNIT_ASSERT(!cookie::parse(str, "example.org", "/", creationDate));
|
||||||
CPPUNIT_ASSERT(!cookie::parse(c, str, "example.org", "/", creationDate));
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::string str = "id=; domain=.";
|
std::string str = "id=; domain=.";
|
||||||
Cookie c;
|
CPPUNIT_ASSERT(!cookie::parse(str, "localhost", "/",creationDate));
|
||||||
CPPUNIT_ASSERT(!cookie::parse(c, str, "localhost", "/",creationDate));
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::string str = "";
|
std::string str = "";
|
||||||
Cookie c;
|
CPPUNIT_ASSERT(!cookie::parse(str, "localhost", "/",creationDate));
|
||||||
CPPUNIT_ASSERT(!cookie::parse(c, str, "localhost", "/",creationDate));
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::string str = "=";
|
std::string str = "=";
|
||||||
Cookie c;
|
CPPUNIT_ASSERT(!cookie::parse(str, "localhost", "/",creationDate));
|
||||||
CPPUNIT_ASSERT(!cookie::parse(c, str, "localhost", "/",creationDate));
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Use domain last time seen.
|
// Use domain last time seen.
|
||||||
std::string str = "id=;domain=a.example.org;domain=.example.org";
|
std::string str = "id=;domain=a.example.org;domain=.example.org";
|
||||||
Cookie c;
|
auto c = cookie::parse(str, "b.example.org", "/",creationDate);
|
||||||
CPPUNIT_ASSERT(cookie::parse(c, str, "b.example.org", "/",creationDate));
|
CPPUNIT_ASSERT(c);
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("example.org"), c.getDomain());
|
CPPUNIT_ASSERT_EQUAL(std::string("example.org"), c->getDomain());
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// numeric host
|
// numeric host
|
||||||
std::string str = "id=;";
|
std::string str = "id=;";
|
||||||
Cookie c;
|
auto c = cookie::parse(str, "192.168.0.1", "/",creationDate);
|
||||||
CPPUNIT_ASSERT(cookie::parse(c, str, "192.168.0.1", "/",creationDate));
|
CPPUNIT_ASSERT(c);
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), c.getDomain());
|
CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), c->getDomain());
|
||||||
CPPUNIT_ASSERT(c.getHostOnly());
|
CPPUNIT_ASSERT(c->getHostOnly());
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// numeric host
|
// numeric host
|
||||||
std::string str = "id=; domain=192.168.0.1";
|
std::string str = "id=; domain=192.168.0.1";
|
||||||
Cookie c;
|
auto c = cookie::parse(str, "192.168.0.1", "/",creationDate);
|
||||||
CPPUNIT_ASSERT(cookie::parse(c, str, "192.168.0.1", "/",creationDate));
|
CPPUNIT_ASSERT(c);
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), c.getDomain());
|
CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), c->getDomain());
|
||||||
CPPUNIT_ASSERT(c.getHostOnly());
|
CPPUNIT_ASSERT(c->getHostOnly());
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// DQUOTE around cookie-value
|
// DQUOTE around cookie-value
|
||||||
std::string str = "id=\"foo\";";
|
std::string str = "id=\"foo\";";
|
||||||
Cookie c;
|
auto c = cookie::parse(str, "localhost", "/", creationDate);
|
||||||
CPPUNIT_ASSERT(cookie::parse(c, str, "localhost", "/", creationDate));
|
CPPUNIT_ASSERT(c);
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("foo"), c.getValue());
|
CPPUNIT_ASSERT_EQUAL(std::string("foo"), c->getValue());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// Default path
|
||||||
|
std::string str = "id=;";
|
||||||
|
auto c = cookie::parse(str, "localhost", "/foo", creationDate);
|
||||||
|
CPPUNIT_ASSERT(c);
|
||||||
|
CPPUNIT_ASSERT_EQUAL(std::string("/foo"), c->getPath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "RecoverableException.h"
|
#include "RecoverableException.h"
|
||||||
#include "File.h"
|
#include "File.h"
|
||||||
#include "TestUtil.h"
|
#include "TestUtil.h"
|
||||||
|
#include "TimerA2.h"
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
@ -29,14 +30,13 @@ class CookieStorageTest:public CppUnit::TestFixture {
|
||||||
CPPUNIT_TEST(testSaveNsFormat_fail);
|
CPPUNIT_TEST(testSaveNsFormat_fail);
|
||||||
CPPUNIT_TEST(testCookieIsFull);
|
CPPUNIT_TEST(testCookieIsFull);
|
||||||
CPPUNIT_TEST(testDomainIsFull);
|
CPPUNIT_TEST(testDomainIsFull);
|
||||||
|
CPPUNIT_TEST(testEviction);
|
||||||
CPPUNIT_TEST_SUITE_END();
|
CPPUNIT_TEST_SUITE_END();
|
||||||
public:
|
public:
|
||||||
void setUp() {}
|
void setUp() {}
|
||||||
|
|
||||||
void tearDown() {}
|
void tearDown() {}
|
||||||
|
|
||||||
void dumpCookie(std::vector<Cookie>& cookies, const CookieStorage& cs);
|
|
||||||
|
|
||||||
void testStore();
|
void testStore();
|
||||||
void testParseAndStore();
|
void testParseAndStore();
|
||||||
void testCriteriaFind();
|
void testCriteriaFind();
|
||||||
|
@ -48,56 +48,67 @@ public:
|
||||||
void testSaveNsFormat_fail();
|
void testSaveNsFormat_fail();
|
||||||
void testCookieIsFull();
|
void testCookieIsFull();
|
||||||
void testDomainIsFull();
|
void testDomainIsFull();
|
||||||
|
void testEviction();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
CPPUNIT_TEST_SUITE_REGISTRATION(CookieStorageTest);
|
CPPUNIT_TEST_SUITE_REGISTRATION(CookieStorageTest);
|
||||||
|
|
||||||
void CookieStorageTest::dumpCookie
|
namespace {
|
||||||
(std::vector<Cookie>& cookies, const CookieStorage& st)
|
std::vector<const Cookie*> dumpCookie(const CookieStorage& st)
|
||||||
{
|
{
|
||||||
st.dumpCookie(std::back_inserter(cookies));
|
auto res = std::vector<const Cookie*>{};
|
||||||
std::sort(cookies.begin(), cookies.end(), CookieSorter());
|
st.dumpCookie(std::back_inserter(res));
|
||||||
|
std::sort(res.begin(), res.end(), CookieSorter());
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
void CookieStorageTest::testStore()
|
void CookieStorageTest::testStore()
|
||||||
{
|
{
|
||||||
time_t now = 1000;
|
time_t now = 1000;
|
||||||
CookieStorage st;
|
auto st = CookieStorage{};
|
||||||
Cookie goodCookie(createCookie("k", "v", "localhost", true, "/", false));
|
auto goodCookie = []() {
|
||||||
CPPUNIT_ASSERT(st.store(goodCookie, now));
|
return createCookie("k", "v", "localhost", true, "/", false);
|
||||||
|
};
|
||||||
|
CPPUNIT_ASSERT(st.store(goodCookie(), now));
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)1, st.size());
|
CPPUNIT_ASSERT_EQUAL((size_t)1, st.size());
|
||||||
CPPUNIT_ASSERT(st.contains(goodCookie));
|
CPPUNIT_ASSERT(st.contains(*goodCookie()));
|
||||||
|
|
||||||
Cookie anotherCookie(createCookie("k", "v", "mirror", true, "/", true));
|
auto anotherCookie = []() {
|
||||||
CPPUNIT_ASSERT(st.store(anotherCookie, now));
|
return createCookie("k", "v", "mirror", true, "/", true);
|
||||||
|
};
|
||||||
|
CPPUNIT_ASSERT(st.store(anotherCookie(), now));
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)2, st.size());
|
CPPUNIT_ASSERT_EQUAL((size_t)2, st.size());
|
||||||
CPPUNIT_ASSERT(st.contains(anotherCookie));
|
CPPUNIT_ASSERT(st.contains(*anotherCookie()));
|
||||||
CPPUNIT_ASSERT(st.contains(goodCookie));
|
CPPUNIT_ASSERT(st.contains(*goodCookie()));
|
||||||
|
|
||||||
Cookie updateGoodCookie(createCookie("k", "v2", "localhost", true,
|
auto updateGoodCookie = []() {
|
||||||
"/", false));
|
return createCookie("k", "v2", "localhost", true, "/", false);
|
||||||
CPPUNIT_ASSERT(st.store(updateGoodCookie, now));
|
};
|
||||||
|
CPPUNIT_ASSERT(st.store(updateGoodCookie(), now));
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)2, st.size());
|
CPPUNIT_ASSERT_EQUAL((size_t)2, st.size());
|
||||||
CPPUNIT_ASSERT(st.contains(updateGoodCookie));
|
CPPUNIT_ASSERT(st.contains(*updateGoodCookie()));
|
||||||
CPPUNIT_ASSERT(st.contains(anotherCookie));
|
CPPUNIT_ASSERT(st.contains(*anotherCookie()));
|
||||||
|
|
||||||
Cookie expireGoodCookie(createCookie("k", "v3", 0, "localhost", true,
|
auto expireGoodCookie = []() {
|
||||||
"/", false));
|
return createCookie("k", "v3", 0, "localhost", true, "/", false);
|
||||||
CPPUNIT_ASSERT(!st.store(expireGoodCookie, now));
|
};
|
||||||
|
CPPUNIT_ASSERT(!st.store(expireGoodCookie(), now));
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)1, st.size());
|
CPPUNIT_ASSERT_EQUAL((size_t)1, st.size());
|
||||||
CPPUNIT_ASSERT(st.contains(anotherCookie));
|
CPPUNIT_ASSERT(st.contains(*anotherCookie()));
|
||||||
|
|
||||||
Cookie fromNumericHost(createCookie("k", "v", "192.168.1.1", true,
|
auto fromNumericHost = []() {
|
||||||
"/", false));
|
return createCookie("k", "v", "192.168.1.1", true, "/", false);
|
||||||
CPPUNIT_ASSERT(st.store(fromNumericHost, now));
|
};
|
||||||
|
CPPUNIT_ASSERT(st.store(fromNumericHost(), now));
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)2, st.size());
|
CPPUNIT_ASSERT_EQUAL((size_t)2, st.size());
|
||||||
CPPUNIT_ASSERT(st.contains(fromNumericHost));
|
CPPUNIT_ASSERT(st.contains(*fromNumericHost()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CookieStorageTest::testParseAndStore()
|
void CookieStorageTest::testParseAndStore()
|
||||||
{
|
{
|
||||||
CookieStorage st;
|
auto st = CookieStorage{};
|
||||||
time_t now = 1000;
|
time_t now = 1000;
|
||||||
std::string localhostCookieStr = "k=v;"
|
std::string localhostCookieStr = "k=v;"
|
||||||
" expires=Fri, 01 Jan 2038 00:00:00 GMT; path=/; domain=localhost;";
|
" expires=Fri, 01 Jan 2038 00:00:00 GMT; path=/; domain=localhost;";
|
||||||
|
@ -122,221 +133,233 @@ void CookieStorageTest::testParseAndStore()
|
||||||
|
|
||||||
void CookieStorageTest::testCriteriaFind()
|
void CookieStorageTest::testCriteriaFind()
|
||||||
{
|
{
|
||||||
CookieStorage st;
|
auto st = CookieStorage{};
|
||||||
time_t now = 1000;
|
time_t now = 1000;
|
||||||
|
|
||||||
Cookie alpha(createCookie("alpha", "ALPHA", "aria2.org", false, "/", false));
|
auto alpha = []() {
|
||||||
Cookie bravo(createCookie("bravo", "BRAVO", 1060, "aria2.org", false,
|
return createCookie("alpha", "ALPHA", "aria2.org", false, "/", false);
|
||||||
"/foo", false));
|
};
|
||||||
Cookie charlie(createCookie("charlie", "CHARLIE", "aria2.org", false,
|
auto bravo = []() {
|
||||||
"/", true));
|
return createCookie("bravo", "BRAVO", 1060, "aria2.org", false,
|
||||||
Cookie delta(createCookie("delta", "DELTA", "aria2.org", false,
|
"/foo", false);
|
||||||
"/foo/bar", false));
|
};
|
||||||
Cookie echo(createCookie("echo", "ECHO", "www.dl.aria2.org", false,
|
auto charlie = []() {
|
||||||
"/", false));
|
return createCookie("charlie", "CHARLIE", "aria2.org", false,
|
||||||
Cookie foxtrot(createCookie("foxtrot", "FOXTROT", "sf.net", false,
|
"/", true);
|
||||||
"/", false));
|
};
|
||||||
Cookie golf(createCookie("golf", "GOLF", "192.168.1.1", true,
|
auto delta = []() {
|
||||||
"/", false));
|
return createCookie("delta", "DELTA", "aria2.org", false,
|
||||||
Cookie hotel1(createCookie("hotel", "HOTEL1", "samename.x", false,
|
"/foo/bar", false);
|
||||||
"/", false));
|
};
|
||||||
Cookie hotel2(createCookie("hotel", "HOTEL2", "samename.x", false,
|
auto echo = []() {
|
||||||
"/hotel", false));
|
return createCookie("echo", "ECHO", "www.dl.aria2.org", false,
|
||||||
Cookie hotel3(createCookie("hotel", "HOTEL3", "samename.x", false,
|
"/", false);
|
||||||
"/bar/wine", false));
|
};
|
||||||
Cookie hotel4(createCookie("hotel", "HOTEL4", "samename.x", false,
|
auto foxtrot = []() {
|
||||||
"/bar/", false));
|
return createCookie("foxtrot", "FOXTROT", "sf.net", false,
|
||||||
Cookie india1(createCookie("india", "INDIA1", "default.domain", true,
|
"/", false);
|
||||||
"/foo", false));
|
};
|
||||||
Cookie india2(createCookie("india", "INDIA2", "default.domain", false,
|
auto golf = []() {
|
||||||
"/", false));
|
return createCookie("golf", "GOLF", "192.168.1.1", true,
|
||||||
Cookie juliet1(createCookie("juliet", "JULIET1", "localhost", true,
|
"/", false);
|
||||||
"/foo", false));
|
};
|
||||||
|
auto hotel1 = []() {
|
||||||
|
return createCookie("hotel", "HOTEL1", "samename.x", false,
|
||||||
|
"/", false);
|
||||||
|
};
|
||||||
|
auto hotel2 = []() {
|
||||||
|
return createCookie("hotel", "HOTEL2", "samename.x", false,
|
||||||
|
"/hotel", false);
|
||||||
|
};
|
||||||
|
auto hotel3 = []() {
|
||||||
|
return createCookie("hotel", "HOTEL3", "samename.x", false,
|
||||||
|
"/bar/wine", false);
|
||||||
|
};
|
||||||
|
auto hotel4 = []() {
|
||||||
|
return createCookie("hotel", "HOTEL4", "samename.x", false,
|
||||||
|
"/bar/", false);
|
||||||
|
};
|
||||||
|
auto india1 = []() {
|
||||||
|
return createCookie("india", "INDIA1", "default.domain", true,
|
||||||
|
"/foo", false);
|
||||||
|
};
|
||||||
|
auto india2 = []() {
|
||||||
|
return createCookie("india", "INDIA2", "default.domain", false,
|
||||||
|
"/", false);
|
||||||
|
};
|
||||||
|
auto juliet1 = []() {
|
||||||
|
return createCookie("juliet", "JULIET1", "localhost", true,
|
||||||
|
"/foo", false);
|
||||||
|
};
|
||||||
|
|
||||||
CPPUNIT_ASSERT(st.store(alpha, now));
|
CPPUNIT_ASSERT(st.store(alpha(), now));
|
||||||
CPPUNIT_ASSERT(st.store(bravo, now));
|
CPPUNIT_ASSERT(st.store(bravo(), now));
|
||||||
CPPUNIT_ASSERT(st.store(charlie, now));
|
CPPUNIT_ASSERT(st.store(charlie(), now));
|
||||||
CPPUNIT_ASSERT(st.store(delta, now));
|
CPPUNIT_ASSERT(st.store(delta(), now));
|
||||||
CPPUNIT_ASSERT(st.store(echo, now));
|
CPPUNIT_ASSERT(st.store(echo(), now));
|
||||||
CPPUNIT_ASSERT(st.store(foxtrot, now));
|
CPPUNIT_ASSERT(st.store(foxtrot(), now));
|
||||||
CPPUNIT_ASSERT(st.store(golf, now));
|
CPPUNIT_ASSERT(st.store(golf(), now));
|
||||||
CPPUNIT_ASSERT(st.store(hotel1, now));
|
CPPUNIT_ASSERT(st.store(hotel1(), now));
|
||||||
CPPUNIT_ASSERT(st.store(hotel2, now));
|
CPPUNIT_ASSERT(st.store(hotel2(), now));
|
||||||
CPPUNIT_ASSERT(st.store(hotel3, now));
|
CPPUNIT_ASSERT(st.store(hotel3(), now));
|
||||||
CPPUNIT_ASSERT(st.store(hotel4, now));
|
CPPUNIT_ASSERT(st.store(hotel4(), now));
|
||||||
CPPUNIT_ASSERT(st.store(india1, now));
|
CPPUNIT_ASSERT(st.store(india1(), now));
|
||||||
CPPUNIT_ASSERT(st.store(india2, now));
|
CPPUNIT_ASSERT(st.store(india2(), now));
|
||||||
CPPUNIT_ASSERT(st.store(juliet1, now));
|
CPPUNIT_ASSERT(st.store(juliet1(), now));
|
||||||
|
|
||||||
std::vector<Cookie> aria2Slash = st.criteriaFind("www.dl.aria2.org", "/",
|
auto aria2Slash = st.criteriaFind("www.dl.aria2.org", "/", 0, false);
|
||||||
0, false);
|
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)2, aria2Slash.size());
|
CPPUNIT_ASSERT_EQUAL((size_t)2, aria2Slash.size());
|
||||||
CPPUNIT_ASSERT(std::find(aria2Slash.begin(), aria2Slash.end(), alpha)
|
CPPUNIT_ASSERT(derefFind(aria2Slash, alpha()));
|
||||||
!= aria2Slash.end());
|
CPPUNIT_ASSERT(derefFind(aria2Slash, echo()));
|
||||||
CPPUNIT_ASSERT(std::find(aria2Slash.begin(), aria2Slash.end(), echo)
|
|
||||||
!= aria2Slash.end());
|
|
||||||
|
|
||||||
std::vector<Cookie> aria2SlashFoo = st.criteriaFind("www.dl.aria2.org","/foo",
|
auto aria2SlashFoo = st.criteriaFind("www.dl.aria2.org","/foo", 0, false);
|
||||||
0, false);
|
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)3, aria2SlashFoo.size());
|
CPPUNIT_ASSERT_EQUAL((size_t)3, aria2SlashFoo.size());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("bravo"), aria2SlashFoo[0].getName());
|
CPPUNIT_ASSERT_EQUAL(std::string("bravo"), aria2SlashFoo[0]->getName());
|
||||||
CPPUNIT_ASSERT(std::find(aria2SlashFoo.begin(), aria2SlashFoo.end(), alpha)
|
CPPUNIT_ASSERT(derefFind(aria2SlashFoo, alpha()));
|
||||||
!= aria2SlashFoo.end());
|
CPPUNIT_ASSERT(derefFind(aria2SlashFoo, echo()));
|
||||||
CPPUNIT_ASSERT(std::find(aria2SlashFoo.begin(), aria2SlashFoo.end(), echo)
|
|
||||||
!= aria2SlashFoo.end());
|
|
||||||
|
|
||||||
std::vector<Cookie> aria2Expires = st.criteriaFind("www.dl.aria2.org", "/foo",
|
auto aria2Expires = st.criteriaFind("www.dl.aria2.org", "/foo", 1120, false);
|
||||||
1120,
|
|
||||||
false);
|
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)2, aria2Expires.size());
|
CPPUNIT_ASSERT_EQUAL((size_t)2, aria2Expires.size());
|
||||||
CPPUNIT_ASSERT(std::find(aria2Expires.begin(), aria2Expires.end(), alpha)
|
CPPUNIT_ASSERT(derefFind(aria2Expires, alpha()));
|
||||||
!= aria2Expires.end());
|
CPPUNIT_ASSERT(derefFind(aria2Expires, echo()));
|
||||||
CPPUNIT_ASSERT(std::find(aria2Expires.begin(), aria2Expires.end(), echo)
|
|
||||||
!= aria2Expires.end());
|
|
||||||
|
|
||||||
std::vector<Cookie> dlAria2 = st.criteriaFind("dl.aria2.org", "/", 0, false);
|
auto dlAria2 = st.criteriaFind("dl.aria2.org", "/", 0, false);
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)1, dlAria2.size());
|
CPPUNIT_ASSERT_EQUAL((size_t)1, dlAria2.size());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("alpha"), dlAria2[0].getName());
|
CPPUNIT_ASSERT_EQUAL(std::string("alpha"), dlAria2[0]->getName());
|
||||||
|
|
||||||
std::vector<Cookie> tailmatchAria2 = st.criteriaFind("myaria2.org", "/", 0,
|
auto tailmatchAria2 = st.criteriaFind("myaria2.org", "/", 0, false);
|
||||||
false);
|
|
||||||
CPPUNIT_ASSERT(tailmatchAria2.empty());
|
CPPUNIT_ASSERT(tailmatchAria2.empty());
|
||||||
|
|
||||||
std::vector<Cookie> numericHostCookies = st.criteriaFind("192.168.1.1", "/",0,
|
auto numericHostCookies = st.criteriaFind("192.168.1.1", "/",0, false);
|
||||||
false);
|
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)1, numericHostCookies.size());
|
CPPUNIT_ASSERT_EQUAL((size_t)1, numericHostCookies.size());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("golf"), numericHostCookies[0].getName());
|
CPPUNIT_ASSERT_EQUAL(std::string("golf"), numericHostCookies[0]->getName());
|
||||||
|
|
||||||
std::vector<Cookie> sameNameCookies =
|
auto sameNameCookies = st.criteriaFind("samename.x", "/bar/wine", 0, false);
|
||||||
st.criteriaFind("samename.x", "/bar/wine", 0, false);
|
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)3, sameNameCookies.size());
|
CPPUNIT_ASSERT_EQUAL((size_t)3, sameNameCookies.size());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("HOTEL3"), sameNameCookies[0].getValue());
|
CPPUNIT_ASSERT_EQUAL(std::string("HOTEL3"), sameNameCookies[0]->getValue());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("HOTEL4"), sameNameCookies[1].getValue());
|
CPPUNIT_ASSERT_EQUAL(std::string("HOTEL4"), sameNameCookies[1]->getValue());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("HOTEL1"), sameNameCookies[2].getValue());
|
CPPUNIT_ASSERT_EQUAL(std::string("HOTEL1"), sameNameCookies[2]->getValue());
|
||||||
|
|
||||||
std::vector<Cookie> defaultDomainCookies =
|
auto defaultDomainCookies = st.criteriaFind("default.domain", "/foo", 0,
|
||||||
st.criteriaFind("default.domain", "/foo", 0, false);
|
false);
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)2, defaultDomainCookies.size());
|
CPPUNIT_ASSERT_EQUAL((size_t)2, defaultDomainCookies.size());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("INDIA1"),
|
CPPUNIT_ASSERT_EQUAL(std::string("INDIA1"),
|
||||||
defaultDomainCookies[0].getValue());
|
defaultDomainCookies[0]->getValue());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("INDIA2"),
|
CPPUNIT_ASSERT_EQUAL(std::string("INDIA2"),
|
||||||
defaultDomainCookies[1].getValue());
|
defaultDomainCookies[1]->getValue());
|
||||||
defaultDomainCookies =
|
defaultDomainCookies =
|
||||||
st.criteriaFind("sub.default.domain", "/foo", 0, false);
|
st.criteriaFind("sub.default.domain", "/foo", 0, false);
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)1, defaultDomainCookies.size());
|
CPPUNIT_ASSERT_EQUAL((size_t)1, defaultDomainCookies.size());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("INDIA2"),
|
CPPUNIT_ASSERT_EQUAL(std::string("INDIA2"),
|
||||||
defaultDomainCookies[0].getValue());
|
defaultDomainCookies[0]->getValue());
|
||||||
|
|
||||||
// localhost.local case
|
// localhost.local case
|
||||||
std::vector<Cookie> localDomainCookies =
|
auto localDomainCookies = st.criteriaFind("localhost", "/foo", 0, false);
|
||||||
st.criteriaFind("localhost", "/foo", 0, false);
|
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)1, localDomainCookies.size());
|
CPPUNIT_ASSERT_EQUAL((size_t)1, localDomainCookies.size());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("JULIET1"),
|
CPPUNIT_ASSERT_EQUAL(std::string("JULIET1"),
|
||||||
localDomainCookies[0].getValue());
|
localDomainCookies[0]->getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CookieStorageTest::testCriteriaFind_cookieOrder()
|
void CookieStorageTest::testCriteriaFind_cookieOrder()
|
||||||
{
|
{
|
||||||
CookieStorage st;
|
auto st = CookieStorage{};
|
||||||
Cookie a(createCookie("a", "0", "host", true, "/", false));
|
auto a = createCookie("a", "0", "host", true, "/", false);
|
||||||
a.setCreationTime(1000);
|
a->setCreationTime(1000);
|
||||||
Cookie b(createCookie("b", "0", "host", true, "/foo", false));
|
auto b = createCookie("b", "0", "host", true, "/foo", false);
|
||||||
b.setCreationTime(5000);
|
b->setCreationTime(5000);
|
||||||
Cookie c(createCookie("c", "0", "host", true, "/foo", false));
|
auto c = createCookie("c", "0", "host", true, "/foo", false);
|
||||||
c.setCreationTime(4000);
|
c->setCreationTime(4000);
|
||||||
Cookie d(createCookie("d", "0", "host", true, "/foo/bar", false));
|
auto d = createCookie("d", "0", "host", true, "/foo/bar", false);
|
||||||
d.setCreationTime(6000);
|
d->setCreationTime(6000);
|
||||||
|
|
||||||
st.store(a, 0);
|
st.store(std::move(a), 0);
|
||||||
st.store(b, 0);
|
st.store(std::move(b), 0);
|
||||||
st.store(c, 0);
|
st.store(std::move(c), 0);
|
||||||
st.store(d, 0);
|
st.store(std::move(d), 0);
|
||||||
|
|
||||||
std::vector<Cookie> cookies = st.criteriaFind("host", "/foo/bar", 0, false);
|
auto cookies = st.criteriaFind("host", "/foo/bar", 0, false);
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)4, cookies.size());
|
CPPUNIT_ASSERT_EQUAL((size_t)4, cookies.size());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("d"), cookies[0].getName());
|
CPPUNIT_ASSERT_EQUAL(std::string("d"), cookies[0]->getName());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("c"), cookies[1].getName());
|
CPPUNIT_ASSERT_EQUAL(std::string("c"), cookies[1]->getName());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("b"), cookies[2].getName());
|
CPPUNIT_ASSERT_EQUAL(std::string("b"), cookies[2]->getName());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("a"), cookies[3].getName());
|
CPPUNIT_ASSERT_EQUAL(std::string("a"), cookies[3]->getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CookieStorageTest::testLoad()
|
void CookieStorageTest::testLoad()
|
||||||
{
|
{
|
||||||
CookieStorage st;
|
auto st = CookieStorage{};
|
||||||
|
|
||||||
st.load(A2_TEST_DIR"/nscookietest.txt", 1001);
|
st.load(A2_TEST_DIR"/nscookietest.txt", 1001);
|
||||||
|
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)4, st.size());
|
CPPUNIT_ASSERT_EQUAL((size_t)4, st.size());
|
||||||
|
|
||||||
std::vector<Cookie> cookies;
|
auto cookies = dumpCookie(st);
|
||||||
dumpCookie(cookies, st);
|
|
||||||
|
|
||||||
Cookie c = cookies[0];
|
auto c = cookies[0];
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("passwd"), c.getName());
|
CPPUNIT_ASSERT_EQUAL(std::string("passwd"), c->getName());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("secret"), c.getValue());
|
CPPUNIT_ASSERT_EQUAL(std::string("secret"), c->getValue());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::numeric_limits<time_t>::max(), c.getExpiryTime());
|
CPPUNIT_ASSERT_EQUAL(std::numeric_limits<time_t>::max(), c->getExpiryTime());
|
||||||
CPPUNIT_ASSERT(!c.getPersistent());
|
CPPUNIT_ASSERT(!c->getPersistent());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("/cgi-bin"), c.getPath());
|
CPPUNIT_ASSERT_EQUAL(std::string("/cgi-bin"), c->getPath());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), c.getDomain());
|
CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), c->getDomain());
|
||||||
CPPUNIT_ASSERT(c.getHostOnly());
|
CPPUNIT_ASSERT(c->getHostOnly());
|
||||||
CPPUNIT_ASSERT(!c.getSecure());
|
CPPUNIT_ASSERT(!c->getSecure());
|
||||||
|
|
||||||
c = cookies[1];
|
c = cookies[1];
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("novalue"), c.getName());
|
CPPUNIT_ASSERT_EQUAL(std::string("novalue"), c->getName());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string(""), c.getValue());
|
CPPUNIT_ASSERT_EQUAL(std::string(""), c->getValue());
|
||||||
CPPUNIT_ASSERT_EQUAL((time_t)2147483647, c.getExpiryTime());
|
CPPUNIT_ASSERT_EQUAL((time_t)2147483647, c->getExpiryTime());
|
||||||
CPPUNIT_ASSERT(c.getPersistent());
|
CPPUNIT_ASSERT(c->getPersistent());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("/"), c.getPath());
|
CPPUNIT_ASSERT_EQUAL(std::string("/"), c->getPath());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("example.org"), c.getDomain());
|
CPPUNIT_ASSERT_EQUAL(std::string("example.org"), c->getDomain());
|
||||||
CPPUNIT_ASSERT(!c.getHostOnly());
|
CPPUNIT_ASSERT(!c->getHostOnly());
|
||||||
CPPUNIT_ASSERT(!c.getSecure());
|
CPPUNIT_ASSERT(!c->getSecure());
|
||||||
|
|
||||||
c = cookies[2];
|
c = cookies[2];
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("JSESSIONID"), c.getName());
|
CPPUNIT_ASSERT_EQUAL(std::string("JSESSIONID"), c->getName());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("123456789"), c.getValue());
|
CPPUNIT_ASSERT_EQUAL(std::string("123456789"), c->getValue());
|
||||||
CPPUNIT_ASSERT_EQUAL((time_t)2147483647, c.getExpiryTime());
|
CPPUNIT_ASSERT_EQUAL((time_t)2147483647, c->getExpiryTime());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("/"), c.getPath());
|
CPPUNIT_ASSERT_EQUAL(std::string("/"), c->getPath());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("localhost"), c.getDomain());
|
CPPUNIT_ASSERT_EQUAL(std::string("localhost"), c->getDomain());
|
||||||
CPPUNIT_ASSERT(c.getHostOnly());
|
CPPUNIT_ASSERT(c->getHostOnly());
|
||||||
CPPUNIT_ASSERT(c.getSecure());
|
CPPUNIT_ASSERT(c->getSecure());
|
||||||
|
|
||||||
c = cookies[3];
|
c = cookies[3];
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("TAX"), c.getName());
|
CPPUNIT_ASSERT_EQUAL(std::string("TAX"), c->getName());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("1000"), c.getValue());
|
CPPUNIT_ASSERT_EQUAL(std::string("1000"), c->getValue());
|
||||||
CPPUNIT_ASSERT((time_t)INT32_MAX <= c.getExpiryTime());
|
CPPUNIT_ASSERT((time_t)INT32_MAX <= c->getExpiryTime());
|
||||||
CPPUNIT_ASSERT(c.getPersistent());
|
CPPUNIT_ASSERT(c->getPersistent());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("/"), c.getPath());
|
CPPUNIT_ASSERT_EQUAL(std::string("/"), c->getPath());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("overflow"), c.getDomain());
|
CPPUNIT_ASSERT_EQUAL(std::string("overflow"), c->getDomain());
|
||||||
CPPUNIT_ASSERT(!c.getSecure());
|
CPPUNIT_ASSERT(!c->getSecure());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CookieStorageTest::testLoad_sqlite3()
|
void CookieStorageTest::testLoad_sqlite3()
|
||||||
{
|
{
|
||||||
CookieStorage st;
|
auto st = CookieStorage{};
|
||||||
#ifdef HAVE_SQLITE3
|
#ifdef HAVE_SQLITE3
|
||||||
st.load(A2_TEST_DIR"/cookies.sqlite", 1000);
|
st.load(A2_TEST_DIR"/cookies.sqlite", 1000);
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)2, st.size());
|
CPPUNIT_ASSERT_EQUAL((size_t)2, st.size());
|
||||||
std::vector<Cookie> cookies;
|
auto cookies = dumpCookie(st);
|
||||||
dumpCookie(cookies, st);
|
auto c = cookies[0];
|
||||||
Cookie c = cookies[0];
|
CPPUNIT_ASSERT_EQUAL(std::string("JSESSIONID"), c->getName());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("JSESSIONID"), c.getName());
|
CPPUNIT_ASSERT_EQUAL(std::string("123456789"), c->getValue());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("123456789"), c.getValue());
|
CPPUNIT_ASSERT_EQUAL((time_t)INT32_MAX, c->getExpiryTime());
|
||||||
CPPUNIT_ASSERT_EQUAL((time_t)INT32_MAX, c.getExpiryTime());
|
CPPUNIT_ASSERT(c->getPersistent());
|
||||||
CPPUNIT_ASSERT(c.getPersistent());
|
CPPUNIT_ASSERT_EQUAL(std::string("localhost"), c->getDomain());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("localhost"), c.getDomain());
|
CPPUNIT_ASSERT(c->getHostOnly());
|
||||||
CPPUNIT_ASSERT(c.getHostOnly());
|
CPPUNIT_ASSERT_EQUAL(std::string("/"), c->getPath());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("/"), c.getPath());
|
CPPUNIT_ASSERT(c->getSecure());
|
||||||
CPPUNIT_ASSERT(c.getSecure());
|
|
||||||
|
|
||||||
c = cookies[1];
|
c = cookies[1];
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("foo"), c.getName());
|
CPPUNIT_ASSERT_EQUAL(std::string("foo"), c->getName());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("bar"), c.getValue());
|
CPPUNIT_ASSERT_EQUAL(std::string("bar"), c->getValue());
|
||||||
CPPUNIT_ASSERT((time_t)INT32_MAX <= c.getExpiryTime());
|
CPPUNIT_ASSERT((time_t)INT32_MAX <= c->getExpiryTime());
|
||||||
CPPUNIT_ASSERT(c.getPersistent());
|
CPPUNIT_ASSERT(c->getPersistent());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("overflow.time_t.org"), c.getDomain());
|
CPPUNIT_ASSERT_EQUAL(std::string("overflow.time_t.org"), c->getDomain());
|
||||||
CPPUNIT_ASSERT(!c.getHostOnly());
|
CPPUNIT_ASSERT(!c->getHostOnly());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("/path/to"), c.getPath());
|
CPPUNIT_ASSERT_EQUAL(std::string("/path/to"), c->getPath());
|
||||||
CPPUNIT_ASSERT(!c.getSecure());
|
CPPUNIT_ASSERT(!c->getSecure());
|
||||||
|
|
||||||
#else // !HAVE_SQLITE3
|
#else // !HAVE_SQLITE3
|
||||||
CPPUNIT_ASSERT(!st.load(A2_TEST_DIR"/cookies.sqlite", 1000));
|
CPPUNIT_ASSERT(!st.load(A2_TEST_DIR"/cookies.sqlite", 1000));
|
||||||
|
@ -345,7 +368,7 @@ void CookieStorageTest::testLoad_sqlite3()
|
||||||
|
|
||||||
void CookieStorageTest::testLoad_fileNotfound()
|
void CookieStorageTest::testLoad_fileNotfound()
|
||||||
{
|
{
|
||||||
CookieStorage st;
|
auto st = CookieStorage{};
|
||||||
CPPUNIT_ASSERT(!st.load("./aria2_CookieStorageTest_testLoad_fileNotfound",0));
|
CPPUNIT_ASSERT(!st.load("./aria2_CookieStorageTest_testLoad_fileNotfound",0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,22 +377,22 @@ void CookieStorageTest::testSaveNsFormat()
|
||||||
// TODO add cookie with default domain
|
// TODO add cookie with default domain
|
||||||
std::string filename = A2_TEST_OUT_DIR"/aria2_CookieStorageTest_testSaveNsFormat";
|
std::string filename = A2_TEST_OUT_DIR"/aria2_CookieStorageTest_testSaveNsFormat";
|
||||||
File(filename).remove();
|
File(filename).remove();
|
||||||
CookieStorage st;
|
auto st = CookieStorage{};
|
||||||
time_t now = 1000;
|
time_t now = 1000;
|
||||||
st.store(Cookie(createCookie("favorite", "classic", "domain.org", false,
|
st.store(createCookie("favorite", "classic", "domain.org", false,
|
||||||
"/config",true)), now);
|
"/config",true), now);
|
||||||
st.store(Cookie(createCookie("uid", "tujikawa", now, "domain.org", true,
|
st.store(createCookie("uid", "tujikawa", now, "domain.org", true,
|
||||||
"/",false)), now);
|
"/",false), now);
|
||||||
CPPUNIT_ASSERT(st.saveNsFormat(filename));
|
CPPUNIT_ASSERT(st.saveNsFormat(filename));
|
||||||
CookieStorage loadst;
|
auto loadst = CookieStorage{};
|
||||||
loadst.load(filename, now);
|
loadst.load(filename, now);
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)2, loadst.size());
|
CPPUNIT_ASSERT_EQUAL((size_t)2, loadst.size());
|
||||||
|
|
||||||
std::vector<Cookie> cookies;
|
auto cookies = dumpCookie(loadst);
|
||||||
dumpCookie(cookies, loadst);
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("favorite"), cookies[0].getName());
|
CPPUNIT_ASSERT_EQUAL((size_t)2, cookies.size());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("uid"), cookies[1].getName());
|
CPPUNIT_ASSERT_EQUAL(std::string("favorite"), cookies[0]->getName());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(std::string("uid"), cookies[1]->getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CookieStorageTest::testSaveNsFormat_fail()
|
void CookieStorageTest::testSaveNsFormat_fail()
|
||||||
|
@ -380,17 +403,16 @@ void CookieStorageTest::testSaveNsFormat_fail()
|
||||||
f.remove();
|
f.remove();
|
||||||
f.mkdirs();
|
f.mkdirs();
|
||||||
CPPUNIT_ASSERT(f.isDir());
|
CPPUNIT_ASSERT(f.isDir());
|
||||||
CookieStorage st;
|
auto st = CookieStorage{};
|
||||||
CPPUNIT_ASSERT(!st.saveNsFormat(filename));
|
CPPUNIT_ASSERT(!st.saveNsFormat(filename));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CookieStorageTest::testCookieIsFull()
|
void CookieStorageTest::testCookieIsFull()
|
||||||
{
|
{
|
||||||
CookieStorage st;
|
auto st = CookieStorage{};
|
||||||
for(size_t i = 0; i < CookieStorage::MAX_COOKIE_PER_DOMAIN+1; ++i) {
|
for(size_t i = 0; i < CookieStorage::MAX_COOKIE_PER_DOMAIN+1; ++i) {
|
||||||
Cookie c(createCookie("k"+util::itos(i), "v", "aria2.org", false,
|
st.store(createCookie("k"+util::itos(i), "v", "aria2.org", false,
|
||||||
"/", false));
|
"/", false), 0);
|
||||||
st.store(c, 0);
|
|
||||||
}
|
}
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)CookieStorage::MAX_COOKIE_PER_DOMAIN, st.size());
|
CPPUNIT_ASSERT_EQUAL((size_t)CookieStorage::MAX_COOKIE_PER_DOMAIN, st.size());
|
||||||
}
|
}
|
||||||
|
@ -399,13 +421,58 @@ void CookieStorageTest::testDomainIsFull()
|
||||||
{
|
{
|
||||||
// See DOMAIN_EVICTION_TRIGGER and DOMAIN_EVICTION_RATE in
|
// See DOMAIN_EVICTION_TRIGGER and DOMAIN_EVICTION_RATE in
|
||||||
// CookieStorage.cc
|
// CookieStorage.cc
|
||||||
CookieStorage st;
|
auto st = CookieStorage{};
|
||||||
for(size_t i = 0; i < 2001; ++i) {
|
for(size_t i = 0; i < 2001; ++i) {
|
||||||
Cookie c(createCookie("k", "v", "domain"+util::itos(i), true,
|
st.store(createCookie("k", "v", "domain"+util::itos(i), true,
|
||||||
"/", false));
|
"/", false), 0);
|
||||||
st.store(c, 0);
|
|
||||||
}
|
}
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)1801, st.size());
|
CPPUNIT_ASSERT_EQUAL((size_t)1801, st.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CookieStorageTest::testEviction()
|
||||||
|
{
|
||||||
|
auto st = CookieStorage{};
|
||||||
|
auto alpha = []() {
|
||||||
|
return createCookie("a", "alpha", "aria2.sf.net", false, "/", false);
|
||||||
|
};
|
||||||
|
auto bravo = []() {
|
||||||
|
return createCookie("b", "bravo", "d.aria2.sf.net", false, "/", false);
|
||||||
|
};
|
||||||
|
auto charlie = []() {
|
||||||
|
return createCookie("c", "charlie", "a2.github.com", false, "/", false);
|
||||||
|
};
|
||||||
|
auto delta = []() {
|
||||||
|
return createCookie("d", "delta", "aria2.sf.net", false, "/", false);
|
||||||
|
};
|
||||||
|
st.store(alpha(), 0);
|
||||||
|
CPPUNIT_ASSERT_EQUAL((size_t)1, st.getLruTrackerSize());
|
||||||
|
st.store(bravo(), 1);
|
||||||
|
CPPUNIT_ASSERT_EQUAL((size_t)2, st.getLruTrackerSize());
|
||||||
|
st.store(charlie(), 2);
|
||||||
|
CPPUNIT_ASSERT_EQUAL((size_t)3, st.getLruTrackerSize());
|
||||||
|
st.store(delta(), 0);
|
||||||
|
CPPUNIT_ASSERT_EQUAL((size_t)3, st.getLruTrackerSize());
|
||||||
|
|
||||||
|
// aria2.sf.net will be evicted
|
||||||
|
st.evictNode(1);
|
||||||
|
CPPUNIT_ASSERT_EQUAL((size_t)2, st.getLruTrackerSize());
|
||||||
|
CPPUNIT_ASSERT(!st.contains(*alpha()));
|
||||||
|
CPPUNIT_ASSERT(st.contains(*bravo()));
|
||||||
|
CPPUNIT_ASSERT(st.contains(*charlie()));
|
||||||
|
CPPUNIT_ASSERT(!st.contains(*delta()));
|
||||||
|
|
||||||
|
// d.aria2.sf.net will be evicted
|
||||||
|
st.evictNode(1);
|
||||||
|
CPPUNIT_ASSERT_EQUAL((size_t)1, st.getLruTrackerSize());
|
||||||
|
CPPUNIT_ASSERT(!st.contains(*bravo()));
|
||||||
|
CPPUNIT_ASSERT(st.contains(*charlie()));
|
||||||
|
|
||||||
|
// a2.github.com will be evicted
|
||||||
|
st.evictNode(1);
|
||||||
|
CPPUNIT_ASSERT_EQUAL((size_t)0, st.getLruTrackerSize());
|
||||||
|
CPPUNIT_ASSERT(!st.contains(*charlie()));
|
||||||
|
CPPUNIT_ASSERT_EQUAL((size_t)0, st.size());
|
||||||
|
CPPUNIT_ASSERT(!st.getRootNode()->hasNext());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -35,67 +35,66 @@ CPPUNIT_TEST_SUITE_REGISTRATION(CookieTest);
|
||||||
|
|
||||||
void CookieTest::testOperatorEqual()
|
void CookieTest::testOperatorEqual()
|
||||||
{
|
{
|
||||||
Cookie a(createCookie("k", "v", "localhost", true, "/", false));
|
auto a = createCookie("k", "v", "localhost", true, "/", false);
|
||||||
Cookie b(createCookie("k", "v", "localhost", true, "/", true));
|
auto b = createCookie("k", "v", "localhost", true, "/", true);
|
||||||
Cookie wrongPath(createCookie("k", "v", "localhost", true, "/a", false));
|
auto wrongPath = createCookie("k", "v", "localhost", true, "/a", false);
|
||||||
Cookie wrongDomain(createCookie("k", "v", "mydomain", true, "/", false));
|
auto wrongDomain = createCookie("k", "v", "mydomain", true, "/", false);
|
||||||
Cookie wrongName(createCookie("h", "v", "localhost", true, "/a", false));
|
auto wrongName = createCookie("h", "v", "localhost", true, "/a", false);
|
||||||
Cookie caseSensitiveName(createCookie("K", "v", "localhost", true,
|
auto caseSensitiveName = createCookie("K", "v", "localhost", true,
|
||||||
"/a", false));
|
"/a", false);
|
||||||
CPPUNIT_ASSERT(a == b);
|
CPPUNIT_ASSERT(*a == *b);
|
||||||
CPPUNIT_ASSERT(!(a == wrongPath));
|
CPPUNIT_ASSERT(!(*a == *wrongPath));
|
||||||
CPPUNIT_ASSERT(!(a == wrongDomain));
|
CPPUNIT_ASSERT(!(*a == *wrongDomain));
|
||||||
CPPUNIT_ASSERT(!(a == wrongName));
|
CPPUNIT_ASSERT(!(*a == *wrongName));
|
||||||
CPPUNIT_ASSERT(!(a == caseSensitiveName));
|
CPPUNIT_ASSERT(!(*a == *caseSensitiveName));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CookieTest::testMatch()
|
void CookieTest::testMatch()
|
||||||
{
|
{
|
||||||
Cookie c(createCookie("k", "v", "aria2.org", false, "/downloads", false));
|
auto c = createCookie("k", "v", "aria2.org", false, "/downloads", false);
|
||||||
Cookie c2(createCookie("k", "v", "aria2.org", false, "/downloads", false));
|
auto c2 = createCookie("k", "v", "aria2.org", false, "/downloads", false);
|
||||||
Cookie c3(createCookie("k", "v", "aria2.org", true, "/downloads", false));
|
auto c3 = createCookie("k", "v", "aria2.org", true, "/downloads", false);
|
||||||
Cookie c4(createCookie("k", "v", "localhost", true, "/downloads", false));
|
auto 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(c2->match("www.aria2.org", "/downloads", 0, false));
|
||||||
CPPUNIT_ASSERT(!c.match("www.aria.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", "/examples", 0, false));
|
||||||
CPPUNIT_ASSERT(c.match("www.aria2.org", "/downloads", 0, true));
|
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", "/downloads/latest", 0, false));
|
||||||
CPPUNIT_ASSERT(!c.match("www.aria2.org", "/downloadss/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(!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));
|
CPPUNIT_ASSERT(c4->match("localhost", "/downloads", 0, false));
|
||||||
|
|
||||||
Cookie secureCookie(createCookie("k", "v", "secure.aria2.org", false,
|
auto secureCookie = createCookie("k", "v", "secure.aria2.org", false,
|
||||||
"/", true));
|
"/", true);
|
||||||
CPPUNIT_ASSERT(secureCookie.match("secure.aria2.org", "/", 0, true));
|
CPPUNIT_ASSERT(secureCookie->match("secure.aria2.org", "/", 0, true));
|
||||||
CPPUNIT_ASSERT(!secureCookie.match("secure.aria2.org", "/", 0, false));
|
CPPUNIT_ASSERT(!secureCookie->match("secure.aria2.org", "/", 0, false));
|
||||||
CPPUNIT_ASSERT(!secureCookie.match("ssecure.aria2.org", "/", 0, true));
|
CPPUNIT_ASSERT(!secureCookie->match("ssecure.aria2.org", "/", 0, true));
|
||||||
CPPUNIT_ASSERT(secureCookie.match("www.secure.aria2.org", "/", 0, true));
|
CPPUNIT_ASSERT(secureCookie->match("www.secure.aria2.org", "/", 0, true));
|
||||||
|
|
||||||
Cookie expireTest(createCookie("k", "v", 1000, "aria2.org", false,
|
auto expireTest = createCookie("k", "v", 1000, "aria2.org", false,
|
||||||
"/", false));
|
"/", false);
|
||||||
CPPUNIT_ASSERT(expireTest.match("www.aria2.org", "/", 999, 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));
|
CPPUNIT_ASSERT(!expireTest->match("www.aria2.org", "/", 1001, false));
|
||||||
|
|
||||||
Cookie fromNumericHost(createCookie("k", "v", "192.168.1.1", true,
|
auto fromNumericHost = createCookie("k", "v", "192.168.1.1", true,
|
||||||
"/foo", false));
|
"/foo", false);
|
||||||
CPPUNIT_ASSERT(fromNumericHost.match("192.168.1.1", "/foo", 0, 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("www.aria2.org", "/foo", 0, false));
|
||||||
CPPUNIT_ASSERT(!fromNumericHost.match("1.192.168.1.1", "/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));
|
CPPUNIT_ASSERT(!fromNumericHost->match("192.168.1.1", "/", 0, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CookieTest::testIsExpired()
|
void CookieTest::testIsExpired()
|
||||||
{
|
{
|
||||||
Cookie cookie(createCookie("k", "v", 1000, "localhost", true,
|
auto cookie = createCookie("k", "v", 1000, "localhost", true, "/", false);
|
||||||
"/", false));
|
CPPUNIT_ASSERT(cookie->isExpired(1001));
|
||||||
CPPUNIT_ASSERT(cookie.isExpired(1001));
|
CPPUNIT_ASSERT(!cookie->isExpired(1000));
|
||||||
CPPUNIT_ASSERT(!cookie.isExpired(1000));
|
CPPUNIT_ASSERT(!cookie->isExpired(999));
|
||||||
CPPUNIT_ASSERT(!cookie.isExpired(999));
|
auto sessionCookie = createCookie("k", "v", "localhost", true, "/", false);
|
||||||
Cookie sessionCookie(createCookie("k", "v", "localhost", true, "/", false));
|
CPPUNIT_ASSERT(!sessionCookie->isExpired(INT32_MAX));
|
||||||
CPPUNIT_ASSERT(!sessionCookie.isExpired(INT32_MAX));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CookieTest::testToNsCookieFormat()
|
void CookieTest::testToNsCookieFormat()
|
||||||
|
@ -103,12 +102,12 @@ void CookieTest::testToNsCookieFormat()
|
||||||
CPPUNIT_ASSERT_EQUAL
|
CPPUNIT_ASSERT_EQUAL
|
||||||
(std::string(".domain.org\tTRUE\t/\tFALSE\t12345678\thello\tworld"),
|
(std::string(".domain.org\tTRUE\t/\tFALSE\t12345678\thello\tworld"),
|
||||||
createCookie("hello", "world", 12345678, "domain.org", false, "/",false)
|
createCookie("hello", "world", 12345678, "domain.org", false, "/",false)
|
||||||
.toNsCookieFormat());
|
->toNsCookieFormat());
|
||||||
// Session cookie
|
// Session cookie
|
||||||
CPPUNIT_ASSERT_EQUAL
|
CPPUNIT_ASSERT_EQUAL
|
||||||
(std::string("domain.org\tFALSE\t/\tTRUE\t0\thello\tworld"),
|
(std::string("domain.org\tFALSE\t/\tTRUE\t0\thello\tworld"),
|
||||||
createCookie("hello", "world", "domain.org", true, "/", true)
|
createCookie("hello", "world", "domain.org", true, "/", true)
|
||||||
.toNsCookieFormat());
|
->toNsCookieFormat());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -368,6 +368,13 @@ void HttpRequestTest::testCreateRequest_ftp()
|
||||||
CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
|
CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename InputIterator>
|
||||||
|
void foo(CookieStorage& st, InputIterator first, InputIterator last, time_t t)
|
||||||
|
{
|
||||||
|
for(; first != last; ++first) {
|
||||||
|
st.store(*first, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
void HttpRequestTest::testCreateRequest_with_cookie()
|
void HttpRequestTest::testCreateRequest_with_cookie()
|
||||||
{
|
{
|
||||||
auto request = std::make_shared<Request>();
|
auto request = std::make_shared<Request>();
|
||||||
|
@ -376,19 +383,17 @@ void HttpRequestTest::testCreateRequest_with_cookie()
|
||||||
auto segment = std::make_shared<PiecedSegment>(1024*1024, p);
|
auto segment = std::make_shared<PiecedSegment>(1024*1024, p);
|
||||||
auto fileEntry = std::make_shared<FileEntry>("file", 1024*1024*10, 0);
|
auto fileEntry = std::make_shared<FileEntry>("file", 1024*1024*10, 0);
|
||||||
|
|
||||||
std::vector<Cookie> cookies {
|
auto st = CookieStorage{};
|
||||||
createCookie("name1", "value1", "localhost", true, "/archives", false),
|
CPPUNIT_ASSERT(st.store(createCookie("name1", "value1", "localhost", true,
|
||||||
createCookie("name2", "value2", "localhost", true,
|
"/archives", false), 0));
|
||||||
"/archives/download", false),
|
CPPUNIT_ASSERT(st.store(createCookie("name2", "value2", "localhost", true,
|
||||||
createCookie("name3", "value3", "aria2.org", false,
|
"/archives/download", false), 0));
|
||||||
"/archives/download", false),
|
CPPUNIT_ASSERT(st.store(createCookie("name3", "value3", "aria2.org", false,
|
||||||
createCookie("name4", "value4", "aria2.org", false, "/archives/", true),
|
"/archives/download", false), 0));
|
||||||
createCookie("name5", "value5", "example.org", false, "/", false)
|
CPPUNIT_ASSERT(st.store(createCookie("name4", "value4", "aria2.org", false,
|
||||||
};
|
"/archives/", true), 0));
|
||||||
CookieStorage st;
|
CPPUNIT_ASSERT(st.store(createCookie("name5", "value5", "example.org", false,
|
||||||
for(auto c : cookies) {
|
"/", false), 0));
|
||||||
CPPUNIT_ASSERT(st.store(c, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpRequest httpRequest;
|
HttpRequest httpRequest;
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include <cppunit/extensions/HelperMacros.h>
|
#include <cppunit/extensions/HelperMacros.h>
|
||||||
|
|
||||||
|
#include "TestUtil.h"
|
||||||
#include "prefs.h"
|
#include "prefs.h"
|
||||||
#include "PiecedSegment.h"
|
#include "PiecedSegment.h"
|
||||||
#include "Piece.h"
|
#include "Piece.h"
|
||||||
|
@ -511,10 +512,11 @@ void HttpResponseTest::testRetrieveCookie()
|
||||||
|
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)2, st.size());
|
CPPUNIT_ASSERT_EQUAL((size_t)2, st.size());
|
||||||
|
|
||||||
std::vector<Cookie> cookies;
|
auto cookies = std::vector<const Cookie*>{};
|
||||||
st.dumpCookie(std::back_inserter(cookies));
|
st.dumpCookie(std::back_inserter(cookies));
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("k2=v2"), cookies[0].toString());
|
std::sort(std::begin(cookies), std::end(cookies), CookieSorter());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("k3=v3"), cookies[1].toString());
|
CPPUNIT_ASSERT_EQUAL(std::string("k2=v2"), cookies[0]->toString());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(std::string("k3=v3"), cookies[1]->toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpResponseTest::testSupportsPersistentConnection()
|
void HttpResponseTest::testSupportsPersistentConnection()
|
||||||
|
|
|
@ -33,58 +33,58 @@ void NsCookieParserTest::testParse()
|
||||||
{
|
{
|
||||||
NsCookieParser parser;
|
NsCookieParser parser;
|
||||||
time_t now = 0;
|
time_t now = 0;
|
||||||
std::vector<Cookie> cookies = parser.parse(A2_TEST_DIR"/nscookietest.txt", now);
|
auto cookies = parser.parse(A2_TEST_DIR"/nscookietest.txt", now);
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)5, cookies.size());
|
CPPUNIT_ASSERT_EQUAL((size_t)5, cookies.size());
|
||||||
|
|
||||||
Cookie c = cookies[0];
|
auto c = cookies[0].get();
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("JSESSIONID"), c.getName());
|
CPPUNIT_ASSERT_EQUAL(std::string("JSESSIONID"), c->getName());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("123456789"), c.getValue());
|
CPPUNIT_ASSERT_EQUAL(std::string("123456789"), c->getValue());
|
||||||
CPPUNIT_ASSERT_EQUAL((time_t)INT32_MAX, c.getExpiryTime());
|
CPPUNIT_ASSERT_EQUAL((time_t)INT32_MAX, c->getExpiryTime());
|
||||||
CPPUNIT_ASSERT(c.getPersistent());
|
CPPUNIT_ASSERT(c->getPersistent());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("localhost"), c.getDomain());
|
CPPUNIT_ASSERT_EQUAL(std::string("localhost"), c->getDomain());
|
||||||
CPPUNIT_ASSERT(c.getHostOnly());
|
CPPUNIT_ASSERT(c->getHostOnly());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("/"), c.getPath());
|
CPPUNIT_ASSERT_EQUAL(std::string("/"), c->getPath());
|
||||||
CPPUNIT_ASSERT(c.getSecure());
|
CPPUNIT_ASSERT(c->getSecure());
|
||||||
|
|
||||||
c = cookies[1];
|
c = cookies[1].get();
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("user"), c.getName());
|
CPPUNIT_ASSERT_EQUAL(std::string("user"), c->getName());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("me"), c.getValue());
|
CPPUNIT_ASSERT_EQUAL(std::string("me"), c->getValue());
|
||||||
CPPUNIT_ASSERT_EQUAL((time_t)1000, c.getExpiryTime());
|
CPPUNIT_ASSERT_EQUAL((time_t)1000, c->getExpiryTime());
|
||||||
CPPUNIT_ASSERT(c.getPersistent());
|
CPPUNIT_ASSERT(c->getPersistent());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("expired"), c.getDomain());
|
CPPUNIT_ASSERT_EQUAL(std::string("expired"), c->getDomain());
|
||||||
CPPUNIT_ASSERT(c.getHostOnly());
|
CPPUNIT_ASSERT(c->getHostOnly());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("/"), c.getPath());
|
CPPUNIT_ASSERT_EQUAL(std::string("/"), c->getPath());
|
||||||
CPPUNIT_ASSERT(!c.getSecure());
|
CPPUNIT_ASSERT(!c->getSecure());
|
||||||
|
|
||||||
c = cookies[2];
|
c = cookies[2].get();
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("passwd"), c.getName());
|
CPPUNIT_ASSERT_EQUAL(std::string("passwd"), c->getName());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("secret"), c.getValue());
|
CPPUNIT_ASSERT_EQUAL(std::string("secret"), c->getValue());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::numeric_limits<time_t>::max(), c.getExpiryTime());
|
CPPUNIT_ASSERT_EQUAL(std::numeric_limits<time_t>::max(), c->getExpiryTime());
|
||||||
CPPUNIT_ASSERT(!c.getPersistent());
|
CPPUNIT_ASSERT(!c->getPersistent());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), c.getDomain());
|
CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), c->getDomain());
|
||||||
CPPUNIT_ASSERT(c.getHostOnly());
|
CPPUNIT_ASSERT(c->getHostOnly());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("/cgi-bin"), c.getPath());
|
CPPUNIT_ASSERT_EQUAL(std::string("/cgi-bin"), c->getPath());
|
||||||
CPPUNIT_ASSERT(!c.getSecure());
|
CPPUNIT_ASSERT(!c->getSecure());
|
||||||
|
|
||||||
c = cookies[3];
|
c = cookies[3].get();
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("TAX"), c.getName());
|
CPPUNIT_ASSERT_EQUAL(std::string("TAX"), c->getName());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("1000"), c.getValue());
|
CPPUNIT_ASSERT_EQUAL(std::string("1000"), c->getValue());
|
||||||
CPPUNIT_ASSERT((time_t)INT32_MAX <= c.getExpiryTime());
|
CPPUNIT_ASSERT((time_t)INT32_MAX <= c->getExpiryTime());
|
||||||
CPPUNIT_ASSERT(c.getPersistent());
|
CPPUNIT_ASSERT(c->getPersistent());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("overflow"), c.getDomain());
|
CPPUNIT_ASSERT_EQUAL(std::string("overflow"), c->getDomain());
|
||||||
CPPUNIT_ASSERT(c.getHostOnly());
|
CPPUNIT_ASSERT(c->getHostOnly());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("/"), c.getPath());
|
CPPUNIT_ASSERT_EQUAL(std::string("/"), c->getPath());
|
||||||
CPPUNIT_ASSERT(!c.getSecure());
|
CPPUNIT_ASSERT(!c->getSecure());
|
||||||
|
|
||||||
c = cookies[4];
|
c = cookies[4].get();
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("novalue"), c.getName());
|
CPPUNIT_ASSERT_EQUAL(std::string("novalue"), c->getName());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string(""), c.getValue());
|
CPPUNIT_ASSERT_EQUAL(std::string(""), c->getValue());
|
||||||
CPPUNIT_ASSERT_EQUAL((time_t)INT32_MAX, c.getExpiryTime());
|
CPPUNIT_ASSERT_EQUAL((time_t)INT32_MAX, c->getExpiryTime());
|
||||||
CPPUNIT_ASSERT(c.getPersistent());
|
CPPUNIT_ASSERT(c->getPersistent());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("example.org"), c.getDomain());
|
CPPUNIT_ASSERT_EQUAL(std::string("example.org"), c->getDomain());
|
||||||
CPPUNIT_ASSERT(!c.getHostOnly());
|
CPPUNIT_ASSERT(!c->getHostOnly());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("/"), c.getPath());
|
CPPUNIT_ASSERT_EQUAL(std::string("/"), c->getPath());
|
||||||
CPPUNIT_ASSERT(!c.getSecure());
|
CPPUNIT_ASSERT(!c->getSecure());
|
||||||
}
|
}
|
||||||
|
|
||||||
void NsCookieParserTest::testParse_fileNotFound()
|
void NsCookieParserTest::testParse_fileNotFound()
|
||||||
|
|
|
@ -35,55 +35,53 @@ CPPUNIT_TEST_SUITE_REGISTRATION(Sqlite3CookieParserTest);
|
||||||
|
|
||||||
void Sqlite3CookieParserTest::testMozParse()
|
void Sqlite3CookieParserTest::testMozParse()
|
||||||
{
|
{
|
||||||
Sqlite3MozCookieParser parser(A2_TEST_DIR"/cookies.sqlite");
|
auto parser = Sqlite3MozCookieParser{A2_TEST_DIR"/cookies.sqlite"};
|
||||||
std::vector<Cookie> cookies;
|
auto cookies = parser.parse();
|
||||||
parser.parse(cookies);
|
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)3, cookies.size());
|
CPPUNIT_ASSERT_EQUAL((size_t)3, cookies.size());
|
||||||
|
|
||||||
const Cookie& localhost = cookies[0];
|
auto& localhost = cookies[0];
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("JSESSIONID"), localhost.getName());
|
CPPUNIT_ASSERT_EQUAL(std::string("JSESSIONID"), localhost->getName());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("123456789"), localhost.getValue());
|
CPPUNIT_ASSERT_EQUAL(std::string("123456789"), localhost->getValue());
|
||||||
CPPUNIT_ASSERT_EQUAL((time_t)INT32_MAX, localhost.getExpiryTime());
|
CPPUNIT_ASSERT_EQUAL((time_t)INT32_MAX, localhost->getExpiryTime());
|
||||||
CPPUNIT_ASSERT(localhost.getPersistent());
|
CPPUNIT_ASSERT(localhost->getPersistent());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("localhost"), localhost.getDomain());
|
CPPUNIT_ASSERT_EQUAL(std::string("localhost"), localhost->getDomain());
|
||||||
CPPUNIT_ASSERT(localhost.getHostOnly());
|
CPPUNIT_ASSERT(localhost->getHostOnly());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("/"), localhost.getPath());
|
CPPUNIT_ASSERT_EQUAL(std::string("/"), localhost->getPath());
|
||||||
CPPUNIT_ASSERT(localhost.getSecure());
|
CPPUNIT_ASSERT(localhost->getSecure());
|
||||||
CPPUNIT_ASSERT_EQUAL((time_t)3000, localhost.getLastAccessTime());
|
CPPUNIT_ASSERT_EQUAL((time_t)3000, localhost->getLastAccessTime());
|
||||||
CPPUNIT_ASSERT_EQUAL((time_t)3000, localhost.getCreationTime());
|
CPPUNIT_ASSERT_EQUAL((time_t)3000, localhost->getCreationTime());
|
||||||
|
|
||||||
const Cookie& nullValue = cookies[1];
|
auto& nullValue = cookies[1];
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("uid"), nullValue.getName());
|
CPPUNIT_ASSERT_EQUAL(std::string("uid"), nullValue->getName());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string(""), nullValue.getValue());
|
CPPUNIT_ASSERT_EQUAL(std::string(""), nullValue->getValue());
|
||||||
CPPUNIT_ASSERT_EQUAL((time_t)0, nullValue.getExpiryTime());
|
CPPUNIT_ASSERT_EQUAL((time_t)0, nullValue->getExpiryTime());
|
||||||
CPPUNIT_ASSERT(nullValue.getPersistent());
|
CPPUNIT_ASSERT(nullValue->getPersistent());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("null_value.com"), nullValue.getDomain());
|
CPPUNIT_ASSERT_EQUAL(std::string("null_value.com"), nullValue->getDomain());
|
||||||
CPPUNIT_ASSERT(!nullValue.getHostOnly());
|
CPPUNIT_ASSERT(!nullValue->getHostOnly());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("/path/to"), nullValue.getPath());
|
CPPUNIT_ASSERT_EQUAL(std::string("/path/to"), nullValue->getPath());
|
||||||
CPPUNIT_ASSERT(!nullValue.getSecure());
|
CPPUNIT_ASSERT(!nullValue->getSecure());
|
||||||
|
|
||||||
// See row id=3 has no name, so it is skipped.
|
// See row id=3 has no name, so it is skipped.
|
||||||
|
|
||||||
const Cookie& overflowTime = cookies[2];
|
auto& overflowTime = cookies[2];
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("foo"), overflowTime.getName());
|
CPPUNIT_ASSERT_EQUAL(std::string("foo"), overflowTime->getName());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("bar"), overflowTime.getValue());
|
CPPUNIT_ASSERT_EQUAL(std::string("bar"), overflowTime->getValue());
|
||||||
CPPUNIT_ASSERT((time_t)INT32_MAX <= overflowTime.getExpiryTime());
|
CPPUNIT_ASSERT((time_t)INT32_MAX <= overflowTime->getExpiryTime());
|
||||||
CPPUNIT_ASSERT(overflowTime.getPersistent());
|
CPPUNIT_ASSERT(overflowTime->getPersistent());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("overflow.time_t.org"),
|
CPPUNIT_ASSERT_EQUAL(std::string("overflow.time_t.org"),
|
||||||
overflowTime.getDomain());
|
overflowTime->getDomain());
|
||||||
CPPUNIT_ASSERT(!overflowTime.getHostOnly());
|
CPPUNIT_ASSERT(!overflowTime->getHostOnly());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("/path/to"), overflowTime.getPath());
|
CPPUNIT_ASSERT_EQUAL(std::string("/path/to"), overflowTime->getPath());
|
||||||
CPPUNIT_ASSERT(!overflowTime.getSecure());
|
CPPUNIT_ASSERT(!overflowTime->getSecure());
|
||||||
|
|
||||||
// See row id=5 has bad path, so it is skipped.
|
// See row id=5 has bad path, so it is skipped.
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sqlite3CookieParserTest::testMozParse_fileNotFound()
|
void Sqlite3CookieParserTest::testMozParse_fileNotFound()
|
||||||
{
|
{
|
||||||
Sqlite3MozCookieParser parser("fileNotFound");
|
auto parser = Sqlite3MozCookieParser{"fileNotFound"};
|
||||||
try {
|
try {
|
||||||
std::vector<Cookie> cookies;
|
parser.parse();
|
||||||
parser.parse(cookies);
|
|
||||||
CPPUNIT_FAIL("exception must be thrown.");
|
CPPUNIT_FAIL("exception must be thrown.");
|
||||||
} catch(RecoverableException& e) {
|
} catch(RecoverableException& e) {
|
||||||
// SUCCESS
|
// SUCCESS
|
||||||
|
@ -95,10 +93,9 @@ void Sqlite3CookieParserTest::testMozParse_fileNotFound()
|
||||||
|
|
||||||
void Sqlite3CookieParserTest::testMozParse_badfile()
|
void Sqlite3CookieParserTest::testMozParse_badfile()
|
||||||
{
|
{
|
||||||
Sqlite3MozCookieParser parser(A2_TEST_DIR"/badcookies.sqlite");
|
auto parser = Sqlite3MozCookieParser{A2_TEST_DIR"/badcookies.sqlite"};
|
||||||
try {
|
try {
|
||||||
std::vector<Cookie> cookies;
|
parser.parse();
|
||||||
parser.parse(cookies);
|
|
||||||
CPPUNIT_FAIL("exception must be thrown.");
|
CPPUNIT_FAIL("exception must be thrown.");
|
||||||
} catch(RecoverableException& e) {
|
} catch(RecoverableException& e) {
|
||||||
// SUCCESS
|
// SUCCESS
|
||||||
|
@ -107,37 +104,37 @@ void Sqlite3CookieParserTest::testMozParse_badfile()
|
||||||
|
|
||||||
void Sqlite3CookieParserTest::testChromumParse()
|
void Sqlite3CookieParserTest::testChromumParse()
|
||||||
{
|
{
|
||||||
Sqlite3ChromiumCookieParser parser(A2_TEST_DIR"/chromium_cookies.sqlite");
|
auto parser = Sqlite3ChromiumCookieParser
|
||||||
std::vector<Cookie> cookies;
|
{A2_TEST_DIR"/chromium_cookies.sqlite"};
|
||||||
parser.parse(cookies);
|
auto cookies = parser.parse();
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)3, cookies.size());
|
CPPUNIT_ASSERT_EQUAL((size_t)3, cookies.size());
|
||||||
|
|
||||||
const Cookie& sfnet = cookies[0];
|
auto& sfnet = cookies[0];
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("mykey"), sfnet.getName());
|
CPPUNIT_ASSERT_EQUAL(std::string("mykey"), sfnet->getName());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("pass"), sfnet.getValue());
|
CPPUNIT_ASSERT_EQUAL(std::string("pass"), sfnet->getValue());
|
||||||
CPPUNIT_ASSERT_EQUAL((time_t)12345679, sfnet.getExpiryTime());
|
CPPUNIT_ASSERT_EQUAL((time_t)12345679, sfnet->getExpiryTime());
|
||||||
CPPUNIT_ASSERT(sfnet.getPersistent());
|
CPPUNIT_ASSERT(sfnet->getPersistent());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("aria2.sourceforge.net"),
|
CPPUNIT_ASSERT_EQUAL(std::string("aria2.sourceforge.net"),
|
||||||
sfnet.getDomain());
|
sfnet->getDomain());
|
||||||
CPPUNIT_ASSERT(!sfnet.getHostOnly());
|
CPPUNIT_ASSERT(!sfnet->getHostOnly());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("/"), sfnet.getPath());
|
CPPUNIT_ASSERT_EQUAL(std::string("/"), sfnet->getPath());
|
||||||
CPPUNIT_ASSERT(!sfnet.getSecure());
|
CPPUNIT_ASSERT(!sfnet->getSecure());
|
||||||
|
|
||||||
const Cookie& sfjp = cookies[1];
|
auto& sfjp = cookies[1];
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("myseckey"), sfjp.getName());
|
CPPUNIT_ASSERT_EQUAL(std::string("myseckey"), sfjp->getName());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("pass2"), sfjp.getValue());
|
CPPUNIT_ASSERT_EQUAL(std::string("pass2"), sfjp->getValue());
|
||||||
CPPUNIT_ASSERT_EQUAL((time_t)0, sfjp.getExpiryTime());
|
CPPUNIT_ASSERT_EQUAL((time_t)0, sfjp->getExpiryTime());
|
||||||
CPPUNIT_ASSERT(sfjp.getPersistent());
|
CPPUNIT_ASSERT(sfjp->getPersistent());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("aria2.sourceforge.jp"), sfjp.getDomain());
|
CPPUNIT_ASSERT_EQUAL(std::string("aria2.sourceforge.jp"), sfjp->getDomain());
|
||||||
CPPUNIT_ASSERT(sfjp.getHostOnly());
|
CPPUNIT_ASSERT(sfjp->getHostOnly());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("/profile"), sfjp.getPath());
|
CPPUNIT_ASSERT_EQUAL(std::string("/profile"), sfjp->getPath());
|
||||||
CPPUNIT_ASSERT(sfjp.getSecure());
|
CPPUNIT_ASSERT(sfjp->getSecure());
|
||||||
|
|
||||||
const Cookie& localnet = cookies[2];
|
auto& localnet = cookies[2];
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), localnet.getDomain());
|
CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), localnet->getDomain());
|
||||||
CPPUNIT_ASSERT(sfjp.getHostOnly());
|
CPPUNIT_ASSERT(localnet->getHostOnly());
|
||||||
CPPUNIT_ASSERT_EQUAL((time_t)3000, localnet.getLastAccessTime());
|
CPPUNIT_ASSERT_EQUAL((time_t)3000, localnet->getLastAccessTime());
|
||||||
CPPUNIT_ASSERT_EQUAL((time_t)3000, localnet.getCreationTime());
|
CPPUNIT_ASSERT_EQUAL((time_t)3000, localnet->getCreationTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -50,7 +50,7 @@ std::string readFile(const std::string& path)
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
Cookie createCookie
|
std::unique_ptr<Cookie> createCookie
|
||||||
(const std::string& name,
|
(const std::string& name,
|
||||||
const std::string& value,
|
const std::string& value,
|
||||||
const std::string& domain,
|
const std::string& domain,
|
||||||
|
@ -58,11 +58,11 @@ Cookie createCookie
|
||||||
const std::string& path,
|
const std::string& path,
|
||||||
bool secure)
|
bool secure)
|
||||||
{
|
{
|
||||||
return Cookie
|
return make_unique<Cookie>
|
||||||
(name, value, 0, false, domain, hostOnly, path, secure, false, 0);
|
(name, value, 0, false, domain, hostOnly, path, secure, false, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Cookie createCookie
|
std::unique_ptr<Cookie> createCookie
|
||||||
(const std::string& name,
|
(const std::string& name,
|
||||||
const std::string& value,
|
const std::string& value,
|
||||||
time_t expiryTime,
|
time_t expiryTime,
|
||||||
|
@ -71,7 +71,7 @@ Cookie createCookie
|
||||||
const std::string& path,
|
const std::string& path,
|
||||||
bool secure)
|
bool secure)
|
||||||
{
|
{
|
||||||
return Cookie
|
return make_unique<Cookie>
|
||||||
(name, value, expiryTime, true, domain, hostOnly, path, secure, false, 0);
|
(name, value, expiryTime, true, domain, hostOnly, path, secure, false, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,17 +21,17 @@ std::string readFile(const std::string& path);
|
||||||
|
|
||||||
class CookieSorter {
|
class CookieSorter {
|
||||||
public:
|
public:
|
||||||
bool operator()(const Cookie& lhs, const Cookie& rhs) const
|
bool operator()(const Cookie* lhs, const Cookie* rhs) const
|
||||||
{
|
{
|
||||||
if(lhs.getDomain() == rhs.getDomain()) {
|
if(lhs->getDomain() == rhs->getDomain()) {
|
||||||
return lhs.getName() < rhs.getName();
|
return lhs->getName() < rhs->getName();
|
||||||
} else {
|
} else {
|
||||||
return lhs.getDomain() < rhs.getDomain();
|
return lhs->getDomain() < rhs->getDomain();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Cookie createCookie
|
std::unique_ptr<Cookie> createCookie
|
||||||
(const std::string& name,
|
(const std::string& name,
|
||||||
const std::string& value,
|
const std::string& value,
|
||||||
const std::string& domain,
|
const std::string& domain,
|
||||||
|
@ -39,7 +39,7 @@ Cookie createCookie
|
||||||
const std::string& path,
|
const std::string& path,
|
||||||
bool secure);
|
bool secure);
|
||||||
|
|
||||||
Cookie createCookie
|
std::unique_ptr<Cookie> createCookie
|
||||||
(const std::string& name,
|
(const std::string& name,
|
||||||
const std::string& value,
|
const std::string& value,
|
||||||
time_t expiryTime,
|
time_t expiryTime,
|
||||||
|
@ -75,4 +75,17 @@ std::shared_ptr<RequestGroup> createRequestGroup(int32_t pieceLength,
|
||||||
std::shared_ptr<DownloadResult> createDownloadResult
|
std::shared_ptr<DownloadResult> createDownloadResult
|
||||||
(error_code::Value result, const std::string& uri);
|
(error_code::Value result, const std::string& uri);
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
template<typename V, typename T>
|
||||||
|
bool derefFind(const V& v, const T& t)
|
||||||
|
{
|
||||||
|
for(auto i : v) {
|
||||||
|
if(*i == *t) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
Loading…
Reference in New Issue