Line data Source code
1 : #pragma once 2 : 3 : #include "envoy/network/connection.h" 4 : #include "envoy/network/transport_socket.h" 5 : 6 : #include "source/common/buffer/buffer_impl.h" 7 : #include "source/common/common/logger.h" 8 : #include "source/common/http/http1/balsa_parser.h" 9 : #include "source/extensions/transport_sockets/common/passthrough.h" 10 : 11 : namespace Envoy { 12 : namespace Extensions { 13 : namespace TransportSockets { 14 : namespace Http11Connect { 15 : 16 : // If the transport socket options contain http11ProxyInfo and the transport is 17 : // secure, this will prepend a CONNECT request to the outbound data and strip 18 : // the CONNECT response from the inbound data. 19 : class UpstreamHttp11ConnectSocket : public TransportSockets::PassthroughSocket, 20 : public Logger::Loggable<Logger::Id::connection> { 21 : public: 22 : // Processes response_payload and returns true if it is a valid connect 23 : // response with status code 200. 24 : // @param response_payload the HTTP response bytes 25 : // @param header_complete will be set to true if the response payload contains complete headers. 26 : // @param bytes_processed will return how many bytes of response_payload were processed. 27 : static bool isValidConnectResponse(absl::string_view response_payload, bool& headers_complete, 28 : size_t& bytes_processed); 29 : 30 : UpstreamHttp11ConnectSocket(Network::TransportSocketPtr&& transport_socket, 31 : Network::TransportSocketOptionsConstSharedPtr options); 32 : 33 : void setTransportSocketCallbacks(Network::TransportSocketCallbacks& callbacks) override; 34 : Network::IoResult doWrite(Buffer::Instance& buffer, bool end_stream) override; 35 : Network::IoResult doRead(Buffer::Instance& buffer) override; 36 : 37 : private: 38 : void generateHeader(); 39 : Network::IoResult writeHeader(); 40 : 41 : Network::TransportSocketOptionsConstSharedPtr options_; 42 : Network::TransportSocketCallbacks* callbacks_{}; 43 : Buffer::OwnedImpl header_buffer_{}; 44 : bool need_to_strip_connect_response_{}; 45 : }; 46 : 47 : class UpstreamHttp11ConnectSocketFactory : public PassthroughFactory { 48 : public: 49 : UpstreamHttp11ConnectSocketFactory( 50 : Network::UpstreamTransportSocketFactoryPtr transport_socket_factory); 51 : 52 : // Network::TransportSocketFactory 53 : Network::TransportSocketPtr 54 : createTransportSocket(Network::TransportSocketOptionsConstSharedPtr options, 55 : std::shared_ptr<const Upstream::HostDescription> host) const override; 56 : void hashKey(std::vector<uint8_t>& key, 57 : Network::TransportSocketOptionsConstSharedPtr options) const override; 58 : }; 59 : 60 : // This is a utility class for isValidConnectResponse. It is only exposed for 61 : // coverage testing purposes. See isValidConnectResponse for intended use. 62 : class SelfContainedParser : public Http::Http1::ParserCallbacks { 63 : public: 64 : SelfContainedParser() 65 : : parser_(Http::Http1::MessageType::Response, this, 2000, /* enable_trailers = */ false, 66 0 : /* allow_custom_methods = */ false) {} 67 0 : Http::Http1::CallbackResult onMessageBegin() override { 68 0 : return Http::Http1::CallbackResult::Success; 69 0 : } 70 0 : Http::Http1::CallbackResult onUrl(const char*, size_t) override { 71 0 : return Http::Http1::CallbackResult::Success; 72 0 : } 73 0 : Http::Http1::CallbackResult onStatus(const char*, size_t) override { 74 0 : return Http::Http1::CallbackResult::Success; 75 0 : } 76 0 : Http::Http1::CallbackResult onHeaderField(const char*, size_t) override { 77 0 : return Http::Http1::CallbackResult::Success; 78 0 : } 79 0 : Http::Http1::CallbackResult onHeaderValue(const char*, size_t) override { 80 0 : return Http::Http1::CallbackResult::Success; 81 0 : } 82 0 : Http::Http1::CallbackResult onHeadersComplete() override { 83 0 : headers_complete_ = true; 84 0 : parser_.pause(); 85 0 : return Http::Http1::CallbackResult::Success; 86 0 : } 87 0 : void bufferBody(const char*, size_t) override {} 88 0 : Http::Http1::CallbackResult onMessageComplete() override { 89 0 : return Http::Http1::CallbackResult::Success; 90 0 : } 91 0 : void onChunkHeader(bool) override {} 92 : 93 0 : bool headersComplete() const { return headers_complete_; } 94 0 : Http::Http1::BalsaParser& parser() { return parser_; } 95 : 96 : private: 97 : bool headers_complete_ = false; 98 : Http::Http1::BalsaParser parser_; 99 : }; 100 : 101 : } // namespace Http11Connect 102 : } // namespace TransportSockets 103 : } // namespace Extensions 104 : } // namespace Envoy