75
86
e_->deleteSocketForReadCheck(socket_, this);
91
createJsonRpcErrorResponse
93
const std::string& msg,
94
const SharedHandle<ValueBase>& id)
96
SharedHandle<Dict> params = Dict::g();
97
params->put("code", Integer::g(code));
98
params->put("message", msg);
99
rpc::RpcResponse res(code, params, id);
105
std::string getJsonRpcContentType(bool script)
107
return script ? "text/javascript" : "application/json-rpc";
111
void HttpServerBodyCommand::sendJsonRpcResponse
112
(const rpc::RpcResponse& res,
113
const std::string& callback)
115
bool gzip = httpServer_->supportsGZip();
116
std::string responseData = res.toJson(callback, gzip);
118
httpServer_->feedResponse(responseData,
119
getJsonRpcContentType(!callback.empty()));
121
httpServer_->disableKeepAlive();
122
std::string httpCode;
125
httpCode = "400 Bad Request";
128
httpCode = "404 Not Found";
131
httpCode = "500 Internal Server Error";
133
httpServer_->feedResponse(httpCode, A2STR::NIL,
135
getJsonRpcContentType(!callback.empty()));
137
addHttpServerResponseCommand();
140
void HttpServerBodyCommand::sendJsonRpcBatchResponse
141
(const std::vector<rpc::RpcResponse>& results,
142
const std::string& callback)
144
bool gzip = httpServer_->supportsGZip();
145
std::string responseData = rpc::toJsonBatch(results, callback, gzip);
146
httpServer_->feedResponse(responseData,
147
getJsonRpcContentType(!callback.empty()));
148
addHttpServerResponseCommand();
151
void HttpServerBodyCommand::addHttpServerResponseCommand()
154
new HttpServerResponseCommand(getCuid(), httpServer_, e_, socket_);
155
e_->addCommand(command);
160
HttpServerBodyCommand::processJsonRpcRequest(const Dict* jsondict)
163
SharedHandle<ValueBase> id = jsondict->get("id");
165
return createJsonRpcErrorResponse(-32600, "Invalid Request.", Null::g());
167
const String* methodName = asString(jsondict->get("method"));
169
return createJsonRpcErrorResponse(-32600, "Invalid Request.", id);
171
SharedHandle<List> params;
172
const SharedHandle<ValueBase>& tempParams = jsondict->get("params");
173
if(asList(tempParams)) {
174
params = static_pointer_cast<List>(tempParams);
175
} else if(!tempParams) {
178
// TODO No support for Named params
179
return createJsonRpcErrorResponse(-32602, "Invalid params.", id);
181
rpc::RpcRequest req(methodName->s(), params, id);
182
SharedHandle<rpc::RpcMethod> method;
184
method = rpc::RpcMethodFactory::create(req.methodName);
185
} catch(RecoverableException& e) {
186
A2_LOG_INFO_EX(EX_EXCEPTION_CAUGHT, e);
187
return createJsonRpcErrorResponse(-32601, "Method not found.", id);
189
method->setJsonRpc(true);
190
rpc::RpcResponse res = method->execute(req, e_);
78
194
bool HttpServerBodyCommand::execute()
80
196
if(e_->getRequestGroupMan()->downloadFinished() || e_->isHaltRequested()) {
84
if(socket_->isReadable(0) || httpServer_->getContentLength() == 0) {
200
if(socket_->isReadable(0) ||
201
!httpServer_->getSocketRecvBuffer()->bufferEmpty() ||
202
httpServer_->getContentLength() == 0) {
85
203
timeoutTimer_ = global::wallclock;
87
205
if(httpServer_->receiveBody()) {
206
std::string reqPath = httpServer_->getRequestPath();
207
reqPath.erase(std::find(reqPath.begin(), reqPath.end(), '#'),
209
std::string query(std::find(reqPath.begin(), reqPath.end(), '?'),
211
reqPath.erase(reqPath.size()-query.size(), query.size());
88
212
// Do something for requestpath and body
89
if(httpServer_->getRequestPath() == "/rpc") {
90
xmlrpc::XmlRpcRequest req =
91
xmlrpc::XmlRpcRequestProcessor().parseMemory(httpServer_->getBody());
93
SharedHandle<xmlrpc::XmlRpcMethod> method =
94
xmlrpc::XmlRpcMethodFactory::create(req.methodName);
95
xmlrpc::XmlRpcResponse res = method->execute(req, e_);
213
if(reqPath == "/rpc") {
214
#ifdef ENABLE_XML_RPC
215
rpc::RpcRequest req =
216
rpc::XmlRpcRequestProcessor().parseMemory(httpServer_->getBody());
217
SharedHandle<rpc::RpcMethod> method =
218
rpc::RpcMethodFactory::create(req.methodName);
219
rpc::RpcResponse res = method->execute(req, e_);
96
220
bool gzip = httpServer_->supportsGZip();
97
221
std::string responseData = res.toXml(gzip);
98
222
httpServer_->feedResponse(responseData, "text/xml");
100
new HttpServerResponseCommand(getCuid(), httpServer_, e_, socket_);
101
e_->addCommand(command);
223
addHttpServerResponseCommand();
224
#endif // ENABLE_XML_RPC
226
} else if(reqPath == "/jsonrpc") {
227
std::string callback;
228
SharedHandle<ValueBase> json;
230
if(httpServer_->getMethod() == "GET") {
231
json::JsonGetParam param = json::decodeGetParams(query);
232
callback = param.callback;
233
json = json::decode(param.request);
235
json = json::decode(httpServer_->getBody());
237
} catch(RecoverableException& e) {
239
(fmt("CUID#%lld - Failed to parse JSON-RPC request",
243
(createJsonRpcErrorResponse(-32700, "Parse error.", Null::g()));
244
sendJsonRpcResponse(res, callback);
247
const Dict* jsondict = asDict(json);
249
rpc::RpcResponse res = processJsonRpcRequest(jsondict);
250
sendJsonRpcResponse(res, callback);
252
const List* jsonlist = asList(json);
254
// This is batch call
255
std::vector<rpc::RpcResponse> results;
256
for(List::ValueType::const_iterator i = jsonlist->begin(),
257
eoi = jsonlist->end(); i != eoi; ++i) {
258
const Dict* jsondict = asDict(*i);
260
rpc::RpcResponse r = processJsonRpcRequest(jsondict);
261
results.push_back(r);
264
sendJsonRpcBatchResponse(results, callback);
267
(createJsonRpcErrorResponse
268
(-32600, "Invalid Request.", Null::g()));
269
sendJsonRpcResponse(res, callback);