Work on fixing compile.

This commit is contained in:
Relintai 2021-02-03 19:43:54 +01:00
parent 647694b576
commit 7d000bb5b5
18 changed files with 652 additions and 703 deletions

View File

@ -68,6 +68,8 @@ env_base.use_ptrcall = False
env_base.module_version_string = "" env_base.module_version_string = ""
env_base.msvc = False 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 # avoid issues when building with different versions of python out of the same directory
env_base.SConsignFile(".sconsign{0}.dblite".format(pickle.HIGHEST_PROTOCOL)) env_base.SConsignFile(".sconsign{0}.dblite".format(pickle.HIGHEST_PROTOCOL))

View File

@ -37,7 +37,7 @@ int HttpFileImpl::save(const std::string &path) const
} }
else else
{ {
auto &uploadPath = HttpAppFrameworkImpl::instance().getUploadPath(); auto &uploadPath = Application::get_instance()->getUploadPath();
if (uploadPath[uploadPath.length() - 1] == '/') if (uploadPath[uploadPath.length() - 1] == '/')
tmpPath = uploadPath + path; tmpPath = uploadPath + path;
else else
@ -59,7 +59,7 @@ int HttpFileImpl::save(const std::string &path) const
} }
int HttpFileImpl::save() const int HttpFileImpl::save() const
{ {
return save(HttpAppFrameworkImpl::instance().getUploadPath()); return save(Application::get_instance()->getUploadPath());
} }
int HttpFileImpl::saveAs(const std::string &filename) const int HttpFileImpl::saveAs(const std::string &filename) const
{ {
@ -74,7 +74,7 @@ int HttpFileImpl::saveAs(const std::string &filename) const
} }
else else
{ {
auto &uploadPath = HttpAppFrameworkImpl::instance().getUploadPath(); auto &uploadPath = Application::get_instance()->getUploadPath();
if (uploadPath[uploadPath.length() - 1] == '/') if (uploadPath[uploadPath.length() - 1] == '/')
pathAndFileName = uploadPath + filename; pathAndFileName = uploadPath + filename;
else else

View File

@ -251,7 +251,7 @@ void Application::run() {
// A fast database client instance should be created in the main event // A fast database client instance should be created in the main event
// loop, so put the main loop into ioLoops. // loop, so put the main loop into ioLoops.
ioLoops.push_back(get_loop()); //ioLoops.push_back(get_loop());
/* /*
dbClientManagerPtr_->createDbClients(ioLoops); dbClientManagerPtr_->createDbClients(ioLoops);

View File

@ -15,8 +15,11 @@
#include "core/http_server_callbacks.h" #include "core/http_server_callbacks.h"
#include "core/listener_manager.h"
using namespace drogon;
class Request; class Request;
class ListenerManager;
class Application { class Application {
public: public:
@ -54,6 +57,50 @@ public:
std::unique_ptr<ListenerManager> listenerManagerPtr_; std::unique_ptr<ListenerManager> 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<size_t>::max();
#endif
}
public: public:
static HandlerInstance index_func; static HandlerInstance index_func;
static std::map<std::string, HandlerInstance> main_route_map; static std::map<std::string, HandlerInstance> main_route_map;
@ -71,6 +118,16 @@ public:
private: private:
static Application *_instance; static Application *_instance;
bool _running; 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 #endif

View File

@ -648,7 +648,7 @@ HttpRequest::~HttpRequest()
void HttpRequest::reserveBodySize(size_t length) void HttpRequest::reserveBodySize(size_t length)
{ {
if (length <= HttpAppFrameworkImpl::instance().getClientMaxMemoryBodySize()) if (length <= Application::get_instance()->getClientMaxMemoryBodySize())
{ {
content_.reserve(length); content_.reserve(length);
} }
@ -668,7 +668,7 @@ void HttpRequest::appendToBody(const char *data, size_t length)
else else
{ {
if (content_.length() + length <= if (content_.length() + length <=
HttpAppFrameworkImpl::instance().getClientMaxMemoryBodySize()) Application::get_instance()->getClientMaxMemoryBodySize())
{ {
content_.append(data, length); content_.append(data, length);
} }
@ -685,7 +685,7 @@ void HttpRequest::appendToBody(const char *data, size_t length)
void HttpRequest::createTmpFile() void HttpRequest::createTmpFile()
{ {
/* /*
auto tmpfile = HttpAppFrameworkImpl::instance().getUploadPath(); auto tmpfile = Application::get_instance()->getUploadPath();
auto fileName = utils::getUuid(); auto fileName = utils::getUuid();

View File

@ -44,6 +44,7 @@
#include <unordered_map> #include <unordered_map>
namespace drogon { namespace drogon {
class HttpRequest; class HttpRequest;
using HttpRequestPtr = std::shared_ptr<HttpRequest>; using HttpRequestPtr = std::shared_ptr<HttpRequest>;
@ -164,6 +165,8 @@ public:
return fromRequest<T>(*this); return fromRequest<T>(*this);
} }
bool setMethod(const char *start, const char *end);
/// Return the method string of the request, such as GET, POST, etc. /// Return the method string of the request, such as GET, POST, etc.
virtual const char *methodString() const; virtual const char *methodString() const;
const char *getMethodString() const { const char *getMethodString() const {

View File

@ -14,8 +14,10 @@
#include "core/http_request_parser.h" #include "core/http_request_parser.h"
//#include "core/http_server_callbacks.h"
#include "core/http_response.h" #include "core/http_response.h"
#include "http_request.h" #include "core/http_request.h"
#include "core/http_utils.h" #include "core/http_utils.h"
#include <core/http_types.h> #include <core/http_types.h>
@ -23,6 +25,8 @@
#include <trantor/utils/Logger.h> #include <trantor/utils/Logger.h>
#include <trantor/utils/MsgBuffer.h> #include <trantor/utils/MsgBuffer.h>
#include "core/application.h"
using namespace trantor; using namespace trantor;
using namespace drogon; using namespace drogon;
@ -83,10 +87,10 @@ bool HttpRequestParser::processRequestLine(const char *begin, const char *end)
} }
return succeed; return succeed;
} }
HttpRequestPtr HttpRequestParser::makeRequestForPool(HttpRequestImpl *ptr) HttpRequestPtr HttpRequestParser::makeRequestForPool(HttpRequest *ptr)
{ {
std::weak_ptr<HttpRequestParser> weakPtr = shared_from_this(); std::weak_ptr<HttpRequestParser> weakPtr = shared_from_this();
return std::shared_ptr<HttpRequestImpl>(ptr, [weakPtr](HttpRequestImpl *p) { return std::shared_ptr<HttpRequest>(ptr, [weakPtr](HttpRequest *p) {
auto thisPtr = weakPtr.lock(); auto thisPtr = weakPtr.lock();
if (thisPtr) if (thisPtr)
{ {
@ -118,7 +122,7 @@ void HttpRequestParser::reset()
status_ = HttpRequestParseStatus::kExpectMethod; status_ = HttpRequestParseStatus::kExpectMethod;
if (requestsPool_.empty()) if (requestsPool_.empty())
{ {
request_ = makeRequestForPool(new HttpRequestImpl(loop_)); request_ = makeRequestForPool(new HttpRequest(loop_));
} }
else else
{ {
@ -264,13 +268,11 @@ bool HttpRequestParser::parseRequest(MsgBuffer *buf)
if (connPtr) if (connPtr)
{ {
auto resp = HttpResponse::newHttpResponse(); auto resp = HttpResponse::newHttpResponse();
if (currentContentLength_ > if (currentContentLength_ > Application::get_instance()->getClientMaxBodySize())
HttpAppFrameworkImpl::instance()
.getClientMaxBodySize())
{ {
resp->setStatusCode(k413RequestEntityTooLarge); resp->setStatusCode(k413RequestEntityTooLarge);
auto httpString = auto httpString =
static_cast<HttpResponseImpl *>(resp.get()) static_cast<HttpResponse *>(resp.get())
->renderToBuffer(); ->renderToBuffer();
reset(); reset();
connPtr->send(std::move(*httpString)); connPtr->send(std::move(*httpString));
@ -279,7 +281,7 @@ bool HttpRequestParser::parseRequest(MsgBuffer *buf)
{ {
resp->setStatusCode(k100Continue); resp->setStatusCode(k100Continue);
auto httpString = auto httpString =
static_cast<HttpResponseImpl *>(resp.get()) static_cast<HttpResponse *>(resp.get())
->renderToBuffer(); ->renderToBuffer();
connPtr->send(std::move(*httpString)); connPtr->send(std::move(*httpString));
} }
@ -297,9 +299,7 @@ bool HttpRequestParser::parseRequest(MsgBuffer *buf)
return false; return false;
} }
} }
else if (currentContentLength_ > else if (currentContentLength_ > Application::get_instance()->getClientMaxBodySize())
HttpAppFrameworkImpl::instance()
.getClientMaxBodySize())
{ {
buf->retrieveAll(); buf->retrieveAll();
shutdownConnection(k413RequestEntityTooLarge); shutdownConnection(k413RequestEntityTooLarge);
@ -365,8 +365,7 @@ bool HttpRequestParser::parseRequest(MsgBuffer *buf)
// responsePtr_->currentChunkLength_; // responsePtr_->currentChunkLength_;
if (currentChunkLength_ != 0) if (currentChunkLength_ != 0)
{ {
if (currentChunkLength_ + currentContentLength_ > if (currentChunkLength_ + currentContentLength_ > Application::get_instance()->getClientMaxBodySize())
HttpAppFrameworkImpl::instance().getClientMaxBodySize())
{ {
buf->retrieveAll(); buf->retrieveAll();
shutdownConnection(k413RequestEntityTooLarge); shutdownConnection(k413RequestEntityTooLarge);

View File

@ -19,31 +19,29 @@
#include <core/http_view_data.h> #include <core/http_view_data.h>
#include <core/io_thread_storage.h>
#include "core/application.h" #include "core/application.h"
#include <core/io_thread_storage.h>
#include <fstream>
#include <memory>
#include <stdio.h> #include <stdio.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <trantor/utils/Logger.h> #include <trantor/utils/Logger.h>
#include <fstream>
#include <memory>
#ifdef _WIN32 #ifdef _WIN32
#define stat _stati64 #define stat _stati64
#endif #endif
using namespace trantor; using namespace trantor;
using namespace drogon; using namespace drogon;
namespace drogon namespace drogon {
{
// "Fri, 23 Aug 2019 12:58:03 GMT" length = 29 // "Fri, 23 Aug 2019 12:58:03 GMT" length = 29
static const size_t httpFullDateStringLength = 29; static const size_t httpFullDateStringLength = 29;
static inline void doResponseCreateAdvices( static inline void doResponseCreateAdvices(
const HttpResponsePtr &responsePtr) const HttpResponsePtr &responsePtr) {
{
/* /*
auto &advices = auto &advices =
HttpAppFrameworkImpl::instance().getResponseCreationAdvices(); Application::get_instance()->getResponseCreationAdvices();
if (!advices.empty()) if (!advices.empty())
{ {
for (auto &advice : advices) for (auto &advice : advices)
@ -53,46 +51,42 @@ static inline void doResponseCreateAdvices(
}*/ }*/
} }
static inline HttpResponsePtr genHttpResponse(std::string viewName, static inline HttpResponsePtr genHttpResponse(std::string viewName,
const HttpViewData &data) const HttpViewData &data) {
{ /*
auto templ = DrTemplateBase::newTemplate(viewName); auto templ = DrTemplateBase::newTemplate(viewName);
if (templ) if (templ)
{ {
auto res = HttpResponse::newHttpResponse(); auto res = HttpResponse::newHttpResponse();
res->setBody(templ->genText(data)); res->setBody(templ->genText(data));
return res; return res;
} }*/
return drogon::HttpResponse::newNotFoundResponse(); return drogon::HttpResponse::newNotFoundResponse();
} }
} // namespace drogon } // namespace drogon
HttpResponsePtr HttpResponse::newHttpResponse() HttpResponsePtr HttpResponse::newHttpResponse() {
{
auto res = std::make_shared<HttpResponse>(k200OK, CT_TEXT_HTML); auto res = std::make_shared<HttpResponse>(k200OK, CT_TEXT_HTML);
doResponseCreateAdvices(res); doResponseCreateAdvices(res);
return res; return res;
} }
HttpResponsePtr HttpResponse::newHttpJsonResponse(const Json::Value &data) HttpResponsePtr HttpResponse::newHttpJsonResponse(const Json::Value &data) {
{
auto res = std::make_shared<HttpResponse>(k200OK, CT_APPLICATION_JSON); auto res = std::make_shared<HttpResponse>(k200OK, CT_APPLICATION_JSON);
res->setJsonObject(data); res->setJsonObject(data);
doResponseCreateAdvices(res); doResponseCreateAdvices(res);
return res; return res;
} }
HttpResponsePtr HttpResponse::newHttpJsonResponse(Json::Value &&data) HttpResponsePtr HttpResponse::newHttpJsonResponse(Json::Value &&data) {
{
auto res = std::make_shared<HttpResponse>(k200OK, CT_APPLICATION_JSON); auto res = std::make_shared<HttpResponse>(k200OK, CT_APPLICATION_JSON);
res->setJsonObject(std::move(data)); res->setJsonObject(std::move(data));
doResponseCreateAdvices(res); doResponseCreateAdvices(res);
return res; return res;
} }
void HttpResponse::generateBodyFromJson() const void HttpResponse::generateBodyFromJson() const {
{ if (!jsonPtr_ || flagForSerializingJson_) {
if (!jsonPtr_ || flagForSerializingJson_)
{
return; return;
} }
flagForSerializingJson_ = true; flagForSerializingJson_ = true;
@ -107,47 +101,36 @@ void HttpResponse::generateBodyFromJson() const
{ {
builder["emitUTF8"] = true; builder["emitUTF8"] = true;
}*/ }*/
}); });
bodyPtr_ = std::make_shared<HttpMessageStringBody>( bodyPtr_ = std::make_shared<HttpMessageStringBody>(
writeString(builder, *jsonPtr_)); writeString(builder, *jsonPtr_));
} }
HttpResponsePtr HttpResponse::newNotFoundResponse() HttpResponsePtr HttpResponse::newNotFoundResponse() {
{
auto loop = trantor::EventLoop::getEventLoopOfCurrentThread(); auto loop = trantor::EventLoop::getEventLoopOfCurrentThread();
auto &resp = HttpAppFrameworkImpl::instance().getCustom404Page();
if (resp) /*
{ auto &resp = Application::get_instance()->getCustom404Page();
if (loop && loop->index() < Application::get_instance()->threadNum_)
{ if (resp) {
if (loop && loop->index() < Application::get_instance()->threadNum_) {
return resp; return resp;
} } else {
else
{
return HttpResponsePtr{ new HttpResponse( return HttpResponsePtr{ new HttpResponse(
*static_cast<HttpResponse *>(resp.get())) }; *static_cast<HttpResponse *>(resp.get())) };
} }
} } else {
else if (loop && loop->index() < Application::get_instance()->threadNum_) {
{
if (loop && loop->index() < Application::get_instance()->threadNum_)
{
// If the current thread is an IO thread // If the current thread is an IO thread
static std::once_flag threadOnce; static std::once_flag threadOnce;
static IOThreadStorage<HttpResponsePtr> thread404Pages; static IOThreadStorage<HttpResponsePtr> thread404Pages;
std::call_once(threadOnce, [] { std::call_once(threadOnce, [] {
thread404Pages.init( thread404Pages.init(
[](drogon::HttpResponsePtr &resp, size_t index) { [](drogon::HttpResponsePtr &resp, size_t index) {
if (HttpAppFrameworkImpl::instance() if (Application::get_instance()->isUsingCustomErrorHandler()) {
.isUsingCustomErrorHandler())
{
//resp = app().getCustomErrorHandler()(k404NotFound); //resp = app().getCustomErrorHandler()(k404NotFound);
//resp->setExpiredTime(0); //resp->setExpiredTime(0);
} } else {
else
{
HttpViewData data; HttpViewData data;
data.insert("version", drogon::getVersion()); data.insert("version", drogon::getVersion());
resp = HttpResponse::newHttpViewResponse( resp = HttpResponse::newHttpViewResponse(
@ -159,16 +142,13 @@ HttpResponsePtr HttpResponse::newNotFoundResponse()
}); });
LOG_TRACE << "Use cached 404 response"; LOG_TRACE << "Use cached 404 response";
return thread404Pages.getThreadData(); return thread404Pages.getThreadData();
} } else {
else //if (Application::get_instance()->isUsingCustomErrorHandler())
{
//if (HttpAppFrameworkImpl::instance().isUsingCustomErrorHandler())
//{ //{
//auto resp = app().getCustomErrorHandler()(k404NotFound); //auto resp = app().getCustomErrorHandler()(k404NotFound);
// return resp; // return resp;
// } // }
HttpViewData data; HttpViewData data;
data.insert("version", drogon::getVersion()); data.insert("version", drogon::getVersion());
auto notFoundResp = auto notFoundResp =
@ -177,11 +157,18 @@ HttpResponsePtr HttpResponse::newNotFoundResponse()
return notFoundResp; 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( HttpResponsePtr HttpResponse::newRedirectionResponse(
const std::string &location, const std::string &location,
HttpStatusCode status) HttpStatusCode status) {
{
auto res = std::make_shared<HttpResponse>(); auto res = std::make_shared<HttpResponse>();
res->setStatusCode(status); res->setStatusCode(status);
res->redirect(location); res->redirect(location);
@ -190,20 +177,17 @@ HttpResponsePtr HttpResponse::newRedirectionResponse(
} }
HttpResponsePtr HttpResponse::newHttpViewResponse(const std::string &viewName, HttpResponsePtr HttpResponse::newHttpViewResponse(const std::string &viewName,
const HttpViewData &data) const HttpViewData &data) {
{
return genHttpResponse(viewName, data); return genHttpResponse(viewName, data);
} }
HttpResponsePtr HttpResponse::newFileResponse( HttpResponsePtr HttpResponse::newFileResponse(
const std::string &fullPath, const std::string &fullPath,
const std::string &attachmentFileName, const std::string &attachmentFileName,
ContentType type) ContentType type) {
{
std::ifstream infile(fullPath, std::ifstream::binary); std::ifstream infile(fullPath, std::ifstream::binary);
LOG_TRACE << "send http file:" << fullPath; LOG_TRACE << "send http file:" << fullPath;
if (!infile) if (!infile) {
{
auto resp = HttpResponse::newNotFoundResponse(); auto resp = HttpResponse::newNotFoundResponse();
return resp; return resp;
} }
@ -211,41 +195,36 @@ HttpResponsePtr HttpResponse::newFileResponse(
std::streambuf *pbuf = infile.rdbuf(); std::streambuf *pbuf = infile.rdbuf();
std::streamsize filesize = pbuf->pubseekoff(0, infile.end); std::streamsize filesize = pbuf->pubseekoff(0, infile.end);
pbuf->pubseekoff(0, infile.beg); // rewind pbuf->pubseekoff(0, infile.beg); // rewind
if (HttpAppFrameworkImpl::instance().useSendfile() && filesize > 1024 * 200)
/*
if (Application::get_instance()->useSendfile() && filesize > 1024 * 200)
// TODO : Is 200k an appropriate value? Or set it to be configurable // TODO : Is 200k an appropriate value? Or set it to be configurable
{ {
// The advantages of sendfile() can only be reflected in sending large // The advantages of sendfile() can only be reflected in sending large
// files. // files.
resp->setSendfile(fullPath); resp->setSendfile(fullPath);
} } else {
else
{
std::string str; std::string str;
str.resize(filesize); str.resize(filesize);
pbuf->sgetn(&str[0], filesize); pbuf->sgetn(&str[0], filesize);
resp->setBody(std::move(str)); resp->setBody(std::move(str));
} }
*/
resp->setStatusCode(k200OK); resp->setStatusCode(k200OK);
if (type == CT_NONE) if (type == CT_NONE) {
{ if (!attachmentFileName.empty()) {
if (!attachmentFileName.empty())
{
resp->setContentTypeCode( resp->setContentTypeCode(
drogon::getContentType(attachmentFileName)); drogon::getContentType(attachmentFileName));
} } else {
else
{
resp->setContentTypeCode(drogon::getContentType(fullPath)); resp->setContentTypeCode(drogon::getContentType(fullPath));
} }
} } else {
else
{
resp->setContentTypeCode(type); resp->setContentTypeCode(type);
} }
if (!attachmentFileName.empty()) if (!attachmentFileName.empty()) {
{
resp->addHeader("Content-Disposition", resp->addHeader("Content-Disposition",
"attachment; filename=" + attachmentFileName); "attachment; filename=" + attachmentFileName);
} }
@ -253,19 +232,15 @@ HttpResponsePtr HttpResponse::newFileResponse(
return resp; return resp;
} }
void HttpResponse::makeHeaderString(trantor::MsgBuffer &buffer) void HttpResponse::makeHeaderString(trantor::MsgBuffer &buffer) {
{
buffer.ensureWritableBytes(128); buffer.ensureWritableBytes(128);
int len{ 0 }; int len{ 0 };
if (version_ == Version::kHttp11) if (version_ == Version::kHttp11) {
{
len = snprintf(buffer.beginWrite(), len = snprintf(buffer.beginWrite(),
buffer.writableBytes(), buffer.writableBytes(),
"HTTP/1.1 %d ", "HTTP/1.1 %d ",
statusCode_); statusCode_);
} } else {
else
{
len = snprintf(buffer.beginWrite(), len = snprintf(buffer.beginWrite(),
buffer.writableBytes(), buffer.writableBytes(),
"HTTP/1.0 %d ", "HTTP/1.0 %d ",
@ -277,22 +252,17 @@ void HttpResponse::makeHeaderString(trantor::MsgBuffer &buffer)
buffer.append(statusMessage_.data(), statusMessage_.length()); buffer.append(statusMessage_.data(), statusMessage_.length());
buffer.append("\r\n"); buffer.append("\r\n");
generateBodyFromJson(); generateBodyFromJson();
if (!passThrough_) if (!passThrough_) {
{
buffer.ensureWritableBytes(64); buffer.ensureWritableBytes(64);
if (sendfileName_.empty()) if (sendfileName_.empty()) {
{
auto bodyLength = bodyPtr_ ? bodyPtr_->length() : 0; auto bodyLength = bodyPtr_ ? bodyPtr_->length() : 0;
len = snprintf(buffer.beginWrite(), len = snprintf(buffer.beginWrite(),
buffer.writableBytes(), buffer.writableBytes(),
contentLengthFormatString<decltype(bodyLength)>(), contentLengthFormatString<decltype(bodyLength)>(),
bodyLength); bodyLength);
} } else {
else
{
struct stat filestat; struct stat filestat;
if (stat(sendfileName_.data(), &filestat) < 0) if (stat(sendfileName_.data(), &filestat) < 0) {
{
LOG_SYSERR << sendfileName_ << " stat error"; LOG_SYSERR << sendfileName_ << " stat error";
return; return;
} }
@ -302,92 +272,71 @@ void HttpResponse::makeHeaderString(trantor::MsgBuffer &buffer)
filestat.st_size); filestat.st_size);
} }
buffer.hasWritten(len); buffer.hasWritten(len);
if (headers_.find("Connection") == headers_.end()) if (headers_.find("Connection") == headers_.end()) {
{ if (closeConnection_) {
if (closeConnection_)
{
buffer.append("Connection: close\r\n"); buffer.append("Connection: close\r\n");
} } else if (version_ == Version::kHttp10) {
else if (version_ == Version::kHttp10)
{
buffer.append("Connection: Keep-Alive\r\n"); buffer.append("Connection: Keep-Alive\r\n");
} }
} }
buffer.append(contentTypeString_.data(), contentTypeString_.length()); buffer.append(contentTypeString_.data(), contentTypeString_.length());
if (HttpAppFrameworkImpl::instance().sendServerHeader())
{
buffer.append( if (Application::get_instance()->sendServerHeader()) {
HttpAppFrameworkImpl::instance().getServerHeaderString()); buffer.append(Application::get_instance()->getServerHeaderString());
} }
} }
for (auto it = headers_.begin(); it != headers_.end(); ++it) for (auto it = headers_.begin(); it != headers_.end(); ++it) {
{
buffer.append(it->first); buffer.append(it->first);
buffer.append(": "); buffer.append(": ");
buffer.append(it->second); buffer.append(it->second);
buffer.append("\r\n"); buffer.append("\r\n");
} }
} }
void HttpResponse::renderToBuffer(trantor::MsgBuffer &buffer) void HttpResponse::renderToBuffer(trantor::MsgBuffer &buffer) {
{ if (expriedTime_ >= 0) {
if (expriedTime_ >= 0)
{
auto strPtr = renderToBuffer(); auto strPtr = renderToBuffer();
buffer.append(strPtr->peek(), strPtr->readableBytes()); buffer.append(strPtr->peek(), strPtr->readableBytes());
return; return;
} }
if (!fullHeaderString_) if (!fullHeaderString_) {
{
makeHeaderString(buffer); makeHeaderString(buffer);
} } else {
else
{
buffer.append(*fullHeaderString_); buffer.append(*fullHeaderString_);
} }
// output cookies // output cookies
if (cookies_.size() > 0) if (cookies_.size() > 0) {
{ for (auto it = cookies_.begin(); it != cookies_.end(); ++it) {
for (auto it = cookies_.begin(); it != cookies_.end(); ++it)
{
buffer.append(it->second.cookieString()); buffer.append(it->second.cookieString());
} }
} }
// output Date header // output Date header
if (!passThrough_ && if (!passThrough_ && Application::get_instance()->sendDateHeader()) {
drogon::HttpAppFrameworkImpl::instance().sendDateHeader())
{
buffer.append("Date: "); buffer.append("Date: ");
buffer.append(utils::getHttpFullDate(trantor::Date::date()), buffer.append(utils::getHttpFullDate(trantor::Date::date()),
httpFullDateStringLength); httpFullDateStringLength);
buffer.append("\r\n\r\n"); buffer.append("\r\n\r\n");
} } else {
else
{
buffer.append("\r\n"); buffer.append("\r\n");
} }
if (bodyPtr_) if (bodyPtr_)
buffer.append(bodyPtr_->data(), bodyPtr_->length()); buffer.append(bodyPtr_->data(), bodyPtr_->length());
} }
std::shared_ptr<trantor::MsgBuffer> HttpResponse::renderToBuffer() std::shared_ptr<trantor::MsgBuffer> HttpResponse::renderToBuffer() {
{ if (expriedTime_ >= 0) {
if (expriedTime_ >= 0) if (!passThrough_ && Application::get_instance()->sendDateHeader()) {
{ if (datePos_ != static_cast<size_t>(-1)) {
if (!passThrough_ &&
drogon::HttpAppFrameworkImpl::instance().sendDateHeader())
{
if (datePos_ != static_cast<size_t>(-1))
{
auto now = trantor::Date::now(); auto now = trantor::Date::now();
bool isDateChanged = bool isDateChanged =
((now.microSecondsSinceEpoch() / MICRO_SECONDS_PRE_SEC) != ((now.microSecondsSinceEpoch() / MICRO_SECONDS_PRE_SEC) !=
httpStringDate_); httpStringDate_);
assert(httpString_); assert(httpString_);
if (isDateChanged) if (isDateChanged) {
{
httpStringDate_ = httpStringDate_ =
now.microSecondsSinceEpoch() / MICRO_SECONDS_PRE_SEC; now.microSecondsSinceEpoch() / MICRO_SECONDS_PRE_SEC;
auto newDate = utils::getHttpFullDate(now); auto newDate = utils::getHttpFullDate(now);
@ -402,45 +351,35 @@ std::shared_ptr<trantor::MsgBuffer> HttpResponse::renderToBuffer()
return httpString_; return httpString_;
} }
} } else {
else
{
if (httpString_) if (httpString_)
return httpString_; return httpString_;
} }
} }
auto httpString = std::make_shared<trantor::MsgBuffer>(256); auto httpString = std::make_shared<trantor::MsgBuffer>(256);
if (!fullHeaderString_) if (!fullHeaderString_) {
{
makeHeaderString(*httpString); makeHeaderString(*httpString);
} } else {
else
{
httpString->append(*fullHeaderString_); httpString->append(*fullHeaderString_);
} }
// output cookies // output cookies
if (cookies_.size() > 0) if (cookies_.size() > 0) {
{ for (auto it = cookies_.begin(); it != cookies_.end(); ++it) {
for (auto it = cookies_.begin(); it != cookies_.end(); ++it)
{
httpString->append(it->second.cookieString()); httpString->append(it->second.cookieString());
} }
} }
// output Date header // output Date header
if (!passThrough_ && if (!passThrough_ &&
drogon::HttpAppFrameworkImpl::instance().sendDateHeader()) Application::get_instance()->sendDateHeader()) {
{
httpString->append("Date: "); httpString->append("Date: ");
auto datePos = httpString->readableBytes(); auto datePos = httpString->readableBytes();
httpString->append(utils::getHttpFullDate(trantor::Date::date()), httpString->append(utils::getHttpFullDate(trantor::Date::date()),
httpFullDateStringLength); httpFullDateStringLength);
httpString->append("\r\n\r\n"); httpString->append("\r\n\r\n");
datePos_ = datePos; datePos_ = datePos;
} } else {
else
{
httpString->append("\r\n"); httpString->append("\r\n");
} }
@ -448,46 +387,36 @@ std::shared_ptr<trantor::MsgBuffer> HttpResponse::renderToBuffer()
<< string_view{ httpString->peek(), httpString->readableBytes() }; << string_view{ httpString->peek(), httpString->readableBytes() };
if (bodyPtr_) if (bodyPtr_)
httpString->append(bodyPtr_->data(), bodyPtr_->length()); httpString->append(bodyPtr_->data(), bodyPtr_->length());
if (expriedTime_ >= 0) if (expriedTime_ >= 0) {
{
httpString_ = httpString; httpString_ = httpString;
} }
return httpString; return httpString;
} }
std::shared_ptr<trantor::MsgBuffer> HttpResponse:: std::shared_ptr<trantor::MsgBuffer> HttpResponse::
renderHeaderForHeadMethod() renderHeaderForHeadMethod() {
{
auto httpString = std::make_shared<trantor::MsgBuffer>(256); auto httpString = std::make_shared<trantor::MsgBuffer>(256);
if (!fullHeaderString_) if (!fullHeaderString_) {
{
makeHeaderString(*httpString); makeHeaderString(*httpString);
} } else {
else
{
httpString->append(*fullHeaderString_); httpString->append(*fullHeaderString_);
} }
// output cookies // output cookies
if (cookies_.size() > 0) if (cookies_.size() > 0) {
{ for (auto it = cookies_.begin(); it != cookies_.end(); ++it) {
for (auto it = cookies_.begin(); it != cookies_.end(); ++it)
{
httpString->append(it->second.cookieString()); httpString->append(it->second.cookieString());
} }
} }
// output Date header // output Date header
if (!passThrough_ && if (!passThrough_ &&
drogon::HttpAppFrameworkImpl::instance().sendDateHeader()) Application::get_instance()->sendDateHeader()) {
{
httpString->append("Date: "); httpString->append("Date: ");
httpString->append(utils::getHttpFullDate(trantor::Date::date()), httpString->append(utils::getHttpFullDate(trantor::Date::date()),
httpFullDateStringLength); httpFullDateStringLength);
httpString->append("\r\n\r\n"); httpString->append("\r\n\r\n");
} } else {
else
{
httpString->append("\r\n"); httpString->append("\r\n");
} }
@ -496,36 +425,30 @@ std::shared_ptr<trantor::MsgBuffer> HttpResponse::
void HttpResponse::addHeader(const char *start, void HttpResponse::addHeader(const char *start,
const char *colon, const char *colon,
const char *end) const char *end) {
{
fullHeaderString_.reset(); fullHeaderString_.reset();
std::string field(start, colon); std::string field(start, colon);
transform(field.begin(), field.end(), field.begin(), ::tolower); transform(field.begin(), field.end(), field.begin(), ::tolower);
++colon; ++colon;
while (colon < end && isspace(*colon)) while (colon < end && isspace(*colon)) {
{
++colon; ++colon;
} }
std::string value(colon, end); std::string value(colon, end);
while (!value.empty() && isspace(value[value.size() - 1])) while (!value.empty() && isspace(value[value.size() - 1])) {
{
value.resize(value.size() - 1); value.resize(value.size() - 1);
} }
if (field == "set-cookie") if (field == "set-cookie") {
{
// LOG_INFO<<"cookies!!!:"<<value; // LOG_INFO<<"cookies!!!:"<<value;
auto values = utils::splitString(value, ";"); auto values = utils::splitString(value, ";");
Cookie cookie; Cookie cookie;
cookie.setHttpOnly(false); cookie.setHttpOnly(false);
for (size_t i = 0; i < values.size(); ++i) for (size_t i = 0; i < values.size(); ++i) {
{
std::string &coo = values[i]; std::string &coo = values[i];
std::string cookie_name; std::string cookie_name;
std::string cookie_value; std::string cookie_value;
auto epos = coo.find('='); auto epos = coo.find('=');
if (epos != std::string::npos) if (epos != std::string::npos) {
{
cookie_name = coo.substr(0, epos); cookie_name = coo.substr(0, epos);
std::string::size_type cpos = 0; std::string::size_type cpos = 0;
while (cpos < cookie_name.length() && while (cpos < cookie_name.length() &&
@ -536,60 +459,42 @@ void HttpResponse::addHeader(const char *start,
while (epos < coo.length() && isspace(coo[epos])) while (epos < coo.length() && isspace(coo[epos]))
++epos; ++epos;
cookie_value = coo.substr(epos); cookie_value = coo.substr(epos);
} } else {
else
{
std::string::size_type cpos = 0; std::string::size_type cpos = 0;
while (cpos < coo.length() && isspace(coo[cpos])) while (cpos < coo.length() && isspace(coo[cpos]))
++cpos; ++cpos;
cookie_name = coo.substr(cpos); cookie_name = coo.substr(cpos);
} }
if (i == 0) if (i == 0) {
{
cookie.setKey(cookie_name); cookie.setKey(cookie_name);
cookie.setValue(cookie_value); cookie.setValue(cookie_value);
} } else {
else
{
std::transform(cookie_name.begin(), std::transform(cookie_name.begin(),
cookie_name.end(), cookie_name.end(),
cookie_name.begin(), cookie_name.begin(),
tolower); tolower);
if (cookie_name == "path") if (cookie_name == "path") {
{
cookie.setPath(cookie_value); cookie.setPath(cookie_value);
} } else if (cookie_name == "domain") {
else if (cookie_name == "domain")
{
cookie.setDomain(cookie_value); cookie.setDomain(cookie_value);
} } else if (cookie_name == "expires") {
else if (cookie_name == "expires")
{
cookie.setExpiresDate(utils::getHttpDate(cookie_value)); cookie.setExpiresDate(utils::getHttpDate(cookie_value));
} } else if (cookie_name == "secure") {
else if (cookie_name == "secure")
{
cookie.setSecure(true); cookie.setSecure(true);
} } else if (cookie_name == "httponly") {
else if (cookie_name == "httponly")
{
cookie.setHttpOnly(true); cookie.setHttpOnly(true);
} }
} }
} }
if (!cookie.key().empty()) if (!cookie.key().empty()) {
{
cookies_[cookie.key()] = cookie; cookies_[cookie.key()] = cookie;
} }
} } else {
else
{
headers_[std::move(field)] = std::move(value); headers_[std::move(field)] = std::move(value);
} }
} }
void HttpResponse::swap(HttpResponse &that) noexcept void HttpResponse::swap(HttpResponse &that) noexcept {
{
using std::swap; using std::swap;
headers_.swap(that.headers_); headers_.swap(that.headers_);
cookies_.swap(that.cookies_); cookies_.swap(that.cookies_);
@ -609,8 +514,7 @@ void HttpResponse::swap(HttpResponse &that) noexcept
swap(jsonParsingErrorPtr_, that.jsonParsingErrorPtr_); swap(jsonParsingErrorPtr_, that.jsonParsingErrorPtr_);
} }
void HttpResponse::clear() void HttpResponse::clear() {
{
statusCode_ = kUnknown; statusCode_ = kUnknown;
version_ = Version::kHttp11; version_ = Version::kHttp11;
statusMessage_ = string_view{}; statusMessage_ = string_view{};
@ -627,50 +531,40 @@ void HttpResponse::clear()
flagForParsingJson_ = false; flagForParsingJson_ = false;
} }
void HttpResponse::parseJson() const void HttpResponse::parseJson() const {
{
static std::once_flag once; static std::once_flag once;
static Json::CharReaderBuilder builder; static Json::CharReaderBuilder builder;
std::call_once(once, []() { builder["collectComments"] = false; }); std::call_once(once, []() { builder["collectComments"] = false; });
JSONCPP_STRING errs; JSONCPP_STRING errs;
std::unique_ptr<Json::CharReader> reader(builder.newCharReader()); std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
if (bodyPtr_) if (bodyPtr_) {
{
jsonPtr_ = std::make_shared<Json::Value>(); jsonPtr_ = std::make_shared<Json::Value>();
if (!reader->parse(bodyPtr_->data(), if (!reader->parse(bodyPtr_->data(),
bodyPtr_->data() + bodyPtr_->length(), bodyPtr_->data() + bodyPtr_->length(),
jsonPtr_.get(), jsonPtr_.get(),
&errs)) &errs)) {
{
LOG_ERROR << errs; LOG_ERROR << errs;
LOG_ERROR << "body: " << bodyPtr_->getString(); LOG_ERROR << "body: " << bodyPtr_->getString();
jsonPtr_.reset(); jsonPtr_.reset();
jsonParsingErrorPtr_ = jsonParsingErrorPtr_ =
std::make_shared<std::string>(std::move(errs)); std::make_shared<std::string>(std::move(errs));
} } else {
else
{
jsonParsingErrorPtr_.reset(); jsonParsingErrorPtr_.reset();
} }
} } else {
else
{
jsonPtr_.reset(); jsonPtr_.reset();
jsonParsingErrorPtr_ = jsonParsingErrorPtr_ =
std::make_shared<std::string>("empty response body"); std::make_shared<std::string>("empty response body");
} }
} }
HttpResponse::~HttpResponse() HttpResponse::~HttpResponse() {
{
} }
bool HttpResponse::shouldBeCompressed() const bool HttpResponse::shouldBeCompressed() const {
{
if (!sendfileName_.empty() || if (!sendfileName_.empty() ||
contentType() >= CT_APPLICATION_OCTET_STREAM || contentType() >= CT_APPLICATION_OCTET_STREAM ||
getBody().length() < 1024 || !(getHeaderBy("content-encoding").empty())) getBody().length() < 1024 || !(getHeaderBy("content-encoding").empty())) {
{
return false; return false;
} }
return true; return true;

View File

@ -22,7 +22,6 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include "core/http_utils.h" #include "core/http_utils.h"
#include "http_message_body.h" #include "http_message_body.h"
@ -38,12 +37,12 @@
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
namespace drogon { namespace drogon {
/// Abstract class for webapp developer to get or set the Http response; /// Abstract class for webapp developer to get or set the Http response;
class HttpResponse; class HttpResponse;
using HttpResponsePtr = std::shared_ptr<HttpResponse>; using HttpResponsePtr = std::shared_ptr<HttpResponse>;
/** /**
* @brief This template is used to convert a response object to a custom * @brief This template is used to convert a response object to a custom
* type object. Users must specialize the template for a particular type. * type object. Users must specialize the template for a particular type.
@ -78,6 +77,7 @@ inline HttpResponsePtr toResponse<Json::Value &>(Json::Value &pJson) {
class HttpResponse { class HttpResponse {
friend class HttpResponseParser; friend class HttpResponseParser;
public: public:
/** /**
* @brief This template enables automatic type conversion. For using this * @brief This template enables automatic type conversion. For using this
@ -162,7 +162,6 @@ public:
flagForParsingContentType_ = true; flagForParsingContentType_ = true;
} }
/// Set the response content type and the content-type string, The string /// Set the response content type and the content-type string, The string
/// must contain the header name and CRLF. /// must contain the header name and CRLF.
/// For example, "content-type: text/plain\r\n" /// For example, "content-type: text/plain\r\n"
@ -183,6 +182,15 @@ public:
/// virtual void setContentTypeCodeAndCharacterSet(ContentType type, const /// virtual void setContentTypeCodeAndCharacterSet(ContentType type, const
/// std::string &charSet = "utf-8") = 0; /// 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. /// Get the response content type.
virtual ContentType contentType() const { virtual ContentType contentType() const {
if (!flagForParsingContentType_) { if (!flagForParsingContentType_) {
@ -208,17 +216,6 @@ public:
return contentType(); 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. /// Get the header string identified by the key parameter.
/** /**
* @note * @note
@ -236,7 +233,6 @@ public:
return getHeaderBy(key); return getHeaderBy(key);
} }
/// Remove the header identified by the key parameter. /// 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; auto field = key;
@ -254,7 +250,6 @@ public:
headers_.erase(lowerKey); headers_.erase(lowerKey);
} }
/// Get all headers of the response /// Get all headers of the response
virtual const std::unordered_map<std::string, std::string> &headers() virtual const std::unordered_map<std::string, std::string> &headers()
const { const {
@ -384,7 +379,6 @@ public:
} }
} }
/// Get the expiration time of the response. /// Get the expiration time of the response.
virtual ssize_t expiredTime() const { virtual ssize_t expiredTime() const {
return expriedTime_; return expriedTime_;
@ -409,7 +403,6 @@ public:
return jsonObject(); return jsonObject();
} }
void setJsonObject(const Json::Value &pJson) { void setJsonObject(const Json::Value &pJson) {
flagForParsingJson_ = true; flagForParsingJson_ = true;
flagForSerializingJson_ = false; flagForSerializingJson_ = false;
@ -454,8 +447,6 @@ public:
} }
#endif #endif
/** /**
* @brief Get the error message of parsing the JSON body received from peer. * @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 * This method usually is called after getting a empty shared_ptr object
@ -484,7 +475,6 @@ public:
passThrough_ = flag; passThrough_ = flag;
} }
void redirect(const std::string &url) { void redirect(const std::string &url) {
headers_["location"] = url; headers_["location"] = url;
} }
@ -493,7 +483,6 @@ public:
void renderToBuffer(trantor::MsgBuffer &buffer); void renderToBuffer(trantor::MsgBuffer &buffer);
std::shared_ptr<trantor::MsgBuffer> renderHeaderForHeadMethod(); std::shared_ptr<trantor::MsgBuffer> renderHeaderForHeadMethod();
/* The following methods are a series of factory methods that help users /* The following methods are a series of factory methods that help users
* create response objects. */ * create response objects. */
@ -564,7 +553,6 @@ public:
virtual ~HttpResponse(); virtual ~HttpResponse();
// virtual void setContentTypeCodeAndCharacterSet(ContentType type, const // virtual void setContentTypeCodeAndCharacterSet(ContentType type, const
// std::string &charSet = "utf-8") // std::string &charSet = "utf-8")
// { // {
@ -572,9 +560,8 @@ public:
// setContentType(webContentTypeAndCharsetToString(type, charSet)); // setContentType(webContentTypeAndCharsetToString(type, charSet));
// } // }
void swap(HttpResponse &that) noexcept; void swap(HttpResponse &that) noexcept;
protected: protected:
void makeHeaderString(trantor::MsgBuffer &headerString); void makeHeaderString(trantor::MsgBuffer &headerString);
@ -597,7 +584,6 @@ private:
return 0; return 0;
} }
void parseJson() const; void parseJson() const;
virtual void setContentTypeCodeAndCustomString( virtual void setContentTypeCodeAndCustomString(
@ -609,7 +595,6 @@ private:
setContentType(string_view{ typeString, typeStringLength }); setContentType(string_view{ typeString, typeStringLength });
} }
std::unordered_map<std::string, std::string> headers_; std::unordered_map<std::string, std::string> headers_;
std::unordered_map<std::string, Cookie> cookies_; std::unordered_map<std::string, Cookie> cookies_;
@ -643,7 +628,6 @@ private:
void setStatusMessage(const string_view &message) { void setStatusMessage(const string_view &message) {
statusMessage_ = message; statusMessage_ = message;
} }
}; };
template <> template <>

View File

@ -15,7 +15,7 @@ void HTTPServer::http_callback_handler(Request *request) {
Application::handle_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 *request = RequestPool::get_request();
request->http_parser = &httpParser; request->http_parser = &httpParser;
@ -30,7 +30,7 @@ void HTTPServer::httpEnterCallbackDefault(const HTTPParser &httpParser, const Ht
http_callback_handler(request); 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 << "frame enter of type:" << int(opcode) << std::endl;
std::cout << "payload is:" << payload << std::endl; std::cout << "payload is:" << payload << std::endl;
@ -51,7 +51,7 @@ void HTTPServer::initialize_old() {
configure_old(); configure_old();
service = TcpService::Create(); service = brynet::net::TcpService::Create();
service->startWorkerThread(threads); service->startWorkerThread(threads);
int p_port = port; int p_port = port;
@ -60,22 +60,22 @@ void HTTPServer::initialize_old() {
if (listenBuilder) if (listenBuilder)
delete listenBuilder; delete listenBuilder;
listenBuilder = new wrapper::HttpListenerBuilder(); listenBuilder = new brynet::net::wrapper::HttpListenerBuilder();
listenBuilder->configureService(service); listenBuilder->configureService(service);
listenBuilder->configureSocketOptions({ listenBuilder->configureSocketOptions({
[](TcpSocket &socket) { [](brynet::net::TcpSocket &socket) {
socket.setNodelay(); 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); 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.setHttpCallback(HTTPServer::httpEnterCallbackDefault);
handlers.setWSCallback(HTTPServer::wsEnterCallbackDefault); handlers.setWSCallback(HTTPServer::wsEnterCallbackDefault);
}); });
@ -203,13 +203,14 @@ void HTTPServer::main_loop() {
*/ */
// Create all listeners. // Create all listeners.
/*
auto ioLoops = listenerManagerPtr_->createListeners( auto ioLoops = listenerManagerPtr_->createListeners(
std::bind(&HttpAppFrameworkImpl::onAsyncRequest, this, _1, _2), std::bind(&Application::onAsyncRequest, this, _1, _2),
std::bind(&HttpAppFrameworkImpl::onNewWebsockRequest, this, _1, _2, _3), std::bind(&Application::onNewWebsockRequest, this, _1, _2, _3),
std::bind(&HttpAppFrameworkImpl::onConnection, this, _1), std::bind(&Application::onConnection, this, _1),
idleConnectionTimeout_, Application::get_instance()->idleConnectionTimeout_,
sslCertPath_, Application::get_instance()->sslCertPath_,
sslKeyPath_, Application::get_instance()->sslKeyPath_,
threads, threads,
syncAdvices_); syncAdvices_);
@ -221,11 +222,11 @@ void HTTPServer::main_loop() {
getLoop()->setIndex(threads); getLoop()->setIndex(threads);
*/
// A fast database client instance should be created in the main event // A fast database client instance should be created in the main event
// loop, so put the main loop into ioLoops. // loop, so put the main loop into ioLoops.
ioLoops.push_back(getLoop()); //ioLoops.push_back(getLoop());
/* /*
dbClientManagerPtr_->createDbClients(ioLoops); dbClientManagerPtr_->createDbClients(ioLoops);
@ -235,7 +236,8 @@ void HTTPServer::main_loop() {
websockCtrlsRouterPtr_->init(); websockCtrlsRouterPtr_->init();
*/ */
getLoop()->queueInLoop([this]() { /*
get_loop()->queueInLoop([this]() {
// Let listener event loops run when everything is ready. // Let listener event loops run when everything is ready.
listenerManagerPtr_->startListening(); listenerManagerPtr_->startListening();
@ -245,14 +247,8 @@ void HTTPServer::main_loop() {
beginningAdvices_.clear(); beginningAdvices_.clear();
}); });
*/
getLoop()->loop(); get_loop()->loop();
}
trantor::EventLoop *HttpAppFrameworkImpl::get_loop() const
{
static trantor::EventLoop loop;
return &loop;
} }
HTTPServer::HTTPServer() { HTTPServer::HTTPServer() {

View File

@ -16,12 +16,14 @@
#include <trantor/net/callbacks.h> #include <trantor/net/callbacks.h>
#include <trantor/utils/NonCopyable.h> #include <trantor/utils/NonCopyable.h>
#include "core/http_server_callbacks.h"
#include "core/http_request_parser.h" #include "core/http_request_parser.h"
#include "core/http_server_callbacks.h"
using namespace brynet; //using namespace brynet;
using namespace brynet::net; //using namespace brynet::net;
using namespace brynet::net::http; //using namespace brynet::net::http;
using namespace drogon;
class Request; class Request;
@ -29,13 +31,13 @@ class HTTPServer {
public: public:
int port; int port;
int threads; int threads;
std::shared_ptr<TcpService> service; std::shared_ptr<brynet::net::TcpService> service;
wrapper::HttpListenerBuilder *listenBuilder; brynet::net::wrapper::HttpListenerBuilder *listenBuilder;
static void http_callback_handler(Request *response); static void http_callback_handler(Request *response);
static void httpEnterCallbackDefault(const HTTPParser &httpParser, const HttpSession::Ptr &session); static void httpEnterCallbackDefault(const brynet::net::http::HTTPParser &httpParser, const brynet::net::http::HttpSession::Ptr &session);
static void wsEnterCallbackDefault(const HttpSession::Ptr &httpSession, WebSocketFormat::WebSocketFrameType opcode, const std::string &payload); 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 configure_old();
virtual void initialize_old(); virtual void initialize_old();
@ -47,7 +49,7 @@ public:
void main_loop(); void main_loop();
trantor::EventLoop *getLoop() const { trantor::EventLoop *get_loop() const {
return server_.getLoop(); return server_.getLoop();
} }
@ -102,6 +104,7 @@ protected:
WebSocketNewAsyncCallback newWebsocketCallback_; WebSocketNewAsyncCallback newWebsocketCallback_;
trantor::ConnectionCallback connectionCallback_; trantor::ConnectionCallback connectionCallback_;
const std::vector<std::function<HttpResponsePtr(const HttpRequestPtr &)> > &syncAdvices_; const std::vector<std::function<HttpResponsePtr(const HttpRequestPtr &)> > &syncAdvices_;
bool _running{ false };
}; };
#endif #endif

View File

@ -5,6 +5,8 @@
#include <memory> #include <memory>
namespace drogon {
class HttpRequest; class HttpRequest;
using HttpRequestPtr = std::shared_ptr<HttpRequest>; using HttpRequestPtr = std::shared_ptr<HttpRequest>;
class HttpResponse; class HttpResponse;
@ -16,4 +18,6 @@ using HttpAsyncCallback = std::function<void(const HttpRequestPtr &,std::functio
using WebSocketNewAsyncCallback = std::function<void(const HttpRequestPtr &, std::function<void(const HttpResponsePtr &)> &&, using WebSocketNewAsyncCallback = std::function<void(const HttpRequestPtr &, std::function<void(const HttpResponsePtr &)> &&,
const WebSocketConnectionPtr &)>; const WebSocketConnectionPtr &)>;
}
#endif #endif

View File

@ -21,6 +21,8 @@
#include <limits> #include <limits>
#include <functional> #include <functional>
#include "core/application.h"
namespace drogon namespace drogon
{ {
/** /**
@ -68,7 +70,7 @@ class IOThreadStorage : public trantor::NonCopyable
{ {
static_assert(std::is_constructible<C, Args &&...>::value, static_assert(std::is_constructible<C, Args &&...>::value,
"Unable to construct storage with given signature"); "Unable to construct storage with given signature");
size_t numThreads = app().getThreadNum(); size_t numThreads = Application::get_instance()->threadNum_;
#ifdef _WIN32 #ifdef _WIN32
assert(numThreads > 0 && numThreads != size_t(-1)); assert(numThreads > 0 && numThreads != size_t(-1));
#else #else
@ -100,14 +102,14 @@ class IOThreadStorage : public trantor::NonCopyable
*/ */
inline ValueType &getThreadData() inline ValueType &getThreadData()
{ {
size_t idx = app().getCurrentThreadIndex(); size_t idx = Application::get_instance()->getCurrentThreadIndex();
assert(idx < storage_.size()); assert(idx < storage_.size());
return storage_[idx]; return storage_[idx];
} }
inline const ValueType &getThreadData() const inline const ValueType &getThreadData() const
{ {
size_t idx = app().getCurrentThreadIndex(); size_t idx = Application::get_instance()->getCurrentThreadIndex();
assert(idx < storage_.size()); assert(idx < storage_.size());
return storage_[idx]; return storage_[idx];
} }
@ -119,21 +121,21 @@ class IOThreadStorage : public trantor::NonCopyable
*/ */
inline void setThreadData(const ValueType &newData) inline void setThreadData(const ValueType &newData)
{ {
size_t idx = app().getCurrentThreadIndex(); size_t idx = Application::get_instance()->getCurrentThreadIndex();
assert(idx < storage_.size()); assert(idx < storage_.size());
storage_[idx] = newData; storage_[idx] = newData;
} }
inline void setThreadData(ValueType &&newData) inline void setThreadData(ValueType &&newData)
{ {
size_t idx = app().getCurrentThreadIndex(); size_t idx = Application::get_instance()->getCurrentThreadIndex();
assert(idx < storage_.size()); assert(idx < storage_.size());
storage_[idx] = std::move(newData); storage_[idx] = std::move(newData);
} }
inline ValueType *operator->() inline ValueType *operator->()
{ {
size_t idx = app().getCurrentThreadIndex(); size_t idx = Application::get_instance()->getCurrentThreadIndex();
assert(idx < storage_.size()); assert(idx < storage_.size());
return &storage_[idx]; return &storage_[idx];
} }
@ -145,7 +147,7 @@ class IOThreadStorage : public trantor::NonCopyable
inline const ValueType *operator->() const inline const ValueType *operator->() const
{ {
size_t idx = app().getCurrentThreadIndex(); size_t idx = Application::get_instance()->getCurrentThreadIndex();
assert(idx < storage_.size()); assert(idx < storage_.size());
return &storage_[idx]; return &storage_[idx];
} }

View File

@ -19,6 +19,8 @@
#include <sys/types.h> #include <sys/types.h>
#include <trantor/utils/Logger.h> #include <trantor/utils/Logger.h>
#include "core/application.h"
#ifndef _WIN32 #ifndef _WIN32
#include <sys/file.h> #include <sys/file.h>
#include <sys/wait.h> #include <sys/wait.h>
@ -83,7 +85,7 @@ std::vector<trantor::EventLoop *> ListenerManager::createListeners(
if (i == 0) { if (i == 0) {
DrogonFileLocker lock; DrogonFileLocker lock;
// Check whether the port is in use. // Check whether the port is in use.
TcpServer server(HttpAppFrameworkImpl::instance().getLoop(), TcpServer server(Application::get_instance()->get_loop(),
InetAddress(ip, listener.port_, isIpv6), InetAddress(ip, listener.port_, isIpv6),
"drogonPortTest", "drogonPortTest",
true, true,
@ -118,12 +120,13 @@ std::vector<trantor::EventLoop *> ListenerManager::createListeners(
serverPtr->enableSSL(cert, key); serverPtr->enableSSL(cert, key);
#endif #endif
} }
/*
serverPtr->setHttpAsyncCallback(httpCallback); serverPtr->setHttpAsyncCallback(httpCallback);
serverPtr->setNewWebsocketCallback(webSocketCallback); serverPtr->setNewWebsocketCallback(webSocketCallback);
serverPtr->setConnectionCallback(connectionCallback); serverPtr->setConnectionCallback(connectionCallback);
serverPtr->kickoffIdleConnections(connectionTimeout); serverPtr->kickoffIdleConnections(connectionTimeout);
serverPtr->start(); serverPtr->start();
*/
servers_.push_back(serverPtr); servers_.push_back(serverPtr);
} }
} }
@ -207,7 +210,7 @@ trantor::EventLoop *ListenerManager::getIOLoop(size_t id) const {
void ListenerManager::stopListening() { void ListenerManager::stopListening() {
for (auto &serverPtr : servers_) { for (auto &serverPtr : servers_) {
serverPtr->stop(); //serverPtr->stop();
} }
for (auto loop : ioLoops_) { for (auto loop : ioLoops_) {

View File

@ -51,7 +51,7 @@ void Request::send() {
std::string result = response->getResult(); 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(); }); (*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"); response->addHeadValue("Connection", "Close");
std::string result = "HTTP/1.1 200 OK\r\nConnection: Close\r\n\r\n"; 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(); }); (*session)->send(result.c_str(), result.size(), [this]() { this->_progress_send_file(); });
} }
@ -99,7 +99,7 @@ void Request::reset() {
if (response) if (response)
delete response; delete response;
response = new HttpResponse(); response = new brynet::net::http::HttpResponse();
} }
void Request::setup_url_stack() { void Request::setup_url_stack() {
@ -186,7 +186,7 @@ Request::~Request() {
} }
void Request::_progress_send_file() { void Request::_progress_send_file() {
const HttpSession::Ptr lsession = (*session); const brynet::net::http::HttpSession::Ptr lsession = (*session);
if (current_file_progress >= file_size) { if (current_file_progress >= file_size) {
lsession->postShutdown(); lsession->postShutdown();

View File

@ -12,7 +12,7 @@
* *
*/ */
#include <core/Utilities.h> #include <core/utilities.h>
#include <trantor/utils/Logger.h> #include <trantor/utils/Logger.h>
#ifdef OpenSSL_FOUND #ifdef OpenSSL_FOUND

View File

@ -6,9 +6,10 @@ env.core_sources = []
#env.add_source_files(env.core_sources, "*.cpp") #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/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/AsyncFileLogger.cc")
env.core_sources.append("./trantor/utils/ConcurrentTaskQueue.cc") env.core_sources.append("./trantor/utils/ConcurrentTaskQueue.cc")

View File

@ -50,6 +50,7 @@ class TcpServer : NonCopyable
const std::string &name, const std::string &name,
bool reUseAddr = true, bool reUseAddr = true,
bool reUsePort = true); bool reUsePort = true);
TcpServer() {}
~TcpServer(); ~TcpServer();
/** /**