Browse Source

Moved jsonRpc flag from RpcMethod to RpcRequest.

Now RpcMethod is stateless, so we can cache and reuse them.
Tatsuhiro Tsujikawa 14 years ago
parent
commit
2d92571cf9
6 changed files with 24 additions and 32 deletions
  1. 1 1
      src/HttpServerBodyCommand.cc
  2. 7 8
      src/RpcMethod.cc
  3. 4 12
      src/RpcMethod.h
  4. 6 6
      src/RpcMethodImpl.cc
  5. 2 2
      src/RpcRequest.cc
  6. 4 3
      src/RpcRequest.h

+ 1 - 1
src/HttpServerBodyCommand.cc

@@ -179,6 +179,7 @@ HttpServerBodyCommand::processJsonRpcRequest(const Dict* jsondict)
     return createJsonRpcErrorResponse(-32602, "Invalid params.", id);
   }
   rpc::RpcRequest req(methodName->s(), params, id);
+  req.jsonRpc = true;
   SharedHandle<rpc::RpcMethod> method;
   try {
     method = rpc::RpcMethodFactory::create(req.methodName);
@@ -186,7 +187,6 @@ HttpServerBodyCommand::processJsonRpcRequest(const Dict* jsondict)
     A2_LOG_INFO_EX(EX_EXCEPTION_CAUGHT, e);
     return createJsonRpcErrorResponse(-32601, "Method not found.", id);
   }
-  method->setJsonRpc(true);
   A2_LOG_INFO(fmt("Executing RPC method %s", req.methodName.c_str()));
   rpc::RpcResponse res = method->execute(req, e_);
   return res;

+ 7 - 8
src/RpcMethod.cc

@@ -53,18 +53,17 @@ namespace aria2 {
 namespace rpc {
 
 RpcMethod::RpcMethod()
-  : optionParser_(OptionParser::getInstance()),
-    jsonRpc_(false)
+  : optionParser_(OptionParser::getInstance())
 {}
 
 RpcMethod::~RpcMethod() {}
 
 SharedHandle<ValueBase> RpcMethod::createErrorResponse
-(const Exception& e)
+(const Exception& e, const RpcRequest& req)
 {
   SharedHandle<Dict> params = Dict::g();
-  params->put((jsonRpc_ ? "code" : "faultCode"), Integer::g(1));
-  params->put((jsonRpc_ ? "message" : "faultString"), std::string(e.what()));
+  params->put((req.jsonRpc ? "code" : "faultCode"), Integer::g(1));
+  params->put((req.jsonRpc ? "message" : "faultString"), std::string(e.what()));
   return params;
 }
 
@@ -73,9 +72,9 @@ RpcResponse RpcMethod::execute
 {
   try {
     return RpcResponse(0, process(req, e), req.id);
-  } catch(RecoverableException& e) {
-    A2_LOG_DEBUG_EX(EX_EXCEPTION_CAUGHT, e);
-    return RpcResponse(1, createErrorResponse(e), req.id);
+  } catch(RecoverableException& ex) {
+    A2_LOG_DEBUG_EX(EX_EXCEPTION_CAUGHT, ex);
+    return RpcResponse(1, createErrorResponse(ex, req), req.id);
   }
 }
 

+ 4 - 12
src/RpcMethod.h

@@ -56,7 +56,8 @@ struct RpcResponse;
 
 // This class offers abstract implementation of processing RPC
 // request. You have to inherit this class and implement process()
-// method to add new RPC API.
+// method to add new RPC API. The derived class must be stateless
+// since we reuse the instances.
 //
 // There is RpcMethodFactory class which instantiates RpcMethod
 // subclass. If you add new RpcMethod subclass, don't forget to add it
@@ -64,7 +65,6 @@ struct RpcResponse;
 class RpcMethod {
 private:
   SharedHandle<OptionParser> optionParser_;
-  bool jsonRpc_;
 protected:
   // Subclass must implement this function to fulfil RpcRequest req.
   // The return value of this method is used as a return value of RPC
@@ -89,7 +89,8 @@ protected:
   // command to dest.
   void applyChangeableGlobalOption(Option* dest, Option* src) const;
 
-  SharedHandle<ValueBase> createErrorResponse(const Exception& e);
+  SharedHandle<ValueBase> createErrorResponse
+  (const Exception& e, const RpcRequest& req);
 
   const SharedHandle<OptionParser>& getOptionParser() const
   {
@@ -103,15 +104,6 @@ public:
   // Do work to fulfill RpcRequest req and returns its result as
   // RpcResponse. This method delegates to process() method.
   RpcResponse execute(const RpcRequest& req, DownloadEngine* e);
-  // Set whether JSON-RPC style parameter handling.
-  void setJsonRpc(bool f)
-  {
-    jsonRpc_ = f;
-  }
-  bool getJsonRpc() const
-  {
-    return jsonRpc_;
-  }
 };
 
 } // namespace rpc

+ 6 - 6
src/RpcMethodImpl.cc

@@ -270,7 +270,7 @@ SharedHandle<ValueBase> AddTorrentRpcMethod::process
     throw DL_ABORT_EX("Torrent data is not provided.");
   }
   SharedHandle<String> tempTorrentParam;
-  if(getJsonRpc()) {
+  if(req.jsonRpc) {
     tempTorrentParam = String::g(Base64::decode(torrentParam->s()));
     torrentParam = tempTorrentParam.get();
   }
@@ -317,7 +317,7 @@ SharedHandle<ValueBase> AddMetalinkRpcMethod::process
     throw DL_ABORT_EX("Metalink data is not provided.");
   }
   SharedHandle<String> tempMetalinkParam;
-  if(getJsonRpc()) {
+  if(req.jsonRpc) {
     tempMetalinkParam = String::g(Base64::decode(metalinkParam->s()));
     metalinkParam = tempMetalinkParam.get();
   }
@@ -1376,7 +1376,7 @@ SharedHandle<ValueBase> SystemMulticallRpcMethod::process
     const Dict* methodDict = asDict(*i);
     if(!methodDict) {
       list->append(createErrorResponse
-                   (DL_ABORT_EX("system.multicall expected struct.")));
+                   (DL_ABORT_EX("system.multicall expected struct."), req));
       continue;
     }
     const String* methodName = asString(methodDict->get(KEY_METHOD_NAME));
@@ -1384,18 +1384,18 @@ SharedHandle<ValueBase> SystemMulticallRpcMethod::process
 
     if(!methodName || !paramsList) {
       list->append(createErrorResponse
-                   (DL_ABORT_EX("Missing methodName or params.")));
+                   (DL_ABORT_EX("Missing methodName or params."), req));
       continue;
     }
     if(methodName->s() == getMethodName()) {
       list->append(createErrorResponse
-                   (DL_ABORT_EX("Recursive system.multicall forbidden.")));
+                   (DL_ABORT_EX("Recursive system.multicall forbidden."), req));
       continue;
     }
     SharedHandle<RpcMethod> method = RpcMethodFactory::create(methodName->s());
