diff --git a/lib/src/HttpRequestImpl.cc b/lib/src/HttpRequestImpl.cc index 8d11d3e1..7f9a2f9b 100755 --- a/lib/src/HttpRequestImpl.cc +++ b/lib/src/HttpRequestImpl.cc @@ -21,7 +21,7 @@ using namespace drogon; -void HttpRequestImpl::parseParameter() +void HttpRequestImpl::parseParameters() const { const std::string &input = query(); if (input.empty()) diff --git a/lib/src/HttpRequestImpl.h b/lib/src/HttpRequestImpl.h index 3f4f13ea..64af8186 100755 --- a/lib/src/HttpRequestImpl.h +++ b/lib/src/HttpRequestImpl.h @@ -30,6 +30,7 @@ #include #include #include +#include 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 &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 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 _headers; std::unordered_map _cookies; - std::unordered_map _parameters; - std::shared_ptr _jsonPtr; + mutable std::unordered_map _parameters; + mutable std::shared_ptr _jsonPtr; SessionPtr _sessionPtr; trantor::InetAddress _peer; trantor::InetAddress _local; diff --git a/lib/src/HttpServer.cc b/lib/src/HttpServer.cc index aecb28ea..fdfb0e78 100755 --- a/lib/src/HttpServer.cc +++ b/lib/src/HttpServer.cc @@ -103,28 +103,26 @@ void HttpServer::onMessage(const TcpConnectionPtr &conn, MsgBuffer *buf) { HttpRequestParser *requestParser = any_cast(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!"< 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)