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/messagebus/rain_check/http/client.cpp | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/messagebus/rain_check/http/client.cpp')
-rw-r--r-- | library/cpp/messagebus/rain_check/http/client.cpp | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/library/cpp/messagebus/rain_check/http/client.cpp b/library/cpp/messagebus/rain_check/http/client.cpp new file mode 100644 index 0000000000..5ef5ceeece --- /dev/null +++ b/library/cpp/messagebus/rain_check/http/client.cpp @@ -0,0 +1,154 @@ +#include "client.h" + +#include "http_code_extractor.h" + +#include <library/cpp/http/io/stream.h> +#include <library/cpp/neh/factory.h> +#include <library/cpp/neh/http_common.h> +#include <library/cpp/neh/location.h> +#include <library/cpp/neh/neh.h> + +#include <util/generic/ptr.h> +#include <util/generic/strbuf.h> +#include <util/network/socket.h> +#include <util/stream/str.h> + +namespace NRainCheck { + class THttpCallback: public NNeh::IOnRecv { + public: + THttpCallback(NRainCheck::THttpFuture* future) + : Future(future) + { + Y_VERIFY(!!future, "future is NULL"); + } + + void OnRecv(NNeh::THandle& handle) override { + THolder<THttpCallback> self(this); + NNeh::TResponseRef response = handle.Get(); + Future->SetDoneAndSchedule(response); + } + + private: + NRainCheck::THttpFuture* const Future; + }; + + THttpFuture::THttpFuture() + : Task(nullptr) + , ErrorCode(THttpFuture::NoError) + { + } + + THttpFuture::~THttpFuture() { + } + + bool THttpFuture::HasError() const { + return (ErrorCode != THttpFuture::NoError); + } + + THttpFuture::EError THttpFuture::GetErrorCode() const { + return ErrorCode; + } + + TString THttpFuture::GetErrorDescription() const { + return ErrorDescription; + } + + THttpClientService::THttpClientService() + : GetProtocol(NNeh::ProtocolFactory()->Protocol("http")) + , FullProtocol(NNeh::ProtocolFactory()->Protocol("full")) + { + Y_VERIFY(!!GetProtocol, "GET protocol is NULL."); + Y_VERIFY(!!FullProtocol, "POST protocol is NULL."); + } + + THttpClientService::~THttpClientService() { + } + + void THttpClientService::SendPost(TString addr, const TString& data, const THttpHeaders& headers, THttpFuture* future) { + Y_VERIFY(!!future, "future is NULL."); + + TTaskRunnerBase* current = TTaskRunnerBase::CurrentTask(); + future->SetRunning(current); + future->Task = current; + + THolder<THttpCallback> callback(new THttpCallback(future)); + NNeh::TServiceStatRef stat; + try { + NNeh::TMessage msg(addr.replace(0, NNeh::TParsedLocation(addr).Scheme.size(), "post"), data); + TStringStream headersText; + headers.OutTo(&headersText); + NNeh::NHttp::MakeFullRequest(msg, headersText.Str(), TString()); + FullProtocol->ScheduleRequest(msg, callback.Get(), stat); + Y_UNUSED(callback.Release()); + } catch (const TNetworkResolutionError& err) { + future->SetFail(THttpFuture::CantResolveNameError, err.AsStrBuf()); + } catch (const yexception& err) { + future->SetFail(THttpFuture::OtherError, err.AsStrBuf()); + } + } + + void THttpClientService::Send(const TString& request, THttpFuture* future) { + Y_VERIFY(!!future, "future is NULL."); + + TTaskRunnerBase* current = TTaskRunnerBase::CurrentTask(); + future->SetRunning(current); + future->Task = current; + + THolder<THttpCallback> callback(new THttpCallback(future)); + NNeh::TServiceStatRef stat; + try { + GetProtocol->ScheduleRequest(NNeh::TMessage::FromString(request), + callback.Get(), + stat); + Y_UNUSED(callback.Release()); + } catch (const TNetworkResolutionError& err) { + future->SetFail(THttpFuture::CantResolveNameError, err.AsStrBuf()); + } catch (const yexception& err) { + future->SetFail(THttpFuture::OtherError, err.AsStrBuf()); + } + } + + bool THttpFuture::HasHttpCode() const { + return !!HttpCode; + } + + bool THttpFuture::HasResponseBody() const { + return !!Response; + } + + ui32 THttpFuture::GetHttpCode() const { + Y_ASSERT(IsDone()); + Y_ASSERT(HasHttpCode()); + + return static_cast<ui32>(*HttpCode); + } + + TString THttpFuture::GetResponseBody() const { + Y_ASSERT(IsDone()); + Y_ASSERT(HasResponseBody()); + + return Response->Data; + } + + void THttpFuture::SetDoneAndSchedule(TAutoPtr<NNeh::TResponse> response) { + if (!response->IsError()) { + ErrorCode = THttpFuture::NoError; + HttpCode = HttpCodes::HTTP_OK; + } else { + ErrorCode = THttpFuture::BadHttpCodeError; + ErrorDescription = response->GetErrorText(); + + HttpCode = TryGetHttpCodeFromErrorDescription(ErrorDescription); + } + Response.Reset(response); + SetDone(); + } + + void THttpFuture::SetFail(THttpFuture::EError errorCode, const TStringBuf& errorDescription) { + ErrorCode = errorCode; + ErrorDescription = errorDescription; + Response.Destroy(); + SetDone(); + } + +} |