diff options
| author | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2009-10-04 09:01:11 +0000 |
|---|---|---|
| committer | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2009-10-04 09:01:11 +0000 |
| commit | c0595d17ff8df87af95cbd3f4a430eecaf85cbf1 (patch) | |
| tree | 6baf88d746aedff380a0680b99d740bad1d76ccf /src | |
| parent | ce3de835b4ca854b73b1f9dcb54131ba704e5115 (diff) | |
2009-10-04 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Fixed the bug that the option values changed by XML-RPC
method(changeOption and changeGlobalOption) are overwritten to the
previous value by the next these request which doesn't contain
that option value. Supporse max-download-limit is initially 0. You
changed this value to 100K by changeOption. Then you issue
changeOption request to change max-upload-limit to 50K. This
second request doesn't contain xml-download-limit, so it is back
to initial value, 0. Another improvement is that exception is
thrown when changeOption and changeGlobalOption request contains
option name which doesn't allowed in each request.
* src/DownloadEngine.h
* src/XmlRpcMethod.cc
* src/XmlRpcMethod.h
* src/XmlRpcMethodImpl.cc
* src/download_helper.cc
* src/download_helper.h
* test/XmlRpcMethodTest.cc
Diffstat (limited to 'src')
| -rw-r--r-- | src/DownloadEngine.h | 2 | ||||
| -rw-r--r-- | src/XmlRpcMethod.cc | 76 | ||||
| -rw-r--r-- | src/XmlRpcMethod.h | 8 | ||||
| -rw-r--r-- | src/XmlRpcMethodImpl.cc | 20 | ||||
| -rw-r--r-- | src/download_helper.cc | 6 | ||||
| -rw-r--r-- | src/download_helper.h | 4 |
6 files changed, 84 insertions, 32 deletions
diff --git a/src/DownloadEngine.h b/src/DownloadEngine.h index 13568c28..401142d7 100644 --- a/src/DownloadEngine.h +++ b/src/DownloadEngine.h @@ -155,7 +155,7 @@ public: SharedHandle<RequestGroupMan> _requestGroupMan; SharedHandle<FileAllocationMan> _fileAllocationMan; SharedHandle<CheckIntegrityMan> _checkIntegrityMan; - const Option* option; + Option* option; DownloadEngine(const SharedHandle<EventPoll>& eventPoll); diff --git a/src/XmlRpcMethod.cc b/src/XmlRpcMethod.cc index 29a320a6..0253d9fd 100644 --- a/src/XmlRpcMethod.cc +++ b/src/XmlRpcMethod.cc @@ -46,6 +46,7 @@ #include "XmlRpcRequest.h" #include "XmlRpcResponse.h" #include "prefs.h" +#include "StringFormat.h" namespace aria2 { @@ -74,23 +75,32 @@ XmlRpcResponse XmlRpcMethod::execute } } - template<typename InputIterator> static void gatherOption (InputIterator first, InputIterator last, - const SharedHandle<Option>& option, const BDE& optionsDict, + const std::set<std::string>& changeableOptions, + const SharedHandle<Option>& option, const SharedHandle<OptionParser>& optionParser) { for(; first != last; ++first) { - if(optionsDict.containsKey(*first)) { - const BDE& value = optionsDict[*first]; + const std::string& optionName = (*first).first; + if(changeableOptions.find(optionName) == changeableOptions.end()) { + throw DL_ABORT_EX + (StringFormat + ("%s cannot be changed or unknown option.", optionName.c_str()).str()); + } else { SharedHandle<OptionHandler> optionHandler = - optionParser->findByName(*first); + optionParser->findByName(optionName); if(optionHandler.isNull()) { - continue; + throw DL_ABORT_EX + (StringFormat + ("We don't know how to deal with %s option", + optionName.c_str()).str()); } // header and index-out option can take array as value - if((*first == PREF_HEADER || *first == PREF_INDEX_OUT) && value.isList()){ + const BDE& value = (*first).second; + if((optionName == PREF_HEADER || optionName == PREF_INDEX_OUT) && + value.isList()){ for(BDE::List::const_iterator argiter = value.listBegin(); argiter != value.listEnd(); ++argiter) { if((*argiter).isString()) { @@ -107,17 +117,33 @@ static void gatherOption void XmlRpcMethod::gatherRequestOption (const SharedHandle<Option>& option, const BDE& optionsDict) { - gatherOption(listRequestOptions().begin(), listRequestOptions().end(), - option, optionsDict, _optionParser); + gatherOption(optionsDict.dictBegin(), optionsDict.dictEnd(), + listRequestOptions(), + option, _optionParser); +} + +// Copy option in the range [optNameFirst, optNameLast) from src to +// dest. +template<typename InputIterator> +static void applyOption(InputIterator optNameFirst, + InputIterator optNameLast, + Option* dest, + Option* src) +{ + for(; optNameFirst != optNameLast; ++optNameFirst) { + if(src->defined(*optNameFirst)) { + dest->put(*optNameFirst, src->get(*optNameFirst)); + } + } } -const std::vector<std::string>& listChangeableOptions() +const std::set<std::string>& listChangeableOptions() { static const std::string OPTIONS[] = { PREF_MAX_UPLOAD_LIMIT, PREF_MAX_DOWNLOAD_LIMIT, }; - static std::vector<std::string> options + static std::set<std::string> options (&OPTIONS[0], &OPTIONS[arrayLength(OPTIONS)]); return options; } @@ -125,18 +151,25 @@ const std::vector<std::string>& listChangeableOptions() void XmlRpcMethod::gatherChangeableOption (const SharedHandle<Option>& option, const BDE& optionsDict) { - gatherOption(listChangeableOptions().begin(), listChangeableOptions().end(), - option, optionsDict, _optionParser); + gatherOption(optionsDict.dictBegin(), optionsDict.dictEnd(), + listChangeableOptions(), + option, _optionParser); } -const std::vector<std::string>& listChangeableGlobalOptions() +void XmlRpcMethod::applyChangeableOption(Option* dest, Option* src) const +{ + applyOption(listChangeableOptions().begin(), listChangeableOptions().end(), + dest, src); +} + +const std::set<std::string>& listChangeableGlobalOptions() { static const std::string OPTIONS[] = { PREF_MAX_OVERALL_UPLOAD_LIMIT, PREF_MAX_OVERALL_DOWNLOAD_LIMIT, PREF_MAX_CONCURRENT_DOWNLOADS, }; - static std::vector<std::string> options + static std::set<std::string> options (&OPTIONS[0], &OPTIONS[arrayLength(OPTIONS)]); return options; } @@ -144,9 +177,16 @@ const std::vector<std::string>& listChangeableGlobalOptions() void XmlRpcMethod::gatherChangeableGlobalOption (const SharedHandle<Option>& option, const BDE& optionsDict) { - gatherOption(listChangeableGlobalOptions().begin(), - listChangeableGlobalOptions().end(), - option, optionsDict, _optionParser); + gatherOption(optionsDict.dictBegin(), optionsDict.dictEnd(), + listChangeableGlobalOptions(), + option, _optionParser); +} + +void XmlRpcMethod::applyChangeableGlobalOption(Option* dest, Option* src) const +{ + applyOption(listChangeableGlobalOptions().begin(), + listChangeableGlobalOptions().end(), + dest, src); } } // namespace xmlrpc diff --git a/src/XmlRpcMethod.h b/src/XmlRpcMethod.h index c9ed0654..476917f2 100644 --- a/src/XmlRpcMethod.h +++ b/src/XmlRpcMethod.h @@ -78,8 +78,16 @@ protected: void gatherChangeableOption(const SharedHandle<Option>& option, const BDE& optionDict); + // Copy options which is changeable in XML-RPC changeOption command + // to dest. + void applyChangeableOption(Option* dest, Option* src) const; + void gatherChangeableGlobalOption(const SharedHandle<Option>& option, const BDE& optionDict); + + // Copy options which is changeable in XML-RPC changeGlobalOption + // command to dest. + void applyChangeableGlobalOption(Option* dest, Option* src) const; public: XmlRpcMethod(); diff --git a/src/XmlRpcMethodImpl.cc b/src/XmlRpcMethodImpl.cc index c08016bd..0eafa1fd 100644 --- a/src/XmlRpcMethodImpl.cc +++ b/src/XmlRpcMethodImpl.cc @@ -592,15 +592,17 @@ BDE ChangeOptionXmlRpcMethod::process throw DL_ABORT_EX (StringFormat("Cannot change option for GID#%d", gid).str()); } - SharedHandle<Option> option(new Option(*group->getOption().get())); + SharedHandle<Option> option(new Option()); if(params.size() > 1 && params[1].isDict()) { gatherChangeableOption(option, params[1]); - } - if(option->defined(PREF_MAX_DOWNLOAD_LIMIT)) { - group->setMaxDownloadSpeedLimit(option->getAsInt(PREF_MAX_DOWNLOAD_LIMIT)); - } - if(option->defined(PREF_MAX_UPLOAD_LIMIT)) { - group->setMaxUploadSpeedLimit(option->getAsInt(PREF_MAX_UPLOAD_LIMIT)); + applyChangeableOption(group->getOption().get(), option.get()); + if(option->defined(PREF_MAX_DOWNLOAD_LIMIT)) { + group->setMaxDownloadSpeedLimit + (option->getAsInt(PREF_MAX_DOWNLOAD_LIMIT)); + } + if(option->defined(PREF_MAX_UPLOAD_LIMIT)) { + group->setMaxUploadSpeedLimit(option->getAsInt(PREF_MAX_UPLOAD_LIMIT)); + } } return BDE_OK; } @@ -613,8 +615,10 @@ BDE ChangeGlobalOptionXmlRpcMethod::process if(params.empty() || !params[0].isDict()) { return BDE_OK; } - SharedHandle<Option> option(new Option(*e->option)); + SharedHandle<Option> option(new Option()); gatherChangeableGlobalOption(option, params[0]); + applyChangeableGlobalOption(e->option, option.get()); + if(option->defined(PREF_MAX_OVERALL_DOWNLOAD_LIMIT)) { e->_requestGroupMan->setMaxOverallDownloadSpeedLimit (option->getAsInt(PREF_MAX_OVERALL_DOWNLOAD_LIMIT)); diff --git a/src/download_helper.cc b/src/download_helper.cc index 2a4bfa8d..4a26312c 100644 --- a/src/download_helper.cc +++ b/src/download_helper.cc @@ -67,7 +67,7 @@ namespace aria2 { -const std::vector<std::string>& listRequestOptions() +const std::set<std::string>& listRequestOptions() { static const std::string REQUEST_OPTIONS[] = { PREF_DIR, @@ -138,7 +138,7 @@ const std::vector<std::string>& listRequestOptions() PREF_PARAMETERIZED_URI, PREF_REALTIME_CHUNK_CHECKSUM }; - static std::vector<std::string> requestOptions + static std::set<std::string> requestOptions (&REQUEST_OPTIONS[0], &REQUEST_OPTIONS[arrayLength(REQUEST_OPTIONS)]);; @@ -385,7 +385,7 @@ static void createRequestGroupForUriList } SharedHandle<Option> requestOption(new Option(*option.get())); - for(std::vector<std::string>::const_iterator i = + for(std::set<std::string>::const_iterator i = listRequestOptions().begin(); i != listRequestOptions().end(); ++i) { if(tempOption->defined(*i)) { requestOption->put(*i, tempOption->get(*i)); diff --git a/src/download_helper.h b/src/download_helper.h index 44fe3bc2..41d7d914 100644 --- a/src/download_helper.h +++ b/src/download_helper.h @@ -39,7 +39,7 @@ #include <string> #include <deque> -#include <vector> +#include <set> #include "SharedHandle.h" @@ -48,7 +48,7 @@ namespace aria2 { class RequestGroup; class Option; -const std::vector<std::string>& listRequestOptions(); +const std::set<std::string>& listRequestOptions(); #ifdef ENABLE_BITTORRENT // Create RequestGroup object using torrent file specified by |
