diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/http/server/http_ex.cpp | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/http/server/http_ex.cpp')
-rw-r--r-- | library/cpp/http/server/http_ex.cpp | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/library/cpp/http/server/http_ex.cpp b/library/cpp/http/server/http_ex.cpp new file mode 100644 index 0000000000..e07db22bfc --- /dev/null +++ b/library/cpp/http/server/http_ex.cpp @@ -0,0 +1,107 @@ +#include "http_ex.h" + +#include <util/generic/buffer.h> +#include <util/generic/cast.h> +#include <util/stream/null.h> + +bool THttpClientRequestExtension::Parse(char* req, TBaseServerRequestData& rd) { + rd.SetSocket(Socket()); + + if (!rd.Parse(req)) { + Output() << "HTTP/1.1 403 Forbidden\r\n" + "Content-Type: text/plain\r\n" + "Content-Length: 39\r\n" + "\r\n" + "The server cannot be used as a proxy.\r\n"; + + return false; + } + + return true; +} + +bool THttpClientRequestExtension::ProcessHeaders(TBaseServerRequestData& rd, TBlob& postData) { + for (const auto& header : ParsedHeaders) { + rd.AddHeader(header.first, header.second); + } + + char* s = RequestString.begin(); + + enum EMethod { + NotImplemented, + Get, + Post, + Put, + Patch, + Delete, + }; + + enum EMethod foundMethod; + char* urlStart; + + if (strnicmp(s, "GET ", 4) == 0) { + foundMethod = Get; + urlStart = s + 4; + } else if (strnicmp(s, "POST ", 5) == 0) { + foundMethod = Post; + urlStart = s + 5; + } else if (strnicmp(s, "PUT ", 4) == 0) { + foundMethod = Put; + urlStart = s + 4; + } else if (strnicmp(s, "PATCH ", 6) == 0) { + foundMethod = Patch; + urlStart = s + 6; + } else if (strnicmp(s, "DELETE ", 7) == 0) { + foundMethod = Delete; + urlStart = s + 7; + } else { + foundMethod = NotImplemented; + } + + switch (foundMethod) { + case Get: + case Delete: + if (!Parse(urlStart, rd)) { + return false; + } + break; + + case Post: + case Put: + case Patch: + try { + ui64 contentLength = 0; + if (Input().HasExpect100Continue()) { + Output().SendContinue(); + } + + if (!Input().ContentEncoded() && Input().GetContentLength(contentLength)) { + if (contentLength > HttpServ()->Options().MaxInputContentLength) { + Output() << "HTTP/1.1 413 Payload Too Large\r\nContent-Length:0\r\n\r\n"; + Output().Finish(); + return false; + } + + TBuffer buf(SafeIntegerCast<size_t>(contentLength)); + buf.Resize(Input().Load(buf.Data(), (size_t)contentLength)); + postData = TBlob::FromBuffer(buf); + } else { + postData = TBlob::FromStream(Input()); + } + } catch (...) { + Output() << "HTTP/1.1 400 Bad request\r\n\r\n"; + return false; + } + + if (!Parse(urlStart, rd)) { + return false; + } + break; + + case NotImplemented: + Output() << "HTTP/1.1 501 Not Implemented\r\n\r\n"; + return false; + } + + return true; +} |