Skip to content

Commit ac0a1b8

Browse files
authored
Fix a bug after removing content-length header in some responses (#2176)
1 parent 912f1d8 commit ac0a1b8

3 files changed

Lines changed: 31 additions & 15 deletions

File tree

lib/src/HttpResponseImpl.cc

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,18 @@ void HttpResponseImpl::makeHeaderString(trantor::MsgBuffer &buffer)
526526
if (!passThrough_)
527527
{
528528
buffer.ensureWritableBytes(64);
529-
if (streamCallback_ || asyncStreamCallback_)
529+
if (!contentLengthIsAllowed())
530+
{
531+
len = 0;
532+
if ((bodyPtr_ && bodyPtr_->length() > 0) ||
533+
!sendfileName_.empty() || streamCallback_ ||
534+
asyncStreamCallback_)
535+
{
536+
LOG_ERROR << "The body should be empty when the content-length "
537+
"is not allowed!";
538+
}
539+
}
540+
else if (streamCallback_ || asyncStreamCallback_)
530541
{
531542
// When the headers are created, it is time to set the transfer
532543
// encoding to chunked if the contents size is not specified
@@ -538,15 +549,15 @@ void HttpResponseImpl::makeHeaderString(trantor::MsgBuffer &buffer)
538549
}
539550
len = 0;
540551
}
541-
else if (sendfileName_.empty() && contentLengthIsAllowed())
552+
else if (sendfileName_.empty())
542553
{
543554
auto bodyLength = bodyPtr_ ? bodyPtr_->length() : 0;
544555
len = snprintf(buffer.beginWrite(),
545556
buffer.writableBytes(),
546557
contentLengthFormatString<decltype(bodyLength)>(),
547558
bodyLength);
548559
}
549-
else if (contentLengthIsAllowed())
560+
else
550561
{
551562
auto bodyLength = sendfileRange_.second;
552563
len = snprintf(buffer.beginWrite(),
@@ -629,7 +640,7 @@ void HttpResponseImpl::renderToBuffer(trantor::MsgBuffer &buffer)
629640
{
630641
buffer.append("\r\n");
631642
}
632-
if (bodyPtr_)
643+
if (bodyPtr_ && contentLengthIsAllowed())
633644
buffer.append(bodyPtr_->data(), bodyPtr_->length());
634645
}
635646

@@ -958,7 +969,8 @@ bool HttpResponseImpl::shouldBeCompressed() const
958969
{
959970
if (streamCallback_ || asyncStreamCallback_ || !sendfileName_.empty() ||
960971
contentType() >= CT_APPLICATION_OCTET_STREAM ||
961-
getBody().length() < 1024 || !(getHeaderBy("content-encoding").empty()))
972+
getBody().length() < 1024 ||
973+
!(getHeaderBy("content-encoding").empty()) || !contentLengthIsAllowed())
962974
{
963975
return false;
964976
}

lib/src/HttpResponseImpl.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,16 @@ class DROGON_EXPORT HttpResponseImpl : public HttpResponse
402402
addHeader("content-length", std::to_string(bodyPtr_->length()));
403403
}
404404
}
405+
406+
bool contentLengthIsAllowed() const
407+
{
408+
int statusCode =
409+
customStatusCode_ >= 0 ? customStatusCode_ : statusCode_;
410+
411+
// return false if status code is 1xx or 204
412+
return (statusCode >= k200OK || statusCode < k100Continue) &&
413+
statusCode != k204NoContent;
414+
}
405415
#ifdef USE_BROTLI
406416
void brDecompress()
407417
{
@@ -537,16 +547,6 @@ class DROGON_EXPORT HttpResponseImpl : public HttpResponse
537547
{
538548
statusMessage_ = message;
539549
}
540-
541-
bool contentLengthIsAllowed()
542-
{
543-
int statusCode =
544-
customStatusCode_ >= 0 ? customStatusCode_ : statusCode_;
545-
546-
// return false if status code is 1xx or 204
547-
return (statusCode >= k200OK || statusCode < k100Continue) &&
548-
statusCode != k204NoContent;
549-
}
550550
};
551551

552552
using HttpResponseImplPtr = std::shared_ptr<HttpResponseImpl>;

lib/src/HttpServer.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -966,6 +966,8 @@ void HttpServer::sendResponse(const TcpConnectionPtr &conn,
966966
{
967967
auto httpString = respImplPtr->renderToBuffer();
968968
conn->send(httpString);
969+
if (!respImplPtr->contentLengthIsAllowed())
970+
return;
969971
auto &asyncStreamCallback = respImplPtr->asyncStreamCallback();
970972
if (asyncStreamCallback)
971973
{
@@ -1046,6 +1048,8 @@ void HttpServer::sendResponses(
10461048
{
10471049
// Not HEAD method
10481050
respImplPtr->renderToBuffer(buffer);
1051+
if (!respImplPtr->contentLengthIsAllowed())
1052+
continue;
10491053
auto &asyncStreamCallback = respImplPtr->asyncStreamCallback();
10501054
if (asyncStreamCallback)
10511055
{

0 commit comments

Comments
 (0)