Remove content-length header from 101 Switching Protocols response (#2164)

This commit is contained in:
Chad Barth 2024-09-25 04:52:41 -05:00 committed by GitHub
parent c9f5754423
commit b0c5331bc1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 54 additions and 2 deletions

View File

@ -516,6 +516,7 @@ void HttpResponseImpl::makeHeaderString(trantor::MsgBuffer &buffer)
statusCode_);
}
}
buffer.hasWritten(len);
if (!statusMessage_.empty())
@ -537,7 +538,7 @@ void HttpResponseImpl::makeHeaderString(trantor::MsgBuffer &buffer)
}
len = 0;
}
else if (sendfileName_.empty())
else if (sendfileName_.empty() && contentLengthIsAllowed())
{
auto bodyLength = bodyPtr_ ? bodyPtr_->length() : 0;
len = snprintf(buffer.beginWrite(),
@ -545,7 +546,7 @@ void HttpResponseImpl::makeHeaderString(trantor::MsgBuffer &buffer)
contentLengthFormatString<decltype(bodyLength)>(),
bodyLength);
}
else
else if (contentLengthIsAllowed())
{
auto bodyLength = sendfileRange_.second;
len = snprintf(buffer.beginWrite(),

View File

@ -537,6 +537,16 @@ 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

@ -28,6 +28,7 @@ set(UNITTEST_SOURCES
unittests/SlashRemoverTest.cc
unittests/UtilitiesTest.cc
unittests/UuidUnittest.cc
unittests/WebsocketResponseTest.cc
)
if(DROGON_CXX_STANDARD GREATER_EQUAL 20 AND HAS_COROUTINE)

View File

@ -0,0 +1,40 @@
#include <drogon/drogon_test.h>
#include "../../lib/src/HttpRequestImpl.h"
#include "../../lib/src/HttpResponseImpl.h"
#include "../../lib/src/HttpControllerBinder.h"
using namespace drogon;
DROGON_TEST(WebsocketReponseTest)
{
WebsocketControllerBinder binder;
auto reqPtr = std::make_shared<HttpRequestImpl>(nullptr);
// Value from rfc6455-1.3
reqPtr->addHeader("sec-websocket-key", "dGhlIHNhbXBsZSBub25jZQ==");
binder.handleRequest(reqPtr, [&](const HttpResponsePtr &resp) {
CHECK(resp->statusCode() == k101SwitchingProtocols);
CHECK(resp->headers().size() == 3);
CHECK(resp->getHeader("Upgrade") == "websocket");
CHECK(resp->getHeader("Connection") == "Upgrade");
// Value from rfc6455-1.3
CHECK(resp->getHeader("Sec-WebSocket-Accept") ==
"s3pPLMBiTxaQ9kYGzzhZRbK+xOo=");
auto implPtr = std::dynamic_pointer_cast<HttpResponseImpl>(resp);
implPtr->makeHeaderString();
auto buffer = implPtr->renderToBuffer();
auto str = std::string{buffer->peek(), buffer->readableBytes()};
CHECK(str.find("upgrade: websocket") != std::string::npos);
CHECK(str.find("connection: Upgrade") != std::string::npos);
CHECK(str.find("sec-websocket-accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=") !=
std::string::npos);
CHECK(str.find("content-length:") == std::string::npos);
});
}