diff --git a/examples/simple_example_test/main.cc b/examples/simple_example_test/main.cc index c9951b66..a5152c0f 100644 --- a/examples/simple_example_test/main.cc +++ b/examples/simple_example_test/main.cc @@ -312,7 +312,7 @@ void doTest(const HttpClientPtr &client) client->sendRequest(req, [=](ReqResult result, const HttpResponsePtr &resp) { if (result == ReqResult::Ok) { - if (resp->getBody().length() == 1754) + if (resp->getBody().length() == 5123) { outputGood(req); } @@ -468,12 +468,16 @@ int main() trantor::EventLoopThread loop[2]; loop[0].run(); loop[1].run(); - auto client = HttpClient::newHttpClient("http://127.0.0.1:8848", loop[0].getLoop()); - doTest(client); + // for (int i = 0; i < 100;i++) + { + auto client = HttpClient::newHttpClient("http://127.0.0.1:8848", loop[0].getLoop()); + doTest(client); #ifdef USE_OPENSSL - auto sslClient = HttpClient::newHttpClient("https://127.0.0.1:8849", loop[1].getLoop()); - doTest(sslClient); + auto sslClient = HttpClient::newHttpClient("https://127.0.0.1:8849", loop[1].getLoop()); + doTest(sslClient); #endif + } + getchar(); loop[0].getLoop()->quit(); loop[1].getLoop()->quit(); diff --git a/lib/inc/drogon/utils/Utilities.h b/lib/inc/drogon/utils/Utilities.h index f0c7dc28..ac58007f 100755 --- a/lib/inc/drogon/utils/Utilities.h +++ b/lib/inc/drogon/utils/Utilities.h @@ -18,6 +18,7 @@ #include #include #include +#include namespace drogon { @@ -64,6 +65,7 @@ int gzipCompress(const char *data, const size_t ndata, char *zdata, size_t *nzdata); int gzipDecompress(const char *zdata, const size_t nzdata, char *data, size_t *ndata); +std::shared_ptr gzipDecompress(const std::shared_ptr &compressedData); /// Get the http full date string /** diff --git a/lib/src/HttpAppFrameworkImpl.cc b/lib/src/HttpAppFrameworkImpl.cc index 045d4ab4..05f1f279 100755 --- a/lib/src/HttpAppFrameworkImpl.cc +++ b/lib/src/HttpAppFrameworkImpl.cc @@ -609,24 +609,24 @@ void HttpAppFrameworkImpl::onAsyncRequest(const HttpRequestImplPtr &req, std::fu LOG_TRACE << "http path=" << req->path(); // LOG_TRACE << "query: " << req->query() ; - std::string session_id = req->getCookie("JSESSIONID"); + std::string sessionId = req->getCookie("JSESSIONID"); bool needSetJsessionid = false; if (_useSession) { - if (session_id == "") + if (sessionId == "") { - session_id = getuuid().c_str(); + sessionId = getuuid().c_str(); needSetJsessionid = true; - _sessionMapPtr->insert(session_id, std::make_shared(), _sessionTimeout); + _sessionMapPtr->insert(sessionId, std::make_shared(), _sessionTimeout); } else { - if (_sessionMapPtr->find(session_id) == false) + if (_sessionMapPtr->find(sessionId) == false) { - _sessionMapPtr->insert(session_id, std::make_shared(), _sessionTimeout); + _sessionMapPtr->insert(sessionId, std::make_shared(), _sessionTimeout); } } - (std::dynamic_pointer_cast(req))->setSession((*_sessionMapPtr)[session_id]); + (std::dynamic_pointer_cast(req))->setSession((*_sessionMapPtr)[sessionId]); } const std::string &path = req->path(); @@ -674,7 +674,7 @@ void HttpAppFrameworkImpl::onAsyncRequest(const HttpRequestImplPtr &req, std::fu resp->setStatusCode(HttpResponse::k304NotModified); if (needSetJsessionid) { - resp->addCookie("JSESSIONID", session_id); + resp->addCookie("JSESSIONID", sessionId); } callback(resp); return; @@ -700,7 +700,7 @@ void HttpAppFrameworkImpl::onAsyncRequest(const HttpRequestImplPtr &req, std::fu resp->setStatusCode(HttpResponse::k304NotModified); if (needSetJsessionid) { - resp->addCookie("JSESSIONID", session_id); + resp->addCookie("JSESSIONID", sessionId); } callback(resp); return; @@ -717,7 +717,7 @@ void HttpAppFrameworkImpl::onAsyncRequest(const HttpRequestImplPtr &req, std::fu { //make a copy auto newCachedResp = std::make_shared(*std::dynamic_pointer_cast(cachedResp)); - newCachedResp->addCookie("JSESSIONID", session_id); + newCachedResp->addCookie("JSESSIONID", sessionId); newCachedResp->setExpiredTime(-1); callback(newCachedResp); return; @@ -779,7 +779,7 @@ void HttpAppFrameworkImpl::onAsyncRequest(const HttpRequestImplPtr &req, std::fu newCachedResp = std::make_shared(*std::dynamic_pointer_cast(resp)); newCachedResp->setExpiredTime(-1); } - newCachedResp->addCookie("JSESSIONID", session_id); + newCachedResp->addCookie("JSESSIONID", sessionId); callback(newCachedResp); return; } @@ -789,7 +789,7 @@ void HttpAppFrameworkImpl::onAsyncRequest(const HttpRequestImplPtr &req, std::fu } //Route to controller - _httpSimpleCtrlsRouter.route(req, std::move(callback), needSetJsessionid, std::move(session_id)); + _httpSimpleCtrlsRouter.route(req, std::move(callback), needSetJsessionid, std::move(sessionId)); } void HttpAppFrameworkImpl::readSendFile(const std::string &filePath, const HttpRequestImplPtr &req, const HttpResponsePtr &resp) diff --git a/lib/src/HttpClientImpl.cc b/lib/src/HttpClientImpl.cc index fdff7dd6..e0792c57 100644 --- a/lib/src/HttpClientImpl.cc +++ b/lib/src/HttpClientImpl.cc @@ -14,7 +14,7 @@ #include "HttpClientImpl.h" #include "HttpRequestImpl.h" -#include "HttpClientParser.h" +#include "HttpResponseParser.h" #include "HttpAppFrameworkImpl.h" #include #include @@ -131,7 +131,7 @@ void HttpClientImpl::sendRequestInLoop(const drogon::HttpRequestPtr &req, _tcpClient->setConnectionCallback([=](const trantor::TcpConnectionPtr &connPtr) { if (connPtr->connected()) { - connPtr->setContext(HttpClientParser(connPtr)); + connPtr->setContext(HttpResponseParser(connPtr)); //send request; LOG_TRACE << "Connection established!"; auto req = thisPtr->_reqAndCallbacks.front().first; @@ -197,10 +197,10 @@ void HttpClientImpl::sendReq(const trantor::TcpConnectionPtr &connPtr, const Htt void HttpClientImpl::onRecvMessage(const trantor::TcpConnectionPtr &connPtr, trantor::MsgBuffer *msg) { - HttpClientParser *context = any_cast(connPtr->getMutableContext()); + HttpResponseParser *responseParser = any_cast(connPtr->getMutableContext()); //LOG_TRACE << "###:" << msg->readableBytes(); - if (!context->parseResponse(msg)) + if (!responseParser->parseResponse(msg)) { assert(!_reqAndCallbacks.empty()); auto cb = _reqAndCallbacks.front().second; @@ -211,10 +211,10 @@ void HttpClientImpl::onRecvMessage(const trantor::TcpConnectionPtr &connPtr, tra return; } - if (context->gotAll()) + if (responseParser->gotAll()) { - auto resp = context->responseImpl(); - context->reset(); + auto resp = responseParser->responseImpl(); + responseParser->reset(); assert(!_reqAndCallbacks.empty()); @@ -223,6 +223,11 @@ void HttpClientImpl::onRecvMessage(const trantor::TcpConnectionPtr &connPtr, tra { resp->parseJson(); } + + if (resp->getHeaderBy("content-encoding")=="gzip") + { + resp->gunzip(); + } auto &cb = _reqAndCallbacks.front().second; cb(ReqResult::Ok, resp); _reqAndCallbacks.pop(); diff --git a/lib/src/HttpControllersRouter.cc b/lib/src/HttpControllersRouter.cc index ef6c7fec..9c3e9648 100644 --- a/lib/src/HttpControllersRouter.cc +++ b/lib/src/HttpControllersRouter.cc @@ -140,7 +140,7 @@ void HttpControllersRouter::addHttpPath(const std::string &path, void HttpControllersRouter::route(const HttpRequestImplPtr &req, std::function &&callback, bool needSetJsessionid, - std::string &&session_id) + std::string &&sessionId) { //find http controller if (_ctrlRegex.mark_count() > 0) @@ -172,7 +172,7 @@ void HttpControllersRouter::route(const HttpRequestImplPtr &req, auto &filters = binder->filtersName; if (!filters.empty()) { - auto sessionIdPtr = std::make_shared(std::move(session_id)); + auto sessionIdPtr = std::make_shared(std::move(sessionId)); auto callbackPtr = std::make_shared>(std::move(callback)); _appImpl.doFilters(filters, req, callbackPtr, needSetJsessionid, sessionIdPtr, [=]() { doControllerHandler(binder, routerItem, req, std::move(*callbackPtr), needSetJsessionid, std::move(*sessionIdPtr)); @@ -180,7 +180,7 @@ void HttpControllersRouter::route(const HttpRequestImplPtr &req, } else { - doControllerHandler(binder, routerItem, req, std::move(callback), needSetJsessionid, std::move(session_id)); + doControllerHandler(binder, routerItem, req, std::move(callback), needSetJsessionid, std::move(sessionId)); } } } @@ -190,7 +190,7 @@ void HttpControllersRouter::route(const HttpRequestImplPtr &req, //No controller found auto res = drogon::HttpResponse::newNotFoundResponse(); if (needSetJsessionid) - res->addCookie("JSESSIONID", session_id); + res->addCookie("JSESSIONID", sessionId); callback(res); } } @@ -199,7 +199,7 @@ void HttpControllersRouter::route(const HttpRequestImplPtr &req, //No controller found auto res = drogon::HttpResponse::newNotFoundResponse(); if (needSetJsessionid) - res->addCookie("JSESSIONID", session_id); + res->addCookie("JSESSIONID", sessionId); callback(res); } } @@ -209,7 +209,7 @@ void HttpControllersRouter::doControllerHandler(const CtrlBinderPtr &ctrlBinderP const HttpRequestImplPtr &req, std::function &&callback, bool needSetJsessionid, - std::string &&session_id) + std::string &&sessionId) { HttpResponsePtr responsePtr; { @@ -229,7 +229,7 @@ void HttpControllersRouter::doControllerHandler(const CtrlBinderPtr &ctrlBinderP //make a copy response; auto newResp = std::make_shared(*std::dynamic_pointer_cast(responsePtr)); newResp->setExpiredTime(-1); //make it temporary - newResp->addCookie("JSESSIONID", session_id); + newResp->addCookie("JSESSIONID", sessionId); callback(newResp); } return; @@ -270,8 +270,8 @@ void HttpControllersRouter::doControllerHandler(const CtrlBinderPtr &ctrlBinderP paraList.push_back(std::move(p)); } - ctrlBinderPtr->binderPtr->handleHttpRequest(paraList, req, [=, callback = std::move(callback), session_id = std::move(session_id)](const HttpResponsePtr &resp) { - LOG_TRACE << "http resp:needSetJsessionid=" << needSetJsessionid << ";JSESSIONID=" << session_id; + ctrlBinderPtr->binderPtr->handleHttpRequest(paraList, req, [=, callback = std::move(callback), sessionId = std::move(sessionId)](const HttpResponsePtr &resp) { + LOG_TRACE << "http resp:needSetJsessionid=" << needSetJsessionid << ";JSESSIONID=" << sessionId; auto newResp = resp; if (resp->expiredTime() >= 0) { @@ -290,7 +290,7 @@ void HttpControllersRouter::doControllerHandler(const CtrlBinderPtr &ctrlBinderP newResp = std::make_shared(*std::dynamic_pointer_cast(resp)); newResp->setExpiredTime(-1); //make it temporary } - newResp->addCookie("JSESSIONID", session_id); + newResp->addCookie("JSESSIONID", sessionId); } callback(newResp); }); diff --git a/lib/src/HttpControllersRouter.h b/lib/src/HttpControllersRouter.h index 7af3a1e4..2eff81f5 100644 --- a/lib/src/HttpControllersRouter.h +++ b/lib/src/HttpControllersRouter.h @@ -38,7 +38,7 @@ class HttpControllersRouter : public trantor::NonCopyable void route(const HttpRequestImplPtr &req, std::function &&callback, bool needSetJsessionid, - std::string &&session_id); + std::string &&sessionId); private: struct CtrlBinder @@ -67,6 +67,6 @@ class HttpControllersRouter : public trantor::NonCopyable const HttpRequestImplPtr &req, std::function &&callback, bool needSetJsessionid, - std::string &&session_id); + std::string &&sessionId); }; } // namespace drogon \ No newline at end of file diff --git a/lib/src/HttpRequestImpl.h b/lib/src/HttpRequestImpl.h index df271cb9..e75148b1 100755 --- a/lib/src/HttpRequestImpl.h +++ b/lib/src/HttpRequestImpl.h @@ -33,7 +33,7 @@ namespace drogon class HttpRequestImpl : public HttpRequest { public: - friend class HttpServerParser; + friend class HttpRequestParser; HttpRequestImpl() : _method(Invalid), _version(kUnknown), diff --git a/lib/src/HttpServerParser.cc b/lib/src/HttpRequestParser.cc similarity index 92% rename from lib/src/HttpServerParser.cc rename to lib/src/HttpRequestParser.cc index 7fafb38e..180666c5 100755 --- a/lib/src/HttpServerParser.cc +++ b/lib/src/HttpRequestParser.cc @@ -1,6 +1,6 @@ /** * - * HttpServerParser.cc + * HttpRequestParser.cc * An Tao * * Copyright 2018, An Tao. All rights reserved. @@ -14,18 +14,18 @@ #include #include -#include "HttpServerParser.h" +#include "HttpRequestParser.h" #include "HttpResponseImpl.h" #include using namespace trantor; using namespace drogon; -HttpServerParser::HttpServerParser(const trantor::TcpConnectionPtr &connPtr) +HttpRequestParser::HttpRequestParser(const trantor::TcpConnectionPtr &connPtr) : _state(kExpectRequestLine), _request(new HttpRequestImpl), _conn(connPtr) { } -bool HttpServerParser::processRequestLine(const char *begin, const char *end) +bool HttpRequestParser::processRequestLine(const char *begin, const char *end) { bool succeed = false; const char *start = begin; @@ -69,7 +69,7 @@ bool HttpServerParser::processRequestLine(const char *begin, const char *end) } // return false if any error -bool HttpServerParser::parseRequest(MsgBuffer *buf) +bool HttpRequestParser::parseRequest(MsgBuffer *buf) { bool ok = true; bool hasMore = true; @@ -196,7 +196,7 @@ bool HttpServerParser::parseRequest(MsgBuffer *buf) return ok; } -void HttpServerParser::pushRquestToPipeLine(const HttpRequestPtr &req) +void HttpRequestParser::pushRquestToPipeLine(const HttpRequestPtr &req) { #ifndef NDEBUG auto conn = _conn.lock(); @@ -209,7 +209,7 @@ void HttpServerParser::pushRquestToPipeLine(const HttpRequestPtr &req) _requestPipeLine.push_back(std::move(reqPair)); } -HttpRequestPtr HttpServerParser::getFirstRequest() const +HttpRequestPtr HttpRequestParser::getFirstRequest() const { #ifndef NDEBUG auto conn = _conn.lock(); @@ -224,7 +224,7 @@ HttpRequestPtr HttpServerParser::getFirstRequest() const } return HttpRequestImplPtr(); } -HttpResponsePtr HttpServerParser::getFirstResponse() const +HttpResponsePtr HttpRequestParser::getFirstResponse() const { #ifndef NDEBUG auto conn = _conn.lock(); @@ -239,7 +239,7 @@ HttpResponsePtr HttpServerParser::getFirstResponse() const } return HttpResponseImplPtr(); } -void HttpServerParser::popFirstRequest() +void HttpRequestParser::popFirstRequest() { #ifndef NDEBUG auto conn = _conn.lock(); @@ -250,7 +250,7 @@ void HttpServerParser::popFirstRequest() #endif _requestPipeLine.pop_front(); } -void HttpServerParser::pushResponseToPipeLine(const HttpRequestPtr &req, +void HttpRequestParser::pushResponseToPipeLine(const HttpRequestPtr &req, const HttpResponsePtr &resp) { #ifndef NDEBUG @@ -270,7 +270,7 @@ void HttpServerParser::pushResponseToPipeLine(const HttpRequestPtr &req, } } -// std::mutex &HttpServerParser::getPipeLineMutex() +// std::mutex &HttpRequestParser::getPipeLineMutex() // { // return *_pipeLineMutex; // } diff --git a/lib/src/HttpServerParser.h b/lib/src/HttpRequestParser.h similarity index 95% rename from lib/src/HttpServerParser.h rename to lib/src/HttpRequestParser.h index 903eb97c..0cf9ea80 100755 --- a/lib/src/HttpServerParser.h +++ b/lib/src/HttpRequestParser.h @@ -1,6 +1,6 @@ /** * - * HttpServerParser.h + * HttpRequestParser.h * An Tao * * Copyright 2018, An Tao. All rights reserved. @@ -25,7 +25,7 @@ using namespace trantor; namespace drogon { -class HttpServerParser +class HttpRequestParser { public: enum HttpRequestParseState @@ -36,7 +36,7 @@ class HttpServerParser kGotAll, }; - HttpServerParser(const trantor::TcpConnectionPtr &connPtr); + HttpRequestParser(const trantor::TcpConnectionPtr &connPtr); // return false if any error bool parseRequest(MsgBuffer *buf); diff --git a/lib/src/HttpResponseImpl.h b/lib/src/HttpResponseImpl.h index 43113ac8..45d025d3 100755 --- a/lib/src/HttpResponseImpl.h +++ b/lib/src/HttpResponseImpl.h @@ -29,7 +29,7 @@ namespace drogon { class HttpResponseImpl : public HttpResponse { - friend class HttpClientParser; + friend class HttpResponseParser; public: explicit HttpResponseImpl() @@ -352,6 +352,13 @@ class HttpResponseImpl : public HttpResponse makeHeaderString(_fullHeaderString); } + void gunzip() + { + auto gunzipBody = gzipDecompress(_bodyPtr); + if(gunzipBody) + _bodyPtr = gunzipBody; + } + protected: static std::string web_content_type_to_string(uint8_t contenttype); static const std::string web_content_type_and_charset_to_string(uint8_t contenttype, diff --git a/lib/src/HttpClientParser.cc b/lib/src/HttpResponseParser.cc similarity index 96% rename from lib/src/HttpClientParser.cc rename to lib/src/HttpResponseParser.cc index 59e55550..1507a9d1 100755 --- a/lib/src/HttpClientParser.cc +++ b/lib/src/HttpResponseParser.cc @@ -1,6 +1,6 @@ /** * - * HttpClientParser.cc + * HttpResponseParser.cc * An Tao * * Copyright 2018, An Tao. All rights reserved. @@ -14,17 +14,17 @@ #include #include -#include "HttpClientParser.h" +#include "HttpResponseParser.h" #include using namespace trantor; using namespace drogon; -HttpClientParser::HttpClientParser(const trantor::TcpConnectionPtr &connPtr) +HttpResponseParser::HttpResponseParser(const trantor::TcpConnectionPtr &connPtr) : _state(HttpResponseParseState::kExpectResponseLine), _response(new HttpResponseImpl) { } -bool HttpClientParser::processResponseLine(const char *begin, const char *end) +bool HttpResponseParser::processResponseLine(const char *begin, const char *end) { const char *start = begin; const char *space = std::find(start, end, ' '); @@ -61,7 +61,7 @@ bool HttpClientParser::processResponseLine(const char *begin, const char *end) } // return false if any error -bool HttpClientParser::parseResponse(MsgBuffer *buf) +bool HttpResponseParser::parseResponse(MsgBuffer *buf) { bool ok = true; bool hasMore = true; diff --git a/lib/src/HttpClientParser.h b/lib/src/HttpResponseParser.h similarity index 91% rename from lib/src/HttpClientParser.h rename to lib/src/HttpResponseParser.h index 28e1a46f..3506520c 100755 --- a/lib/src/HttpClientParser.h +++ b/lib/src/HttpResponseParser.h @@ -1,6 +1,6 @@ /** * - * HttpClientParser.h + * HttpResponseParser.h * An Tao * * Copyright 2018, An Tao. All rights reserved. @@ -24,7 +24,7 @@ using namespace trantor; namespace drogon { -class HttpClientParser +class HttpResponseParser { public: enum class HttpResponseParseState @@ -39,7 +39,7 @@ class HttpClientParser kGotAll, }; - explicit HttpClientParser(const trantor::TcpConnectionPtr &connPtr); + explicit HttpResponseParser(const trantor::TcpConnectionPtr &connPtr); // default copy-ctor, dtor and assignment are fine diff --git a/lib/src/HttpServer.cc b/lib/src/HttpServer.cc index 1e706002..88ed8754 100755 --- a/lib/src/HttpServer.cc +++ b/lib/src/HttpServer.cc @@ -15,7 +15,7 @@ #include "HttpServer.h" #include -#include "HttpServerParser.h" +#include "HttpRequestParser.h" #include "HttpResponseImpl.h" #include #include @@ -76,17 +76,17 @@ void HttpServer::onConnection(const TcpConnectionPtr &conn) { if (conn->connected()) { - conn->setContext(HttpServerParser(conn)); + conn->setContext(HttpRequestParser(conn)); } else if (conn->disconnected()) { LOG_TRACE << "conn disconnected!"; - HttpServerParser *context = any_cast(conn->getMutableContext()); + HttpRequestParser *requestParser = any_cast(conn->getMutableContext()); // LOG_INFO << "###:" << string(buf->peek(), buf->readableBytes()); - if (context->webSocketConn()) + if (requestParser->webSocketConn()) { - _disconnectWebsocketCallback(context->webSocketConn()); + _disconnectWebsocketCallback(requestParser->webSocketConn()); } conn->getMutableContext()->reset(); } @@ -96,35 +96,35 @@ void HttpServer::onConnection(const TcpConnectionPtr &conn) void HttpServer::onMessage(const TcpConnectionPtr &conn, MsgBuffer *buf) { - HttpServerParser *context = any_cast(conn->getMutableContext()); + HttpRequestParser *requestParser = any_cast(conn->getMutableContext()); // LOG_INFO << "###:" << string(buf->peek(), buf->readableBytes()); - if (context->webSocketConn()) + if (requestParser->webSocketConn()) { //websocket payload,we shouldn't parse it - _webSocketMessageCallback(context->webSocketConn(), buf); + _webSocketMessageCallback(requestParser->webSocketConn(), buf); return; } - if (!context->parseRequest(buf)) + if (!requestParser->parseRequest(buf)) { conn->send("HTTP/1.1 400 Bad Request\r\n\r\n"); //conn->shutdown(); } - if (context->gotAll()) + if (requestParser->gotAll()) { - context->requestImpl()->parseParameter(); - context->requestImpl()->setPeerAddr(conn->peerAddr()); - context->requestImpl()->setLocalAddr(conn->localAddr()); - context->requestImpl()->setReceiveDate(trantor::Date::date()); - if (context->firstReq() && isWebSocket(conn, context->request())) + requestParser->requestImpl()->parseParameter(); + requestParser->requestImpl()->setPeerAddr(conn->peerAddr()); + requestParser->requestImpl()->setLocalAddr(conn->localAddr()); + requestParser->requestImpl()->setReceiveDate(trantor::Date::date()); + if (requestParser->firstReq() && isWebSocket(conn, requestParser->request())) { auto wsConn = std::make_shared(conn); - _newWebsocketCallback(context->request(), + _newWebsocketCallback(requestParser->request(), [=](const HttpResponsePtr &resp) mutable { if (resp->statusCode() == HttpResponse::k101SwitchingProtocols) { - context->setWebsockConnection(wsConn); + requestParser->setWebsockConnection(wsConn); } auto httpString = std::dynamic_pointer_cast(resp)->renderToString(); conn->send(httpString); @@ -132,8 +132,8 @@ void HttpServer::onMessage(const TcpConnectionPtr &conn, wsConn); } else - onRequest(conn, context->request()); - context->reset(); + onRequest(conn, requestParser->request()); + requestParser->reset(); } } bool HttpServer::isWebSocket(const TcpConnectionPtr &conn, const HttpRequestImplPtr &req) @@ -158,10 +158,10 @@ void HttpServer::onRequest(const TcpConnectionPtr &conn, const HttpRequestImplPt { req->setMethod(Get); } - HttpServerParser *context = any_cast(conn->getMutableContext()); + HttpRequestParser *requestParser = any_cast(conn->getMutableContext()); { - //std::lock_guard guard(context->getPipeLineMutex()); - context->pushRquestToPipeLine(req); + //std::lock_guard guard(requestParser->getPipeLineMutex()); + requestParser->pushRquestToPipeLine(req); } _httpAsyncCallback(req, [=](const HttpResponsePtr &response) { if (!response) @@ -224,17 +224,17 @@ void HttpServer::onRequest(const TcpConnectionPtr &conn, const HttpRequestImplPt * requests in the same order that the requests were received. * rfc2616-8.1.1.2 */ - //std::lock_guard guard(context->getPipeLineMutex()); - if (context->getFirstRequest() == req) + //std::lock_guard guard(requestParser->getPipeLineMutex()); + if (requestParser->getFirstRequest() == req) { - context->popFirstRequest(); + requestParser->popFirstRequest(); sendResponse(conn, newResp); while (1) { - auto resp = context->getFirstResponse(); + auto resp = requestParser->getFirstResponse(); if (resp) { - context->popFirstRequest(); + requestParser->popFirstRequest(); sendResponse(conn, resp); } else @@ -244,25 +244,25 @@ void HttpServer::onRequest(const TcpConnectionPtr &conn, const HttpRequestImplPt else { //some earlier requests are waiting for responses; - context->pushResponseToPipeLine(req, newResp); + requestParser->pushResponseToPipeLine(req, newResp); } } else { conn->getLoop()->queueInLoop([conn, req, newResp, this]() { - HttpServerParser *context = any_cast(conn->getMutableContext()); - if (context) + HttpRequestParser *requestParser = any_cast(conn->getMutableContext()); + if (requestParser) { - if (context->getFirstRequest() == req) + if (requestParser->getFirstRequest() == req) { - context->popFirstRequest(); + requestParser->popFirstRequest(); sendResponse(conn, newResp); while (1) { - auto resp = context->getFirstResponse(); + auto resp = requestParser->getFirstResponse(); if (resp) { - context->popFirstRequest(); + requestParser->popFirstRequest(); sendResponse(conn, resp); } else @@ -272,7 +272,7 @@ void HttpServer::onRequest(const TcpConnectionPtr &conn, const HttpRequestImplPt else { //some earlier requests are waiting for responses; - context->pushResponseToPipeLine(req, newResp); + requestParser->pushResponseToPipeLine(req, newResp); } } }); diff --git a/lib/src/HttpSimpleControllersRouter.cc b/lib/src/HttpSimpleControllersRouter.cc index 8370983b..3e6a60ef 100644 --- a/lib/src/HttpSimpleControllersRouter.cc +++ b/lib/src/HttpSimpleControllersRouter.cc @@ -67,7 +67,7 @@ void HttpSimpleControllersRouter::registerHttpSimpleController(const std::string void HttpSimpleControllersRouter::route(const HttpRequestImplPtr &req, std::function &&callback, bool needSetJsessionid, - std::string &&session_id) + std::string &&sessionId) { std::string pathLower(req->path().length(), 0); std::transform(req->path().begin(), req->path().end(), pathLower.begin(), tolower); @@ -90,7 +90,7 @@ void HttpSimpleControllersRouter::route(const HttpRequestImplPtr &req, auto &filters = ctrlInfo.filtersName; if (!filters.empty()) { - auto sessionIdPtr = std::make_shared(std::move(session_id)); + auto sessionIdPtr = std::make_shared(std::move(sessionId)); auto callbackPtr = std::make_shared>(std::move(callback)); _appImpl.doFilters(filters, req, callbackPtr, needSetJsessionid, sessionIdPtr, [=, pathLower = std::move(pathLower)]() mutable { doControllerHandler(std::move(pathLower), req, std::move(*callbackPtr), needSetJsessionid, std::move(*sessionIdPtr)); @@ -98,18 +98,18 @@ void HttpSimpleControllersRouter::route(const HttpRequestImplPtr &req, } else { - doControllerHandler(std::move(pathLower), req, std::move(callback), needSetJsessionid, std::move(session_id)); + doControllerHandler(std::move(pathLower), req, std::move(callback), needSetJsessionid, std::move(sessionId)); } return; } - _httpCtrlsRouter.route(req, std::move(callback), needSetJsessionid, std::move(session_id)); + _httpCtrlsRouter.route(req, std::move(callback), needSetJsessionid, std::move(sessionId)); } void HttpSimpleControllersRouter::doControllerHandler(std::string &&pathLower, const HttpRequestImplPtr &req, std::function &&callback, bool needSetJsessionid, - std::string &&session_id) + std::string &&sessionId) { auto &ctrlItem = _simpCtrlMap[pathLower]; const std::string &ctrlName = ctrlItem.controllerName; @@ -141,14 +141,14 @@ void HttpSimpleControllersRouter::doControllerHandler(std::string &&pathLower, //make a copy response; auto newResp = std::make_shared(*std::dynamic_pointer_cast(responsePtr)); newResp->setExpiredTime(-1); //make it temporary - newResp->addCookie("JSESSIONID", session_id); + newResp->addCookie("JSESSIONID", sessionId); callback(newResp); } return; } else { - controller->asyncHandleHttpRequest(req, [=, callback = std::move(callback), pathLower = std::move(pathLower), session_id = std::move(session_id)](const HttpResponsePtr &resp) { + controller->asyncHandleHttpRequest(req, [=, callback = std::move(callback), pathLower = std::move(pathLower), sessionId = std::move(sessionId)](const HttpResponsePtr &resp) { auto newResp = resp; if (resp->expiredTime() >= 0) { @@ -168,7 +168,7 @@ void HttpSimpleControllersRouter::doControllerHandler(std::string &&pathLower, newResp = std::make_shared(*std::dynamic_pointer_cast(resp)); newResp->setExpiredTime(-1); //make it temporary } - newResp->addCookie("JSESSIONID", session_id); + newResp->addCookie("JSESSIONID", sessionId); } callback(newResp); }); @@ -181,7 +181,7 @@ void HttpSimpleControllersRouter::doControllerHandler(std::string &&pathLower, LOG_ERROR << "can't find controller " << ctrlName; auto res = drogon::HttpResponse::newNotFoundResponse(); if (needSetJsessionid) - res->addCookie("JSESSIONID", session_id); + res->addCookie("JSESSIONID", sessionId); callback(res); } diff --git a/lib/src/HttpSimpleControllersRouter.h b/lib/src/HttpSimpleControllersRouter.h index 65ab8c60..2c729de8 100644 --- a/lib/src/HttpSimpleControllersRouter.h +++ b/lib/src/HttpSimpleControllersRouter.h @@ -40,7 +40,7 @@ class HttpSimpleControllersRouter : public trantor::NonCopyable void route(const HttpRequestImplPtr &req, std::function &&callback, bool needSetJsessionid, - std::string &&session_id); + std::string &&sessionId); private: HttpAppFrameworkImpl &_appImpl; @@ -61,6 +61,6 @@ class HttpSimpleControllersRouter : public trantor::NonCopyable const HttpRequestImplPtr &req, std::function &&callback, bool needSetJsessionid, - std::string &&session_id); + std::string &&sessionId); }; } // namespace drogon diff --git a/lib/src/Utilities.cc b/lib/src/Utilities.cc index 2176f508..4f6310b3 100755 --- a/lib/src/Utilities.cc +++ b/lib/src/Utilities.cc @@ -442,6 +442,61 @@ int gzipDecompress(const char *zdata, const size_t nzdata, *ndata = d_stream.total_out; return 0; } + +std::shared_ptr gzipDecompress(const std::shared_ptr &compressedData) +{ + + if (compressedData->length() == 0) + return compressedData; + + auto full_length = compressedData->length(); + + auto decompressed = std::make_shared(full_length * 2, 0); + bool done = false; + int status; + z_stream strm = {0}; + strm.next_in = (Bytef *)compressedData->data(); + strm.avail_in = compressedData->length(); + strm.total_out = 0; + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + if (inflateInit2(&strm, (15 + 32)) != Z_OK) + return nullptr; + while (!done) + { + // Make sure we have enough room and reset the lengths. + if (strm.total_out >= decompressed->length()) + { + decompressed->resize(decompressed->length() * 2); + } + // chadeltu 加了(Bytef *) + strm.next_out = (Bytef *)decompressed->data() + strm.total_out; + strm.avail_out = decompressed->length() - strm.total_out; + // Inflate another chunk. + status = inflate(&strm, Z_SYNC_FLUSH); + if (status == Z_STREAM_END) + { + done = true; + } + else if (status != Z_OK) + { + break; + } + } + if (inflateEnd(&strm) != Z_OK) + return nullptr; + // Set real length. + if (done) + { + decompressed->resize(strm.total_out); + return decompressed; + } + else + { + return nullptr; + } +} + char *getHttpFullDate(const trantor::Date &date) { static __thread int64_t lastSecond = 0; diff --git a/lib/tests/CMakeLists.txt b/lib/tests/CMakeLists.txt index 38f11dc7..228e0eed 100755 --- a/lib/tests/CMakeLists.txt +++ b/lib/tests/CMakeLists.txt @@ -7,4 +7,5 @@ add_executable(class_name_test ClassNameTest.cc) add_executable(sha1_test Sha1Test.cc) add_executable(view_data_test HttpViewDataTest.cc) add_executable(md5_test Md5Test.cc ../src/ssl_funcs/Md5.cc) -add_executable(http_full_date_test HttpFullDateTest.cc) \ No newline at end of file +add_executable(http_full_date_test HttpFullDateTest.cc) +add_executable(gzip_test GzipTest.cc) \ No newline at end of file diff --git a/lib/tests/GzipTest.cc b/lib/tests/GzipTest.cc new file mode 100644 index 00000000..864b3d5d --- /dev/null +++ b/lib/tests/GzipTest.cc @@ -0,0 +1,325 @@ +#include +#include + +using namespace drogon; + +int main() +{ + const std::string inStr = "Applications\n" + "Developer\n" + "Library\n" + "Network\n" + "System\n" + "Users\n" + "Volumes\n" + "bin\n" + "cores\n" + "dev\n" + "etc\n" + "home\n" + "installer.failurerequests\n" + "net\n" + "opt\n" + "private\n" + "sbin\n" + "tmp\n" + "usb\n" + "usr\n" + "var\n" + "vm\n" + "用户信息\n" + "\n" + "/Applications:\n" + "Adobe\n" + "Adobe Creative Cloud\n" + "Adobe Photoshop CC\n" + "AirPlayer Pro.app\n" + "Android Studio.app\n" + "App Store.app\n" + "Autodesk\n" + "Automator.app\n" + "Axure RP Pro 7.0.app\n" + "BaiduNetdisk_mac.app\n" + "CLion.app\n" + "Calculator.app\n" + "Calendar.app\n" + "Chess.app\n" + "CleanApp.app\n" + "Contacts.app\n" + "DVD Player.app\n" + "Dashboard.app\n" + "Dictionary.app\n" + "Docs for Xcode.app\n" + "FaceTime.app\n" + "FinalShell\n" + "Firefox.app\n" + "Folx.app\n" + "Font Book.app\n" + "GitHub.app\n" + "Google Chrome.app\n" + "Grammarly.app\n" + "Image Capture.app\n" + "Lantern.app\n" + "Launchpad.app\n" + "License.rtf\n" + "MacPorts\n" + "Mail.app\n" + "Maps.app\n" + "Messages.app\n" + "Microsoft Excel.app\n" + "Microsoft Office 2011\n" + "Microsoft OneNote.app\n" + "Microsoft Outlook.app\n" + "Microsoft PowerPoint.app\n" + "Microsoft Word.app\n" + "Mindjet MindManager.app\n" + "Mission Control.app\n" + "Mockplus.app\n" + "MyEclipse 2015\n" + "Notes.app\n" + "OmniGraffle.app\n" + "PP助手.app\n" + "Pages.app\n" + "Photo Booth.app\n" + "Photos.app\n" + "Preview.app\n" + "QJVPN.app\n" + "QQ.app\n" + "QuickTime Player.app\n" + "RAR Extractor Lite.app\n" + "Reminders.app\n" + "Remote Desktop Connection.app\n" + "Renee Undeleter.app\n" + "Sabaki.app\n" + "Safari.app\n" + "ShadowsocksX.app\n" + "Siri.app\n" + "SogouInputPad.app\n" + "Stickies.app\n" + "System Preferences.app\n" + "TeX\n" + "Telegram.app\n" + "Termius.app\n" + "Tesumego - How to Make a Professional Go Player.app\n" + "TextEdit.app\n" + "Thunder.app\n" + "Time Machine.app\n" + "Tunnelblick.app\n" + "Utilities\n" + "VPN Shield.appdownload\n" + "VirtualBox.app\n" + "WeChat.app\n" + "WinOnX2.app\n" + "Wireshark.app\n" + "Xcode.app\n" + "Yose.app\n" + "YoudaoNote.localized\n" + "finalshelldata\n" + "iBooks.app\n" + "iPhoto.app\n" + "iTools.app\n" + "iTunes.app\n" + "pgAdmin 4.app\n" + "wechatwebdevtools.app\n" + "搜狐影音.appdownload\n" + "网易有道词典.app\n" + "万能数据恢复大师.app\n" + "\n" + "/Applications/Adobe:\n" + "Flash Player\n" + "\n" + "/Applications/Adobe/Flash Player:\n" + "AddIns\n" + "\n" + "/Applications/Adobe/Flash Player/AddIns:\n" + "airappinstaller\n" + "\n" + "/Applications/Adobe/Flash Player/AddIns/airappinstaller:\n" + "airappinstaller\n" + "digest.s\n" + "\n" + "/Applications/Adobe Creative Cloud:\n" + "Adobe Creative Cloud\n" + "Icon\n" + "Uninstall Adobe Creative Cloud\n" + "\n" + "/Applications/Adobe Photoshop CC:\n" + "Adobe Photoshop CC.app\n" + "Configuration\n" + "Icon\n" + "Legal\n" + "LegalNotices.pdf\n" + "Locales\n" + "Plug-ins\n" + "Presets\n" + "卸载 Adobe Photoshop CC\n" + "\n" + "/Applications/Adobe Photoshop CC/Adobe Photoshop CC.app:\n" + "Contents\n" + "Linguistics\n" + "\n" + "/Applications/Adobe Photoshop CC/Adobe Photoshop CC.app/Contents:\n" + "Application Data\n" + "Frameworks\n" + "Info.plist\n" + "MacOS\n" + "PkgInfo\n" + "Required\n" + "Resources\n" + "_CodeSignature\n" + "\n" + "/Applications/Adobe Photoshop CC/Adobe Photoshop CC.app/Contents/Application Data:\n" + "Custom File Info Panels\n" + "\n" + "/Applications/Adobe Photoshop CC/Adobe Photoshop CC.app/Contents/Application Data/Custom File Info Panels:\n" + "4.0\n" + "\n" + "/Applications/Adobe Photoshop CC/Adobe Photoshop CC.app/Contents/Application Data/Custom File Info Panels/4.0:\n" + "bin\n" + "custom\n" + "panels\n" + "\n" + "/Applications/Adobe Photoshop CC/Adobe Photoshop CC.app/Contents/Application Data/Custom File Info Panels/4.0/bin:\n" + "FileInfoFoundation.swf\n" + "FileInfoUI.swf\n" + "framework.swf\n" + "loc\n" + "\n" + "/Applications/Adobe Photoshop CC/Adobe Photoshop CC.app/Contents/Application Data/Custom File Info Panels/4.0/bin/loc:\n" + "FileInfo_ar_AE.dat\n" + "FileInfo_bg_BG.dat\n" + "FileInfo_cs_CZ.dat\n" + "FileInfo_da_DK.dat\n" + "FileInfo_de_DE.dat\n" + "FileInfo_el_GR.dat\n" + "FileInfo_en_US.dat\n" + "FileInfo_es_ES.dat\n" + "FileInfo_et_EE.dat\n" + "FileInfo_fi_FI.dat\n" + "FileInfo_fr_FR.dat\n" + "FileInfo_he_IL.dat\n" + "FileInfo_hr_HR.dat\n" + "FileInfo_hu_HU.dat\n" + "FileInfo_it_IT.dat\n" + "FileInfo_ja_JP.dat\n" + "FileInfo_ko_KR.dat\n" + "FileInfo_lt_LT.dat\n" + "FileInfo_lv_LV.dat\n" + "FileInfo_nb_NO.dat\n" + "FileInfo_nl_NL.dat\n" + "FileInfo_pl_PL.dat\n" + "FileInfo_pt_BR.dat\n" + "FileInfo_ro_RO.dat\n" + "FileInfo_ru_RU.dat\n" + "FileInfo_sk_SK.dat\n" + "FileInfo_sl_SI.dat\n" + "FileInfo_sv_SE.dat\n" + "FileInfo_tr_TR.dat\n" + "FileInfo_uk_UA.dat\n" + "FileInfo_zh_CN.dat\n" + "FileInfo_zh_TW.dat\n" + "\n" + "/Applications/Adobe Photoshop CC/Adobe Photoshop CC.app/Contents/Application Data/Custom File Info Panels/4.0/custom:\n" + "DICOM.xml\n" + "Mobile.xml\n" + "loc\n" + "\n" + "/Applications/Adobe Photoshop CC/Adobe Photoshop CC.app/Contents/Application Data/Custom File Info Panels/4.0/custom/loc:\n" + "DICOM_ar_AE.dat\n" + "DICOM_bg_BG.dat\n" + "DICOM_cs_CZ.dat\n" + "DICOM_da_DK.dat\n" + "DICOM_de_DE.dat\n" + "DICOM_el_GR.dat\n" + "DICOM_en_US.dat\n" + "DICOM_es_ES.dat\n" + "DICOM_et_EE.dat\n" + "DICOM_fi_FI.dat\n" + "DICOM_fr_FR.dat\n" + "DICOM_he_IL.dat\n" + "DICOM_hr_HR.dat\n" + "DICOM_hu_HU.dat\n" + "DICOM_it_IT.dat\n" + "DICOM_ja_JP.dat\n" + "DICOM_ko_KR.dat\n" + "DICOM_lt_LT.dat\n" + "DICOM_lv_LV.dat\n" + "DICOM_nb_NO.dat\n" + "DICOM_nl_NL.dat\n" + "DICOM_pl_PL.dat\n" + "DICOM_pt_BR.dat\n" + "DICOM_ro_RO.dat\n" + "DICOM_ru_RU.dat\n" + "DICOM_sk_SK.dat\n" + "DICOM_sl_SI.dat\n" + "DICOM_sv_SE.dat\n" + "DICOM_tr_TR.dat\n" + "DICOM_uk_UA.dat\n" + "DICOM_zh_CN.dat\n" + "DICOM_zh_TW.dat\n" + "Mobile_ar_AE.dat\n" + "Mobile_bg_BG.dat\n" + "Mobile_cs_CZ.dat\n" + "Mobile_da_DK.dat\n" + "Mobile_de_DE.dat\n" + "Mobile_el_GR.dat\n" + "Mobile_en_US.dat\n" + "Mobile_es_ES.dat\n" + "Mobile_et_EE.dat\n" + "Mobile_fi_FI.dat\n" + "Mobile_fr_FR.dat\n" + "Mobile_he_IL.dat\n" + "Mobile_hr_HR.dat\n" + "Mobile_hu_HU.dat\n" + "Mobile_it_IT.dat\n" + "Mobile_ja_JP.dat\n" + "Mobile_ko_KR.dat\n" + "Mobile_lt_LT.dat\n" + "Mobile_lv_LV.dat\n" + "Mobile_nb_NO.dat\n" + "Mobile_nl_NL.dat\n" + "Mobile_pl_PL.dat\n" + "Mobile_pt_BR.dat\n" + "Mobile_ro_RO.dat\n" + "Mobile_ru_RU.dat\n" + "Mobile_sk_SK.dat\n" + "Mobile_sl_SI.dat\n" + "Mobile_sv_SE.dat\n" + "Mobile_tr_TR.dat\n" + "Mobile_uk_UA.dat\n" + "Mobile_zh_CN.dat\n" + "Mobile_zh_TW.dat\n" + "\n" + "/Applications/Adobe Photoshop CC/Adobe Photoshop CC.app/Contents/Application Data/Custom File Info Panels/4.0/panels:\n" + "IPTC\n" + "IPTCExt\n" + "advanced\n" + "audioData\n" + "camera\n" + "categories\n" + "description\n" + "dicom\n" + "gpsData\n" + "history\n" + "mobile\n" + "origin\n" + "rawpacket"; + std::string out; + out.resize(inStr.length()); + size_t len = out.length(); + auto ret=gzipCompress(inStr.c_str(), inStr.length(), out.data(), &len); + if(ret==0) + { + out.resize(len); + std::cout << "origin length=" << inStr.length() << " compressing length=" << out.length() << std::endl; + + auto decompressStr = gzipDecompress(std::make_shared(out)); + if (decompressStr) + { + std::cout << "decompressing length=" << decompressStr->length() << std::endl; + std::cout << *decompressStr; + } + } + + return 0; +} \ No newline at end of file