summaryrefslogtreecommitdiffstats
path: root/library/cpp/actors/http/http.cpp
diff options
context:
space:
mode:
authorAlexey Efimov <[email protected]>2022-05-04 10:13:58 +0300
committerAlexey Efimov <[email protected]>2022-05-04 10:13:58 +0300
commit6faf680f58ba8341a694dcbadf572d37197ae888 (patch)
treee5fd053607e59e6db7bdec1ea100f46e149a6f97 /library/cpp/actors/http/http.cpp
parentb4c4f96bf4475170a9ac5e4568cc7b05789986c8 (diff)
add async monitoring http KIKIMR-14742
ref:c51d608f0ae78f08597b88f837491da33a953ef6
Diffstat (limited to 'library/cpp/actors/http/http.cpp')
-rw-r--r--library/cpp/actors/http/http.cpp61
1 files changed, 55 insertions, 6 deletions
diff --git a/library/cpp/actors/http/http.cpp b/library/cpp/actors/http/http.cpp
index 7125f9d8b04..3d07c870ced 100644
--- a/library/cpp/actors/http/http.cpp
+++ b/library/cpp/actors/http/http.cpp
@@ -63,6 +63,14 @@ void THttpRequest::Clear() {
}
template <>
+bool THttpParser<THttpRequest, TSocketBuffer>::HaveBody() const {
+ if (!Body.empty()) {
+ return true;
+ }
+ return (!ContentType.empty() || !ContentLength.empty() || !TransferEncoding.empty());
+}
+
+template <>
void THttpParser<THttpRequest, TSocketBuffer>::Advance(size_t len) {
TStringBuf data(Pos(), len);
while (!data.empty()) {
@@ -98,7 +106,6 @@ void THttpParser<THttpRequest, TSocketBuffer>::Advance(size_t len) {
case EParseStage::Header: {
if (ProcessData(Header, data, "\r\n", MaxHeaderSize)) {
if (Header.empty()) {
- Headers = TStringBuf(Headers.data(), data.begin() - Headers.begin());
if (HaveBody()) {
Stage = EParseStage::Body;
} else {
@@ -107,6 +114,7 @@ void THttpParser<THttpRequest, TSocketBuffer>::Advance(size_t len) {
} else {
ProcessHeader(Header);
}
+ Headers = TStringBuf(Headers.data(), data.data() - Headers.data());
}
break;
}
@@ -116,8 +124,13 @@ void THttpParser<THttpRequest, TSocketBuffer>::Advance(size_t len) {
Body = Content;
Stage = EParseStage::Done;
}
- } else if (TransferEncoding == "chunked") {
+ } else if (TEqNoCase()(TransferEncoding, "chunked")) {
Stage = EParseStage::ChunkLength;
+ } else if (TotalSize.has_value()) {
+ if (ProcessData(Content, data, GetBodySizeFromTotalSize())) {
+ Body = Content;
+ Stage = EParseStage::Done;
+ }
} else {
// Invalid body encoding
Stage = EParseStage::Error;
@@ -189,6 +202,15 @@ THttpParser<THttpRequest, TSocketBuffer>::EParseStage THttpParser<THttpRequest,
}
template <>
+bool THttpParser<THttpResponse, TSocketBuffer>::HaveBody() const {
+ if (!Body.empty()) {
+ return true;
+ }
+ return (!Status.starts_with("1") && Status != "204" && Status != "304")
+ && (!ContentType.empty() || !ContentLength.empty() || !TransferEncoding.empty());
+}
+
+template <>
THttpParser<THttpResponse, TSocketBuffer>::EParseStage THttpParser<THttpResponse, TSocketBuffer>::GetInitialStage() {
return EParseStage::Protocol;
}
@@ -237,6 +259,8 @@ void THttpParser<THttpResponse, TSocketBuffer>::Advance(size_t len) {
if (Header.empty()) {
if (HaveBody() && (ContentLength.empty() || ContentLength != "0")) {
Stage = EParseStage::Body;
+ } else if (TotalSize.has_value() && !data.empty()) {
+ Stage = EParseStage::Body;
} else {
Stage = EParseStage::Done;
}
@@ -252,8 +276,13 @@ void THttpParser<THttpResponse, TSocketBuffer>::Advance(size_t len) {
if (ProcessData(Body, data, FromString(ContentLength))) {
Stage = EParseStage::Done;
}
- } else if (TransferEncoding == "chunked") {
+ } else if (TEqNoCase()(TransferEncoding, "chunked")) {
Stage = EParseStage::ChunkLength;
+ } else if (TotalSize.has_value()) {
+ if (ProcessData(Content, data, GetBodySizeFromTotalSize())) {
+ Body = Content;
+ Stage = EParseStage::Done;
+ }
} else {
// Invalid body encoding
Stage = EParseStage::Error;
@@ -333,9 +362,19 @@ void THttpParser<THttpResponse, TSocketBuffer>::ConnectionClosed() {
}
THttpOutgoingResponsePtr THttpIncomingRequest::CreateResponseString(TStringBuf data) {
+ THttpParser<THttpResponse, TSocketBuffer> parser(data);
+ THeadersBuilder headers(parser.Headers);
+ if (!WorkerName.empty()) {
+ headers.Set("X-Worker-Name", WorkerName);
+ }
THttpOutgoingResponsePtr response = new THttpOutgoingResponse(this);
- response->Append(data);
- response->Reparse();
+ response->InitResponse(parser.Protocol, parser.Version, parser.Status, parser.Message);
+ response->Set(headers);
+ if (parser.HaveBody()) {
+ response->SetBody(parser.Body);
+ } else {
+ response->Set<&THttpResponse::ContentLength>("0");
+ }
return response;
}
@@ -601,11 +640,17 @@ void TCookiesBuilder::Set(TStringBuf name, TStringBuf data) {
}
THeaders::THeaders(TStringBuf headers) {
+ Parse(headers);
+}
+
+size_t THeaders::Parse(TStringBuf headers) {
+ auto start = headers.begin();
for (TStringBuf param = headers.NextTok("\r\n"); !param.empty(); param = headers.NextTok("\r\n")) {
TStringBuf name = param.NextTok(":");
param.SkipPrefix(" ");
Headers[name] = param;
}
+ return headers.begin() - start;
}
TStringBuf THeaders::operator [](TStringBuf name) const {
@@ -636,7 +681,11 @@ TString THeaders::Render() const {
}
THeadersBuilder::THeadersBuilder()
- :THeaders(TStringBuf())
+ : THeaders(TStringBuf())
+{}
+
+THeadersBuilder::THeadersBuilder(TStringBuf headers)
+ : THeaders(headers)
{}
THeadersBuilder::THeadersBuilder(const THeadersBuilder& builder) {