summaryrefslogtreecommitdiffstats
path: root/library/cpp/http
diff options
context:
space:
mode:
authorkomels <[email protected]>2022-04-15 16:53:39 +0300
committerkomels <[email protected]>2022-04-15 16:53:39 +0300
commit703a2fb6e100d202d1c7fcd052d73bd5affef408 (patch)
tree22b7320c06bb04d86dbf7b9af9ae44281331cd15 /library/cpp/http
parent3375bbfda1e2afb03aa2072bf5f2f2c3a26026e8 (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/.arcignore1
-rw-r--r--library/cpp/http/simple/CMakeLists.txt21
-rw-r--r--library/cpp/http/simple/http_client.cpp356
-rw-r--r--library/cpp/http/simple/http_client.h276
-rw-r--r--library/cpp/http/simple/http_client_options.h59
-rw-r--r--library/cpp/http/simple/ut/http_ut.cpp439
-rw-r--r--library/cpp/http/simple/ut/https_server/http_server.crt19
-rw-r--r--library/cpp/http/simple/ut/https_server/http_server.key28
-rw-r--r--library/cpp/http/simple/ut/https_server/main.go70
-rw-r--r--library/cpp/http/simple/ut/https_ut.cpp97
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);
- }
-}