Fix a bug after removing content-length header in some responses (#2176)

This commit is contained in:
An Tao 2024-10-02 16:42:40 +08:00 committed by GitHub
parent 912f1d803c
commit ac0a1b873e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 31 additions and 15 deletions

View File

@ -526,7 +526,18 @@ void HttpResponseImpl::makeHeaderString(trantor::MsgBuffer &buffer)
if (!passThrough_)
{
buffer.ensureWritableBytes(64);
if (streamCallback_ || asyncStreamCallback_)
if (!contentLengthIsAllowed())
{
len = 0;
if ((bodyPtr_ && bodyPtr_->length() > 0) ||
!sendfileName_.empty() || streamCallback_ ||
asyncStreamCallback_)
{
LOG_ERROR << "The body should be empty when the content-length "
"is not allowed!";
}
}
else if (streamCallback_ || asyncStreamCallback_)
{
// When the headers are created, it is time to set the transfer
// encoding to chunked if the contents size is not specified
@ -538,7 +549,7 @@ void HttpResponseImpl::makeHeaderString(trantor::MsgBuffer &buffer)
}
len = 0;
}
else if (sendfileName_.empty() && contentLengthIsAllowed())
else if (sendfileName_.empty())
{
auto bodyLength = bodyPtr_ ? bodyPtr_->length() : 0;
len = snprintf(buffer.beginWrite(),
@ -546,7 +557,7 @@ void HttpResponseImpl::makeHeaderString(trantor::MsgBuffer &buffer)
contentLengthFormatString<decltype(bodyLength)>(),
bodyLength);
}
else if (contentLengthIsAllowed())
else
{
auto bodyLength = sendfileRange_.second;
len = snprintf(buffer.beginWrite(),
@ -629,7 +640,7 @@ void HttpResponseImpl::renderToBuffer(trantor::MsgBuffer &buffer)
{
buffer.append("\r\n");
}
if (bodyPtr_)
if (bodyPtr_ && contentLengthIsAllowed())
buffer.append(bodyPtr_->data(), bodyPtr_->length());
}
@ -958,7 +969,8 @@ bool HttpResponseImpl::shouldBeCompressed() const
{
if (streamCallback_ || asyncStreamCallback_ || !sendfileName_.empty() ||
contentType() >= CT_APPLICATION_OCTET_STREAM ||
getBody().length() < 1024 || !(getHeaderBy("content-encoding").empty()))
getBody().length() < 1024 ||
!(getHeaderBy("content-encoding").empty()) || !contentLengthIsAllowed())
{
return false;
}

View File

@ -402,6 +402,16 @@ class DROGON_EXPORT HttpResponseImpl : public HttpResponse
addHeader("content-length", std::to_string(bodyPtr_->length()));
}
}
bool contentLengthIsAllowed() const
{
int statusCode =
customStatusCode_ >= 0 ? customStatusCode_ : statusCode_;
// return false if status code is 1xx or 204
return (statusCode >= k200OK || statusCode < k100Continue) &&
statusCode != k204NoContent;
}
#ifdef USE_BROTLI
void brDecompress()
{
@ -537,16 +547,6 @@ class DROGON_EXPORT HttpResponseImpl : public HttpResponse
{
statusMessage_ = message;
}
bool contentLengthIsAllowed()
{
int statusCode =
customStatusCode_ >= 0 ? customStatusCode_ : statusCode_;
// return false if status code is 1xx or 204
return (statusCode >= k200OK || statusCode < k100Continue) &&
statusCode != k204NoContent;
}
};
using HttpResponseImplPtr = std::shared_ptr<HttpResponseImpl>;

View File

@ -966,6 +966,8 @@ void HttpServer::sendResponse(const TcpConnectionPtr &conn,
{
auto httpString = respImplPtr->renderToBuffer();
conn->send(httpString);
if (!respImplPtr->contentLengthIsAllowed())
return;
auto &asyncStreamCallback = respImplPtr->asyncStreamCallback();
if (asyncStreamCallback)
{
@ -1046,6 +1048,8 @@ void HttpServer::sendResponses(
{
// Not HEAD method
respImplPtr->renderToBuffer(buffer);
if (!respImplPtr->contentLengthIsAllowed())
continue;
auto &asyncStreamCallback = respImplPtr->asyncStreamCallback();
if (asyncStreamCallback)
{