summaryrefslogtreecommitdiffstats
path: root/library/cpp/actors/http/http.cpp
diff options
context:
space:
mode:
authorDaniil Cherednik <[email protected]>2022-11-24 13:14:34 +0300
committerDaniil Cherednik <[email protected]>2022-11-24 14:46:00 +0300
commit87f7fceed34bcafb8aaff351dd493a35c916986f (patch)
tree26809ec8f550aba8eb019e59adc3d48e51913eb2 /library/cpp/actors/http/http.cpp
parent11bc4015b8010ae201bf3eb33db7dba425aca35e (diff)
Ydb stable 22-4-4322.4.43
x-stable-origin-commit: 8d49d46cc834835bf3e50870516acd7376a63bcf
Diffstat (limited to 'library/cpp/actors/http/http.cpp')
-rw-r--r--library/cpp/actors/http/http.cpp28
1 files changed, 20 insertions, 8 deletions
diff --git a/library/cpp/actors/http/http.cpp b/library/cpp/actors/http/http.cpp
index 7da6ace0b99..5d0c25fa8ce 100644
--- a/library/cpp/actors/http/http.cpp
+++ b/library/cpp/actors/http/http.cpp
@@ -22,6 +22,10 @@ inline TStringBuf operator +=(TStringBuf& l, TStringBuf r) {
return l = l + r;
}
+static bool is_not_number(TStringBuf v) {
+ return v.empty() || std::find_if_not(v.begin(), v.end(), [](unsigned char c) { return std::isdigit(c); }) != v.end();
+}
+
namespace NHttp {
template <> TStringBuf THttpRequest::GetName<&THttpRequest::Host>() { return "Host"; }
@@ -126,13 +130,16 @@ void THttpParser<THttpRequest, TSocketBuffer>::Advance(size_t len) {
[[fallthrough]];
}
case EParseStage::Body: {
- if (!ContentLength.empty()) {
- if (ProcessData(Content, data, FromString(ContentLength))) {
+ if (TEqNoCase()(TransferEncoding, "chunked")) {
+ Stage = EParseStage::ChunkLength;
+ } else if (!ContentLength.empty()) {
+ if (is_not_number(ContentLength)) {
+ // Invalid content length
+ Stage = EParseStage::Error;
+ } else if (ProcessData(Content, data, FromStringWithDefault(ContentLength, 0))) {
Body = Content;
Stage = EParseStage::Done;
}
- } else if (TEqNoCase()(TransferEncoding, "chunked")) {
- Stage = EParseStage::ChunkLength;
} else if (TotalSize.has_value()) {
if (ProcessData(Content, data, GetBodySizeFromTotalSize())) {
Body = Content;
@@ -282,16 +289,19 @@ void THttpParser<THttpResponse, TSocketBuffer>::Advance(size_t len) {
[[fallthrough]];
}
case EParseStage::Body: {
- if (!ContentLength.empty()) {
- if (ProcessData(Body, data, FromString(ContentLength))) {
+ if (TEqNoCase()(TransferEncoding, "chunked")) {
+ Stage = EParseStage::ChunkLength;
+ } else if (!ContentLength.empty()) {
+ if (is_not_number(ContentLength)) {
+ // Invalid content length
+ Stage = EParseStage::Error;
+ } else if (ProcessData(Body, data, FromStringWithDefault(ContentLength, 0))) {
Stage = EParseStage::Done;
if (Body && ContentEncoding == "deflate") {
Content = DecompressDeflate(Body);
Body = Content;
}
}
- } else if (TEqNoCase()(TransferEncoding, "chunked")) {
- Stage = EParseStage::ChunkLength;
} else if (TotalSize.has_value()) {
if (ProcessData(Content, data, GetBodySizeFromTotalSize())) {
Body = Content;
@@ -401,9 +411,11 @@ THttpOutgoingResponsePtr THttpIncomingRequest::CreateResponseString(TStringBuf d
}
}
}
+ headers.Erase("Transfer-Encoding"); // we erase transfer-encoding because we convert body to content-length
response->Set(headers);
response->SetBody(parser.Body);
} else {
+ headers.Erase("Transfer-Encoding"); // we erase transfer-encoding because we convert body to content-length
response->Set(headers);
if (!response->ContentLength) {
response->Set<&THttpResponse::ContentLength>("0");