diff --git a/SConstruct b/SConstruct index 49f06a9..8cce216 100644 --- a/SConstruct +++ b/SConstruct @@ -68,6 +68,8 @@ env_base.use_ptrcall = False env_base.module_version_string = "" env_base.msvc = False +env_base.ParseConfig("pkg-config uuid --cflags --libs") + # avoid issues when building with different versions of python out of the same directory env_base.SConsignFile(".sconsign{0}.dblite".format(pickle.HIGHEST_PROTOCOL)) diff --git a/core/HttpFileImpl.cc b/core/HttpFileImpl.cc index 18921c2..4ab35b8 100644 --- a/core/HttpFileImpl.cc +++ b/core/HttpFileImpl.cc @@ -37,7 +37,7 @@ int HttpFileImpl::save(const std::string &path) const } else { - auto &uploadPath = HttpAppFrameworkImpl::instance().getUploadPath(); + auto &uploadPath = Application::get_instance()->getUploadPath(); if (uploadPath[uploadPath.length() - 1] == '/') tmpPath = uploadPath + path; else @@ -59,7 +59,7 @@ int HttpFileImpl::save(const std::string &path) const } int HttpFileImpl::save() const { - return save(HttpAppFrameworkImpl::instance().getUploadPath()); + return save(Application::get_instance()->getUploadPath()); } int HttpFileImpl::saveAs(const std::string &filename) const { @@ -74,7 +74,7 @@ int HttpFileImpl::saveAs(const std::string &filename) const } else { - auto &uploadPath = HttpAppFrameworkImpl::instance().getUploadPath(); + auto &uploadPath = Application::get_instance()->getUploadPath(); if (uploadPath[uploadPath.length() - 1] == '/') pathAndFileName = uploadPath + filename; else diff --git a/core/application.cpp b/core/application.cpp index acbd4d9..4e8872a 100644 --- a/core/application.cpp +++ b/core/application.cpp @@ -251,7 +251,7 @@ void Application::run() { // A fast database client instance should be created in the main event // loop, so put the main loop into ioLoops. - ioLoops.push_back(get_loop()); + //ioLoops.push_back(get_loop()); /* dbClientManagerPtr_->createDbClients(ioLoops); diff --git a/core/application.h b/core/application.h index d8dc163..ea37205 100644 --- a/core/application.h +++ b/core/application.h @@ -15,8 +15,11 @@ #include "core/http_server_callbacks.h" +#include "core/listener_manager.h" + +using namespace drogon; + class Request; -class ListenerManager; class Application { public: @@ -54,6 +57,50 @@ public: std::unique_ptr listenerManagerPtr_; + size_t getClientMaxBodySize() const { + return clientMaxBodySize_; + } + size_t getClientMaxMemoryBodySize() const { + return clientMaxMemoryBodySize_; + } + size_t getClientMaxWebSocketMessageSize() const { + return clientMaxWebSocketMessageSize_; + } + size_t keepaliveRequestsNumber() const { + return keepaliveRequestsNumber_; + } + size_t pipeliningRequestsNumber() const { + return pipeliningRequestsNumber_; + } + + bool sendDateHeader() const { + return enableDateHeader_; + } + + bool sendServerHeader() const { + return enableServerHeader_; + } + + const std::string &getServerHeaderString() const { + return serverHeader_; + } + + virtual const std::string &getUploadPath() const { + return uploadPath_; + } + + virtual size_t getCurrentThreadIndex() const { + auto *loop = trantor::EventLoop::getEventLoopOfCurrentThread(); + if (loop) { + return loop->index(); + } +#ifdef _WIN32 + return size_t(-1); +#else + return std::numeric_limits::max(); +#endif + } + public: static HandlerInstance index_func; static std::map main_route_map; @@ -71,6 +118,16 @@ public: private: static Application *_instance; bool _running; + + size_t clientMaxBodySize_{ 1024 * 1024 }; + size_t clientMaxMemoryBodySize_{ 64 * 1024 }; + size_t clientMaxWebSocketMessageSize_{ 128 * 1024 }; + size_t keepaliveRequestsNumber_{ 0 }; + size_t pipeliningRequestsNumber_{ 0 }; + std::string uploadPath_; + bool enableServerHeader_{ false }; + std::string serverHeader_{ "Server: rcpp_cms\r\n" }; + bool enableDateHeader_{ true }; }; #endif \ No newline at end of file diff --git a/core/http_request.cpp b/core/http_request.cpp index fc67aa2..b67c409 100644 --- a/core/http_request.cpp +++ b/core/http_request.cpp @@ -648,7 +648,7 @@ HttpRequest::~HttpRequest() void HttpRequest::reserveBodySize(size_t length) { - if (length <= HttpAppFrameworkImpl::instance().getClientMaxMemoryBodySize()) + if (length <= Application::get_instance()->getClientMaxMemoryBodySize()) { content_.reserve(length); } @@ -668,7 +668,7 @@ void HttpRequest::appendToBody(const char *data, size_t length) else { if (content_.length() + length <= - HttpAppFrameworkImpl::instance().getClientMaxMemoryBodySize()) + Application::get_instance()->getClientMaxMemoryBodySize()) { content_.append(data, length); } @@ -685,7 +685,7 @@ void HttpRequest::appendToBody(const char *data, size_t length) void HttpRequest::createTmpFile() { /* - auto tmpfile = HttpAppFrameworkImpl::instance().getUploadPath(); + auto tmpfile = Application::get_instance()->getUploadPath(); auto fileName = utils::getUuid(); diff --git a/core/http_request.h b/core/http_request.h index bd33fb7..255b973 100644 --- a/core/http_request.h +++ b/core/http_request.h @@ -44,6 +44,7 @@ #include namespace drogon { + class HttpRequest; using HttpRequestPtr = std::shared_ptr; @@ -164,6 +165,8 @@ public: return fromRequest(*this); } + bool setMethod(const char *start, const char *end); + /// Return the method string of the request, such as GET, POST, etc. virtual const char *methodString() const; const char *getMethodString() const { diff --git a/core/http_request_parser.cpp b/core/http_request_parser.cpp index 03bd039..9e4ac11 100644 --- a/core/http_request_parser.cpp +++ b/core/http_request_parser.cpp @@ -14,8 +14,10 @@ #include "core/http_request_parser.h" +//#include "core/http_server_callbacks.h" + #include "core/http_response.h" -#include "http_request.h" +#include "core/http_request.h" #include "core/http_utils.h" #include @@ -23,6 +25,8 @@ #include #include +#include "core/application.h" + using namespace trantor; using namespace drogon; @@ -83,10 +87,10 @@ bool HttpRequestParser::processRequestLine(const char *begin, const char *end) } return succeed; } -HttpRequestPtr HttpRequestParser::makeRequestForPool(HttpRequestImpl *ptr) +HttpRequestPtr HttpRequestParser::makeRequestForPool(HttpRequest *ptr) { std::weak_ptr weakPtr = shared_from_this(); - return std::shared_ptr(ptr, [weakPtr](HttpRequestImpl *p) { + return std::shared_ptr(ptr, [weakPtr](HttpRequest *p) { auto thisPtr = weakPtr.lock(); if (thisPtr) { @@ -118,7 +122,7 @@ void HttpRequestParser::reset() status_ = HttpRequestParseStatus::kExpectMethod; if (requestsPool_.empty()) { - request_ = makeRequestForPool(new HttpRequestImpl(loop_)); + request_ = makeRequestForPool(new HttpRequest(loop_)); } else { @@ -264,13 +268,11 @@ bool HttpRequestParser::parseRequest(MsgBuffer *buf) if (connPtr) { auto resp = HttpResponse::newHttpResponse(); - if (currentContentLength_ > - HttpAppFrameworkImpl::instance() - .getClientMaxBodySize()) + if (currentContentLength_ > Application::get_instance()->getClientMaxBodySize()) { resp->setStatusCode(k413RequestEntityTooLarge); auto httpString = - static_cast(resp.get()) + static_cast(resp.get()) ->renderToBuffer(); reset(); connPtr->send(std::move(*httpString)); @@ -279,7 +281,7 @@ bool HttpRequestParser::parseRequest(MsgBuffer *buf) { resp->setStatusCode(k100Continue); auto httpString = - static_cast(resp.get()) + static_cast(resp.get()) ->renderToBuffer(); connPtr->send(std::move(*httpString)); } @@ -297,9 +299,7 @@ bool HttpRequestParser::parseRequest(MsgBuffer *buf) return false; } } - else if (currentContentLength_ > - HttpAppFrameworkImpl::instance() - .getClientMaxBodySize()) + else if (currentContentLength_ > Application::get_instance()->getClientMaxBodySize()) { buf->retrieveAll(); shutdownConnection(k413RequestEntityTooLarge); @@ -365,8 +365,7 @@ bool HttpRequestParser::parseRequest(MsgBuffer *buf) // responsePtr_->currentChunkLength_; if (currentChunkLength_ != 0) { - if (currentChunkLength_ + currentContentLength_ > - HttpAppFrameworkImpl::instance().getClientMaxBodySize()) + if (currentChunkLength_ + currentContentLength_ > Application::get_instance()->getClientMaxBodySize()) { buf->retrieveAll(); shutdownConnection(k413RequestEntityTooLarge); diff --git a/core/http_response.cpp b/core/http_response.cpp index 27ffaf6..4f07ccd 100644 --- a/core/http_response.cpp +++ b/core/http_response.cpp @@ -19,31 +19,29 @@ #include -#include #include "core/application.h" +#include -#include -#include #include #include #include +#include +#include #ifdef _WIN32 #define stat _stati64 #endif using namespace trantor; using namespace drogon; -namespace drogon -{ +namespace drogon { // "Fri, 23 Aug 2019 12:58:03 GMT" length = 29 static const size_t httpFullDateStringLength = 29; static inline void doResponseCreateAdvices( - const HttpResponsePtr &responsePtr) -{ - /* + const HttpResponsePtr &responsePtr) { + /* auto &advices = - HttpAppFrameworkImpl::instance().getResponseCreationAdvices(); + Application::get_instance()->getResponseCreationAdvices(); if (!advices.empty()) { for (auto &advice : advices) @@ -53,625 +51,521 @@ static inline void doResponseCreateAdvices( }*/ } static inline HttpResponsePtr genHttpResponse(std::string viewName, - const HttpViewData &data) -{ + const HttpViewData &data) { + /* auto templ = DrTemplateBase::newTemplate(viewName); if (templ) { auto res = HttpResponse::newHttpResponse(); res->setBody(templ->genText(data)); return res; - } - return drogon::HttpResponse::newNotFoundResponse(); -} -} // namespace drogon + }*/ -HttpResponsePtr HttpResponse::newHttpResponse() -{ - auto res = std::make_shared(k200OK, CT_TEXT_HTML); - doResponseCreateAdvices(res); - return res; + return drogon::HttpResponse::newNotFoundResponse(); +} +} // namespace drogon + +HttpResponsePtr HttpResponse::newHttpResponse() { + auto res = std::make_shared(k200OK, CT_TEXT_HTML); + doResponseCreateAdvices(res); + return res; } -HttpResponsePtr HttpResponse::newHttpJsonResponse(const Json::Value &data) -{ - auto res = std::make_shared(k200OK, CT_APPLICATION_JSON); - res->setJsonObject(data); - doResponseCreateAdvices(res); - return res; +HttpResponsePtr HttpResponse::newHttpJsonResponse(const Json::Value &data) { + auto res = std::make_shared(k200OK, CT_APPLICATION_JSON); + res->setJsonObject(data); + doResponseCreateAdvices(res); + return res; } -HttpResponsePtr HttpResponse::newHttpJsonResponse(Json::Value &&data) -{ - auto res = std::make_shared(k200OK, CT_APPLICATION_JSON); - res->setJsonObject(std::move(data)); - doResponseCreateAdvices(res); - return res; +HttpResponsePtr HttpResponse::newHttpJsonResponse(Json::Value &&data) { + auto res = std::make_shared(k200OK, CT_APPLICATION_JSON); + res->setJsonObject(std::move(data)); + doResponseCreateAdvices(res); + return res; } -void HttpResponse::generateBodyFromJson() const -{ - if (!jsonPtr_ || flagForSerializingJson_) - { - return; - } - flagForSerializingJson_ = true; - static std::once_flag once; - static Json::StreamWriterBuilder builder; - std::call_once(once, []() { - builder["commentStyle"] = "None"; - builder["indentation"] = ""; +void HttpResponse::generateBodyFromJson() const { + if (!jsonPtr_ || flagForSerializingJson_) { + return; + } + flagForSerializingJson_ = true; + static std::once_flag once; + static Json::StreamWriterBuilder builder; + std::call_once(once, []() { + builder["commentStyle"] = "None"; + builder["indentation"] = ""; -/* + /* if (!app().isUnicodeEscapingUsedInJson()) { builder["emitUTF8"] = true; }*/ - - - }); - bodyPtr_ = std::make_shared( - writeString(builder, *jsonPtr_)); + }); + bodyPtr_ = std::make_shared( + writeString(builder, *jsonPtr_)); } -HttpResponsePtr HttpResponse::newNotFoundResponse() -{ - auto loop = trantor::EventLoop::getEventLoopOfCurrentThread(); - auto &resp = HttpAppFrameworkImpl::instance().getCustom404Page(); - if (resp) - { - if (loop && loop->index() < Application::get_instance()->threadNum_) - { - return resp; - } - else - { - return HttpResponsePtr{new HttpResponse( - *static_cast(resp.get()))}; - } - } - else - { - if (loop && loop->index() < Application::get_instance()->threadNum_) - { - // If the current thread is an IO thread - static std::once_flag threadOnce; - static IOThreadStorage thread404Pages; - std::call_once(threadOnce, [] { - thread404Pages.init( - [](drogon::HttpResponsePtr &resp, size_t index) { - if (HttpAppFrameworkImpl::instance() - .isUsingCustomErrorHandler()) - { - //resp = app().getCustomErrorHandler()(k404NotFound); - //resp->setExpiredTime(0); - } - else - { - HttpViewData data; - data.insert("version", drogon::getVersion()); - resp = HttpResponse::newHttpViewResponse( - "drogon::NotFound", data); - resp->setStatusCode(k404NotFound); - resp->setExpiredTime(0); - } - }); - }); - LOG_TRACE << "Use cached 404 response"; - return thread404Pages.getThreadData(); - } - else - { - //if (HttpAppFrameworkImpl::instance().isUsingCustomErrorHandler()) - //{ - //auto resp = app().getCustomErrorHandler()(k404NotFound); - // return resp; - // } +HttpResponsePtr HttpResponse::newNotFoundResponse() { + auto loop = trantor::EventLoop::getEventLoopOfCurrentThread(); +/* + auto &resp = Application::get_instance()->getCustom404Page(); - HttpViewData data; - data.insert("version", drogon::getVersion()); - auto notFoundResp = - HttpResponse::newHttpViewResponse("drogon::NotFound", data); - notFoundResp->setStatusCode(k404NotFound); - return notFoundResp; - } - } + if (resp) { + if (loop && loop->index() < Application::get_instance()->threadNum_) { + return resp; + } else { + return HttpResponsePtr{ new HttpResponse( + *static_cast(resp.get())) }; + } + } else { + if (loop && loop->index() < Application::get_instance()->threadNum_) { + // If the current thread is an IO thread + static std::once_flag threadOnce; + static IOThreadStorage thread404Pages; + std::call_once(threadOnce, [] { + thread404Pages.init( + [](drogon::HttpResponsePtr &resp, size_t index) { + if (Application::get_instance()->isUsingCustomErrorHandler()) { + //resp = app().getCustomErrorHandler()(k404NotFound); + //resp->setExpiredTime(0); + } else { + HttpViewData data; + data.insert("version", drogon::getVersion()); + resp = HttpResponse::newHttpViewResponse( + "drogon::NotFound", data); + resp->setStatusCode(k404NotFound); + resp->setExpiredTime(0); + } + }); + }); + LOG_TRACE << "Use cached 404 response"; + return thread404Pages.getThreadData(); + } else { + //if (Application::get_instance()->isUsingCustomErrorHandler()) + //{ + //auto resp = app().getCustomErrorHandler()(k404NotFound); + // return resp; + // } + + HttpViewData data; + data.insert("version", drogon::getVersion()); + auto notFoundResp = + HttpResponse::newHttpViewResponse("drogon::NotFound", data); + notFoundResp->setStatusCode(k404NotFound); + return notFoundResp; + } + } +*/ + //temp + HttpViewData data; + //data.insert("version", drogon::getVersion()); + auto notFoundResp = + HttpResponse::newHttpViewResponse("drogon::NotFound", data); + notFoundResp->setStatusCode(k404NotFound); + return notFoundResp; } HttpResponsePtr HttpResponse::newRedirectionResponse( - const std::string &location, - HttpStatusCode status) -{ - auto res = std::make_shared(); - res->setStatusCode(status); - res->redirect(location); - doResponseCreateAdvices(res); - return res; + const std::string &location, + HttpStatusCode status) { + auto res = std::make_shared(); + res->setStatusCode(status); + res->redirect(location); + doResponseCreateAdvices(res); + return res; } HttpResponsePtr HttpResponse::newHttpViewResponse(const std::string &viewName, - const HttpViewData &data) -{ - return genHttpResponse(viewName, data); + const HttpViewData &data) { + return genHttpResponse(viewName, data); } HttpResponsePtr HttpResponse::newFileResponse( - const std::string &fullPath, - const std::string &attachmentFileName, - ContentType type) -{ - std::ifstream infile(fullPath, std::ifstream::binary); - LOG_TRACE << "send http file:" << fullPath; - if (!infile) - { - auto resp = HttpResponse::newNotFoundResponse(); - return resp; - } - auto resp = std::make_shared(); - std::streambuf *pbuf = infile.rdbuf(); - std::streamsize filesize = pbuf->pubseekoff(0, infile.end); - pbuf->pubseekoff(0, infile.beg); // rewind - if (HttpAppFrameworkImpl::instance().useSendfile() && filesize > 1024 * 200) - // TODO : Is 200k an appropriate value? Or set it to be configurable - { - // The advantages of sendfile() can only be reflected in sending large - // files. - resp->setSendfile(fullPath); - } - else - { - std::string str; - str.resize(filesize); - pbuf->sgetn(&str[0], filesize); - resp->setBody(std::move(str)); - } - resp->setStatusCode(k200OK); + const std::string &fullPath, + const std::string &attachmentFileName, + ContentType type) { + std::ifstream infile(fullPath, std::ifstream::binary); + LOG_TRACE << "send http file:" << fullPath; + if (!infile) { + auto resp = HttpResponse::newNotFoundResponse(); + return resp; + } + auto resp = std::make_shared(); + std::streambuf *pbuf = infile.rdbuf(); + std::streamsize filesize = pbuf->pubseekoff(0, infile.end); + pbuf->pubseekoff(0, infile.beg); // rewind - if (type == CT_NONE) - { - if (!attachmentFileName.empty()) - { - resp->setContentTypeCode( - drogon::getContentType(attachmentFileName)); - } - else - { - resp->setContentTypeCode(drogon::getContentType(fullPath)); - } - } - else - { - resp->setContentTypeCode(type); - } +/* + if (Application::get_instance()->useSendfile() && filesize > 1024 * 200) + // TODO : Is 200k an appropriate value? Or set it to be configurable + { + // The advantages of sendfile() can only be reflected in sending large + // files. + resp->setSendfile(fullPath); + } else { + std::string str; + str.resize(filesize); + pbuf->sgetn(&str[0], filesize); + resp->setBody(std::move(str)); + } +*/ - if (!attachmentFileName.empty()) - { - resp->addHeader("Content-Disposition", - "attachment; filename=" + attachmentFileName); - } - doResponseCreateAdvices(resp); - return resp; + resp->setStatusCode(k200OK); + + if (type == CT_NONE) { + if (!attachmentFileName.empty()) { + resp->setContentTypeCode( + drogon::getContentType(attachmentFileName)); + } else { + resp->setContentTypeCode(drogon::getContentType(fullPath)); + } + } else { + resp->setContentTypeCode(type); + } + + if (!attachmentFileName.empty()) { + resp->addHeader("Content-Disposition", + "attachment; filename=" + attachmentFileName); + } + doResponseCreateAdvices(resp); + return resp; } -void HttpResponse::makeHeaderString(trantor::MsgBuffer &buffer) -{ - buffer.ensureWritableBytes(128); - int len{0}; - if (version_ == Version::kHttp11) - { - len = snprintf(buffer.beginWrite(), - buffer.writableBytes(), - "HTTP/1.1 %d ", - statusCode_); - } - else - { - len = snprintf(buffer.beginWrite(), - buffer.writableBytes(), - "HTTP/1.0 %d ", - statusCode_); - } - buffer.hasWritten(len); +void HttpResponse::makeHeaderString(trantor::MsgBuffer &buffer) { + buffer.ensureWritableBytes(128); + int len{ 0 }; + if (version_ == Version::kHttp11) { + len = snprintf(buffer.beginWrite(), + buffer.writableBytes(), + "HTTP/1.1 %d ", + statusCode_); + } else { + len = snprintf(buffer.beginWrite(), + buffer.writableBytes(), + "HTTP/1.0 %d ", + statusCode_); + } + buffer.hasWritten(len); - if (!statusMessage_.empty()) - buffer.append(statusMessage_.data(), statusMessage_.length()); - buffer.append("\r\n"); - generateBodyFromJson(); - if (!passThrough_) - { - buffer.ensureWritableBytes(64); - if (sendfileName_.empty()) - { - auto bodyLength = bodyPtr_ ? bodyPtr_->length() : 0; - len = snprintf(buffer.beginWrite(), - buffer.writableBytes(), - contentLengthFormatString(), - bodyLength); - } - else - { - struct stat filestat; - if (stat(sendfileName_.data(), &filestat) < 0) - { - LOG_SYSERR << sendfileName_ << " stat error"; - return; - } - len = snprintf(buffer.beginWrite(), - buffer.writableBytes(), - contentLengthFormatString(), - filestat.st_size); - } - buffer.hasWritten(len); - if (headers_.find("Connection") == headers_.end()) - { - if (closeConnection_) - { - buffer.append("Connection: close\r\n"); - } - else if (version_ == Version::kHttp10) - { - buffer.append("Connection: Keep-Alive\r\n"); - } - } - buffer.append(contentTypeString_.data(), contentTypeString_.length()); - if (HttpAppFrameworkImpl::instance().sendServerHeader()) - { - buffer.append( - HttpAppFrameworkImpl::instance().getServerHeaderString()); - } - } + if (!statusMessage_.empty()) + buffer.append(statusMessage_.data(), statusMessage_.length()); + buffer.append("\r\n"); + generateBodyFromJson(); + if (!passThrough_) { + buffer.ensureWritableBytes(64); + if (sendfileName_.empty()) { + auto bodyLength = bodyPtr_ ? bodyPtr_->length() : 0; + len = snprintf(buffer.beginWrite(), + buffer.writableBytes(), + contentLengthFormatString(), + bodyLength); + } else { + struct stat filestat; + if (stat(sendfileName_.data(), &filestat) < 0) { + LOG_SYSERR << sendfileName_ << " stat error"; + return; + } + len = snprintf(buffer.beginWrite(), + buffer.writableBytes(), + contentLengthFormatString(), + filestat.st_size); + } + buffer.hasWritten(len); + if (headers_.find("Connection") == headers_.end()) { + if (closeConnection_) { + buffer.append("Connection: close\r\n"); + } else if (version_ == Version::kHttp10) { + buffer.append("Connection: Keep-Alive\r\n"); + } + } - for (auto it = headers_.begin(); it != headers_.end(); ++it) - { - buffer.append(it->first); - buffer.append(": "); - buffer.append(it->second); - buffer.append("\r\n"); - } + buffer.append(contentTypeString_.data(), contentTypeString_.length()); + + + if (Application::get_instance()->sendServerHeader()) { + buffer.append(Application::get_instance()->getServerHeaderString()); + } + } + + for (auto it = headers_.begin(); it != headers_.end(); ++it) { + buffer.append(it->first); + buffer.append(": "); + buffer.append(it->second); + buffer.append("\r\n"); + } } -void HttpResponse::renderToBuffer(trantor::MsgBuffer &buffer) -{ - if (expriedTime_ >= 0) - { - auto strPtr = renderToBuffer(); - buffer.append(strPtr->peek(), strPtr->readableBytes()); - return; - } +void HttpResponse::renderToBuffer(trantor::MsgBuffer &buffer) { + if (expriedTime_ >= 0) { + auto strPtr = renderToBuffer(); + buffer.append(strPtr->peek(), strPtr->readableBytes()); + return; + } - if (!fullHeaderString_) - { - makeHeaderString(buffer); - } - else - { - buffer.append(*fullHeaderString_); - } + if (!fullHeaderString_) { + makeHeaderString(buffer); + } else { + buffer.append(*fullHeaderString_); + } - // output cookies - if (cookies_.size() > 0) - { - for (auto it = cookies_.begin(); it != cookies_.end(); ++it) - { - buffer.append(it->second.cookieString()); - } - } + // output cookies + if (cookies_.size() > 0) { + for (auto it = cookies_.begin(); it != cookies_.end(); ++it) { + buffer.append(it->second.cookieString()); + } + } - // output Date header - if (!passThrough_ && - drogon::HttpAppFrameworkImpl::instance().sendDateHeader()) - { - buffer.append("Date: "); - buffer.append(utils::getHttpFullDate(trantor::Date::date()), - httpFullDateStringLength); - buffer.append("\r\n\r\n"); - } - else - { - buffer.append("\r\n"); - } - if (bodyPtr_) - buffer.append(bodyPtr_->data(), bodyPtr_->length()); + // output Date header + if (!passThrough_ && Application::get_instance()->sendDateHeader()) { + buffer.append("Date: "); + buffer.append(utils::getHttpFullDate(trantor::Date::date()), + httpFullDateStringLength); + buffer.append("\r\n\r\n"); + } else { + buffer.append("\r\n"); + } + if (bodyPtr_) + buffer.append(bodyPtr_->data(), bodyPtr_->length()); } -std::shared_ptr HttpResponse::renderToBuffer() -{ - if (expriedTime_ >= 0) - { - if (!passThrough_ && - drogon::HttpAppFrameworkImpl::instance().sendDateHeader()) - { - if (datePos_ != static_cast(-1)) - { - auto now = trantor::Date::now(); - bool isDateChanged = - ((now.microSecondsSinceEpoch() / MICRO_SECONDS_PRE_SEC) != - httpStringDate_); - assert(httpString_); - if (isDateChanged) - { - httpStringDate_ = - now.microSecondsSinceEpoch() / MICRO_SECONDS_PRE_SEC; - auto newDate = utils::getHttpFullDate(now); +std::shared_ptr HttpResponse::renderToBuffer() { + if (expriedTime_ >= 0) { + if (!passThrough_ && Application::get_instance()->sendDateHeader()) { + if (datePos_ != static_cast(-1)) { + auto now = trantor::Date::now(); + bool isDateChanged = + ((now.microSecondsSinceEpoch() / MICRO_SECONDS_PRE_SEC) != + httpStringDate_); + assert(httpString_); + if (isDateChanged) { + httpStringDate_ = + now.microSecondsSinceEpoch() / MICRO_SECONDS_PRE_SEC; + auto newDate = utils::getHttpFullDate(now); - httpString_ = - std::make_shared(*httpString_); - memcpy((void *)&(*httpString_)[datePos_], - newDate, - httpFullDateStringLength); - return httpString_; - } + httpString_ = + std::make_shared(*httpString_); + memcpy((void *)&(*httpString_)[datePos_], + newDate, + httpFullDateStringLength); + return httpString_; + } - return httpString_; - } - } - else - { - if (httpString_) - return httpString_; - } - } - auto httpString = std::make_shared(256); - if (!fullHeaderString_) - { - makeHeaderString(*httpString); - } - else - { - httpString->append(*fullHeaderString_); - } + return httpString_; + } + } else { + if (httpString_) + return httpString_; + } + } + auto httpString = std::make_shared(256); + if (!fullHeaderString_) { + makeHeaderString(*httpString); + } else { + httpString->append(*fullHeaderString_); + } - // output cookies - if (cookies_.size() > 0) - { - for (auto it = cookies_.begin(); it != cookies_.end(); ++it) - { - httpString->append(it->second.cookieString()); - } - } + // output cookies + if (cookies_.size() > 0) { + for (auto it = cookies_.begin(); it != cookies_.end(); ++it) { + httpString->append(it->second.cookieString()); + } + } - // output Date header - if (!passThrough_ && - drogon::HttpAppFrameworkImpl::instance().sendDateHeader()) - { - httpString->append("Date: "); - auto datePos = httpString->readableBytes(); - httpString->append(utils::getHttpFullDate(trantor::Date::date()), - httpFullDateStringLength); - httpString->append("\r\n\r\n"); - datePos_ = datePos; - } - else - { - httpString->append("\r\n"); - } + // output Date header + if (!passThrough_ && + Application::get_instance()->sendDateHeader()) { + httpString->append("Date: "); + auto datePos = httpString->readableBytes(); + httpString->append(utils::getHttpFullDate(trantor::Date::date()), + httpFullDateStringLength); + httpString->append("\r\n\r\n"); + datePos_ = datePos; + } else { + httpString->append("\r\n"); + } - LOG_TRACE << "reponse(no body):" - << string_view{httpString->peek(), httpString->readableBytes()}; - if (bodyPtr_) - httpString->append(bodyPtr_->data(), bodyPtr_->length()); - if (expriedTime_ >= 0) - { - httpString_ = httpString; - } - return httpString; + LOG_TRACE << "reponse(no body):" + << string_view{ httpString->peek(), httpString->readableBytes() }; + if (bodyPtr_) + httpString->append(bodyPtr_->data(), bodyPtr_->length()); + if (expriedTime_ >= 0) { + httpString_ = httpString; + } + return httpString; } std::shared_ptr HttpResponse:: - renderHeaderForHeadMethod() -{ - auto httpString = std::make_shared(256); - if (!fullHeaderString_) - { - makeHeaderString(*httpString); - } - else - { - httpString->append(*fullHeaderString_); - } + renderHeaderForHeadMethod() { + auto httpString = std::make_shared(256); + if (!fullHeaderString_) { + makeHeaderString(*httpString); + } else { + httpString->append(*fullHeaderString_); + } - // output cookies - if (cookies_.size() > 0) - { - for (auto it = cookies_.begin(); it != cookies_.end(); ++it) - { - httpString->append(it->second.cookieString()); - } - } + // output cookies + if (cookies_.size() > 0) { + for (auto it = cookies_.begin(); it != cookies_.end(); ++it) { + httpString->append(it->second.cookieString()); + } + } - // output Date header - if (!passThrough_ && - drogon::HttpAppFrameworkImpl::instance().sendDateHeader()) - { - httpString->append("Date: "); - httpString->append(utils::getHttpFullDate(trantor::Date::date()), - httpFullDateStringLength); - httpString->append("\r\n\r\n"); - } - else - { - httpString->append("\r\n"); - } + // output Date header + if (!passThrough_ && + Application::get_instance()->sendDateHeader()) { + httpString->append("Date: "); + httpString->append(utils::getHttpFullDate(trantor::Date::date()), + httpFullDateStringLength); + httpString->append("\r\n\r\n"); + } else { + httpString->append("\r\n"); + } - return httpString; + return httpString; } void HttpResponse::addHeader(const char *start, - const char *colon, - const char *end) -{ - fullHeaderString_.reset(); - std::string field(start, colon); - transform(field.begin(), field.end(), field.begin(), ::tolower); - ++colon; - while (colon < end && isspace(*colon)) - { - ++colon; - } - std::string value(colon, end); - while (!value.empty() && isspace(value[value.size() - 1])) - { - value.resize(value.size() - 1); - } + const char *colon, + const char *end) { + fullHeaderString_.reset(); + std::string field(start, colon); + transform(field.begin(), field.end(), field.begin(), ::tolower); + ++colon; + while (colon < end && isspace(*colon)) { + ++colon; + } + std::string value(colon, end); + while (!value.empty() && isspace(value[value.size() - 1])) { + value.resize(value.size() - 1); + } - if (field == "set-cookie") - { - // LOG_INFO<<"cookies!!!:"< reader(builder.newCharReader()); - if (bodyPtr_) - { - jsonPtr_ = std::make_shared(); - if (!reader->parse(bodyPtr_->data(), - bodyPtr_->data() + bodyPtr_->length(), - jsonPtr_.get(), - &errs)) - { - LOG_ERROR << errs; - LOG_ERROR << "body: " << bodyPtr_->getString(); - jsonPtr_.reset(); - jsonParsingErrorPtr_ = - std::make_shared(std::move(errs)); - } - else - { - jsonParsingErrorPtr_.reset(); - } - } - else - { - jsonPtr_.reset(); - jsonParsingErrorPtr_ = - std::make_shared("empty response body"); - } +void HttpResponse::parseJson() const { + static std::once_flag once; + static Json::CharReaderBuilder builder; + std::call_once(once, []() { builder["collectComments"] = false; }); + JSONCPP_STRING errs; + std::unique_ptr reader(builder.newCharReader()); + if (bodyPtr_) { + jsonPtr_ = std::make_shared(); + if (!reader->parse(bodyPtr_->data(), + bodyPtr_->data() + bodyPtr_->length(), + jsonPtr_.get(), + &errs)) { + LOG_ERROR << errs; + LOG_ERROR << "body: " << bodyPtr_->getString(); + jsonPtr_.reset(); + jsonParsingErrorPtr_ = + std::make_shared(std::move(errs)); + } else { + jsonParsingErrorPtr_.reset(); + } + } else { + jsonPtr_.reset(); + jsonParsingErrorPtr_ = + std::make_shared("empty response body"); + } } -HttpResponse::~HttpResponse() -{ +HttpResponse::~HttpResponse() { } -bool HttpResponse::shouldBeCompressed() const -{ - if (!sendfileName_.empty() || - contentType() >= CT_APPLICATION_OCTET_STREAM || - getBody().length() < 1024 || !(getHeaderBy("content-encoding").empty())) - { - return false; - } - return true; +bool HttpResponse::shouldBeCompressed() const { + if (!sendfileName_.empty() || + contentType() >= CT_APPLICATION_OCTET_STREAM || + getBody().length() < 1024 || !(getHeaderBy("content-encoding").empty())) { + return false; + } + return true; } diff --git a/core/http_response.h b/core/http_response.h index 6b2d0ce..7787fa8 100644 --- a/core/http_response.h +++ b/core/http_response.h @@ -22,7 +22,6 @@ #include #include - #include "core/http_utils.h" #include "http_message_body.h" @@ -38,12 +37,12 @@ #include #include - namespace drogon { /// Abstract class for webapp developer to get or set the Http response; class HttpResponse; using HttpResponsePtr = std::shared_ptr; + /** * @brief This template is used to convert a response object to a custom * type object. Users must specialize the template for a particular type. @@ -77,7 +76,8 @@ inline HttpResponsePtr toResponse(Json::Value &pJson) { } class HttpResponse { - friend class HttpResponseParser; + friend class HttpResponseParser; + public: /** * @brief This template enables automatic type conversion. For using this @@ -105,7 +105,7 @@ public: } /// Get the status code such as 200, 404 - virtual HttpStatusCode statusCode() const { + virtual HttpStatusCode statusCode() const { return statusCode_; } @@ -114,13 +114,13 @@ public: } /// Set the status code of the response. - virtual void setStatusCode(HttpStatusCode code) { + virtual void setStatusCode(HttpStatusCode code) { statusCode_ = code; setStatusMessage(statusCodeToString(code)); } /// Get the creation timestamp of the response. - virtual const trantor::Date &creationDate() const { + virtual const trantor::Date &creationDate() const { return creationDate_; } @@ -129,7 +129,7 @@ public: } /// Set the http version, http1.0 or http1.1 - virtual void setVersion(const Version v) { + virtual void setVersion(const Version v) { version_ = v; if (version_ == Version::kHttp10) { closeConnection_ = true; @@ -143,26 +143,25 @@ public: * is closed immediately after sending the last byte of the response. It's * false by default when the response is created. */ - virtual void setCloseConnection(bool on) { + virtual void setCloseConnection(bool on) { closeConnection_ = on; } /// Get the status set by the setCloseConnetion() method. - virtual bool ifCloseConnection() const { + virtual bool ifCloseConnection() const { return closeConnection_; } /// Set the response content type, such as text/html, text/plaint, image/png /// and so on. If the content type /// is a text type, the character set is utf8. - virtual void setContentTypeCode(ContentType type) { + virtual void setContentTypeCode(ContentType type) { contentType_ = type; setContentType(webContentTypeToString(type)); flagForParsingContentType_ = true; } - /// Set the response content type and the content-type string, The string /// must contain the header name and CRLF. /// For example, "content-type: text/plain\r\n" @@ -183,8 +182,17 @@ public: /// virtual void setContentTypeCodeAndCharacterSet(ContentType type, const /// std::string &charSet = "utf-8") = 0; + const std::string &getHeaderBy(const std::string &lowerKey) const { + const static std::string defaultVal; + auto iter = headers_.find(lowerKey); + if (iter == headers_.end()) { + return defaultVal; + } + return iter->second; + } + /// Get the response content type. - virtual ContentType contentType() const { + virtual ContentType contentType() const { if (!flagForParsingContentType_) { flagForParsingContentType_ = true; auto &contentTypeString = getHeaderBy("content-type"); @@ -208,44 +216,32 @@ public: return contentType(); } - - const std::string &getHeaderBy(const std::string &lowerKey) const { - const static std::string defaultVal; - auto iter = headers_.find(lowerKey); - if (iter == headers_.end()) { - return defaultVal; - } - return iter->second; - } - - /// Get the header string identified by the key parameter. /** * @note * If there is no the header, a empty string is retured. * The key is case insensitive */ - virtual const std::string &getHeader(const std::string &key) const { + virtual const std::string &getHeader(const std::string &key) const { auto field = key; transform(field.begin(), field.end(), field.begin(), ::tolower); return getHeaderBy(field); } - virtual const std::string &getHeader(std::string &&key) const { + virtual const std::string &getHeader(std::string &&key) const { transform(key.begin(), key.end(), key.begin(), ::tolower); return getHeaderBy(key); } - /// Remove the header identified by the key parameter. - virtual void removeHeader(const std::string &key) { + virtual void removeHeader(const std::string &key) { auto field = key; transform(field.begin(), field.end(), field.begin(), ::tolower); removeHeaderBy(field); } - + /// Remove the header identified by the key parameter. - virtual void removeHeader(std::string &&key) { + virtual void removeHeader(std::string &&key) { transform(key.begin(), key.end(), key.begin(), ::tolower); removeHeaderBy(key); } @@ -254,10 +250,9 @@ public: headers_.erase(lowerKey); } - /// Get all headers of the response virtual const std::unordered_map &headers() - const { + const { return headers_; } @@ -268,7 +263,7 @@ public: /// Add a header. virtual void addHeader(const std::string &key, - const std::string &value) { + const std::string &value) { fullHeaderString_.reset(); auto field = key; transform(field.begin(), field.end(), field.begin(), ::tolower); @@ -276,33 +271,33 @@ public: } /// Add a header. - virtual void addHeader(const std::string &key, std::string &&value) { + virtual void addHeader(const std::string &key, std::string &&value) { fullHeaderString_.reset(); auto field = key; transform(field.begin(), field.end(), field.begin(), ::tolower); headers_[std::move(field)] = std::move(value); } - void addHeader(const char *start, const char *colon, const char *end); + void addHeader(const char *start, const char *colon, const char *end); /// Add a cookie virtual void addCookie(const std::string &key, - const std::string &value) { + const std::string &value) { cookies_[key] = Cookie(key, value); } /// Add a cookie - virtual void addCookie(const Cookie &cookie) { + virtual void addCookie(const Cookie &cookie) { cookies_[cookie.key()] = cookie; } - virtual void addCookie(Cookie &&cookie) { + virtual void addCookie(Cookie &&cookie) { cookies_[cookie.key()] = std::move(cookie); } /// Get the cookie identified by the key parameter. /// If there is no the cookie, the empty cookie is retured. - virtual const Cookie &getCookie(const std::string &key) const { + virtual const Cookie &getCookie(const std::string &key) const { static const Cookie defaultCookie; auto it = cookies_.find(key); if (it != cookies_.end()) { @@ -313,7 +308,7 @@ public: /// Get all cookies. virtual const std::unordered_map &cookies() - const { + const { return cookies_; } @@ -323,7 +318,7 @@ public: } /// Remove the cookie identified by the key parameter. - virtual void removeCookie(const std::string &key) { + virtual void removeCookie(const std::string &key) { cookies_.erase(key); } @@ -331,11 +326,11 @@ public: /** * @note The body must match the content type */ - virtual void setBody(const std::string &body) { + virtual void setBody(const std::string &body) { bodyPtr_ = std::make_shared(body); } /// Set the response body(content). - virtual void setBody(std::string &&body) { + virtual void setBody(std::string &&body) { bodyPtr_ = std::make_shared(std::move(body)); } @@ -361,7 +356,7 @@ public: * kHttp10 means Http version is 1.0 * kHttp11 means Http verison is 1.1 */ - virtual Version version() const { + virtual Version version() const { return version_; } @@ -376,7 +371,7 @@ public: /// Set the expiration time of the response cache in memory. /// in seconds, 0 means always cache, negative means not cache, default is /// -1. - virtual void setExpiredTime(ssize_t expiredTime) { + virtual void setExpiredTime(ssize_t expiredTime) { expriedTime_ = expiredTime; datePos_ = std::string::npos; if (expriedTime_ < 0 && version_ == Version::kHttp10) { @@ -384,9 +379,8 @@ public: } } - /// Get the expiration time of the response. - virtual ssize_t expiredTime() const { + virtual ssize_t expiredTime() const { return expriedTime_; } ssize_t getExpiredTime() const { @@ -396,7 +390,7 @@ public: /// Get the json object from the server response. /// If the response is not in json format, then a empty shared_ptr is /// retured. - virtual const std::shared_ptr &jsonObject() const { + virtual const std::shared_ptr &jsonObject() const { // Not multi-thread safe but good, because we basically call this // function in a single thread if (!flagForParsingJson_) { @@ -409,7 +403,6 @@ public: return jsonObject(); } - void setJsonObject(const Json::Value &pJson) { flagForParsingJson_ = true; flagForSerializingJson_ = false; @@ -454,8 +447,6 @@ public: } #endif - - /** * @brief Get the error message of parsing the JSON body received from peer. * This method usually is called after getting a empty shared_ptr object @@ -464,7 +455,7 @@ public: * @return const std::string& The error message. An empty string is returned * when no error occurs. */ - virtual const std::string &getJsonError() const { + virtual const std::string &getJsonError() const { const static std::string none{ "" }; if (jsonParsingErrorPtr_) return *jsonParsingErrorPtr_; @@ -480,20 +471,18 @@ public: * * @param flag */ - virtual void setPassThrough(bool flag) { + virtual void setPassThrough(bool flag) { passThrough_ = flag; } - void redirect(const std::string &url) { headers_["location"] = url; } - std::shared_ptr renderToBuffer(); + std::shared_ptr renderToBuffer(); void renderToBuffer(trantor::MsgBuffer &buffer); std::shared_ptr renderHeaderForHeadMethod(); - /* The following methods are a series of factory methods that help users * create response objects. */ @@ -564,25 +553,23 @@ public: virtual ~HttpResponse(); - // virtual void setContentTypeCodeAndCharacterSet(ContentType type, const - // std::string &charSet = "utf-8") + // std::string &charSet = "utf-8") // { // contentType_ = type; // setContentType(webContentTypeAndCharsetToString(type, charSet)); // } - - void swap(HttpResponse &that) noexcept; + protected: void makeHeaderString(trantor::MsgBuffer &headerString); private: - virtual void setBody(const char *body, size_t len) { + virtual void setBody(const char *body, size_t len) { bodyPtr_ = std::make_shared(body, len); } - virtual const char *getBodyData() const { + virtual const char *getBodyData() const { if (!flagForSerializingJson_ && jsonPtr_) { generateBodyFromJson(); } else if (!bodyPtr_) { @@ -591,25 +578,23 @@ private: return bodyPtr_->data(); } - virtual size_t getBodyLength() const { + virtual size_t getBodyLength() const { if (bodyPtr_) return bodyPtr_->length(); return 0; } - void parseJson() const; virtual void setContentTypeCodeAndCustomString( ContentType type, const char *typeString, - size_t typeStringLength) { + size_t typeStringLength) { contentType_ = type; flagForParsingContentType_ = true; setContentType(string_view{ typeString, typeStringLength }); } - std::unordered_map headers_; std::unordered_map cookies_; @@ -643,7 +628,6 @@ private: void setStatusMessage(const string_view &message) { statusMessage_ = message; } - }; template <> diff --git a/core/http_server.cpp b/core/http_server.cpp index 4e0685e..7213635 100644 --- a/core/http_server.cpp +++ b/core/http_server.cpp @@ -15,7 +15,7 @@ void HTTPServer::http_callback_handler(Request *request) { Application::handle_request(request); } -void HTTPServer::httpEnterCallbackDefault(const HTTPParser &httpParser, const HttpSession::Ptr &session) { +void HTTPServer::httpEnterCallbackDefault(const brynet::net::http::HTTPParser &httpParser, const brynet::net::http::HttpSession::Ptr &session) { Request *request = RequestPool::get_request(); request->http_parser = &httpParser; @@ -30,7 +30,7 @@ void HTTPServer::httpEnterCallbackDefault(const HTTPParser &httpParser, const Ht http_callback_handler(request); } -void HTTPServer::wsEnterCallbackDefault(const HttpSession::Ptr &httpSession, WebSocketFormat::WebSocketFrameType opcode, const std::string &payload) { +void HTTPServer::wsEnterCallbackDefault(const brynet::net::http::HttpSession::Ptr &httpSession, brynet::net::http::WebSocketFormat::WebSocketFrameType opcode, const std::string &payload) { std::cout << "frame enter of type:" << int(opcode) << std::endl; std::cout << "payload is:" << payload << std::endl; @@ -51,7 +51,7 @@ void HTTPServer::initialize_old() { configure_old(); - service = TcpService::Create(); + service = brynet::net::TcpService::Create(); service->startWorkerThread(threads); int p_port = port; @@ -60,22 +60,22 @@ void HTTPServer::initialize_old() { if (listenBuilder) delete listenBuilder; - listenBuilder = new wrapper::HttpListenerBuilder(); + listenBuilder = new brynet::net::wrapper::HttpListenerBuilder(); listenBuilder->configureService(service); listenBuilder->configureSocketOptions({ - [](TcpSocket &socket) { + [](brynet::net::TcpSocket &socket) { socket.setNodelay(); }, }); - listenBuilder->configureConnectionOptions({ AddSocketOption::WithMaxRecvBufferSize(1024) }); + listenBuilder->configureConnectionOptions({ brynet::net::AddSocketOption::WithMaxRecvBufferSize(1024) }); - listenBuilder->configureListen([p_port](wrapper::BuildListenConfig builder) { + listenBuilder->configureListen([p_port](brynet::net::wrapper::BuildListenConfig builder) { builder.setAddr(false, "0.0.0.0", p_port); }); - listenBuilder->configureEnterCallback([](const HttpSession::Ptr &httpSession, HttpSessionHandlers &handlers) { + listenBuilder->configureEnterCallback([](const brynet::net::http::HttpSession::Ptr &httpSession, brynet::net::http::HttpSessionHandlers &handlers) { handlers.setHttpCallback(HTTPServer::httpEnterCallbackDefault); handlers.setWSCallback(HTTPServer::wsEnterCallbackDefault); }); @@ -203,13 +203,14 @@ void HTTPServer::main_loop() { */ // Create all listeners. + /* auto ioLoops = listenerManagerPtr_->createListeners( - std::bind(&HttpAppFrameworkImpl::onAsyncRequest, this, _1, _2), - std::bind(&HttpAppFrameworkImpl::onNewWebsockRequest, this, _1, _2, _3), - std::bind(&HttpAppFrameworkImpl::onConnection, this, _1), - idleConnectionTimeout_, - sslCertPath_, - sslKeyPath_, + std::bind(&Application::onAsyncRequest, this, _1, _2), + std::bind(&Application::onNewWebsockRequest, this, _1, _2, _3), + std::bind(&Application::onConnection, this, _1), + Application::get_instance()->idleConnectionTimeout_, + Application::get_instance()->sslCertPath_, + Application::get_instance()->sslKeyPath_, threads, syncAdvices_); @@ -221,11 +222,11 @@ void HTTPServer::main_loop() { getLoop()->setIndex(threads); - +*/ // A fast database client instance should be created in the main event // loop, so put the main loop into ioLoops. - ioLoops.push_back(getLoop()); + //ioLoops.push_back(getLoop()); /* dbClientManagerPtr_->createDbClients(ioLoops); @@ -235,7 +236,8 @@ void HTTPServer::main_loop() { websockCtrlsRouterPtr_->init(); */ - getLoop()->queueInLoop([this]() { +/* + get_loop()->queueInLoop([this]() { // Let listener event loops run when everything is ready. listenerManagerPtr_->startListening(); @@ -245,14 +247,8 @@ void HTTPServer::main_loop() { beginningAdvices_.clear(); }); - - getLoop()->loop(); -} - -trantor::EventLoop *HttpAppFrameworkImpl::get_loop() const -{ - static trantor::EventLoop loop; - return &loop; +*/ + get_loop()->loop(); } HTTPServer::HTTPServer() { diff --git a/core/http_server.h b/core/http_server.h index cf8f127..ac99452 100644 --- a/core/http_server.h +++ b/core/http_server.h @@ -16,12 +16,14 @@ #include #include -#include "core/http_server_callbacks.h" #include "core/http_request_parser.h" +#include "core/http_server_callbacks.h" -using namespace brynet; -using namespace brynet::net; -using namespace brynet::net::http; +//using namespace brynet; +//using namespace brynet::net; +//using namespace brynet::net::http; + +using namespace drogon; class Request; @@ -29,13 +31,13 @@ class HTTPServer { public: int port; int threads; - std::shared_ptr service; - wrapper::HttpListenerBuilder *listenBuilder; + std::shared_ptr service; + brynet::net::wrapper::HttpListenerBuilder *listenBuilder; static void http_callback_handler(Request *response); - static void httpEnterCallbackDefault(const HTTPParser &httpParser, const HttpSession::Ptr &session); - static void wsEnterCallbackDefault(const HttpSession::Ptr &httpSession, WebSocketFormat::WebSocketFrameType opcode, const std::string &payload); + static void httpEnterCallbackDefault(const brynet::net::http::HTTPParser &httpParser, const brynet::net::http::HttpSession::Ptr &session); + static void wsEnterCallbackDefault(const brynet::net::http::HttpSession::Ptr &httpSession, brynet::net::http::WebSocketFormat::WebSocketFrameType opcode, const std::string &payload); virtual void configure_old(); virtual void initialize_old(); @@ -47,7 +49,7 @@ public: void main_loop(); - trantor::EventLoop *getLoop() const { + trantor::EventLoop *get_loop() const { return server_.getLoop(); } @@ -102,6 +104,7 @@ protected: WebSocketNewAsyncCallback newWebsocketCallback_; trantor::ConnectionCallback connectionCallback_; const std::vector > &syncAdvices_; + bool _running{ false }; }; #endif \ No newline at end of file diff --git a/core/http_server_callbacks.h b/core/http_server_callbacks.h index edceb5f..d89e6fb 100644 --- a/core/http_server_callbacks.h +++ b/core/http_server_callbacks.h @@ -5,6 +5,8 @@ #include +namespace drogon { + class HttpRequest; using HttpRequestPtr = std::shared_ptr; class HttpResponse; @@ -16,4 +18,6 @@ using HttpAsyncCallback = std::function &&, const WebSocketConnectionPtr &)>; +} + #endif \ No newline at end of file diff --git a/core/io_thread_storage.h b/core/io_thread_storage.h index 940e782..7ac8347 100644 --- a/core/io_thread_storage.h +++ b/core/io_thread_storage.h @@ -21,6 +21,8 @@ #include #include +#include "core/application.h" + namespace drogon { /** @@ -68,7 +70,7 @@ class IOThreadStorage : public trantor::NonCopyable { static_assert(std::is_constructible::value, "Unable to construct storage with given signature"); - size_t numThreads = app().getThreadNum(); + size_t numThreads = Application::get_instance()->threadNum_; #ifdef _WIN32 assert(numThreads > 0 && numThreads != size_t(-1)); #else @@ -100,14 +102,14 @@ class IOThreadStorage : public trantor::NonCopyable */ inline ValueType &getThreadData() { - size_t idx = app().getCurrentThreadIndex(); + size_t idx = Application::get_instance()->getCurrentThreadIndex(); assert(idx < storage_.size()); return storage_[idx]; } inline const ValueType &getThreadData() const { - size_t idx = app().getCurrentThreadIndex(); + size_t idx = Application::get_instance()->getCurrentThreadIndex(); assert(idx < storage_.size()); return storage_[idx]; } @@ -119,21 +121,21 @@ class IOThreadStorage : public trantor::NonCopyable */ inline void setThreadData(const ValueType &newData) { - size_t idx = app().getCurrentThreadIndex(); + size_t idx = Application::get_instance()->getCurrentThreadIndex(); assert(idx < storage_.size()); storage_[idx] = newData; } inline void setThreadData(ValueType &&newData) { - size_t idx = app().getCurrentThreadIndex(); + size_t idx = Application::get_instance()->getCurrentThreadIndex(); assert(idx < storage_.size()); storage_[idx] = std::move(newData); } inline ValueType *operator->() { - size_t idx = app().getCurrentThreadIndex(); + size_t idx = Application::get_instance()->getCurrentThreadIndex(); assert(idx < storage_.size()); return &storage_[idx]; } @@ -145,7 +147,7 @@ class IOThreadStorage : public trantor::NonCopyable inline const ValueType *operator->() const { - size_t idx = app().getCurrentThreadIndex(); + size_t idx = Application::get_instance()->getCurrentThreadIndex(); assert(idx < storage_.size()); return &storage_[idx]; } diff --git a/core/listener_manager.cpp b/core/listener_manager.cpp index 871b7bd..8b4d53b 100644 --- a/core/listener_manager.cpp +++ b/core/listener_manager.cpp @@ -19,6 +19,8 @@ #include #include +#include "core/application.h" + #ifndef _WIN32 #include #include @@ -83,7 +85,7 @@ std::vector ListenerManager::createListeners( if (i == 0) { DrogonFileLocker lock; // Check whether the port is in use. - TcpServer server(HttpAppFrameworkImpl::instance().getLoop(), + TcpServer server(Application::get_instance()->get_loop(), InetAddress(ip, listener.port_, isIpv6), "drogonPortTest", true, @@ -118,12 +120,13 @@ std::vector ListenerManager::createListeners( serverPtr->enableSSL(cert, key); #endif } - +/* serverPtr->setHttpAsyncCallback(httpCallback); serverPtr->setNewWebsocketCallback(webSocketCallback); serverPtr->setConnectionCallback(connectionCallback); serverPtr->kickoffIdleConnections(connectionTimeout); serverPtr->start(); + */ servers_.push_back(serverPtr); } } @@ -207,7 +210,7 @@ trantor::EventLoop *ListenerManager::getIOLoop(size_t id) const { void ListenerManager::stopListening() { for (auto &serverPtr : servers_) { - serverPtr->stop(); + //serverPtr->stop(); } for (auto loop : ioLoops_) { diff --git a/core/request.cpp b/core/request.cpp index 3f40592..ab1777e 100644 --- a/core/request.cpp +++ b/core/request.cpp @@ -51,7 +51,7 @@ void Request::send() { std::string result = response->getResult(); - const HttpSession::Ptr lsession = (*session); + const brynet::net::http::HttpSession::Ptr lsession = (*session); (*session)->send(result.c_str(), result.size(), [lsession]() { lsession->postShutdown(); }); } @@ -76,7 +76,7 @@ void Request::send_file(const std::string &p_file_path) { response->addHeadValue("Connection", "Close"); std::string result = "HTTP/1.1 200 OK\r\nConnection: Close\r\n\r\n"; - const HttpSession::Ptr lsession = (*session); + const brynet::net::http::HttpSession::Ptr lsession = (*session); (*session)->send(result.c_str(), result.size(), [this]() { this->_progress_send_file(); }); } @@ -99,7 +99,7 @@ void Request::reset() { if (response) delete response; - response = new HttpResponse(); + response = new brynet::net::http::HttpResponse(); } void Request::setup_url_stack() { @@ -186,7 +186,7 @@ Request::~Request() { } void Request::_progress_send_file() { - const HttpSession::Ptr lsession = (*session); + const brynet::net::http::HttpSession::Ptr lsession = (*session); if (current_file_progress >= file_size) { lsession->postShutdown(); diff --git a/core/utilities.cpp b/core/utilities.cpp index 446b6b4..eda2a47 100644 --- a/core/utilities.cpp +++ b/core/utilities.cpp @@ -12,7 +12,7 @@ * */ -#include +#include #include #ifdef OpenSSL_FOUND diff --git a/libs/trantor/SCsub b/libs/trantor/SCsub index f756347..8865122 100644 --- a/libs/trantor/SCsub +++ b/libs/trantor/SCsub @@ -6,9 +6,10 @@ env.core_sources = [] #env.add_source_files(env.core_sources, "*.cpp") -env.add_source_files(env.core_sources, "./trantor/net/*.cc") -env.add_source_files(env.core_sources, "./trantor/net/inner/*.cc") env.add_source_files(env.core_sources, "./trantor/net/inner/poller/*.cc") +env.add_source_files(env.core_sources, "./trantor/net/inner/*.cc") +env.add_source_files(env.core_sources, "./trantor/net/*.cc") + env.core_sources.append("./trantor/utils/AsyncFileLogger.cc") env.core_sources.append("./trantor/utils/ConcurrentTaskQueue.cc") diff --git a/libs/trantor/trantor/net/TcpServer.h b/libs/trantor/trantor/net/TcpServer.h index 8cb2eb3..c82808e 100644 --- a/libs/trantor/trantor/net/TcpServer.h +++ b/libs/trantor/trantor/net/TcpServer.h @@ -50,6 +50,7 @@ class TcpServer : NonCopyable const std::string &name, bool reUseAddr = true, bool reUsePort = true); + TcpServer() {} ~TcpServer(); /**