aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/messagebus/rain_check/http/client.cpp
diff options
context:
space:
mode:
authorDevtools Arcadia <arcadia-devtools@yandex-team.ru>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/messagebus/rain_check/http/client.cpp
downloadydb-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.cpp154
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();
+ }
+
+}