#pragma once #include #include #include #include #include #include #include #include #include #include #include #include "http.h" #include "http_proxy_sock64.h" #include "http_proxy_ssl.h" namespace NHttp { struct TSocketDescriptor : NActors::TSharedDescriptor, THttpConfig { SocketType Socket; TSocketDescriptor() = default; TSocketDescriptor(int af) : Socket(af) { } TSocketDescriptor(SocketType&& s) : Socket(std::move(s)) {} int GetDescriptor() override { return static_cast(Socket); } }; struct TEvHttpProxy { enum EEv { EvAddListeningPort = EventSpaceBegin(NActors::TEvents::ES_HTTP), EvConfirmListen, EvRegisterHandler, EvHttpIncomingRequest, EvHttpOutgoingRequest, EvHttpIncomingResponse, EvHttpOutgoingResponse, EvHttpConnectionOpened, EvHttpConnectionClosed, EvHttpAcceptorClosed, EvResolveHostRequest, EvResolveHostResponse, EvReportSensors, EvEnd }; static_assert(EvEnd < EventSpaceEnd(NActors::TEvents::ES_HTTP), "ES_HTTP event space is too small."); struct TEvAddListeningPort : NActors::TEventLocal { TString Address; TIpPort Port; TString WorkerName; bool Secure = false; TString CertificateFile; TString PrivateKeyFile; TString SslCertificatePem; std::vector CompressContentTypes; TEvAddListeningPort() = default; TEvAddListeningPort(TIpPort port) : Port(port) {} TEvAddListeningPort(TIpPort port, const TString& workerName) : Port(port) , WorkerName(workerName) {} }; struct TEvConfirmListen : NActors::TEventLocal { THttpConfig::SocketAddressType Address; std::shared_ptr Endpoint; TEvConfirmListen(const THttpConfig::SocketAddressType& address, std::shared_ptr endpoint) : Address(address) , Endpoint(std::move(endpoint)) {} }; struct TEvRegisterHandler : NActors::TEventLocal { TString Path; TActorId Handler; TEvRegisterHandler(const TString& path, const TActorId& handler) : Path(path) , Handler(handler) {} }; struct TEvHttpIncomingRequest : NActors::TEventLocal { THttpIncomingRequestPtr Request; TEvHttpIncomingRequest(THttpIncomingRequestPtr request) : Request(std::move(request)) {} }; struct TEvHttpOutgoingRequest : NActors::TEventLocal { THttpOutgoingRequestPtr Request; TDuration Timeout; TEvHttpOutgoingRequest(THttpOutgoingRequestPtr request) : Request(std::move(request)) {} TEvHttpOutgoingRequest(THttpOutgoingRequestPtr request, TDuration timeout) : Request(std::move(request)) , Timeout(timeout) {} }; struct TEvHttpIncomingResponse : NActors::TEventLocal { THttpOutgoingRequestPtr Request; THttpIncomingResponsePtr Response; TString Error; TEvHttpIncomingResponse(THttpOutgoingRequestPtr request, THttpIncomingResponsePtr response, const TString& error) : Request(std::move(request)) , Response(std::move(response)) , Error(error) {} TEvHttpIncomingResponse(THttpOutgoingRequestPtr request, THttpIncomingResponsePtr response) : Request(std::move(request)) , Response(std::move(response)) {} TString GetError() const { TStringBuilder error; if (Response != nullptr && !Response->Status.StartsWith('2')) { error << Response->Status << ' ' << Response->Message; } if (!Error.empty()) { if (!error.empty()) { error << ';'; } error << Error; } return error; } }; struct TEvHttpOutgoingResponse : NActors::TEventLocal { THttpOutgoingResponsePtr Response; TEvHttpOutgoingResponse(THttpOutgoingResponsePtr response) : Response(std::move(response)) {} }; struct TEvHttpConnectionOpened : NActors::TEventLocal { TString PeerAddress; TActorId ConnectionID; TEvHttpConnectionOpened(const TString& peerAddress, const TActorId& connectionID) : PeerAddress(peerAddress) , ConnectionID(connectionID) {} }; struct TEvHttpConnectionClosed : NActors::TEventLocal { TActorId ConnectionID; TDeque RecycledRequests; TEvHttpConnectionClosed(const TActorId& connectionID) : ConnectionID(connectionID) {} TEvHttpConnectionClosed(const TActorId& connectionID, TDeque recycledRequests) : ConnectionID(connectionID) , RecycledRequests(std::move(recycledRequests)) {} }; struct TEvHttpAcceptorClosed : NActors::TEventLocal { TActorId ConnectionID; TEvHttpAcceptorClosed(const TActorId& connectionID) : ConnectionID(connectionID) {} }; struct TEvResolveHostRequest : NActors::TEventLocal { TString Host; TEvResolveHostRequest(const TString& host) : Host(host) {} }; struct TEvResolveHostResponse : NActors::TEventLocal { TString Host; THttpConfig::SocketAddressType Address; TString Error; TEvResolveHostResponse(const TString& host, THttpConfig::SocketAddressType address) : Host(host) , Address(address) {} TEvResolveHostResponse(const TString& error) : Error(error) {} }; struct TEvReportSensors : TSensors, NActors::TEventLocal { using TSensors::TSensors; TEvReportSensors(const TSensors& sensors) : TSensors(sensors) {} }; }; struct TPrivateEndpointInfo : THttpEndpointInfo { TActorId Proxy; TActorId Owner; TSslHelpers::TSslHolder SecureContext; TPrivateEndpointInfo(const std::vector& compressContentTypes) : THttpEndpointInfo(compressContentTypes) {} }; NActors::IActor* CreateHttpProxy(std::weak_ptr registry = NMonitoring::TMetricRegistry::SharedInstance()); NActors::IActor* CreateHttpAcceptorActor(const TActorId& owner, const TActorId& poller); NActors::IActor* CreateOutgoingConnectionActor(const TActorId& owner, bool secure, const TActorId& poller); NActors::IActor* CreateIncomingConnectionActor( std::shared_ptr endpoint, TIntrusivePtr socket, THttpConfig::SocketAddressType address, THttpIncomingRequestPtr recycledRequest = nullptr); TEvHttpProxy::TEvReportSensors* BuildOutgoingRequestSensors(const THttpOutgoingRequestPtr& request, const THttpIncomingResponsePtr& response); TEvHttpProxy::TEvReportSensors* BuildIncomingRequestSensors(const THttpIncomingRequestPtr& request, const THttpOutgoingResponsePtr& response); }