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

            
9
#include "quiche/common/platform/api/quiche_reference_counted.h"
10
#include "quiche/quic/core/http/quic_spdy_server_stream_base.h"
11
#include "quiche/quic/core/qpack/qpack_encoder.h"
12
#include "quiche/quic/core/qpack/qpack_instruction_encoder.h"
13

            
14
namespace Envoy {
15
namespace Quic {
16

            
17
// This class is a quic stream and also a response encoder.
18
class EnvoyQuicServerStream : public quic::QuicSpdyServerStreamBase,
19
                              public EnvoyQuicStream,
20
                              public Http::ResponseEncoder,
21
                              public quic::QuicSpdyStream::MetadataVisitor {
22
public:
23
  EnvoyQuicServerStream(quic::QuicStreamId id, quic::QuicSpdySession* session,
24
                        quic::StreamType type, Http::Http3::CodecStats& stats,
25
                        const envoy::config::core::v3::Http3ProtocolOptions& http3_options,
26
                        envoy::config::core::v3::HttpProtocolOptions::HeadersWithUnderscoresAction
27
                            headers_with_underscores_action);
28

            
29
4035
  void setRequestDecoder(Http::RequestDecoder& decoder) override {
30
4035
    request_decoder_ = decoder.getRequestDecoderHandle();
31
4035
    stats_gatherer_->setAccessLogHandlers(request_decoder_->get()->accessLogHandlers());
32
4035
  }
33

            
34
  // Http::StreamEncoder
35
  void encode1xxHeaders(const Http::ResponseHeaderMap& headers) override;
36
  void encodeHeaders(const Http::ResponseHeaderMap& headers, bool end_stream) override;
37
  void encodeTrailers(const Http::ResponseTrailerMap& trailers) override;
38
3
  Http::Http1StreamEncoderOptionsOptRef http1StreamEncoderOptions() override {
39
3
    return absl::nullopt;
40
3
  }
41
2
  bool streamErrorOnInvalidHttpMessage() const override {
42
2
    return http3_options_.override_stream_error_on_invalid_http_message().value();
43
2
  }
44

            
45
  // Accept headers/trailers and stream info from HCM for deferred logging. We pass on the
46
  // header/trailer shared pointers, but copy the non-shared stream info to avoid lifetime issues if
47
  // the stream is destroyed before logging is complete.
48
  void
49
  setDeferredLoggingHeadersAndTrailers(Http::RequestHeaderMapConstSharedPtr request_header_map,
50
                                       Http::ResponseHeaderMapConstSharedPtr response_header_map,
51
                                       Http::ResponseTrailerMapConstSharedPtr response_trailer_map,
52
1507
                                       StreamInfo::StreamInfo& stream_info) override {
53
1507
    std::unique_ptr<StreamInfo::StreamInfoImpl> new_stream_info =
54
1507
        std::make_unique<StreamInfo::StreamInfoImpl>(
55
1507
            filterManagerConnection()->dispatcher().timeSource(),
56
1507
            filterManagerConnection()->connectionInfoProviderSharedPtr(),
57
1507
            StreamInfo::FilterState::LifeSpan::FilterChain);
58
1507
    new_stream_info->setFrom(stream_info, request_header_map.get());
59
1507
    stats_gatherer_->setDeferredLoggingHeadersAndTrailers(
60
1507
        request_header_map, response_header_map, response_trailer_map, std::move(new_stream_info));
61
1507
  };
62

            
63
  // Http::Stream
64
  void resetStream(Http::StreamResetReason reason) override;
65
2537
  absl::optional<uint32_t> codecStreamId() const override { return id(); }
66

            
67
  // quic::QuicStream
68
  void OnStreamFrame(const quic::QuicStreamFrame& frame) override;
69
  void OnSoonToBeDestroyed() override;
70
  // quic::QuicSpdyStream
71
  void OnBodyAvailable() override;
72
  bool OnStopSending(quic::QuicResetStreamError error) override;
73
  void OnStreamReset(const quic::QuicRstStreamFrame& frame) override;
74
  void ResetWithError(quic::QuicResetStreamError error) override;
75
  void OnClose() override;
76
  void OnCanWrite() override;
77
  // quic::QuicSpdyServerStreamBase
78
  void OnConnectionClosed(const quic::QuicConnectionCloseFrame& frame,
79
                          quic::ConnectionCloseSource source) override;
80
  void CloseWriteSide() override;
81

            
82
  void clearWatermarkBuffer();
83

            
84
  // EnvoyQuicStream
85
  Http::HeaderUtility::HeaderValidationResult
86
  validateHeader(absl::string_view header_name, absl::string_view header_value) override;
87

            
88
  // quic::QuicSpdyStream::MetadataVisitor
89
  void OnMetadataComplete(size_t frame_len, const quic::QuicHeaderList& header_list) override;
90

            
91
protected:
92
  // EnvoyQuicStream
93
  void switchStreamBlockState() override;
94
  uint32_t streamId() override;
95
  Network::Connection* connection() override;
96

            
97
  // quic::QuicSpdyStream
98
  void OnInitialHeadersComplete(bool fin, size_t frame_len,
99
                                const quic::QuicHeaderList& header_list) override;
100
  void OnTrailingHeadersComplete(bool fin, size_t frame_len,
101
                                 const quic::QuicHeaderList& header_list) override;
102
  void OnHeadersTooLarge() override;
103
  void OnInvalidHeaders() override;
104

            
105
  // Http::MultiplexedStreamImplBase
106
  void onPendingFlushTimer() override;
107
  bool hasPendingData() override;
108

            
109
  void
110
  onStreamError(absl::optional<bool> should_close_connection,
111
                quic::QuicRstStreamErrorCode rst = quic::QUIC_BAD_APPLICATION_PAYLOAD) override;
112

            
113
private:
114
  QuicFilterManagerConnectionImpl* filterManagerConnection();
115

            
116
  // Deliver awaiting trailers if body has been delivered.
117
  void maybeDecodeTrailers();
118

            
119
#ifdef ENVOY_ENABLE_HTTP_DATAGRAMS
120
  // Makes the QUIC stream use Capsule Protocol. Once this method is called, any calls to encodeData
121
  // are expected to contain capsules which will be sent along as HTTP Datagrams. Also, the stream
122
  // starts to receive HTTP/3 Datagrams and decode into Capsules.
123
  void useCapsuleProtocol();
124
#endif
125

            
126
  Http::RequestDecoderHandlePtr request_decoder_;
127
  envoy::config::core::v3::HttpProtocolOptions::HeadersWithUnderscoresAction
128
      headers_with_underscores_action_;
129

            
130
  // True if a :path header has been seen before.
131
  bool saw_path_{false};
132
};
133

            
134
} // namespace Quic
135
} // namespace Envoy