-    method->setJsonRpc(getJsonRpc());
     RpcRequest innerReq
       (methodName->s(), static_pointer_cast<List>(methodDict->get(KEY_PARAMS)));
+    innerReq.jsonRpc = req.jsonRpc;
     RpcResponse res = method->execute(innerReq, e);
     if(res.code == 0) {
       SharedHandle<List> l = List::g();

+ 2 - 2
src/RpcRequest.cc

@@ -40,13 +40,13 @@ namespace rpc {
 
 RpcRequest::RpcRequest(const std::string& methodName,
                        const SharedHandle<List>& params)
-  : methodName(methodName), params(params)
+  : methodName(methodName), params(params), jsonRpc(false)
 {}
 
 RpcRequest::RpcRequest(const std::string& methodName,
                        const SharedHandle<List>& params,
                        const SharedHandle<ValueBase>& id)
-  : methodName(methodName), params(params), id(id)
+  : methodName(methodName), params(params), id(id), jsonRpc(false)
 {}
 
 RpcRequest::RpcRequest(const RpcRequest& c)

+ 4 - 3
src/RpcRequest.h

@@ -49,13 +49,14 @@ struct RpcRequest {
   std::string methodName;
   SharedHandle<List> params;
   SharedHandle<ValueBase> id;
+  bool jsonRpc;
 
   RpcRequest(const std::string& methodName,
-                const SharedHandle<List>& params);
+             const SharedHandle<List>& params);
 
   RpcRequest(const std::string& methodName,
-                const SharedHandle<List>& params,
-                const SharedHandle<ValueBase>& id);
+             const SharedHandle<List>& params,
+             const SharedHandle<ValueBase>& id);
 
   ~RpcRequest();