Line data Source code
1 : #pragma once 2 : 3 : #include "source/common/quic/envoy_quic_stream.h" 4 : 5 : #ifdef ENVOY_ENABLE_HTTP_DATAGRAMS 6 : #include "source/common/quic/http_datagram_handler.h" 7 : #endif 8 : #include "source/common/quic/quic_stats_gatherer.h" 9 : 10 : #include "quiche/common/platform/api/quiche_reference_counted.h" 11 : #include "quiche/quic/core/http/quic_spdy_server_stream_base.h" 12 : 13 : namespace Envoy { 14 : namespace Quic { 15 : 16 : // This class is a quic stream and also a response encoder. 17 : class EnvoyQuicServerStream : public quic::QuicSpdyServerStreamBase, 18 : public EnvoyQuicStream, 19 : public Http::ResponseEncoder { 20 : public: 21 : EnvoyQuicServerStream(quic::QuicStreamId id, quic::QuicSpdySession* session, 22 : quic::StreamType type, Http::Http3::CodecStats& stats, 23 : const envoy::config::core::v3::Http3ProtocolOptions& http3_options, 24 : envoy::config::core::v3::HttpProtocolOptions::HeadersWithUnderscoresAction 25 : headers_with_underscores_action); 26 : 27 232 : void setRequestDecoder(Http::RequestDecoder& decoder) override { 28 232 : request_decoder_ = &decoder; 29 232 : stats_gatherer_->setAccessLogHandlers(request_decoder_->accessLogHandlers()); 30 232 : } 31 0 : QuicStatsGatherer* statsGatherer() { return stats_gatherer_.get(); } 32 : 33 : // Http::StreamEncoder 34 : void encode1xxHeaders(const Http::ResponseHeaderMap& headers) override; 35 : void encodeHeaders(const Http::ResponseHeaderMap& headers, bool end_stream) override; 36 : void encodeData(Buffer::Instance& data, bool end_stream) override; 37 : void encodeTrailers(const Http::ResponseTrailerMap& trailers) override; 38 : void encodeMetadata(const Http::MetadataMapVector& metadata_map_vector) override; 39 0 : Http::Http1StreamEncoderOptionsOptRef http1StreamEncoderOptions() override { 40 0 : return absl::nullopt; 41 0 : } 42 0 : bool streamErrorOnInvalidHttpMessage() const override { 43 0 : return http3_options_.override_stream_error_on_invalid_http_message().value(); 44 0 : } 45 : 46 : // Accept headers/trailers and stream info from HCM for deferred logging. We pass on the 47 : // header/trailer shared pointers, but copy the non-shared stream info to avoid lifetime issues if 48 : // the stream is destroyed before logging is complete. 49 : void 50 : setDeferredLoggingHeadersAndTrailers(Http::RequestHeaderMapConstSharedPtr request_header_map, 51 : Http::ResponseHeaderMapConstSharedPtr response_header_map, 52 : Http::ResponseTrailerMapConstSharedPtr response_trailer_map, 53 0 : StreamInfo::StreamInfo& stream_info) override { 54 0 : std::unique_ptr<StreamInfo::StreamInfoImpl> new_stream_info = 55 0 : std::make_unique<StreamInfo::StreamInfoImpl>( 56 0 : filterManagerConnection()->dispatcher().timeSource(), 57 0 : filterManagerConnection()->connectionInfoProviderSharedPtr()); 58 0 : new_stream_info->setFrom(stream_info, request_header_map.get()); 59 0 : stats_gatherer_->setDeferredLoggingHeadersAndTrailers( 60 0 : request_header_map, response_header_map, response_trailer_map, std::move(new_stream_info)); 61 0 : }; 62 : 63 : // Http::Stream 64 : void resetStream(Http::StreamResetReason reason) override; 65 : 66 : // quic::QuicStream 67 : void OnStreamFrame(const quic::QuicStreamFrame& frame) override; 68 : // quic::QuicSpdyStream 69 : void OnBodyAvailable() override; 70 : bool OnStopSending(quic::QuicResetStreamError error) override; 71 : void OnStreamReset(const quic::QuicRstStreamFrame& frame) override; 72 : void ResetWithError(quic::QuicResetStreamError error) override; 73 : void OnClose() override; 74 : void OnCanWrite() override; 75 : // quic::QuicSpdyServerStreamBase 76 : void OnConnectionClosed(quic::QuicErrorCode error, quic::ConnectionCloseSource source) override; 77 : void CloseWriteSide() override; 78 : 79 : void clearWatermarkBuffer(); 80 : 81 : // EnvoyQuicStream 82 : Http::HeaderUtility::HeaderValidationResult 83 : validateHeader(absl::string_view header_name, absl::string_view header_value) override; 84 : 85 : protected: 86 : // EnvoyQuicStream 87 : void switchStreamBlockState() override; 88 : uint32_t streamId() override; 89 : Network::Connection* connection() override; 90 : 91 : // quic::QuicSpdyStream 92 : void OnInitialHeadersComplete(bool fin, size_t frame_len, 93 : const quic::QuicHeaderList& header_list) override; 94 : void OnTrailingHeadersComplete(bool fin, size_t frame_len, 95 : const quic::QuicHeaderList& header_list) override; 96 : void OnHeadersTooLarge() override; 97 : void OnInvalidHeaders() override; 98 : 99 : // Http::MultiplexedStreamImplBase 100 : void onPendingFlushTimer() override; 101 : bool hasPendingData() override; 102 : 103 : void 104 : onStreamError(absl::optional<bool> should_close_connection, 105 : quic::QuicRstStreamErrorCode rst = quic::QUIC_BAD_APPLICATION_PAYLOAD) override; 106 : 107 : private: 108 : QuicFilterManagerConnectionImpl* filterManagerConnection(); 109 : 110 : // Deliver awaiting trailers if body has been delivered. 111 : void maybeDecodeTrailers(); 112 : 113 : #ifdef ENVOY_ENABLE_HTTP_DATAGRAMS 114 : // Makes the QUIC stream use Capsule Protocol. Once this method is called, any calls to encodeData 115 : // are expected to contain capsules which will be sent along as HTTP Datagrams. Also, the stream 116 : // starts to receive HTTP/3 Datagrams and decode into Capsules. 117 : void useCapsuleProtocol(); 118 : #endif 119 : 120 : Http::RequestDecoder* request_decoder_{nullptr}; 121 : envoy::config::core::v3::HttpProtocolOptions::HeadersWithUnderscoresAction 122 : headers_with_underscores_action_; 123 : 124 : quiche::QuicheReferenceCountedPointer<QuicStatsGatherer> stats_gatherer_; 125 : #ifdef ENVOY_ENABLE_HTTP_DATAGRAMS 126 : // Setting |http_datagram_handler_| enables HTTP Datagram support. 127 : std::unique_ptr<HttpDatagramHandler> http_datagram_handler_; 128 : #endif 129 : // True if a :path header has been seen before. 130 : bool saw_path_{false}; 131 : }; 132 : 133 : } // namespace Quic 134 : } // namespace Envoy