From 7100b1b9ca10f8bd940ff436b2a16f91d34d5429 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sat, 14 Jul 2012 18:59:56 +0900 Subject: Parse HTTP RPC request on the fly without buffering --- src/HttpServerBodyCommand.cc | 67 +++++++++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 23 deletions(-) (limited to 'src/HttpServerBodyCommand.cc') diff --git a/src/HttpServerBodyCommand.cc b/src/HttpServerBodyCommand.cc index 44cd6b95..ff9e3eb0 100644 --- a/src/HttpServerBodyCommand.cc +++ b/src/HttpServerBodyCommand.cc @@ -57,8 +57,11 @@ #include "RpcRequest.h" #include "RpcResponse.h" #include "rpc_helper.h" +#include "JsonDiskWriter.h" +#include "ValueBaseJsonParser.h" #ifdef ENABLE_XML_RPC -# include "XmlRpcRequestParserStateMachine.h" +# include "XmlRpcRequestParserStateMachine.h" +# include "XmlRpcDiskWriter.h" #endif // ENABLE_XML_RPC namespace aria2 { @@ -187,17 +190,22 @@ bool HttpServerBodyCommand::execute() } // Do something for requestpath and body - if(reqPath == "/rpc") { + switch(httpServer_->getRequestType()) { + case RPC_TYPE_XML: { #ifdef ENABLE_XML_RPC - std::string body = httpServer_->getBody(); + SharedHandle dw = + static_pointer_cast(httpServer_->getBody()); + int error; + error = dw->finalize(); rpc::RpcRequest req; - try { - req = rpc::xmlParseMemory(body.c_str(), body.size()); - } catch(RecoverableException& e) { - A2_LOG_INFO_EX + if(error == 0) { + req = dw->getResult(); + } + dw->reset(); + if(error < 0) { + A2_LOG_INFO (fmt("CUID#%" PRId64 " - Failed to parse XML-RPC request", - getCuid()), - e); + getCuid())); httpServer_->feedResponse(400); addHttpServerResponseCommand(); return true; @@ -215,22 +223,33 @@ bool HttpServerBodyCommand::execute() addHttpServerResponseCommand(); #endif // !ENABLE_XML_RPC return true; - } else if(reqPath == "/jsonrpc") { + } + case RPC_TYPE_JSON: + case RPC_TYPE_JSONP: { std::string callback; SharedHandle json; - try { - if(httpServer_->getMethod() == "GET") { - json::JsonGetParam param = json::decodeGetParams(query); - callback = param.callback; - json = json::decode(param.request); - } else { - json = json::decode(httpServer_->getBody()); + ssize_t error = 0; + if(httpServer_->getRequestType() == RPC_TYPE_JSONP) { + json::JsonGetParam param = json::decodeGetParams(query); + callback = param.callback; + ssize_t error = 0; + json = json::ValueBaseJsonParser().parseFinal + (param.request.c_str(), + param.request.size(), + error); + } else { + SharedHandle dw = + static_pointer_cast(httpServer_->getBody()); + error = dw->finalize(); + if(error == 0) { + json = dw->getResult(); } - } catch(RecoverableException& e) { - A2_LOG_INFO_EX + dw->reset(); + } + if(error < 0) { + A2_LOG_INFO (fmt("CUID#%" PRId64 " - Failed to parse JSON-RPC request", - getCuid()), - e); + getCuid())); rpc::RpcResponse res (rpc::createJsonRpcErrorResponse(-32700, "Parse error.", Null::g())); @@ -250,7 +269,8 @@ bool HttpServerBodyCommand::execute() eoi = jsonlist->end(); i != eoi; ++i) { const Dict* jsondict = downcast(*i); if(jsondict) { - rpc::RpcResponse r = rpc::processJsonRpcRequest(jsondict, e_); + rpc::RpcResponse r = + rpc::processJsonRpcRequest(jsondict, e_); results.push_back(r); } } @@ -263,7 +283,8 @@ bool HttpServerBodyCommand::execute() } } return true; - } else { + } + default: httpServer_->feedResponse(404); addHttpServerResponseCommand(); return true; -- cgit