| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 | /* <!-- copyright *//* * aria2 - The high speed download utility * * Copyright (C) 2009 Tatsuhiro Tsujikawa * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL.  If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so.  If you * do not wish to do so, delete this exception statement from your * version.  If you delete this exception statement from all source * files in the program, then also delete it here. *//* copyright --> */#include "RpcMethod.h"#include "DownloadEngine.h"#include "LogFactory.h"#include "RecoverableException.h"#include "message.h"#include "OptionParser.h"#include "OptionHandler.h"#include "Option.h"#include "array_fun.h"#include "download_helper.h"#include "RpcRequest.h"#include "RpcResponse.h"#include "prefs.h"#include "fmt.h"#include "DlAbortEx.h"#include "a2functional.h"#include "util.h"namespace aria2 {namespace rpc {RpcMethod::RpcMethod() : optionParser_(OptionParser::getInstance()) {}RpcMethod::~RpcMethod() {}std::unique_ptr<ValueBase> RpcMethod::createErrorResponse(const Exception& e,                                                          const RpcRequest& req){  auto params = Dict::g();  params->put((req.jsonRpc ? "code" : "faultCode"), Integer::g(1));  params->put((req.jsonRpc ? "message" : "faultString"), std::string(e.what()));  return std::move(params);}void RpcMethod::authorize(RpcRequest& req, DownloadEngine* e){  std::string token;  // We always treat first parameter as token if it is string and  // starts with "token:" and remove it from parameter list, so that  // we don't have to add conditionals to all RPCMethod  // implementations.  if (req.params && !req.params->empty()) {    auto t = downcast<String>(req.params->get(0));    if (t) {      if (util::startsWith(t->s(), "token:")) {        token = t->s().substr(6);        req.params->pop_front();      }    }  }  if (!e || !e->validateToken(token)) {    throw DL_ABORT_EX("Unauthorized");  }}RpcResponse RpcMethod::execute(RpcRequest req, DownloadEngine* e){  auto authorized = RpcResponse::NOTAUTHORIZED;  try {    authorize(req, e);    authorized = RpcResponse::AUTHORIZED;    auto r = process(req, e);    return RpcResponse(0, authorized, std::move(r), std::move(req.id));  }  catch (RecoverableException& ex) {    A2_LOG_DEBUG_EX(EX_EXCEPTION_CAUGHT, ex);    return RpcResponse(1, authorized, createErrorResponse(ex, req),                       std::move(req.id));  }}namespace {template <typename InputIterator, typename Pred>void gatherOption(InputIterator first, InputIterator last, Pred pred,                  Option* option,                  const std::shared_ptr<OptionParser>& optionParser){  for (; first != last; ++first) {    const std::string& optionName = (*first).first;    PrefPtr pref = option::k2p(optionName);    const OptionHandler* handler = optionParser->find(pref);    if (!handler || !pred(handler)) {      // Just ignore the unacceptable options in this context.      continue;    }    const String* opval = downcast<String>((*first).second);    if (opval) {      handler->parse(*option, opval->s());    }    else if (handler->getCumulative()) {      // header and index-out option can take array as value      const List* oplist = downcast<List>((*first).second);      if (oplist) {        for (auto& elem : *oplist) {          const String* opval = downcast<String>(elem);          if (opval) {            handler->parse(*option, opval->s());          }        }      }    }  }}} // namespacevoid RpcMethod::gatherRequestOption(Option* option, const Dict* optionsDict){  if (optionsDict) {    gatherOption(optionsDict->begin(), optionsDict->end(),                 std::mem_fn(&OptionHandler::getInitialOption), option,                 optionParser_);  }}void RpcMethod::gatherChangeableOption(Option* option, const Dict* optionsDict){  if (optionsDict) {    gatherOption(optionsDict->begin(), optionsDict->end(),                 std::mem_fn(&OptionHandler::getChangeOption), option,                 optionParser_);  }}void RpcMethod::gatherChangeableOptionForReserved(Option* option,                                                  const Dict* optionsDict){  if (optionsDict) {    gatherOption(optionsDict->begin(), optionsDict->end(),                 std::mem_fn(&OptionHandler::getChangeOptionForReserved),                 option, optionParser_);  }}void RpcMethod::gatherChangeableGlobalOption(Option* option,                                             const Dict* optionsDict){  if (optionsDict) {    gatherOption(optionsDict->begin(), optionsDict->end(),                 std::mem_fn(&OptionHandler::getChangeGlobalOption), option,                 optionParser_);  }}} // namespace rpc} // namespace aria2
 |