diff --git a/lib/src/HttpResponseImpl.cc b/lib/src/HttpResponseImpl.cc index 01201aae..77401fef 100755 --- a/lib/src/HttpResponseImpl.cc +++ b/lib/src/HttpResponseImpl.cc @@ -20,6 +20,7 @@ #include #include #include +#include using namespace trantor; using namespace drogon; @@ -307,13 +308,14 @@ std::string HttpResponseImpl::web_response_code_to_string(int code) return "Undefined Error"; } } -void HttpResponseImpl::makeHeaderString(MsgBuffer *output) const +void HttpResponseImpl::makeHeaderString(const std::shared_ptr &headerStringPtr) const { char buf[64]; + assert(headerStringPtr); snprintf(buf, sizeof buf, "HTTP/1.1 %d ", _statusCode); - output->append(buf); - output->append(_statusMessage); - output->append("\r\n"); + headerStringPtr->append(buf); + headerStringPtr->append(_statusMessage); + headerStringPtr->append("\r\n"); if (_sendfileName.empty()) { snprintf(buf, sizeof buf, "Content-Length: %lu\r\n", static_cast(_bodyPtr->size())); @@ -329,12 +331,12 @@ void HttpResponseImpl::makeHeaderString(MsgBuffer *output) const snprintf(buf, sizeof buf, "Content-Length: %llu\r\n", static_cast(filestat.st_size)); } - output->append(buf); + headerStringPtr->append(buf); if (_headers.find("Connection") == _headers.end()) { if (_closeConnection) { - output->append("Connection: close\r\n"); + headerStringPtr->append("Connection: close\r\n"); } else { @@ -347,18 +349,18 @@ void HttpResponseImpl::makeHeaderString(MsgBuffer *output) const it != _headers.end(); ++it) { - output->append(it->first); - output->append(": "); - output->append(it->second); - output->append("\r\n"); + headerStringPtr->append(it->first); + headerStringPtr->append(": "); + headerStringPtr->append(it->second); + headerStringPtr->append("\r\n"); } - output->append("Server: drogon/"); - output->append(drogon::getVersion()); - output->append("\r\n"); + headerStringPtr->append("Server: drogon/"); + headerStringPtr->append(drogon::getVersion()); + headerStringPtr->append("\r\n"); } -void HttpResponseImpl::appendToBuffer(MsgBuffer *output) const +std::shared_ptr HttpResponseImpl::renderToString() const { if (_expriedTime >= 0) { @@ -366,24 +368,25 @@ void HttpResponseImpl::appendToBuffer(MsgBuffer *output) const { bool isDateChanged = false; auto newDate = getHttpFullDate(trantor::Date::now(), &isDateChanged); - { + { std::lock_guard lock(*_httpStringMutex); if (isDateChanged) { + _httpString = std::make_shared(*_httpString); memcpy(_httpString->data() + _datePos, newDate, strlen(newDate)); } - output->append(*_httpString); } - return; + return _httpString; } } + auto httpString = std::make_shared(); if (!_fullHeaderString) { - makeHeaderString(output); + makeHeaderString(httpString); } else { - output->append(*_fullHeaderString); + httpString->append(*_fullHeaderString); } //output cookies @@ -392,22 +395,23 @@ void HttpResponseImpl::appendToBuffer(MsgBuffer *output) const for (auto it = _cookies.begin(); it != _cookies.end(); it++) { - output->append(it->second.cookieString()); + httpString->append(it->second.cookieString()); } } //output Date header - output->append("Date: "); - auto datePos = output->readableBytes(); - output->append(getHttpFullDate(trantor::Date::date())); - output->append("\r\n\r\n"); + httpString->append("Date: "); + auto datePos = httpString->length(); + httpString->append(getHttpFullDate(trantor::Date::date())); + httpString->append("\r\n\r\n"); - LOG_TRACE << "reponse(no body):" << output->peek(); - output->append(*_bodyPtr); + LOG_TRACE << "reponse(no body):" << httpString->c_str(); + httpString->append(*_bodyPtr); if (_expriedTime >= 0) { std::lock_guard lock(*_httpStringMutex); _datePos = datePos; - _httpString = std::make_shared(output->peek(), output->readableBytes()); + _httpString = httpString; } + return httpString; } diff --git a/lib/src/HttpResponseImpl.h b/lib/src/HttpResponseImpl.h index f569cce0..1036c1cb 100755 --- a/lib/src/HttpResponseImpl.h +++ b/lib/src/HttpResponseImpl.h @@ -207,7 +207,7 @@ class HttpResponseImpl : public HttpResponse { _headers["Location"] = url; } - void appendToBuffer(MsgBuffer *output) const; + std::shared_ptr renderToString() const; virtual void clear() override { @@ -292,9 +292,8 @@ class HttpResponseImpl : public HttpResponse } void makeHeaderString() { - trantor::MsgBuffer buf; - makeHeaderString(&buf); - _fullHeaderString = std::make_shared(buf.peek(), buf.readableBytes()); + _fullHeaderString = std::make_shared(); + makeHeaderString(_fullHeaderString); } protected: @@ -304,7 +303,7 @@ class HttpResponseImpl : public HttpResponse static std::string web_response_code_to_string(int code); - void makeHeaderString(MsgBuffer *output) const; + void makeHeaderString(const std::shared_ptr &headerStringPtr) const; private: std::map _headers; diff --git a/lib/src/HttpServer.cc b/lib/src/HttpServer.cc index b50b43b3..699dbcc3 100755 --- a/lib/src/HttpServer.cc +++ b/lib/src/HttpServer.cc @@ -120,15 +120,16 @@ void HttpServer::onMessage(const TcpConnectionPtr &conn, if (context->firstReq() && isWebSocket(conn, context->request())) { auto wsConn = std::make_shared(conn); - newWebsocketCallback_(context->request(), [=](const HttpResponsePtr &resp) mutable { - if (resp->statusCode() == HttpResponse::k101SwitchingProtocols) - { - context->setWebsockConnection(wsConn); - } - MsgBuffer buffer; - std::dynamic_pointer_cast(resp)->appendToBuffer(&buffer); - conn->send(std::move(buffer)); - }, + newWebsocketCallback_(context->request(), + [=](const HttpResponsePtr &resp) mutable { + if (resp->statusCode() == HttpResponse::k101SwitchingProtocols) + { + context->setWebsockConnection(wsConn); + } + MsgBuffer buffer; + auto httpString = std::dynamic_pointer_cast(resp)->renderToString(); + conn->send(httpString); + }, wsConn); } else @@ -252,8 +253,8 @@ void HttpServer::sendResponse(const TcpConnectionPtr &conn, const HttpResponsePtr &response) { MsgBuffer buf; - std::dynamic_pointer_cast(response)->appendToBuffer(&buf); - conn->send(std::move(buf)); + auto httpString = std::dynamic_pointer_cast(response)->renderToString(); + conn->send(httpString); auto &sendfileName = std::dynamic_pointer_cast(response)->sendfileName(); if (!sendfileName.empty()) { diff --git a/lib/src/HttpServerContext.cc b/lib/src/HttpServerContext.cc index fca87569..3ee88956 100755 --- a/lib/src/HttpServerContext.cc +++ b/lib/src/HttpServerContext.cc @@ -129,10 +129,8 @@ bool HttpServerContext::parseRequest(MsgBuffer *buf) { auto resp = HttpResponse::newHttpResponse(); resp->setStatusCode(HttpResponse::k100Continue); - MsgBuffer buffer; - std::dynamic_pointer_cast(resp) - ->appendToBuffer(&buffer); - connPtr->send(std::move(buffer)); + auto httpString = std::dynamic_pointer_cast(resp)->renderToString(); + connPtr->send(httpString); } } else if (!expect.empty()) @@ -144,9 +142,8 @@ bool HttpServerContext::parseRequest(MsgBuffer *buf) auto resp = HttpResponse::newHttpResponse(); resp->setStatusCode(HttpResponse::k417ExpectationFailed); MsgBuffer buffer; - std::dynamic_pointer_cast(resp) - ->appendToBuffer(&buffer); - connPtr->send(std::move(buffer)); + auto httpString = std::dynamic_pointer_cast(resp)->renderToString(); + connPtr->send(httpString); buf->retrieveAll(); connPtr->forceClose(); diff --git a/trantor b/trantor index 088af9a4..69f6ece8 160000 --- a/trantor +++ b/trantor @@ -1 +1 @@ -Subproject commit 088af9a4d5351d7e027894836c3f93ff2b7191f5 +Subproject commit 69f6ece8d83b251842d633aa7a2fb3a6bd6ba2e5