Delay parsing parameters untils needed

This commit is contained in:
antao 2019-03-05 11:08:14 +08:00
parent bbd840bd3b
commit 7232536aee
3 changed files with 36 additions and 21 deletions

View File

@ -21,7 +21,7 @@
using namespace drogon;
void HttpRequestImpl::parseParameter()
void HttpRequestImpl::parseParameters() const
{
const std::string &input = query();
if (input.empty())

View File

@ -30,6 +30,7 @@
#include <stdio.h>
#include <algorithm>
#include <string>
#include <thread>
using std::string;
using namespace trantor;
@ -63,8 +64,6 @@ class HttpRequestImpl : public HttpRequest
return _version;
}
void parseParameter();
bool setMethod(const char *start, const char *end)
{
@ -159,11 +158,13 @@ class HttpRequestImpl : public HttpRequest
virtual const std::unordered_map<std::string, std::string> &getParameters() const override
{
parseParametersOnce();
return _parameters;
}
virtual const std::string &getParameter(const std::string &key, const std::string &defaultVal = std::string()) const override
{
parseParametersOnce();
auto iter = _parameters.find(key);
if (iter != _parameters.end())
return iter->second;
@ -280,6 +281,7 @@ class HttpRequestImpl : public HttpRequest
virtual void setParameter(const std::string &key, const std::string &value) override
{
_flagForParsingParameters = true;
_parameters[key] = value;
}
@ -337,6 +339,7 @@ class HttpRequestImpl : public HttpRequest
virtual const std::shared_ptr<Json::Value> getJsonObject() const override
{
parseParametersOnce();
return _jsonPtr;
}
@ -370,14 +373,25 @@ class HttpRequestImpl : public HttpRequest
}
private:
void parseParameters() const;
void parseParametersOnce() const
{
// Multi-thread is not safe but good enough
if(!_flagForParsingParameters)
{
_flagForParsingParameters = true;
parseParameters();
}
}
mutable bool _flagForParsingParameters=false;
HttpMethod _method;
Version _version;
std::string _path;
std::string _query;
std::unordered_map<std::string, std::string> _headers;
std::unordered_map<std::string, std::string> _cookies;
std::unordered_map<std::string, std::string> _parameters;
std::shared_ptr<Json::Value> _jsonPtr;
mutable std::unordered_map<std::string, std::string> _parameters;
mutable std::shared_ptr<Json::Value> _jsonPtr;
SessionPtr _sessionPtr;
trantor::InetAddress _peer;
trantor::InetAddress _local;

View File

@ -103,28 +103,26 @@ void HttpServer::onMessage(const TcpConnectionPtr &conn,
MsgBuffer *buf)
{
HttpRequestParser *requestParser = any_cast<HttpRequestParser>(conn->getMutableContext());
// LOG_INFO << "###:" << string(buf->peek(), buf->readableBytes());
if (requestParser->webSocketConn())
{
//websocket payload,we shouldn't parse it
_webSocketMessageCallback(requestParser->webSocketConn(), buf);
return;
}
int counter=0;
int counter = 0;
// With the pipelining feature or web socket, it is possible to receice multiple messages at once, so
// the while loop is necessary
while (buf->readableBytes() > 0)
{
if (requestParser->webSocketConn())
{
//Websocket payload,we shouldn't parse it
_webSocketMessageCallback(requestParser->webSocketConn(), buf);
return;
}
if (!requestParser->parseRequest(buf))
{
conn->send("HTTP/1.1 400 Bad Request\r\n\r\n");
//conn->shutdown();
requestParser->reset();
break;
return;
}
if (requestParser->gotAll())
{
requestParser->requestImpl()->parseParameter();
requestParser->requestImpl()->setPeerAddr(conn->peerAddr());
requestParser->requestImpl()->setLocalAddr(conn->localAddr());
requestParser->requestImpl()->setReceiveDate(trantor::Date::date());
@ -146,15 +144,16 @@ void HttpServer::onMessage(const TcpConnectionPtr &conn,
onRequest(conn, requestParser->requestImpl());
requestParser->reset();
counter++;
if(counter>1)
LOG_WARN<<"HAHAHAHA, more than 1 req received!"<<counter;
if (counter > 1)
LOG_TRACE << "More than one requests are parsed (" << counter << ")";
}
else
{
break;
return;
}
}
}
bool HttpServer::isWebSocket(const TcpConnectionPtr &conn, const HttpRequestImplPtr &req)
{
if (req->getHeaderBy("connection") == "Upgrade" &&
@ -166,6 +165,7 @@ bool HttpServer::isWebSocket(const TcpConnectionPtr &conn, const HttpRequestImpl
}
return false;
}
void HttpServer::onRequest(const TcpConnectionPtr &conn, const HttpRequestImplPtr &req)
{
const std::string &connection = req->getHeaderBy("connection");
@ -299,6 +299,7 @@ void HttpServer::onRequest(const TcpConnectionPtr &conn, const HttpRequestImplPt
}
});
}
void HttpServer::sendResponse(const TcpConnectionPtr &conn,
const HttpResponsePtr &response,
bool isHeadMethod)