From 461a542c5e236a22bb4edba3fae9610df4ba44c6 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sat, 22 Sep 2012 23:19:41 +0900 Subject: [PATCH] Rewritten DownloadHandlerConstants DownloadHandlerConstants was simplified. MIME type handling in Accept header was also reworked. DownloadContext's metalinkServerContacted_ is replaced with acceptMetalink_ and its boolean value is reverted. RequestGroup and HttpRequest now do not hold vector of accepting types. HttpRequest has the flag acceptMetalink_ which will be set by the same value of DownloadContext::accpetMetalink_ and if it is true, Metalink MIME types are added to Accept header field. --- src/BtPostDownloadHandler.cc | 5 +- src/ContentTypeRequestGroupCriteria.cc | 41 +++++++--------- src/ContentTypeRequestGroupCriteria.h | 15 +++--- src/DownloadContext.cc | 4 +- src/DownloadContext.h | 14 +++--- src/DownloadHandlerConstants.cc | 67 ++++++++++++++------------ src/DownloadHandlerConstants.h | 24 +++------ src/DownloadHandlerFactory.cc | 10 +--- src/HttpRequest.cc | 18 +++---- src/HttpRequest.h | 8 +-- src/HttpRequestCommand.cc | 4 +- src/HttpResponseCommand.cc | 6 +-- src/Metalink2RequestGroup.cc | 4 +- src/MetalinkPostDownloadHandler.cc | 5 +- src/RequestGroup.cc | 19 -------- src/RequestGroup.h | 22 --------- src/TrackerWatcherCommand.cc | 2 +- src/download_helper.cc | 2 +- src/util.cc | 25 ++++------ src/util.h | 6 +-- test/HttpRequestTest.cc | 13 ++--- 21 files changed, 118 insertions(+), 196 deletions(-) diff --git a/src/BtPostDownloadHandler.cc b/src/BtPostDownloadHandler.cc index c3faccfc..35976814 100644 --- a/src/BtPostDownloadHandler.cc +++ b/src/BtPostDownloadHandler.cc @@ -59,10 +59,7 @@ BtPostDownloadHandler::BtPostDownloadHandler() { SharedHandle cri (new ContentTypeRequestGroupCriteria - (DownloadHandlerConstants::getBtContentTypes().begin(), - DownloadHandlerConstants::getBtContentTypes().end(), - DownloadHandlerConstants::getBtExtensions().begin(), - DownloadHandlerConstants::getBtExtensions().end())); + (getBtContentTypes(), getBtExtensions())); setCriteria(cri); } diff --git a/src/ContentTypeRequestGroupCriteria.cc b/src/ContentTypeRequestGroupCriteria.cc index 078ef7df..68cc7f07 100644 --- a/src/ContentTypeRequestGroupCriteria.cc +++ b/src/ContentTypeRequestGroupCriteria.cc @@ -34,8 +34,6 @@ /* copyright --> */ #include "ContentTypeRequestGroupCriteria.h" -#include - #include "RequestGroup.h" #include "util.h" #include "FileEntry.h" @@ -43,19 +41,13 @@ namespace aria2 { -namespace { -template -bool tailMatch -(InputIterator first, InputIterator last, const std::string& target) -{ - for(; first != last; ++first) { - if(util::endsWith(target, *first)) { - return true; - } - } - return false; -} -} // namespace +ContentTypeRequestGroupCriteria::ContentTypeRequestGroupCriteria +(const char** contentTypes, const char** extensions) + : contentTypes_(contentTypes), + extensions_(extensions) +{} + +ContentTypeRequestGroupCriteria::~ContentTypeRequestGroupCriteria() {} bool ContentTypeRequestGroupCriteria::match (const RequestGroup* requestGroup) const @@ -63,15 +55,18 @@ bool ContentTypeRequestGroupCriteria::match if(requestGroup->getDownloadContext()->getFileEntries().size() != 1) { return false; } - if(tailMatch(extensions_.begin(), extensions_.end(), - requestGroup->getFirstFilePath())) { - return true; - } else { - return - std::find(contentTypes_.begin(), contentTypes_.end(), - requestGroup->getDownloadContext()->getFirstFileEntry()-> - getContentType()) != contentTypes_.end(); + for(size_t i = 0; extensions_[i]; ++i) { + if(util::iendsWith(requestGroup->getFirstFilePath(), extensions_[i])) { + return true; + } } + for(size_t i = 0; contentTypes_[i]; ++i) { + if(util::strieq(requestGroup->getDownloadContext()->getFirstFileEntry()-> + getContentType(), contentTypes_[i])) { + return true; + } + } + return false; } } // namespace aria2 diff --git a/src/ContentTypeRequestGroupCriteria.h b/src/ContentTypeRequestGroupCriteria.h index 1c8c7c41..67e6be3a 100644 --- a/src/ContentTypeRequestGroupCriteria.h +++ b/src/ContentTypeRequestGroupCriteria.h @@ -44,16 +44,13 @@ namespace aria2 { class ContentTypeRequestGroupCriteria:public RequestGroupCriteria { private: - std::vector contentTypes_; - std::vector extensions_; + const char** contentTypes_; + const char** extensions_; public: - template - ContentTypeRequestGroupCriteria(InputIterator contentTypeFirst, - InputIterator contentTypeLast, - InputIterator extensionFirst, - InputIterator extensionLast): - contentTypes_(contentTypeFirst, contentTypeLast), - extensions_(extensionFirst, extensionLast) {} + ContentTypeRequestGroupCriteria(const char** contentTypes, + const char** extensions); + + virtual ~ContentTypeRequestGroupCriteria(); virtual bool match(const RequestGroup* requestGroup) const; }; diff --git a/src/DownloadContext.cc b/src/DownloadContext.cc index 16ddd159..dbc355ea 100644 --- a/src/DownloadContext.cc +++ b/src/DownloadContext.cc @@ -54,7 +54,7 @@ DownloadContext::DownloadContext(): attrs_(MAX_CTX_ATTR), downloadStartTime_(0), downloadStopTime_(downloadStartTime_), - metalinkServerContacted_(false) {} + acceptMetalink_(true) {} DownloadContext::DownloadContext(int32_t pieceLength, int64_t totalLength, @@ -66,7 +66,7 @@ DownloadContext::DownloadContext(int32_t pieceLength, attrs_(MAX_CTX_ATTR), downloadStartTime_(0), downloadStopTime_(0), - metalinkServerContacted_(false) + acceptMetalink_(true) { SharedHandle fileEntry(new FileEntry(path, totalLength, 0)); fileEntries_.push_back(fileEntry); diff --git a/src/DownloadContext.h b/src/DownloadContext.h index 29d4840a..faca8174 100644 --- a/src/DownloadContext.h +++ b/src/DownloadContext.h @@ -84,9 +84,9 @@ private: Timer downloadStopTime_; SharedHandle signature_; - // This member variable is required to avoid to parse Metalink/HTTP - // Link header fields multiple times. - bool metalinkServerContacted_; + // This member variable is required to avoid to use parse Metalink + // (including both Metalink XML and Metalink/HTTP) twice. + bool acceptMetalink_; public: DownloadContext(); @@ -226,13 +226,13 @@ public: void releaseRuntimeResource(); - void setMetalinkServerContacted(bool f) + void setAcceptMetalink(bool f) { - metalinkServerContacted_ = f; + acceptMetalink_ = f; } - bool getMetalinkServerContacted() const + bool getAcceptMetalink() const { - return metalinkServerContacted_; + return acceptMetalink_; } }; diff --git a/src/DownloadHandlerConstants.cc b/src/DownloadHandlerConstants.cc index 3cd6ca6e..0f86c6da 100644 --- a/src/DownloadHandlerConstants.cc +++ b/src/DownloadHandlerConstants.cc @@ -2,7 +2,7 @@ /* * aria2 - The high speed download utility * - * Copyright (C) 2006 Tatsuhiro Tsujikawa + * Copyright (C) 2012 Tatsuhiro Tsujikawa * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,54 +33,57 @@ */ /* copyright --> */ #include "DownloadHandlerConstants.h" -#include "array_fun.h" namespace aria2 { -const char* DownloadHandlerConstants::METALINK_EXTENSIONS[] = { +namespace { +const char* METALINK_EXTENSIONS[] = { ".metalink", // Metalink3Spec - ".meta4" // Metalink4Spec + ".meta4", // Metalink4Spec + 0 }; +} // namespace -const char* DownloadHandlerConstants::METALINK_CONTENT_TYPES[] = { +const char** getMetalinkExtensions() +{ + return METALINK_EXTENSIONS; +} + +namespace { +const char* METALINK_CONTENT_TYPES[] = { "application/metalink4+xml", // Metalink4Spec - "application/metalink+xml" // Metalink3Spec + "application/metalink+xml", // Metalink3Spec + 0 }; +} // namespace -const char* DownloadHandlerConstants::BT_EXTENSIONS[] = { ".torrent" }; +const char** getMetalinkContentTypes() +{ + return METALINK_CONTENT_TYPES; +} -const char* DownloadHandlerConstants::BT_CONTENT_TYPES[] = { - "application/x-bittorrent" +namespace { +const char* BT_EXTENSIONS[] = { + ".torrent", + 0 }; +} // namespace -const std::vector& -DownloadHandlerConstants::getMetalinkExtensions() +const char** getBtExtensions() { - static const std::vector l - (vbegin(METALINK_EXTENSIONS), vend(METALINK_EXTENSIONS)); - return l; + return BT_EXTENSIONS; } -const std::vector& -DownloadHandlerConstants::getMetalinkContentTypes() -{ - static const std::vector l - (vbegin(METALINK_CONTENT_TYPES), vend(METALINK_CONTENT_TYPES)); - return l; -} +namespace { +const char* BT_CONTENT_TYPES[] = { + "application/x-bittorrent", + 0 +}; +} // namespace -const std::vector& DownloadHandlerConstants::getBtExtensions() +const char** getBtContentTypes() { - static const std::vector l - (vbegin(BT_EXTENSIONS), vend(BT_EXTENSIONS)); - return l; -} - -const std::vector& DownloadHandlerConstants::getBtContentTypes() -{ - static const std::vector l - (vbegin(BT_CONTENT_TYPES), vend(BT_CONTENT_TYPES)); - return l; + return BT_CONTENT_TYPES; } } // namespace aria2 diff --git a/src/DownloadHandlerConstants.h b/src/DownloadHandlerConstants.h index 4d773a03..7d05c676 100644 --- a/src/DownloadHandlerConstants.h +++ b/src/DownloadHandlerConstants.h @@ -2,7 +2,7 @@ /* * aria2 - The high speed download utility * - * Copyright (C) 2006 Tatsuhiro Tsujikawa + * Copyright (C) 2012 Tatsuhiro Tsujikawa * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -36,30 +36,18 @@ #define D_DOWNLOAD_HANDLER_CONSTANTS_H #include "common.h" -#include -#include namespace aria2 { -class DownloadHandlerConstants -{ -public: - static const char* METALINK_EXTENSIONS[]; +// These methods returns NULL-terminated list of c-strings. - static const std::vector& getMetalinkExtensions(); +const char** getMetalinkExtensions(); - static const char* METALINK_CONTENT_TYPES[]; +const char** getMetalinkContentTypes(); - static const std::vector& getMetalinkContentTypes(); +const char** getBtExtensions(); - static const char* BT_EXTENSIONS[]; - - static const std::vector& getBtExtensions(); - - static const char* BT_CONTENT_TYPES[]; - - static const std::vector& getBtContentTypes(); -}; +const char** getBtContentTypes(); } // namespace aria2 diff --git a/src/DownloadHandlerFactory.cc b/src/DownloadHandlerFactory.cc index 8fdb7a35..0a9387c0 100644 --- a/src/DownloadHandlerFactory.cc +++ b/src/DownloadHandlerFactory.cc @@ -74,10 +74,7 @@ DownloadHandlerFactory::getMetalinkPreDownloadHandler() RequestGroupCriteriaHandle criteria (new ContentTypeRequestGroupCriteria - (DownloadHandlerConstants::getMetalinkContentTypes().begin(), - DownloadHandlerConstants::getMetalinkContentTypes().end(), - DownloadHandlerConstants::getMetalinkExtensions().begin(), - DownloadHandlerConstants::getMetalinkExtensions().end())); + (getMetalinkContentTypes(), getMetalinkExtensions())); metalinkPreDownloadHandler_->setCriteria(criteria); } return metalinkPreDownloadHandler_; @@ -105,10 +102,7 @@ DownloadHandlerFactory::getBtPreDownloadHandler() RequestGroupCriteriaHandle criteria (new ContentTypeRequestGroupCriteria - (DownloadHandlerConstants::getBtContentTypes().begin(), - DownloadHandlerConstants::getBtContentTypes().end(), - DownloadHandlerConstants::getBtExtensions().begin(), - DownloadHandlerConstants::getBtExtensions().end())); + (getBtContentTypes(), getBtExtensions())); btPreDownloadHandler_->setCriteria(criteria); } return btPreDownloadHandler_; diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index 4a1593d1..09254d1c 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -51,6 +51,7 @@ #include "TimeA2.h" #include "array_fun.h" #include "Request.h" +#include "DownloadHandlerConstants.h" namespace aria2 { @@ -58,6 +59,7 @@ const std::string HttpRequest::USER_AGENT("aria2"); HttpRequest::HttpRequest():contentEncodingEnabled_(true), userAgent_(USER_AGENT), + acceptMetalink_(false), noCache_(true), acceptGzip_(false), endOffsetOverride_(0) @@ -164,10 +166,13 @@ std::string HttpRequest::createRequest() builtinHds.reserve(20); builtinHds.push_back(std::make_pair("User-Agent:", userAgent_)); std::string acceptTypes = "*/*"; - for(std::vector::const_iterator i = acceptTypes_.begin(), - eoi = acceptTypes_.end(); i != eoi; ++i) { - acceptTypes += ","; - acceptTypes += *i; + if(acceptMetalink_) { + // The mime types of Metalink are used for "transparent metalink". + const char** metalinkTypes = getMetalinkContentTypes(); + for(size_t i = 0; metalinkTypes[i]; ++i) { + acceptTypes += ","; + acceptTypes += metalinkTypes[i]; + } } builtinHds.push_back(std::make_pair("Accept:", acceptTypes)); if(contentEncodingEnabled_) { @@ -328,11 +333,6 @@ void HttpRequest::clearHeader() headers_.clear(); } -void HttpRequest::addAcceptType(const std::string& type) -{ - acceptTypes_.push_back(type); -} - void HttpRequest::setCookieStorage (const SharedHandle& cookieStorage) { diff --git a/src/HttpRequest.h b/src/HttpRequest.h index 6b5e948b..c467d601 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -71,7 +71,8 @@ private: std::vector headers_; - std::vector acceptTypes_; + // If true, metalink content types are sent in Accept header field. + bool acceptMetalink_; SharedHandle cookieStorage_; @@ -172,10 +173,9 @@ public: void addAcceptType(const std::string& type); - template - void addAcceptType(InputIterator first, InputIterator last) + void setAcceptMetalink(bool f) { - acceptTypes_.insert(acceptTypes_.end(), first, last); + acceptMetalink_ = f; } void setCookieStorage(const SharedHandle& cookieStorage); diff --git a/src/HttpRequestCommand.cc b/src/HttpRequestCommand.cc index 3d0ba593..11f1fdb8 100644 --- a/src/HttpRequestCommand.cc +++ b/src/HttpRequestCommand.cc @@ -103,8 +103,8 @@ createHttpRequest(const SharedHandle& req, httpRequest->setCookieStorage(cookieStorage); httpRequest->setAuthConfigFactory(authConfigFactory, option.get()); httpRequest->setProxyRequest(proxyRequest); - httpRequest->addAcceptType(rg->getAcceptTypes().begin(), - rg->getAcceptTypes().end()); + httpRequest->setAcceptMetalink(rg->getDownloadContext()-> + getAcceptMetalink()); if(option->getAsBool(PREF_HTTP_ACCEPT_GZIP)) { httpRequest->enableAcceptGZip(); } else { diff --git a/src/HttpResponseCommand.cc b/src/HttpResponseCommand.cc index 57a9a1cc..66d5035c 100644 --- a/src/HttpResponseCommand.cc +++ b/src/HttpResponseCommand.cc @@ -197,9 +197,9 @@ bool HttpResponseCommand::executeInternal() } if(!getPieceStorage()) { // Metalink/HTTP - if(!getDownloadContext()->getMetalinkServerContacted()) { + if(getDownloadContext()->getAcceptMetalink()) { if(httpHeader->defined(HttpHeader::LINK)) { - getDownloadContext()->setMetalinkServerContacted(true); + getDownloadContext()->setAcceptMetalink(false); std::vector entries; httpResponse->getMetalinKHttpEntries(entries, getOption()); for(std::vector::iterator i = entries.begin(), @@ -245,7 +245,7 @@ bool HttpResponseCommand::executeInternal() } } if(!getPieceStorage()) { - util::removeMetalinkContentTypes(getRequestGroup()); + getDownloadContext()->setAcceptMetalink(false); int64_t totalLength = httpResponse->getEntityLength(); getFileEntry()->setLength(totalLength); if(getFileEntry()->getPath().empty()) { diff --git a/src/Metalink2RequestGroup.cc b/src/Metalink2RequestGroup.cc index b266cd77..6f15f85e 100644 --- a/src/Metalink2RequestGroup.cc +++ b/src/Metalink2RequestGroup.cc @@ -229,7 +229,7 @@ Metalink2RequestGroup::createRequestGroup torrentRg->clearPostDownloadHandler(); // remove "metalink" from Accept Type list to avoid loop in // tranparent metalink - util::removeMetalinkContentTypes(torrentRg); + torrentRg->getDownloadContext()->setAcceptMetalink(false); // make it in-memory download SharedHandle preh (new MemoryBufferPreDownloadHandler()); @@ -328,7 +328,7 @@ Metalink2RequestGroup::createRequestGroup removeOneshotOption(option); // remove "metalink" from Accept Type list to avoid loop in // tranparent metalink - util::removeMetalinkContentTypes(rg); + dctx->setAcceptMetalink(false); #ifdef ENABLE_BITTORRENT // Inject depenency between rg and torrentRg here if // torrentRg is true diff --git a/src/MetalinkPostDownloadHandler.cc b/src/MetalinkPostDownloadHandler.cc index c611bc62..f504bf01 100644 --- a/src/MetalinkPostDownloadHandler.cc +++ b/src/MetalinkPostDownloadHandler.cc @@ -58,10 +58,7 @@ MetalinkPostDownloadHandler::MetalinkPostDownloadHandler() { SharedHandle cri (new ContentTypeRequestGroupCriteria - (DownloadHandlerConstants::getMetalinkContentTypes().begin(), - DownloadHandlerConstants::getMetalinkContentTypes().end(), - DownloadHandlerConstants::getMetalinkExtensions().begin(), - DownloadHandlerConstants::getMetalinkExtensions().end())); + (getMetalinkContentTypes(), getMetalinkExtensions())); setCriteria(cri); } diff --git a/src/RequestGroup.cc b/src/RequestGroup.cc index 6b95beab..18522c53 100644 --- a/src/RequestGroup.cc +++ b/src/RequestGroup.cc @@ -154,12 +154,6 @@ RequestGroup::RequestGroup(const SharedHandle