diff options
Diffstat (limited to 'src/CookieStorage.cc')
| -rw-r--r-- | src/CookieStorage.cc | 288 |
1 files changed, 129 insertions, 159 deletions
diff --git a/src/CookieStorage.cc b/src/CookieStorage.cc index c82cf7df..383bcb35 100644 --- a/src/CookieStorage.cc +++ b/src/CookieStorage.cc @@ -51,25 +51,28 @@ #include "cookie_helper.h" #include "BufferedFile.h" #ifdef HAVE_SQLITE3 -# include "Sqlite3CookieParserImpl.h" +#include "Sqlite3CookieParserImpl.h" #endif // HAVE_SQLITE3 namespace aria2 { DomainNode::DomainNode(std::string label, DomainNode* parent) - : label_{std::move(label)}, parent_{parent}, lastAccessTime_{0}, - lruAccessTime_{0}, inLru_{false} -{} - -void DomainNode::findCookie -(std::vector<const Cookie*>& out, - const std::string& requestHost, - const std::string& requestPath, - time_t now, bool secure) + : label_{std::move(label)}, + parent_{parent}, + lastAccessTime_{0}, + lruAccessTime_{0}, + inLru_{false} { - if(cookies_) { - for(auto& c : *cookies_) { - if(c->match(requestHost, requestPath, now, secure)) { +} + +void DomainNode::findCookie(std::vector<const Cookie*>& out, + const std::string& requestHost, + const std::string& requestPath, time_t now, + bool secure) +{ + if (cookies_) { + for (auto& c : *cookies_) { + if (c->match(requestHost, requestPath, now, secure)) { c->setLastAccessTime(now); out.push_back(c.get()); } @@ -81,51 +84,54 @@ bool DomainNode::addCookie(std::unique_ptr<Cookie> cookie, time_t now) { using namespace std::placeholders; setLastAccessTime(now); - if(!cookies_) { - if(cookie->isExpired(now)) { + if (!cookies_) { + if (cookie->isExpired(now)) { return false; - } else { + } + else { cookies_ = make_unique<std::deque<std::unique_ptr<Cookie>>>(); cookies_->push_back(std::move(cookie)); 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)) { + 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::end(*cookies_)); - if(cookies_->size() >= CookieStorage::MAX_COOKIE_PER_DOMAIN) { + } + 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::end(*cookies_)); + if (cookies_->size() >= CookieStorage::MAX_COOKIE_PER_DOMAIN) { auto m = std::min_element(std::begin(*cookies_), std::end(*cookies_), [](const std::unique_ptr<Cookie>& lhs, - const std::unique_ptr<Cookie>& rhs) - { + const std::unique_ptr<Cookie>& rhs) { return lhs->getLastAccessTime() < - rhs->getLastAccessTime(); + rhs->getLastAccessTime(); }); *m = std::move(cookie); - } else { + } + else { cookies_->push_back(std::move(cookie)); } - } else { + } + else { cookies_->push_back(std::move(cookie)); } return true; } - } else if(cookie->isExpired(now)) { + } + else if (cookie->isExpired(now)) { cookies_->erase(i); return false; - } else { + } + else { cookie->setCreationTime((*i)->getCreationTime()); *i = std::move(cookie); return true; @@ -134,9 +140,9 @@ bool DomainNode::addCookie(std::unique_ptr<Cookie> cookie, time_t now) bool DomainNode::contains(const Cookie& cookie) const { - if(cookies_) { - for(auto& i : *cookies_) { - if(*i == cookie) { + if (cookies_) { + for (auto& i : *cookies_) { + if (*i == cookie) { return true; } } @@ -146,11 +152,11 @@ bool DomainNode::contains(const Cookie& cookie) const bool DomainNode::writeCookie(BufferedFile& fp) const { - if(cookies_) { - for(const auto& c : *cookies_) { + if (cookies_) { + for (const auto& c : *cookies_) { std::string data = c->toNsCookieFormat(); data += "\n"; - if(fp.write(data.data(), data.size()) != data.size()) { + if (fp.write(data.data(), data.size()) != data.size()) { return false; } } @@ -160,64 +166,42 @@ bool DomainNode::writeCookie(BufferedFile& fp) const size_t DomainNode::countCookie() const { - if(cookies_) { + if (cookies_) { return cookies_->size(); - } else { + } + else { return 0; } } -void DomainNode::clearCookie() -{ - cookies_->clear(); -} +void DomainNode::clearCookie() { cookies_->clear(); } void DomainNode::setLastAccessTime(time_t lastAccessTime) { lastAccessTime_ = lastAccessTime; } -time_t DomainNode::getLastAccessTime() const -{ - return lastAccessTime_; -} +time_t DomainNode::getLastAccessTime() const { return lastAccessTime_; } -void DomainNode::setLruAccessTime(time_t t) -{ - lruAccessTime_ = t; -} +void DomainNode::setLruAccessTime(time_t t) { lruAccessTime_ = t; } -time_t DomainNode::getLruAccessTime() const -{ - return lruAccessTime_; -} +time_t DomainNode::getLruAccessTime() const { return lruAccessTime_; } -bool DomainNode::empty() const -{ - return !cookies_ || cookies_->empty(); -} +bool DomainNode::empty() const { return !cookies_ || cookies_->empty(); } -bool DomainNode::hasNext() const -{ - return !next_.empty(); -} +bool DomainNode::hasNext() const { return !next_.empty(); } -DomainNode* DomainNode::getParent() const -{ - return parent_; -} +DomainNode* DomainNode::getParent() const { return parent_; } -void DomainNode::removeNode(DomainNode* node) -{ - next_.erase(node->getLabel()); -} +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_)) { + if (i == std::end(next_)) { return nullptr; - } else { + } + else { return (*i).second.get(); } } @@ -229,25 +213,16 @@ DomainNode* DomainNode::addNext(std::string label, return res.get(); } -const std::string& DomainNode::getLabel() const -{ - return label_; -} +const std::string& DomainNode::getLabel() const { return label_; } -bool DomainNode::getInLru() const -{ - return inLru_; -} +bool DomainNode::getInLru() const { return inLru_; } + +void DomainNode::setInLru(bool f) { inLru_ = f; } -void DomainNode::setInLru(bool f) +CookieStorage::CookieStorage() : rootNode_{make_unique<DomainNode>("", nullptr)} { - inLru_ = f; } -CookieStorage::CookieStorage() - : rootNode_{make_unique<DomainNode>("", nullptr)} -{} - namespace { // See CookieStorageTest::testDomainIsFull() in CookieStorageTest.cc const size_t DOMAIN_EVICTION_TRIGGER = 2000; @@ -259,9 +234,10 @@ namespace { std::vector<std::string> splitDomainLabel(const std::string& domain) { auto labels = std::vector<std::string>{}; - if(util::isNumericHost(domain)) { + if (util::isNumericHost(domain)) { labels.push_back(domain); - } else { + } + else { util::split(std::begin(domain), std::end(domain), std::back_inserter(labels), '.'); } @@ -269,28 +245,23 @@ std::vector<std::string> splitDomainLabel(const std::string& domain) } } // namespace - -size_t CookieStorage::getLruTrackerSize() const -{ - return lruTracker_.size(); -} +size_t CookieStorage::getLruTrackerSize() const { return lruTracker_.size(); } void CookieStorage::evictNode(size_t delnum) { - for(; delnum > 0 && !lruTracker_.empty(); --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()) { + while (node->empty() && !node->hasNext()) { auto parent = node->getParent(); parent->removeNode(node); - if(!parent->empty() || parent->hasNext() || - parent == rootNode_.get()) { + if (!parent->empty() || parent->hasNext() || parent == rootNode_.get()) { break; } node = parent; - if(node->getInLru()) { + if (node->getInLru()) { lruTracker_.erase({node->getLruAccessTime(), node}); node->setInLru(false); } @@ -298,29 +269,27 @@ void CookieStorage::evictNode(size_t delnum) } } -const DomainNode* CookieStorage::getRootNode() const -{ - return rootNode_.get(); -} +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); + 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) { + for (auto i = labels.rbegin(), eoi = labels.rend(); i != eoi; ++i) { auto nextNode = node->findNext(*i); - if(nextNode) { + if (nextNode) { node = nextNode; - } else { + } + else { node = node->addNext(*i, make_unique<DomainNode>(*i, node)); } } bool ok = node->addCookie(std::move(cookie), now); - if(ok) { + if (ok) { updateLru(node, now); } return ok; @@ -328,20 +297,19 @@ bool CookieStorage::store(std::unique_ptr<Cookie> cookie, time_t now) void CookieStorage::updateLru(DomainNode* node, time_t now) { - if(node->getInLru()) { + if (node->getInLru()) { lruTracker_.erase({node->getLruAccessTime(), node}); - } else { + } + else { node->setInLru(true); } node->setLruAccessTime(now); lruTracker_.insert({node->getLruAccessTime(), node}); } -bool CookieStorage::parseAndStore -(const std::string& setCookieString, - const std::string& requestHost, - const std::string& defaultPath, - time_t now) +bool CookieStorage::parseAndStore(const std::string& setCookieString, + const std::string& requestHost, + const std::string& defaultPath, time_t now) { auto cookie = cookie::parse(setCookieString, requestHost, defaultPath, now); return cookie && store(std::move(cookie), now); @@ -351,16 +319,16 @@ namespace { struct CookiePathDivider { const Cookie* cookie_; int pathDepth_; - CookiePathDivider(const Cookie* cookie):cookie_(cookie), pathDepth_(0) + CookiePathDivider(const Cookie* cookie) : cookie_(cookie), pathDepth_(0) { const std::string& path = cookie_->getPath(); - if(!path.empty()) { - for(size_t i = 1, len = path.size(); i < len; ++i) { - if(path[i] == '/' && path[i-1] != '/') { + if (!path.empty()) { + for (size_t i = 1, len = path.size(); i < len; ++i) { + if (path[i] == '/' && path[i - 1] != '/') { ++pathDepth_; } } - if(path[path.size()-1] != '/') { + if (path[path.size() - 1] != '/') { ++pathDepth_; } } @@ -384,10 +352,10 @@ public: } // namespace namespace { -class OrderByPathDepthDesc:public std::binary_function<Cookie, Cookie, bool> { +class OrderByPathDepthDesc : public std::binary_function<Cookie, Cookie, bool> { public: - bool operator() - (const CookiePathDivider& lhs, const CookiePathDivider& rhs) const + bool operator()(const CookiePathDivider& lhs, + const CookiePathDivider& rhs) const { // From http://tools.ietf.org/html/rfc6265#section-5.4: // 2. The user agent SHOULD sort the cookie-list in the following @@ -400,8 +368,8 @@ public: // earlier creation-times are listed before cookies with later // creation-times. return lhs.pathDepth_ > rhs.pathDepth_ || - (!(rhs.pathDepth_ > lhs.pathDepth_) && - lhs.cookie_->getCreationTime() < rhs.cookie_->getCreationTime()); + (!(rhs.pathDepth_ > lhs.pathDepth_) && + lhs.cookie_->getCreationTime() < rhs.cookie_->getCreationTime()); } }; } // namespace @@ -410,7 +378,7 @@ namespace { DomainNode* findNode(const std::string& domain, DomainNode* node) { auto labels = splitDomainLabel(domain); - for(auto i = labels.rbegin(), eoi = labels.rend(); i != eoi && node; ++i) { + for (auto i = labels.rbegin(), eoi = labels.rend(); i != eoi && node; ++i) { node = node->findNext(*i); } return node; @@ -423,25 +391,24 @@ bool CookieStorage::contains(const Cookie& cookie) const return node && node->contains(cookie); } -std::vector<const Cookie*> CookieStorage::criteriaFind -(const std::string& requestHost, - const std::string& requestPath, - time_t now, - bool secure) +std::vector<const Cookie*> +CookieStorage::criteriaFind(const std::string& requestHost, + const std::string& requestPath, time_t now, + bool secure) { auto res = std::vector<const Cookie*>{}; - if(requestPath.empty()) { + if (requestPath.empty()) { return res; } auto labels = splitDomainLabel(requestHost); auto node = rootNode_.get(); for (auto i = labels.rbegin(), eoi = labels.rend(); i != eoi; ++i) { auto nextNode = node->findNext(*i); - if(!nextNode) { + if (!nextNode) { break; } nextNode->setLastAccessTime(now); - if(nextNode->getInLru()) { + if (nextNode->getInLru()) { updateLru(nextNode, now); } nextNode->findCookie(res, requestHost, requestPath, now, secure); @@ -459,7 +426,7 @@ std::vector<const Cookie*> CookieStorage::criteriaFind size_t CookieStorage::size() const { size_t n = 0; - for(auto& p : lruTracker_) { + for (auto& p : lruTracker_) { n += p.second->countCookie(); } return n; @@ -471,20 +438,21 @@ bool CookieStorage::load(const std::string& filename, time_t now) size_t headlen; { BufferedFile fp{filename.c_str(), BufferedFile::READ}; - if(!fp) { + if (!fp) { A2_LOG_ERROR(fmt("Failed to open cookie file %s", filename.c_str())); return false; } headlen = fp.read(header, sizeof(header)); } 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 try { 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("This does not look like Firefox3 cookie file." " Retrying, assuming it is Chromium cookie file."); @@ -493,18 +461,20 @@ bool CookieStorage::load(const std::string& filename, time_t now) storeCookies(std::make_move_iterator(std::begin(cookies)), std::make_move_iterator(std::end(cookies)), now); } -#else // !HAVE_SQLITE3 - throw DL_ABORT_EX - ("Cannot read SQLite3 database because SQLite3 support is disabled by" - " configuration."); +#else // !HAVE_SQLITE3 + throw DL_ABORT_EX( + "Cannot read SQLite3 database because SQLite3 support is disabled by" + " configuration."); #endif // !HAVE_SQLITE3 - } else { + } + else { auto cookies = NsCookieParser().parse(filename, now); storeCookies(std::make_move_iterator(std::begin(cookies)), std::make_move_iterator(std::end(cookies)), now); } return true; - } catch(RecoverableException& e) { + } + catch (RecoverableException& e) { A2_LOG_ERROR(fmt("Failed to load cookies from %s", filename.c_str())); return false; } @@ -516,26 +486,26 @@ bool CookieStorage::saveNsFormat(const std::string& filename) tempfilename += "__temp"; { BufferedFile fp{tempfilename.c_str(), BufferedFile::WRITE}; - if(!fp) { + if (!fp) { A2_LOG_ERROR(fmt("Cannot create cookie file %s", filename.c_str())); return false; } - for(auto& p : lruTracker_) { - if(!p.second->writeCookie(fp)) { + for (auto& p : lruTracker_) { + if (!p.second->writeCookie(fp)) { A2_LOG_ERROR(fmt("Failed to save cookies to %s", filename.c_str())); return false; } } - if(fp.close() == EOF) { + if (fp.close() == EOF) { A2_LOG_ERROR(fmt("Failed to save cookies to %s", filename.c_str())); return false; } } - if(File(tempfilename).renameTo(filename)) { + if (File(tempfilename).renameTo(filename)) { return true; - } else { - A2_LOG_ERROR(fmt("Could not rename file %s as %s", - tempfilename.c_str(), + } + else { + A2_LOG_ERROR(fmt("Could not rename file %s as %s", tempfilename.c_str(), filename.c_str())); return false; } |
