diff options
author | komels <[email protected]> | 2022-04-15 16:53:39 +0300 |
---|---|---|
committer | komels <[email protected]> | 2022-04-15 16:53:39 +0300 |
commit | 703a2fb6e100d202d1c7fcd052d73bd5affef408 (patch) | |
tree | 22b7320c06bb04d86dbf7b9af9ae44281331cd15 /library/cpp/http | |
parent | 3375bbfda1e2afb03aa2072bf5f2f2c3a26026e8 (diff) |
Move 'kikimr/yndx'-depending tests out of ydb/core
ref:0a380e13308d579e0545a76924330d1ca5129c43
Diffstat (limited to 'library/cpp/http')
-rw-r--r-- | library/cpp/http/simple/.arcignore | 1 | ||||
-rw-r--r-- | library/cpp/http/simple/CMakeLists.txt | 21 | ||||
-rw-r--r-- | library/cpp/http/simple/http_client.cpp | 356 | ||||
-rw-r--r-- | library/cpp/http/simple/http_client.h | 276 | ||||
-rw-r--r-- | library/cpp/http/simple/http_client_options.h | 59 | ||||
-rw-r--r-- | library/cpp/http/simple/ut/http_ut.cpp | 439 | ||||
-rw-r--r-- | library/cpp/http/simple/ut/https_server/http_server.crt | 19 | ||||
-rw-r--r-- | library/cpp/http/simple/ut/https_server/http_server.key | 28 | ||||
-rw-r--r-- | library/cpp/http/simple/ut/https_server/main.go | 70 | ||||
-rw-r--r-- | library/cpp/http/simple/ut/https_ut.cpp | 97 |
10 files changed, 0 insertions, 1366 deletions
diff --git a/library/cpp/http/simple/.arcignore b/library/cpp/http/simple/.arcignore deleted file mode 100644 index 26741320244..00000000000 --- a/library/cpp/http/simple/.arcignore +++ /dev/null @@ -1 +0,0 @@ -*-ut* diff --git a/library/cpp/http/simple/CMakeLists.txt b/library/cpp/http/simple/CMakeLists.txt deleted file mode 100644 index 317a748a895..00000000000 --- a/library/cpp/http/simple/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ - -# This file was gererated by the build system used internally in the Yandex monorepo. -# Only simple modifications are allowed (adding source-files to targets, adding simple properties -# like target_include_directories). These modifications will be ported to original -# ya.make files by maintainers. Any complex modifications which can't be ported back to the -# original buildsystem will not be accepted. - - - -add_library(cpp-http-simple) -target_link_libraries(cpp-http-simple PUBLIC - contrib-libs-cxxsupp - yutil - cpp-http-io - cpp-openssl-io - cpp-string_utils-url - library-cpp-uri -) -target_sources(cpp-http-simple PRIVATE - ${CMAKE_SOURCE_DIR}/library/cpp/http/simple/http_client.cpp -) diff --git a/library/cpp/http/simple/http_client.cpp b/library/cpp/http/simple/http_client.cpp deleted file mode 100644 index 818dc048ad1..00000000000 --- a/library/cpp/http/simple/http_client.cpp +++ /dev/null @@ -1,356 +0,0 @@ -#include "http_client.h" - -#include <library/cpp/string_utils/url/url.h> -#include <library/cpp/uri/http_url.h> - -#include <util/stream/output.h> -#include <util/string/cast.h> -#include <util/string/join.h> -#include <util/string/split.h> - -TKeepAliveHttpClient::TKeepAliveHttpClient(const TString& host, - ui32 port, - TDuration socketTimeout, - TDuration connectTimeout) - : Host(CutHttpPrefix(host)) - , Port(port) - , SocketTimeout(socketTimeout) - , ConnectTimeout(connectTimeout) - , IsHttps(host.StartsWith("https")) - , IsClosingRequired(false) - , HttpsVerification(TVerifyCert{Host}) - , IfResponseRequired([](const THttpInput&) { return true; }) -{ -} - -TKeepAliveHttpClient::THttpCode TKeepAliveHttpClient::DoGet(const TStringBuf relativeUrl, - IOutputStream* output, - const THeaders& headers, - THttpHeaders* outHeaders) { - return DoRequest(TStringBuf("GET"), - relativeUrl, - {}, - output, - headers, - outHeaders); -} - -TKeepAliveHttpClient::THttpCode TKeepAliveHttpClient::DoPost(const TStringBuf relativeUrl, - const TStringBuf body, - IOutputStream* output, - const THeaders& headers, - THttpHeaders* outHeaders) { - return DoRequest(TStringBuf("POST"), - relativeUrl, - body, - output, - headers, - outHeaders); -} - -TKeepAliveHttpClient::THttpCode TKeepAliveHttpClient::DoRequest(const TStringBuf method, - const TStringBuf relativeUrl, - const TStringBuf body, - IOutputStream* output, - const THeaders& inHeaders, - THttpHeaders* outHeaders) { - const TString contentLength = IntToString<10, size_t>(body.size()); - return DoRequestReliable(FormRequest(method, relativeUrl, body, inHeaders, contentLength), output, outHeaders); -} - -TKeepAliveHttpClient::THttpCode TKeepAliveHttpClient::DoRequestRaw(const TStringBuf raw, - IOutputStream* output, - THttpHeaders* outHeaders) { - return DoRequestReliable(raw, output, outHeaders); -} - -void TKeepAliveHttpClient::DisableVerificationForHttps() { - HttpsVerification.Clear(); - Connection.Reset(); -} - -void TKeepAliveHttpClient::SetClientCertificate(const TOpenSslClientIO::TOptions::TClientCert& options) { - ClientCertificate = options; -} - -void TKeepAliveHttpClient::ResetConnection() { - Connection.Reset(); -} - -TVector<IOutputStream::TPart> TKeepAliveHttpClient::FormRequest(TStringBuf method, - const TStringBuf relativeUrl, - TStringBuf body, - const TKeepAliveHttpClient::THeaders& headers, - TStringBuf contentLength) const { - TVector<IOutputStream::TPart> parts; - - parts.reserve(16 + 4 * headers.size()); - parts.push_back(method); - parts.push_back(TStringBuf(" ")); - parts.push_back(relativeUrl); - parts.push_back(TStringBuf(" HTTP/1.1")); - parts.push_back(IOutputStream::TPart::CrLf()); - parts.push_back(TStringBuf("Host: ")); - parts.push_back(TStringBuf(Host)); - parts.push_back(IOutputStream::TPart::CrLf()); - parts.push_back(TStringBuf("Content-Length: ")); - parts.push_back(contentLength); - parts.push_back(IOutputStream::TPart::CrLf()); - - for (const auto& entry : headers) { - parts.push_back(IOutputStream::TPart(entry.first)); - parts.push_back(IOutputStream::TPart(TStringBuf(": "))); - parts.push_back(IOutputStream::TPart(entry.second)); - parts.push_back(IOutputStream::TPart::CrLf()); - } - - parts.push_back(IOutputStream::TPart::CrLf()); - if (body) { - parts.push_back(IOutputStream::TPart(body)); - } - - return parts; -} - -TKeepAliveHttpClient::THttpCode TKeepAliveHttpClient::ReadAndTransferHttp(THttpInput& input, - IOutputStream* output, - THttpHeaders* outHeaders) const { - TKeepAliveHttpClient::THttpCode statusCode; - try { - statusCode = ParseHttpRetCode(input.FirstLine()); - } catch (TFromStringException& e) { - TString rest = input.ReadAll(); - ythrow THttpRequestException() << "Failed parse status code in response of " << Host << ": " << e.what() << " (" << input.FirstLine() << ")" - << "\nFull http response:\n" - << rest; - } - - auto canContainBody = [](auto statusCode) { - return statusCode != HTTP_NOT_MODIFIED && statusCode != HTTP_NO_CONTENT; - }; - - if (output && canContainBody(statusCode) && IfResponseRequired(input)) { - TransferData(&input, output); - } - if (outHeaders) { - *outHeaders = input.Headers(); - } - - return statusCode; -} - -THttpInput* TKeepAliveHttpClient::GetHttpInput() { - return Connection ? Connection->GetHttpInput() : nullptr; -} - -bool TKeepAliveHttpClient::CreateNewConnectionIfNeeded() { - if (IsClosingRequired || (Connection && !Connection->IsOk())) { - Connection.Reset(); - } - if (!Connection) { - Connection = MakeHolder<NPrivate::THttpConnection>(Host, - Port, - SocketTimeout, - ConnectTimeout, - IsHttps, - ClientCertificate, - HttpsVerification); - IsClosingRequired = false; - return true; - } - return false; -} - -THttpRequestException::THttpRequestException(int statusCode) - : StatusCode(statusCode) -{ -} - -int THttpRequestException::GetStatusCode() const { - return StatusCode; -} - -TSimpleHttpClient::TSimpleHttpClient(const TOptions& options) - : Host(options.Host()) - , Port(options.Port()) - , SocketTimeout(options.SocketTimeout()) - , ConnectTimeout(options.ConnectTimeout()) -{ -} - -TSimpleHttpClient::TSimpleHttpClient(const TString& host, ui32 port, TDuration socketTimeout, TDuration connectTimeout) - : Host(host) - , Port(port) - , SocketTimeout(socketTimeout) - , ConnectTimeout(connectTimeout) -{ -} - -void TSimpleHttpClient::EnableVerificationForHttps() { - HttpsVerification = true; -} - -void TSimpleHttpClient::DoGet(const TStringBuf relativeUrl, IOutputStream* output, const THeaders& headers) const { - TKeepAliveHttpClient cl = CreateClient(); - - TKeepAliveHttpClient::THttpCode code = cl.DoGet(relativeUrl, output, headers); - - Y_ENSURE(cl.GetHttpInput()); - ProcessResponse(relativeUrl, *cl.GetHttpInput(), output, code); -} - -void TSimpleHttpClient::DoPost(const TStringBuf relativeUrl, TStringBuf body, IOutputStream* output, const THashMap<TString, TString>& headers) const { - TKeepAliveHttpClient cl = CreateClient(); - - TKeepAliveHttpClient::THttpCode code = cl.DoPost(relativeUrl, body, output, headers); - - Y_ENSURE(cl.GetHttpInput()); - ProcessResponse(relativeUrl, *cl.GetHttpInput(), output, code); -} - -void TSimpleHttpClient::DoPostRaw(const TStringBuf relativeUrl, const TStringBuf rawRequest, IOutputStream* output) const { - TKeepAliveHttpClient cl = CreateClient(); - - TKeepAliveHttpClient::THttpCode code = cl.DoRequestRaw(rawRequest, output); - - Y_ENSURE(cl.GetHttpInput()); - ProcessResponse(relativeUrl, *cl.GetHttpInput(), output, code); -} - -namespace NPrivate { - THttpConnection::THttpConnection(const TString& host, - ui32 port, - TDuration sockTimeout, - TDuration connTimeout, - bool isHttps, - const TMaybe<TOpenSslClientIO::TOptions::TClientCert>& clientCert, - const TMaybe<TOpenSslClientIO::TOptions::TVerifyCert>& verifyCert) - : Addr(Resolve(host, port)) - , Socket(Connect(Addr, sockTimeout, connTimeout, host, port)) - , SocketIn(Socket) - , SocketOut(Socket) - { - if (isHttps) { - TOpenSslClientIO::TOptions opts; - if (clientCert) { - opts.ClientCert_ = clientCert; - } - if (verifyCert) { - opts.VerifyCert_ = verifyCert; - } - - Ssl = MakeHolder<TOpenSslClientIO>(&SocketIn, &SocketOut, opts); - HttpOut = MakeHolder<THttpOutput>(Ssl.Get()); - } else { - HttpOut = MakeHolder<THttpOutput>(&SocketOut); - } - - HttpOut->EnableKeepAlive(true); - } - - TNetworkAddress THttpConnection::Resolve(const TString& host, ui32 port) { - try { - return TNetworkAddress(host, port); - } catch (const yexception& e) { - ythrow THttpRequestException() << "Resolve of " << host << ": " << e.what(); - } - } - - TSocket THttpConnection::Connect(TNetworkAddress& addr, - TDuration sockTimeout, - TDuration connTimeout, - const TString& host, - ui32 port) { - try { - TSocket socket(addr, connTimeout); - TDuration socketTimeout = Max(sockTimeout, TDuration::MilliSeconds(1)); // timeout less than 1ms will be interpreted as 0 in SetSocketTimeout() call below and will result in infinite wait - - ui32 seconds = socketTimeout.Seconds(); - ui32 milliSeconds = (socketTimeout - TDuration::Seconds(seconds)).MilliSeconds(); - socket.SetSocketTimeout(seconds, milliSeconds); - return socket; - } catch (const yexception& e) { - ythrow THttpRequestException() << "Connect to " << host << ':' << port << " failed: " << e.what(); - } - } -} - -void TSimpleHttpClient::ProcessResponse(const TStringBuf relativeUrl, THttpInput& input, IOutputStream*, const unsigned statusCode) const { - if (!(statusCode >= 200 && statusCode < 300)) { - TString rest = input.ReadAll(); - ythrow THttpRequestException(statusCode) << "Got " << statusCode << " at " << Host << relativeUrl << "\nFull http response:\n" - << rest; - } -} - -TSimpleHttpClient::~TSimpleHttpClient() { -} - -TKeepAliveHttpClient TSimpleHttpClient::CreateClient() const { - TKeepAliveHttpClient cl(Host, Port, SocketTimeout, ConnectTimeout); - - if (!HttpsVerification) { - cl.DisableVerificationForHttps(); - } - - PrepareClient(cl); - - return cl; -} - -void TSimpleHttpClient::PrepareClient(TKeepAliveHttpClient&) const { -} - -TRedirectableHttpClient::TRedirectableHttpClient(const TString& host, ui32 port, TDuration socketTimeout, TDuration connectTimeout) - : TSimpleHttpClient(host, port, socketTimeout, connectTimeout) -{ -} - -void TRedirectableHttpClient::PrepareClient(TKeepAliveHttpClient& cl) const { - cl.IfResponseRequired = [](const THttpInput& input) { - return !input.Headers().HasHeader("Location"); - }; -} - -void TRedirectableHttpClient::ProcessResponse(const TStringBuf relativeUrl, THttpInput& input, IOutputStream* output, const unsigned statusCode) const { - for (auto i = input.Headers().Begin(), e = input.Headers().End(); i != e; ++i) { - if (0 == TString::compare(i->Name(), TStringBuf("Location"))) { - TVector<TString> request_url_parts, request_body_parts; - - size_t splitted_index = 0; - for (auto& iter : StringSplitter(i->Value()).Split('/')) { - if (splitted_index < 3) { - request_url_parts.push_back(TString(iter.Token())); - } else { - request_body_parts.push_back(TString(iter.Token())); - } - ++splitted_index; - } - - TString url = JoinSeq("/", request_url_parts); - ui16 port = 443; - - THttpURL u; - if (THttpURL::ParsedOK == u.Parse(url)) { - const char* p = u.Get(THttpURL::FieldPort); - if (p) { - port = FromString<ui16>(p); - url = u.PrintS(THttpURL::FlagScheme | THttpURL::FlagHost); - } - } - - TRedirectableHttpClient cl(url, port, TDuration::Seconds(60), TDuration::Seconds(60)); - if (HttpsVerification) { - cl.EnableVerificationForHttps(); - } - cl.DoGet(TString("/") + JoinSeq("/", request_body_parts), output); - return; - } - } - if (!(statusCode >= 200 && statusCode < 300)) { - TString rest = input.ReadAll(); - ythrow THttpRequestException(statusCode) << "Got " << statusCode << " at " << Host << relativeUrl << "\nFull http response:\n" - << rest; - } - TransferData(&input, output); -} diff --git a/library/cpp/http/simple/http_client.h b/library/cpp/http/simple/http_client.h deleted file mode 100644 index 94ee487202b..00000000000 --- a/library/cpp/http/simple/http_client.h +++ /dev/null @@ -1,276 +0,0 @@ -#pragma once - -#include "http_client_options.h" - -#include <util/datetime/base.h> -#include <util/generic/hash.h> -#include <util/generic/ptr.h> -#include <util/generic/strbuf.h> -#include <util/generic/yexception.h> -#include <util/network/socket.h> - -#include <library/cpp/http/io/stream.h> -#include <library/cpp/http/misc/httpcodes.h> -#include <library/cpp/openssl/io/stream.h> - -class TNetworkAddress; -class IOutputStream; -class TSocket; - -namespace NPrivate { - class THttpConnection; -} - -/*! - * HTTPS is supported in two modes. - * HTTPS verification enabled by default in TKeepAliveHttpClient and disabled by default in TSimpleHttpClient. - * HTTPS verification requires valid private certificate on server side and valid public certificate on client side. - * - * For client: - * Uses builtin certs. - * Also uses default CA path /etc/ssl/certs/ - can be provided with debian package: ca-certificates.deb. - * It can be expanded with ENV: SSL_CERT_DIR. - */ - -/*! - * TKeepAliveHttpClient can keep connection alive with HTTP and HTTPS only if you use the same instance of class. - * It closes connection on every socket/network error and throws error. - * For example, HTTP code == 500 is NOT error - connection will be still open. - * It is THREAD UNSAFE because it stores connection state in attributes. - * If you need thread safe client, look at TSimpleHttpClient - */ - -class TKeepAliveHttpClient { -public: - using THeaders = THashMap<TString, TString>; - using THttpCode = unsigned; - -public: - TKeepAliveHttpClient(const TString& host, - ui32 port, - TDuration socketTimeout = TDuration::Seconds(5), - TDuration connectTimeout = TDuration::Seconds(30)); - - THttpCode DoGet(const TStringBuf relativeUrl, - IOutputStream* output = nullptr, - const THeaders& headers = THeaders(), - THttpHeaders* outHeaders = nullptr); - - // builds post request from headers and body - THttpCode DoPost(const TStringBuf relativeUrl, - const TStringBuf body, - IOutputStream* output = nullptr, - const THeaders& headers = THeaders(), - THttpHeaders* outHeaders = nullptr); - - // builds request with any HTTP method from headers and body - THttpCode DoRequest(const TStringBuf method, - const TStringBuf relativeUrl, - const TStringBuf body, - IOutputStream* output = nullptr, - const THeaders& inHeaders = THeaders(), - THttpHeaders* outHeaders = nullptr); - - // requires already well-formed request - THttpCode DoRequestRaw(const TStringBuf raw, - IOutputStream* output = nullptr, - THttpHeaders* outHeaders = nullptr); - - void DisableVerificationForHttps(); - void SetClientCertificate(const TOpenSslClientIO::TOptions::TClientCert& options); - - void ResetConnection(); - - const TString& GetHost() const { - return Host; - } - - ui32 GetPort() const { - return Port; - } - -private: - template <class T> - THttpCode DoRequestReliable(const T& raw, - IOutputStream* output, - THttpHeaders* outHeaders); - - TVector<IOutputStream::TPart> FormRequest(TStringBuf method, const TStringBuf relativeUrl, - TStringBuf body, - const THeaders& headers, TStringBuf contentLength) const; - - THttpCode ReadAndTransferHttp(THttpInput& input, IOutputStream* output, THttpHeaders* outHeaders) const; - - bool CreateNewConnectionIfNeeded(); // Returns true if now we have a new connection. - -private: - using TVerifyCert = TOpenSslClientIO::TOptions::TVerifyCert; - using TClientCert = TOpenSslClientIO::TOptions::TClientCert; - - const TString Host; - const ui32 Port; - const TDuration SocketTimeout; - const TDuration ConnectTimeout; - const bool IsHttps; - - THolder<NPrivate::THttpConnection> Connection; - bool IsClosingRequired; - TMaybe<TClientCert> ClientCertificate; - TMaybe<TVerifyCert> HttpsVerification; - -private: - THttpInput* GetHttpInput(); - - using TIfResponseRequired = std::function<bool(const THttpInput&)>; - TIfResponseRequired IfResponseRequired; - - friend class TSimpleHttpClient; - friend class TRedirectableHttpClient; -}; - -class THttpRequestException: public yexception { -private: - int StatusCode; - -public: - THttpRequestException(int statusCode = 0); - int GetStatusCode() const; -}; - -/*! - * TSimpleHttpClient can NOT keep connection alive. - * It closes connection after each request. - * HTTP code < 200 || code >= 300 is error - exception will be thrown. - * It is THREAD SAFE because it stores only consts. - */ - -class TSimpleHttpClient { -protected: - using TVerifyCert = TKeepAliveHttpClient::TVerifyCert; - - const TString Host; - const ui32 Port; - const TDuration SocketTimeout; - const TDuration ConnectTimeout; - bool HttpsVerification = false; - -public: - using THeaders = TKeepAliveHttpClient::THeaders; - using TOptions = TSimpleHttpClientOptions; - -public: - explicit TSimpleHttpClient(const TOptions& options); - - TSimpleHttpClient(const TString& host, ui32 port, - TDuration socketTimeout = TDuration::Seconds(5), TDuration connectTimeout = TDuration::Seconds(30)); - - void EnableVerificationForHttps(); - - void DoGet(const TStringBuf relativeUrl, IOutputStream* output, const THeaders& headers = THeaders()) const; - - // builds post request from headers and body - void DoPost(const TStringBuf relativeUrl, TStringBuf body, IOutputStream* output, const THeaders& headers = THeaders()) const; - - // requires already well-formed post request - void DoPostRaw(const TStringBuf relativeUrl, TStringBuf rawRequest, IOutputStream* output) const; - - virtual ~TSimpleHttpClient(); - -private: - TKeepAliveHttpClient CreateClient() const; - - virtual void PrepareClient(TKeepAliveHttpClient& cl) const; - virtual void ProcessResponse(const TStringBuf relativeUrl, THttpInput& input, IOutputStream* output, const unsigned statusCode) const; -}; - -class TRedirectableHttpClient: public TSimpleHttpClient { -public: - TRedirectableHttpClient(const TString& host, ui32 port, TDuration socketTimeout = TDuration::Seconds(5), - TDuration connectTimeout = TDuration::Seconds(30)); - -private: - void PrepareClient(TKeepAliveHttpClient& cl) const override; - void ProcessResponse(const TStringBuf relativeUrl, THttpInput& input, IOutputStream* output, const unsigned statusCode) const override; -}; - -namespace NPrivate { - class THttpConnection { - public: - THttpConnection(const TString& host, - ui32 port, - TDuration sockTimeout, - TDuration connTimeout, - bool isHttps, - const TMaybe<TOpenSslClientIO::TOptions::TClientCert>& clientCert, - const TMaybe<TOpenSslClientIO::TOptions::TVerifyCert>& verifyCert); - - bool IsOk() const { - return IsNotSocketClosedByOtherSide(Socket); - } - - template <typename TContainer> - void Write(const TContainer& request) { - HttpOut->Write(request.data(), request.size()); - HttpIn = Ssl ? MakeHolder<THttpInput>(Ssl.Get()) - : MakeHolder<THttpInput>(&SocketIn); - HttpOut->Flush(); - } - - THttpInput* GetHttpInput() { - return HttpIn.Get(); - } - - private: - static TNetworkAddress Resolve(const TString& host, ui32 port); - - static TSocket Connect(TNetworkAddress& addr, - TDuration sockTimeout, - TDuration connTimeout, - const TString& host, - ui32 port); - - private: - TNetworkAddress Addr; - TSocket Socket; - TSocketInput SocketIn; - TSocketOutput SocketOut; - THolder<TOpenSslClientIO> Ssl; - THolder<THttpInput> HttpIn; - THolder<THttpOutput> HttpOut; - }; -} - -template <class T> -TKeepAliveHttpClient::THttpCode TKeepAliveHttpClient::DoRequestReliable(const T& raw, - IOutputStream* output, - THttpHeaders* outHeaders) { - for (int i = 0; i < 2; ++i) { - const bool haveNewConnection = CreateNewConnectionIfNeeded(); - const bool couldRetry = !haveNewConnection && i == 0; // Actually old connection could be already closed by server, - // so we should try one more time in this case. - try { - Connection->Write(raw); - - THttpCode code = ReadAndTransferHttp(*Connection->GetHttpInput(), output, outHeaders); - if (!Connection->GetHttpInput()->IsKeepAlive()) { - IsClosingRequired = true; - } - return code; - } catch (const TSystemError& e) { - Connection.Reset(); - if (!couldRetry || e.Status() != EPIPE) { - throw; - } - } catch (const THttpReadException&) { // Actually old connection is already closed by server - Connection.Reset(); - if (!couldRetry) { - throw; - } - } catch (const std::exception&) { - Connection.Reset(); - throw; - } - } - Y_FAIL(); // We should never be here. - return 0; -} diff --git a/library/cpp/http/simple/http_client_options.h b/library/cpp/http/simple/http_client_options.h deleted file mode 100644 index f2e964a462a..00000000000 --- a/library/cpp/http/simple/http_client_options.h +++ /dev/null @@ -1,59 +0,0 @@ -#pragma once - -#include <util/datetime/base.h> -#include <library/cpp/string_utils/url/url.h> - -class TSimpleHttpClientOptions { - using TSelf = TSimpleHttpClientOptions; - -public: - TSimpleHttpClientOptions() = default; - - explicit TSimpleHttpClientOptions(TStringBuf url) { - TStringBuf scheme, host; - GetSchemeHostAndPort(url, scheme, host, Port_); - Host_ = url.Head(scheme.size() + host.size()); - } - - TSelf& Host(TStringBuf host) { - Host_ = host; - return *this; - } - - const TString& Host() const noexcept { - return Host_; - } - - TSelf& Port(ui16 port) { - Port_ = port; - return *this; - } - - ui16 Port() const noexcept { - return Port_; - } - - TSelf& SocketTimeout(TDuration timeout) { - SocketTimeout_ = timeout; - return *this; - } - - TDuration SocketTimeout() const noexcept { - return SocketTimeout_; - } - - TSelf& ConnectTimeout(TDuration timeout) { - ConnectTimeout_ = timeout; - return *this; - } - - TDuration ConnectTimeout() const noexcept { - return ConnectTimeout_; - } - -private: - TString Host_; - ui16 Port_; - TDuration SocketTimeout_ = TDuration::Seconds(5); - TDuration ConnectTimeout_ = TDuration::Seconds(30); -}; diff --git a/library/cpp/http/simple/ut/http_ut.cpp b/library/cpp/http/simple/ut/http_ut.cpp deleted file mode 100644 index bf7e767428e..00000000000 --- a/library/cpp/http/simple/ut/http_ut.cpp +++ /dev/null @@ -1,439 +0,0 @@ -#include <library/cpp/http/simple/http_client.h> - -#include <library/cpp/http/server/response.h> - -#include <library/cpp/testing/mock_server/server.h> -#include <library/cpp/testing/unittest/registar.h> -#include <library/cpp/testing/unittest/tests_data.h> - -#include <util/system/event.h> -#include <util/system/thread.h> - -#include <thread> - -Y_UNIT_TEST_SUITE(SimpleHttp) { - static THttpServerOptions createOptions(ui16 port, bool keepAlive) { - THttpServerOptions o; - o.AddBindAddress("localhost", port); - o.SetThreads(1); - o.SetMaxConnections(1); - o.SetMaxQueueSize(1); - o.EnableKeepAlive(keepAlive); - return o; - } - - class TPong: public TRequestReplier { - TDuration Sleep_; - ui16 Port_; - - public: - TPong(TDuration sleep = TDuration(), ui16 port = 80) - : Sleep_(sleep) - , Port_(port) - { - } - - bool DoReply(const TReplyParams& params) override { - TStringBuf path = TParsedHttpFull(params.Input.FirstLine()).Path; - params.Input.ReadAll(); - if (path == "/redirect") { - params.Output << "HTTP/1.1 307 Internal Redirect\r\n" - "Location: http://localhost:" - << Port_ - << "/redirect2?some_param=qwe\r\n" - "Non-Authoritative-Reason: HSTS\r\n\r\n" - "must be missing"; - return true; - } - - if (path == "/redirect2") { - UNIT_ASSERT_VALUES_EQUAL("some_param=qwe", TParsedHttpFull(params.Input.FirstLine()).Cgi); - params.Output << "HTTP/1.1 307 Internal Redirect\r\n" - "Location: http://localhost:" - << Port_ - << "/ping\r\n" - "Non-Authoritative-Reason: HSTS\r\n\r\n" - "must be missing too"; - return true; - } - - if (path != "/ping") { - UNIT_ASSERT_C(false, "path is incorrect: '" << path << "'"); - } - - Sleep(Sleep_); - - THttpResponse resp(HTTP_OK); - resp.SetContent("pong"); - resp.OutTo(params.Output); - - return true; - } - }; - - class TCodedPong: public TRequestReplier { - HttpCodes Code_; - - public: - TCodedPong(HttpCodes code) - : Code_(code) - { - } - - bool DoReply(const TReplyParams& params) override { - if (TParsedHttpFull(params.Input.FirstLine()).Path != "/ping") { - UNIT_ASSERT(false); - } - - THttpResponse resp(Code_); - resp.SetContent("pong"); - resp.OutTo(params.Output); - - return true; - } - }; - - class T500: public TRequestReplier { - ui16 Port_; - - public: - T500(ui16 port) - : Port_(port) - { - } - - bool DoReply(const TReplyParams& params) override { - TStringBuf path = TParsedHttpFull(params.Input.FirstLine()).Path; - - if (path == "/bad_redirect") { - params.Output << "HTTP/1.1 500 Internal Redirect\r\n" - "Location: http://localhost:1/qwerty\r\n" - "Non-Authoritative-Reason: HSTS\r\n\r\n"; - return true; - } - - if (path == "/redirect_to_500") { - params.Output << "HTTP/1.1 307 Internal Redirect\r\n" - "Location: http://localhost:" - << Port_ - << "/500\r\n" - "Non-Authoritative-Reason: HSTS\r\n\r\n"; - return true; - } - - THttpResponse resp(HTTP_INTERNAL_SERVER_ERROR); - resp.SetContent("bang"); - resp.OutTo(params.Output); - - return true; - } - }; - - Y_UNIT_TEST(simpleSuccessful) { - TPortManager pm; - ui16 port = pm.GetPort(80); - NMock::TMockServer server(createOptions(port, false), []() { return new TPong; }); - - TSimpleHttpClient cl("localhost", port); - UNIT_ASSERT_VALUES_EQUAL(0, server.GetClientCount()); - - { - TStringStream s; - UNIT_ASSERT_NO_EXCEPTION(cl.DoGet("/ping", &s)); - UNIT_ASSERT_VALUES_EQUAL("pong", s.Str()); - Sleep(TDuration::MilliSeconds(500)); - UNIT_ASSERT_VALUES_EQUAL(0, server.GetClientCount()); - } - { - TStringStream s; - UNIT_ASSERT_NO_EXCEPTION(cl.DoGet("/ping", &s)); - UNIT_ASSERT_VALUES_EQUAL("pong", s.Str()); - Sleep(TDuration::MilliSeconds(500)); - UNIT_ASSERT_VALUES_EQUAL(0, server.GetClientCount()); - } - - { - TStringStream s; - UNIT_ASSERT_NO_EXCEPTION(cl.DoPost("/ping", "", &s)); - UNIT_ASSERT_VALUES_EQUAL("pong", s.Str()); - Sleep(TDuration::MilliSeconds(500)); - UNIT_ASSERT_VALUES_EQUAL(0, server.GetClientCount()); - } - { - TStringStream s; - UNIT_ASSERT_NO_EXCEPTION(cl.DoPost("/ping", "", &s)); - UNIT_ASSERT_VALUES_EQUAL("pong", s.Str()); - Sleep(TDuration::MilliSeconds(500)); - UNIT_ASSERT_VALUES_EQUAL(0, server.GetClientCount()); - } - } - - Y_UNIT_TEST(simpleMessages) { - TPortManager pm; - ui16 port = pm.GetPort(80); - NMock::TMockServer server(createOptions(port, false), []() { return new TPong; }); - - TSimpleHttpClient cl("localhost", port); - UNIT_ASSERT_VALUES_EQUAL(0, server.GetClientCount()); - - { - TStringStream s; - UNIT_ASSERT_NO_EXCEPTION(cl.DoGet("/ping", &s)); - UNIT_ASSERT_VALUES_EQUAL("pong", s.Str()); - Sleep(TDuration::MilliSeconds(500)); - UNIT_ASSERT_VALUES_EQUAL(0, server.GetClientCount()); - } - { - UNIT_ASSERT_NO_EXCEPTION(cl.DoGet("/ping", nullptr)); - Sleep(TDuration::MilliSeconds(500)); - UNIT_ASSERT_VALUES_EQUAL(0, server.GetClientCount()); - } - - server.SetGenerator([]() { return new TCodedPong(HTTP_CONTINUE); }); - { - TStringStream s; - UNIT_ASSERT_EXCEPTION_CONTAINS(cl.DoPost("/ping", "", &s), - THttpRequestException, - "Got 100 at localhost/ping\n" - "Full http response:\n"); - UNIT_ASSERT_VALUES_EQUAL("pong", s.Str()); - Sleep(TDuration::MilliSeconds(500)); - UNIT_ASSERT_VALUES_EQUAL(0, server.GetClientCount()); - } - { - UNIT_ASSERT_EXCEPTION_CONTAINS(cl.DoPost("/ping", "", nullptr), - THttpRequestException, - "Got 100 at localhost/ping\n" - "Full http response:\n" - "pong"); - Sleep(TDuration::MilliSeconds(500)); - UNIT_ASSERT_VALUES_EQUAL(0, server.GetClientCount()); - } - } - - Y_UNIT_TEST(simpleTimeout) { - TPortManager pm; - ui16 port = pm.GetPort(80); - NMock::TMockServer server(createOptions(port, true), []() { return new TPong(TDuration::MilliSeconds(300)); }); - - TSimpleHttpClient cl("localhost", port, TDuration::MilliSeconds(50), TDuration::MilliSeconds(50)); - - TStringStream s; - UNIT_ASSERT_EXCEPTION_CONTAINS(cl.DoGet("/ping", &s), - TSystemError, - "Resource temporarily unavailable"); - UNIT_ASSERT_EXCEPTION_CONTAINS(cl.DoPost("/ping", "", &s), - TSystemError, - "Resource temporarily unavailable"); - } - - Y_UNIT_TEST(simpleError) { - TPortManager pm; - ui16 port = pm.GetPort(80); - NMock::TMockServer server(createOptions(port, true), []() { return new TPong; }); - - TSimpleHttpClient cl("localhost", port); - UNIT_ASSERT_VALUES_EQUAL(0, server.GetClientCount()); - - { - TStringStream s; - server.SetGenerator([]() { return new TCodedPong(HTTP_CONTINUE); }); - UNIT_ASSERT_EXCEPTION_CONTAINS(cl.DoGet("/ping", &s), - THttpRequestException, - "Got 100 at localhost/ping\n" - "Full http response:"); - UNIT_ASSERT_VALUES_EQUAL("pong", s.Str()); - Sleep(TDuration::MilliSeconds(500)); - UNIT_ASSERT_VALUES_EQUAL(0, server.GetClientCount()); - } - - { - TStringStream s; - server.SetGenerator([]() { return new TCodedPong(HTTP_OK); }); - UNIT_ASSERT_NO_EXCEPTION(cl.DoGet("/ping", &s)); - UNIT_ASSERT_VALUES_EQUAL("pong", s.Str()); - Sleep(TDuration::MilliSeconds(500)); - UNIT_ASSERT_VALUES_EQUAL(0, server.GetClientCount()); - - server.SetGenerator([]() { return new TCodedPong(HTTP_PARTIAL_CONTENT); }); - UNIT_ASSERT_NO_EXCEPTION(cl.DoGet("/ping", &s)); - Sleep(TDuration::MilliSeconds(500)); - UNIT_ASSERT_VALUES_EQUAL(0, server.GetClientCount()); - } - - { - TStringStream s; - server.SetGenerator([]() { return new TCodedPong(HTTP_MULTIPLE_CHOICES); }); - UNIT_ASSERT_EXCEPTION_CONTAINS(cl.DoGet("/ping", &s), - THttpRequestException, - "Got 300 at localhost/ping\n" - "Full http response:"); - UNIT_ASSERT_VALUES_EQUAL("pong", s.Str()); - Sleep(TDuration::MilliSeconds(500)); - UNIT_ASSERT_VALUES_EQUAL(0, server.GetClientCount()); - } - } - - Y_UNIT_TEST(redirectable) { - TPortManager pm; - ui16 port = pm.GetPort(80); - NMock::TMockServer server(createOptions(port, true), [port]() { return new TPong(TDuration(), port); }); - - TRedirectableHttpClient cl("localhost", port); - UNIT_ASSERT_VALUES_EQUAL(0, server.GetClientCount()); - - { - TStringStream s; - UNIT_ASSERT_NO_EXCEPTION(cl.DoGet("/redirect", &s)); - UNIT_ASSERT_VALUES_EQUAL("pong", s.Str()); - Sleep(TDuration::MilliSeconds(500)); - UNIT_ASSERT_VALUES_EQUAL(0, server.GetClientCount()); - } - - server.SetGenerator([port]() { return new T500(port); }); - - TStringStream s; - UNIT_ASSERT_EXCEPTION_CONTAINS(cl.DoGet("/bad_redirect", &s), - THttpRequestException, - "can not connect to "); - Sleep(TDuration::MilliSeconds(500)); - UNIT_ASSERT_VALUES_EQUAL(0, server.GetClientCount()); - - UNIT_ASSERT_EXCEPTION_CONTAINS(cl.DoGet("/redirect_to_500", &s), - THttpRequestException, - "Got 500 at http://localhost/500\n" - "Full http response:\n"); - UNIT_ASSERT_VALUES_EQUAL("bang", s.Str()); - Sleep(TDuration::MilliSeconds(500)); - UNIT_ASSERT_VALUES_EQUAL(0, server.GetClientCount()); - } - - Y_UNIT_TEST(keepaliveSuccessful) { - auto test = [](bool keepalive, i64 clientCount) { - TPortManager pm; - ui16 port = pm.GetPort(80); - NMock::TMockServer server(createOptions(port, keepalive), []() { return new TPong; }); - - TKeepAliveHttpClient cl("localhost", port); - UNIT_ASSERT_VALUES_EQUAL(0, server.GetClientCount()); - { - TStringStream s; - int code = -1; - UNIT_ASSERT_NO_EXCEPTION_C(code = cl.DoGet("/ping", &s), keepalive); - UNIT_ASSERT_VALUES_EQUAL_C(200, code, keepalive); - UNIT_ASSERT_VALUES_EQUAL_C("pong", s.Str(), keepalive); - Sleep(TDuration::MilliSeconds(500)); - UNIT_ASSERT_VALUES_EQUAL(clientCount, server.GetClientCount()); - } - { - TStringStream s; - int code = -1; - UNIT_ASSERT_NO_EXCEPTION_C(code = cl.DoGet("/ping", &s), keepalive); - UNIT_ASSERT_VALUES_EQUAL_C(200, code, keepalive); - UNIT_ASSERT_VALUES_EQUAL_C("pong", s.Str(), keepalive); - Sleep(TDuration::MilliSeconds(500)); - UNIT_ASSERT_VALUES_EQUAL(clientCount, server.GetClientCount()); - } - - { - TStringStream s; - int code = -1; - UNIT_ASSERT_NO_EXCEPTION_C(code = cl.DoPost("/ping", "", &s), keepalive); - UNIT_ASSERT_VALUES_EQUAL_C(200, code, keepalive); - UNIT_ASSERT_VALUES_EQUAL_C("pong", s.Str(), keepalive); - Sleep(TDuration::MilliSeconds(500)); - UNIT_ASSERT_VALUES_EQUAL(clientCount, server.GetClientCount()); - } - { - TStringStream s; - int code = -1; - UNIT_ASSERT_NO_EXCEPTION_C(code = cl.DoPost("/ping", "", &s), keepalive); - UNIT_ASSERT_VALUES_EQUAL_C(200, code, keepalive); - UNIT_ASSERT_VALUES_EQUAL_C("pong", s.Str(), keepalive); - Sleep(TDuration::MilliSeconds(500)); - UNIT_ASSERT_VALUES_EQUAL(clientCount, server.GetClientCount()); - } - }; - - test(true, 1); - test(false, 0); - } - - Y_UNIT_TEST(keepaliveTimeout) { - TPortManager pm; - ui16 port = pm.GetPort(80); - NMock::TMockServer server(createOptions(port, true), []() { return new TPong(TDuration::MilliSeconds(300)); }); - - TKeepAliveHttpClient cl("localhost", port, TDuration::MilliSeconds(50), TDuration::MilliSeconds(50)); - - TStringStream s; - UNIT_ASSERT_EXCEPTION_CONTAINS(cl.DoGet("/ping", &s), - TSystemError, - "Resource temporarily unavailable"); - UNIT_ASSERT_EXCEPTION_CONTAINS(cl.DoPost("/ping", "", &s), - TSystemError, - "Resource temporarily unavailable"); - } - - Y_UNIT_TEST(keepaliveHeaders) { - TPortManager pm; - ui16 port = pm.GetPort(80); - NMock::TMockServer server(createOptions(port, true), []() { return new TPong; }); - - TKeepAliveHttpClient cl("localhost", port); - - TStringStream s; - THttpHeaders h; - UNIT_ASSERT_VALUES_EQUAL(200, cl.DoGet("/ping", &s, {}, &h)); - TStringStream hs; - h.OutTo(&hs); - UNIT_ASSERT_VALUES_EQUAL("Content-Length: 4\r\nConnection: Keep-Alive\r\n", hs.Str()); - } - - Y_UNIT_TEST(keepaliveRaw) { - TPortManager pm; - ui16 port = pm.GetPort(80); - NMock::TMockServer server(createOptions(port, true), []() { return new TPong; }); - - TKeepAliveHttpClient cl("localhost", port); - - TStringStream s; - THttpHeaders h; - - TString raw = "POST /ping HTTP/1.1\r\n" - "Connection: Keep-Alive\r\n" - "Accept-Encoding: gzip, deflate\r\n" - "Content-Length: 9\r\n" - "Content-Type: application/x-www-form-urlencoded\r\n" - "User-Agent: Python-urllib/2.6\r\n" - "\r\n" - "some body"; - - UNIT_ASSERT_VALUES_EQUAL(200, cl.DoRequestRaw(raw, &s, &h)); - TStringStream hs; - h.OutTo(&hs); - UNIT_ASSERT_VALUES_EQUAL("Content-Length: 4\r\nConnection: Keep-Alive\r\n", hs.Str()); - - raw = "GET /ping HT TP/1.1\r\n"; - UNIT_ASSERT_EXCEPTION_CONTAINS(cl.DoRequestRaw(raw, &s, &h), TSystemError, "can not read from socket input stream"); - } - - Y_UNIT_TEST(keepaliveWithClosedByPeer) { - TPortManager pm; - ui16 port = pm.GetPort(80); - NMock::TMockServer::TGenerator gen = []() { return new TPong; }; - THolder<NMock::TMockServer> server = MakeHolder<NMock::TMockServer>(createOptions(port, true), gen); - - TKeepAliveHttpClient cl("localhost", port); - UNIT_ASSERT_NO_EXCEPTION(cl.DoGet("/ping")); - - server.Reset(); - server = MakeHolder<NMock::TMockServer>(createOptions(port, true), gen); - UNIT_ASSERT_NO_EXCEPTION(cl.DoGet("/ping")); - - TKeepAliveHttpClient cl2("localhost", port); - UNIT_ASSERT_NO_EXCEPTION(cl2.DoGet("/ping")); - Sleep(TDuration::MilliSeconds(500)); - UNIT_ASSERT_NO_EXCEPTION(cl.DoGet("/ping")); - } -} diff --git a/library/cpp/http/simple/ut/https_server/http_server.crt b/library/cpp/http/simple/ut/https_server/http_server.crt deleted file mode 100644 index 74d74fafea0..00000000000 --- a/library/cpp/http/simple/ut/https_server/http_server.crt +++ /dev/null @@ -1,19 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDATCCAemgAwIBAgIJAKnfUOUcLEqUMA0GCSqGSIb3DQEBCwUAMBcxFTATBgNV -BAMMDGxvY2FsaG9zdC5teTAeFw0xODA1MDgwOTIxMDZaFw0xOTA1MDgwOTIxMDZa -MBcxFTATBgNVBAMMDGxvY2FsaG9zdC5teTCCASIwDQYJKoZIhvcNAQEBBQADggEP -ADCCAQoCggEBAMVe3pFwlPCrniAAsDyhoolnwv0gOQ4SX81nA0NggabKbUBJwwfN -nKP5dvFNHCo100fzoiWbFmZnu9pUMtjeucQzaA38i501rXCkiPmTkE+tDdIJqO8J -lLV+oaNvFtaAVcRIiuU9fTp/MdZhG3tLj/AXx9dcc1xHRjg/tngepAsvZ2oRoBVU -ijvkOSCm1xwew+ZTzazLARnLOvHok1tJPepMCVlGaEaL9r1aJ86hMUSg+sli2ayW -myI4Pt7ZrsyrHpHDYF9ecWWGbmHfgLdaAdyulrPuvtwavl6KtgSuy3SxwigOfdBI -h4Xw2u6gq4v40OuZGWgkNdJ000ddwurWfosCAwEAAaNQME4wHQYDVR0OBBYEFAd+ -0uv5elelwrjB/0C7EDO7VauqMB8GA1UdIwQYMBaAFAd+0uv5elelwrjB/0C7EDO7 -VauqMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAEauDMNWqCIIZXmY -HLqkoPmy+BDX7N4F2ZuWntes8D/igFhZOYQfD+ksJEv3zgs6N5Qd8HbSCbZR0Hh+ -1g+RjVBu8T67h6+vIDZuu0jORjknUp2XbD+aWG+7UcuUjDY8KF9St50ZniSieiSA -dV09VrJ/JFwxaeFzgOHnk9oP5eggwZjEZJqSc4qzL0JlhFcxV8R4OVUCjRyHG73p -cN7nUDL9xN5XZY+6t6+rzdYi4UAhEW0odFVfyXqhOhupSgQkBBdIjxVuov+3h/aV -D2YweTg6cKtuaISsFmDEPht7cVQuy5z3PPkV6kQBeECA9vTFP3wCxA0n7Iyyn2IK -8gvWZXk= ------END CERTIFICATE----- diff --git a/library/cpp/http/simple/ut/https_server/http_server.key b/library/cpp/http/simple/ut/https_server/http_server.key deleted file mode 100644 index f58ab049fd7..00000000000 --- a/library/cpp/http/simple/ut/https_server/http_server.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDFXt6RcJTwq54g -ALA8oaKJZ8L9IDkOEl/NZwNDYIGmym1AScMHzZyj+XbxTRwqNdNH86IlmxZmZ7va -VDLY3rnEM2gN/IudNa1wpIj5k5BPrQ3SCajvCZS1fqGjbxbWgFXESIrlPX06fzHW -YRt7S4/wF8fXXHNcR0Y4P7Z4HqQLL2dqEaAVVIo75DkgptccHsPmU82sywEZyzrx -6JNbST3qTAlZRmhGi/a9WifOoTFEoPrJYtmslpsiOD7e2a7Mqx6Rw2BfXnFlhm5h -34C3WgHcrpaz7r7cGr5eirYErst0scIoDn3QSIeF8NruoKuL+NDrmRloJDXSdNNH -XcLq1n6LAgMBAAECggEAdN+wvD8Gc12szRabRcwRC3y+IlYqcwK+aEtPy14iaDoG -Z8NGEiDXWOIoZMtcmkI1Uq4anlov8YQL4UVqtrFtH5mxTFb39agLhGBqHCAdnJDF -VlMSDjqGLNNHtBfcVji4kPrEBOtcdH9Na70lIOWl3m62j/jW9xXdpwFTc93xFg14 -Ivtjtv7KHZAPgN0pdgsqen1js6Z3O5tkcy4yFLldBl+8/ZbYSMM+Rh4GbR5qvWfA -23vBu9EprJKPhFQlNZPbesEKe8EA+SCuLo0RzAZq1E2nZRH0HasKT2hhr/kobkN6 -oLIo2dNgIYL7xMhHLcBt1/08CXKZIqEAfA9Tx/eVgQKBgQD7/oN/XA0pMVCqS8f6 -8Z9VI4NxHJoPFLskrXjXhbxgLgUjuz28cuoyaIKcv8f9Qo7f+hOwR2F3zjwyVexB -G+0fuyIbqD8Po43F+SBJCVSE3EV5k0AQJJN74a+UuKC39NhGaXsmj+s6ArWrURV5 -thay+308pF5HvYCnmQD3UfOJiQKBgQDIghDarcID6/Q0Nv8xvfd8p9kUu5vX/Tw0 -W22JDDMxpUoYCGXvOEx+IoVzqLOTw+NcEXSmDA41VqXlphYopwZkfNV6kIXVymdu -oNKisgfe4Hrfrq9BUl5p8gvU/Ev5zY7N4kVirUJgNvRHDElp8h6Ek/KRTv8Q0xRX -ZW6UqmKGcwKBgDsQZ7/1UnxiO7b+tivicGcjQM7FVnLMeCTbqCRUC1g70SaT35+J -C82u41ZcOULqU9S5p928jWLoawGdVBfatNSoJxF2ePlwa22IvAGCd1YAzyP02KIw -AIWb22yvbbRQZlTyqlPajdb2BaDXC4KQpHdlLPCG0jZce4hM+4X8pmmJAoGALW4S -5YlTGVJf7Wi8n4ecSJk7PVBYujJ9bpt8kP27p7b8t79HYVFPO5EUzaTes09B931Z -AbpficRNKGBeSu21LBWAxRlzyYHnt5AmyYgu8lfIX2AUA2fnTnfyKFrV2A60GX/4 -GqiJDoXFCUgGZkPemElxP203q5c316l6yaJlWnMCgYAqk1G65THRmdTKcnUEOqo8 -pD3SWuBvbOHYLyg+f0zNAqpnTFbaPVmsWfx3CsX2m8WdH3dD28SGfvepQlWj1yp/ -TmXs14nFUuJWir2VbPgp8W/uZl8bQ0YlI8UPUbN3XbLkVIno+jXuUopcgrXmi7Gb -Y2QnQfHePgpszWR0o+WiYg== ------END PRIVATE KEY----- diff --git a/library/cpp/http/simple/ut/https_server/main.go b/library/cpp/http/simple/ut/https_server/main.go deleted file mode 100644 index 4282810675e..00000000000 --- a/library/cpp/http/simple/ut/https_server/main.go +++ /dev/null @@ -1,70 +0,0 @@ -package main - -import ( - "fmt" - "log" - "net/http" - "os" - - "github.com/spf13/cobra" - "github.com/spf13/pflag" -) - -type Opts struct { - Port uint16 - KeyFile string - CertFile string -} - -func handler(writer http.ResponseWriter, request *http.Request) { - res := "pong.my" - - writer.Header().Set("Content-Type", "text/plain") - writer.WriteHeader(http.StatusOK) - - _, _ = writer.Write([]byte(res)) -} - -func runServer(opts *Opts) error { - mainMux := http.NewServeMux() - mainMux.Handle("/ping", http.HandlerFunc(handler)) - - server := &http.Server{ - Addr: fmt.Sprintf("localhost:%d", opts.Port), - Handler: mainMux, - ErrorLog: log.New(os.Stdout, "", log.LstdFlags), - } - - return server.ListenAndServeTLS(opts.CertFile, opts.KeyFile) -} - -func markFlagRequired(flags *pflag.FlagSet, names ...string) { - for _, n := range names { - name := n - if err := cobra.MarkFlagRequired(flags, name); err != nil { - panic(err) - } - } -} - -func main() { - opts := Opts{} - - cmd := cobra.Command{ - RunE: func(cmd *cobra.Command, args []string) error { - return runServer(&opts) - }, - } - - flags := cmd.Flags() - flags.Uint16Var(&opts.Port, "port", 0, "") - flags.StringVar(&opts.KeyFile, "keyfile", "", "path to key file") - flags.StringVar(&opts.CertFile, "certfile", "", "path to cert file") - - markFlagRequired(flags, "port", "keyfile", "certfile") - - if err := cmd.Execute(); err != nil { - _, _ = fmt.Fprintf(os.Stderr, "Exit with err: %s", err) - os.Exit(1) - } -} diff --git a/library/cpp/http/simple/ut/https_ut.cpp b/library/cpp/http/simple/ut/https_ut.cpp deleted file mode 100644 index 3849b9ac9ac..00000000000 --- a/library/cpp/http/simple/ut/https_ut.cpp +++ /dev/null @@ -1,97 +0,0 @@ -#include <library/cpp/http/simple/http_client.h> - -#include <library/cpp/http/server/response.h> - -#include <library/cpp/testing/unittest/registar.h> -#include <library/cpp/testing/unittest/tests_data.h> - -#include <util/system/shellcommand.h> - -Y_UNIT_TEST_SUITE(Https) { - using TShellCommandPtr = std::unique_ptr<TShellCommand>; - - static TShellCommandPtr start(ui16 port) { - const TString data = ArcadiaSourceRoot() + "/library/cpp/http/simple/ut/https_server"; - - const TString command = - TStringBuilder() - << BuildRoot() << "/library/cpp/http/simple/ut/https_server/https_server" - << " --port " << port - << " --keyfile " << data << "/http_server.key" - << " --certfile " << data << "/http_server.crt"; - - auto res = std::make_unique<TShellCommand>( - command, - TShellCommandOptions() - .SetAsync(true) - .SetLatency(50) - .SetErrorStream(&Cerr)); - - res->Run(); - - i32 tries = 100000; - while (tries-- > 0) { - try { - TKeepAliveHttpClient client("https://localhost", port); - client.DisableVerificationForHttps(); - client.DoGet("/ping"); - break; - } catch (const std::exception& e) { - Cout << "== failed to connect to new server: " << e.what() << Endl; - Sleep(TDuration::MilliSeconds(1)); - } - } - - return res; - } - - static void get(TKeepAliveHttpClient & client) { - TStringStream out; - ui32 code = 0; - - UNIT_ASSERT_NO_EXCEPTION(code = client.DoGet("/ping", &out)); - UNIT_ASSERT_VALUES_EQUAL_C(code, 200, out.Str()); - UNIT_ASSERT_VALUES_EQUAL(out.Str(), "pong.my"); - } - - Y_UNIT_TEST(keepAlive) { - TPortManager pm; - ui16 port = pm.GetPort(443); - TShellCommandPtr httpsServer = start(port); - - TKeepAliveHttpClient client("https://localhost", - port, - TDuration::Seconds(40), - TDuration::Seconds(40)); - client.DisableVerificationForHttps(); - - get(client); - get(client); - - httpsServer->Terminate().Wait(); - httpsServer = start(port); - - get(client); - } - - static void get(TSimpleHttpClient & client) { - TStringStream out; - - UNIT_ASSERT_NO_EXCEPTION_C(client.DoGet("/ping", &out), out.Str()); - UNIT_ASSERT_VALUES_EQUAL(out.Str(), "pong.my"); - } - - Y_UNIT_TEST(simple) { - TPortManager pm; - ui16 port = pm.GetPort(443); - TShellCommandPtr httpsServer = start(port); - - TSimpleHttpClient client("https://localhost", - port, - TDuration::Seconds(40), - TDuration::Seconds(40)); - - get(client); - get(client); - } -} |