aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorarcadia-devtools <arcadia-devtools@yandex-team.ru>2022-05-05 17:03:26 +0300
committerarcadia-devtools <arcadia-devtools@yandex-team.ru>2022-05-05 17:03:26 +0300
commitb94ffc4f9fb0de2cccb10069715302687b494c34 (patch)
tree0a992a17f01285d3976b78bd57be64a3691e9a59
parentf8831bfbf91cd9e5f400dbc59372651bf756d87a (diff)
downloadydb-b94ffc4f9fb0de2cccb10069715302687b494c34.tar.gz
intermediate changes
ref:670915a6a4cf5edb3a63ce999d592acd20f1f248
-rw-r--r--build/rules/autocheck.blacklist2
-rw-r--r--library/cpp/actors/http/CMakeLists.txt1
-rw-r--r--library/cpp/actors/http/http.cpp2
-rw-r--r--library/cpp/actors/http/http.h99
-rw-r--r--library/cpp/actors/http/http_compress.cpp42
-rw-r--r--library/cpp/actors/http/http_ut.cpp14
6 files changed, 125 insertions, 35 deletions
diff --git a/build/rules/autocheck.blacklist b/build/rules/autocheck.blacklist
index 0b3fde6b40e..7f811535479 100644
--- a/build/rules/autocheck.blacklist
+++ b/build/rules/autocheck.blacklist
@@ -1416,3 +1416,5 @@ admins/icecream/node-icecream
adv/pcode/mobileadssdk/sdk/ios/library
admins/icecream/agent
trunk/arcadia/crm/space/frontend_static
+crm/space/frontend_static
+samsara/samsara-poll
diff --git a/library/cpp/actors/http/CMakeLists.txt b/library/cpp/actors/http/CMakeLists.txt
index 5f8197e3c6c..166af4cec53 100644
--- a/library/cpp/actors/http/CMakeLists.txt
+++ b/library/cpp/actors/http/CMakeLists.txt
@@ -21,6 +21,7 @@ target_link_libraries(cpp-actors-http PUBLIC
)
target_sources(cpp-actors-http PRIVATE
${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_cache.cpp
+ ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_compress.cpp
${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_proxy_acceptor.cpp
${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_proxy_incoming.cpp
${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_proxy_outgoing.cpp
diff --git a/library/cpp/actors/http/http.cpp b/library/cpp/actors/http/http.cpp
index 3d07c870ced..09381d0fb3e 100644
--- a/library/cpp/actors/http/http.cpp
+++ b/library/cpp/actors/http/http.cpp
@@ -30,6 +30,7 @@ template <> TStringBuf THttpRequest::GetName<&THttpRequest::Connection>() { retu
template <> TStringBuf THttpRequest::GetName<&THttpRequest::ContentType>() { return "Content-Type"; }
template <> TStringBuf THttpRequest::GetName<&THttpRequest::ContentLength>() { return "Content-Length"; }
template <> TStringBuf THttpRequest::GetName<&THttpRequest::TransferEncoding>() { return "Transfer-Encoding"; }
+template <> TStringBuf THttpRequest::GetName<&THttpRequest::AcceptEncoding>() { return "Accept-Encoding"; }
const TMap<TStringBuf, TStringBuf THttpRequest::*, TLessNoCase> THttpRequest::HeadersLocation = {
{ THttpRequest::GetName<&THttpRequest::Host>(), &THttpRequest::Host },
@@ -38,6 +39,7 @@ const TMap<TStringBuf, TStringBuf THttpRequest::*, TLessNoCase> THttpRequest::He
{ THttpRequest::GetName<&THttpRequest::ContentType>(), &THttpRequest::ContentType },
{ THttpRequest::GetName<&THttpRequest::ContentLength>(), &THttpRequest::ContentLength },
{ THttpRequest::GetName<&THttpRequest::TransferEncoding>(), &THttpRequest::TransferEncoding },
+ { THttpRequest::GetName<&THttpRequest::AcceptEncoding>(), &THttpRequest::AcceptEncoding },
};
template <> TStringBuf THttpResponse::GetName<&THttpResponse::Connection>() { return "Connection"; }
diff --git a/library/cpp/actors/http/http.h b/library/cpp/actors/http/http.h
index 3e5e39e7194..6d51cf589c2 100644
--- a/library/cpp/actors/http/http.h
+++ b/library/cpp/actors/http/http.h
@@ -130,6 +130,7 @@ public:
TStringBuf Connection;
TStringBuf ContentType;
TStringBuf ContentLength;
+ TStringBuf AcceptEncoding;
TStringBuf TransferEncoding;
TStringBuf Body;
@@ -200,7 +201,7 @@ public:
TStringBuf& Header = Line;
size_t ChunkLength = 0;
size_t ContentSize = 0;
- TString Content;
+ TString Content; // body storage
std::optional<size_t> TotalSize;
THttpParser(const THttpParser& src)
@@ -436,6 +437,36 @@ public:
ERenderStage Stage = ERenderStage::Init;
+ //THttpRenderer(TStringBuf method, TStringBuf url, TStringBuf protocol, TStringBuf version); // request
+ void InitRequest(TStringBuf method, TStringBuf url, TStringBuf protocol, TStringBuf version) {
+ Y_VERIFY_DEBUG(Stage == ERenderStage::Init);
+ AppendParsedValue<&THttpRequest::Method>(method);
+ Append(' ');
+ AppendParsedValue<&THttpRequest::URL>(url);
+ Append(' ');
+ AppendParsedValue<&THttpRequest::Protocol>(protocol);
+ Append('/');
+ AppendParsedValue<&THttpRequest::Version>(version);
+ Append("\r\n");
+ Stage = ERenderStage::Header;
+ HeaderType::Headers = TStringBuf(BufferType::Pos(), size_t(0));
+ }
+
+ //THttpRenderer(TStringBuf protocol, TStringBuf version, TStringBuf status, TStringBuf message); // response
+ void InitResponse(TStringBuf protocol, TStringBuf version, TStringBuf status, TStringBuf message) {
+ Y_VERIFY_DEBUG(Stage == ERenderStage::Init);
+ AppendParsedValue<&THttpResponse::Protocol>(protocol);
+ Append('/');
+ AppendParsedValue<&THttpResponse::Version>(version);
+ Append(' ');
+ AppendParsedValue<&THttpResponse::Status>(status);
+ Append(' ');
+ AppendParsedValue<&THttpResponse::Message>(message);
+ Append("\r\n");
+ Stage = ERenderStage::Header;
+ HeaderType::Headers = TStringBuf(BufferType::Pos(), size_t(0));
+ }
+
void Append(TStringBuf text) {
EnsureEnoughSpaceAvailable(text.size());
BufferType::Append(text.data(), text.size());
@@ -484,34 +515,13 @@ public:
HeaderType::Headers = TStringBuf(HeaderType::Headers.Data(), BufferType::Pos() - HeaderType::Headers.Data());
}
- //THttpRenderer(TStringBuf method, TStringBuf url, TStringBuf protocol, TStringBuf version); // request
- void InitRequest(TStringBuf method, TStringBuf url, TStringBuf protocol, TStringBuf version) {
- Y_VERIFY_DEBUG(Stage == ERenderStage::Init);
- AppendParsedValue<&THttpRequest::Method>(method);
- Append(' ');
- AppendParsedValue<&THttpRequest::URL>(url);
- Append(' ');
- AppendParsedValue<&THttpRequest::Protocol>(protocol);
- Append('/');
- AppendParsedValue<&THttpRequest::Version>(version);
- Append("\r\n");
- Stage = ERenderStage::Header;
- HeaderType::Headers = TStringBuf(BufferType::Pos(), size_t(0));
- }
+ static constexpr TStringBuf ALLOWED_CONTENT_ENCODINGS[] = {"deflate"};
- //THttpRenderer(TStringBuf protocol, TStringBuf version, TStringBuf status, TStringBuf message); // response
- void InitResponse(TStringBuf protocol, TStringBuf version, TStringBuf status, TStringBuf message) {
- Y_VERIFY_DEBUG(Stage == ERenderStage::Init);
- AppendParsedValue<&THttpResponse::Protocol>(protocol);
- Append('/');
- AppendParsedValue<&THttpResponse::Version>(version);
- Append(' ');
- AppendParsedValue<&THttpResponse::Status>(status);
- Append(' ');
- AppendParsedValue<&THttpResponse::Message>(message);
- Append("\r\n");
- Stage = ERenderStage::Header;
- HeaderType::Headers = TStringBuf(BufferType::Pos(), size_t(0));
+ void SetContentEncoding(TStringBuf contentEncoding) {
+ Y_VERIFY_DEBUG(Stage == ERenderStage::Header);
+ if (Count(ALLOWED_CONTENT_ENCODINGS, contentEncoding) != 0) {
+ Set("Content-Encoding", contentEncoding);
+ }
}
void FinishHeader() {
@@ -621,6 +631,12 @@ inline void THttpRenderer<THttpRequest, TSocketBuffer>::Set<&THttpRequest::Body>
SetBody(value);
}
+template <>
+template <>
+inline void THttpRenderer<THttpResponse, TSocketBuffer>::Set<&THttpResponse::ContentEncoding>(TStringBuf value) {
+ SetContentEncoding(value);
+}
+
class THttpIncomingRequest;
using THttpIncomingRequestPtr = TIntrusivePtr<THttpIncomingRequest>;
@@ -730,6 +746,33 @@ public:
return GetRequest()->Method != "HEAD" && Status != "204";
}
+ void EnableCompression() {
+ TStringBuf acceptEncoding = Request->AcceptEncoding;
+ std::vector<TStringBuf> encodings;
+ TStringBuf encoding;
+ while (acceptEncoding.NextTok(',', encoding)) {
+ Trim(encoding, ' ');
+ if (Count(ALLOWED_CONTENT_ENCODINGS, encoding) != 0) {
+ encodings.push_back(encoding);
+ }
+ }
+ if (!encodings.empty()) {
+ // TODO: prioritize encodings
+ SetContentEncoding(encodings.front());
+ }
+ }
+
+ static TString CompressDeflate(TStringBuf source);
+
+ void SetBody(TStringBuf body) {
+ if (ContentEncoding == "deflate") {
+ TString compressedBody = CompressDeflate(body);
+ THttpRenderer<THttpResponse, TSocketBuffer>::SetBody(compressedBody);
+ } else {
+ THttpRenderer<THttpResponse, TSocketBuffer>::SetBody(body);
+ }
+ }
+
THttpIncomingRequestPtr GetRequest() const {
return Request;
}
diff --git a/library/cpp/actors/http/http_compress.cpp b/library/cpp/actors/http/http_compress.cpp
new file mode 100644
index 00000000000..33ff3e16746
--- /dev/null
+++ b/library/cpp/actors/http/http_compress.cpp
@@ -0,0 +1,42 @@
+#include "http.h"
+
+#include <contrib/libs/zlib/zlib.h>
+
+namespace NHttp {
+
+TString THttpOutgoingResponse::CompressDeflate(TStringBuf source) {
+ int compressionlevel = Z_BEST_COMPRESSION;
+ z_stream zs = {};
+
+ if (deflateInit(&zs, compressionlevel) != Z_OK) {
+ throw yexception() << "deflateInit failed while compressing";
+ }
+
+ zs.next_in = (Bytef*)source.data();
+ zs.avail_in = source.size();
+
+ int ret;
+ char outbuffer[32768];
+ TString result;
+
+ // retrieve the compressed bytes blockwise
+ do {
+ zs.next_out = reinterpret_cast<Bytef*>(outbuffer);
+ zs.avail_out = sizeof(outbuffer);
+
+ ret = deflate(&zs, Z_FINISH);
+
+ if (result.size() < zs.total_out) {
+ result.append(outbuffer, zs.total_out - result.size());
+ }
+ } while (ret == Z_OK);
+
+ deflateEnd(&zs);
+
+ if (ret != Z_STREAM_END) {
+ throw yexception() << "Exception during zlib compression: (" << ret << ") " << zs.msg;
+ }
+ return result;
+}
+
+}
diff --git a/library/cpp/actors/http/http_ut.cpp b/library/cpp/actors/http/http_ut.cpp
index cdb9025ff17..4ec7761da91 100644
--- a/library/cpp/actors/http/http_ut.cpp
+++ b/library/cpp/actors/http/http_ut.cpp
@@ -96,15 +96,15 @@ Y_UNIT_TEST_SUITE(HttpProxy) {
UNIT_ASSERT_EQUAL(response->Body, "this\r\n is test.");
}
- Y_UNIT_TEST(CreateResponseWithCompressedBody) {
- NHttp::THttpIncomingRequestPtr request = nullptr;
+ Y_UNIT_TEST(CreateCompressedResponse) {
+ NHttp::THttpIncomingRequestPtr request = new NHttp::THttpIncomingRequest();
+ EatWholeString(request, "GET /Url HTTP/1.1\r\nConnection: close\r\nAccept-Encoding: gzip, deflate\r\n\r\n");
NHttp::THttpOutgoingResponsePtr response = new NHttp::THttpOutgoingResponse(request, "HTTP", "1.1", "200", "OK");
- response->Set<&NHttp::THttpResponse::ContentEncoding>("gzip");
- TString compressedBody = "compressed body";
+ TString compressedBody = "something very long to compress with deflate algorithm. something very long to compress with deflate algorithm.";
+ response->EnableCompression();
response->SetBody(compressedBody);
- UNIT_ASSERT_VALUES_EQUAL("gzip", response->ContentEncoding);
- UNIT_ASSERT_VALUES_EQUAL(ToString(compressedBody.size()), response->ContentLength);
- UNIT_ASSERT_VALUES_EQUAL(compressedBody, response->Body);
+ UNIT_ASSERT_VALUES_EQUAL("deflate", response->ContentEncoding);
+ UNIT_ASSERT_VALUES_UNEQUAL(compressedBody, response->Body);
}
Y_UNIT_TEST(BasicPartialParsing) {