Lines
100 %
Functions
#pragma once
#include "envoy/buffer/buffer.h"
#include "source/common/quic/envoy_quic_stream.h"
#include "source/common/runtime/runtime_features.h"
#ifdef ENVOY_ENABLE_HTTP_DATAGRAMS
#include "source/common/quic/http_datagram_handler.h"
#endif
#include "quiche/common/simple_buffer_allocator.h"
#include "quiche/quic/core/http/quic_spdy_client_stream.h"
#include "quiche/quic/core/qpack/qpack_encoder.h"
#include "quiche/quic/core/qpack/qpack_instruction_encoder.h"
namespace Envoy {
namespace Quic {
// This class is a quic stream and also a request encoder.
class EnvoyQuicClientStream : public quic::QuicSpdyClientStream,
public EnvoyQuicStream,
public Http::RequestEncoder,
public quic::QuicSpdyStream::MetadataVisitor {
public:
EnvoyQuicClientStream(quic::QuicStreamId id, quic::QuicSpdyClientSession* client_session,
quic::StreamType type, Http::Http3::CodecStats& stats,
const envoy::config::core::v3::Http3ProtocolOptions& http3_options);
void setResponseDecoder(Http::ResponseDecoder& decoder);
// Http::StreamEncoder
Http::Http1StreamEncoderOptionsOptRef http1StreamEncoderOptions() override {
return absl::nullopt;
}
// Http::RequestEncoder
Http::Status encodeHeaders(const Http::RequestHeaderMap& headers, bool end_stream) override;
void encodeTrailers(const Http::RequestTrailerMap& trailers) override;
void enableTcpTunneling() override {}
// Http::Stream
void resetStream(Http::StreamResetReason reason) override;
void setFlushTimeout(std::chrono::milliseconds) override {}
absl::optional<uint32_t> codecStreamId() const override { return id(); }
// quic::QuicStream
void OnStreamFrame(const quic::QuicStreamFrame& frame) override;
bool OnStopSending(quic::QuicResetStreamError error) override;
// quic::QuicSpdyStream
void OnBodyAvailable() override;
void OnStreamReset(const quic::QuicRstStreamFrame& frame) override;
void ResetWithError(quic::QuicResetStreamError error) override;
void OnClose() override;
void OnCanWrite() override;
// quic::Stream
void OnConnectionClosed(const quic::QuicConnectionCloseFrame& frame,
quic::ConnectionCloseSource source) override;
void clearWatermarkBuffer();
// quic::QuicSpdyStream::MetadataVisitor
void OnMetadataComplete(size_t frame_len, const quic::QuicHeaderList& header_list) override;
protected:
// EnvoyQuicStream
void switchStreamBlockState() override;
uint32_t streamId() override;
Network::Connection* connection() override;
// Overridden to pass headers to decoder.
void OnInitialHeadersComplete(bool fin, size_t frame_len,
const quic::QuicHeaderList& header_list) override;
void OnTrailingHeadersComplete(bool fin, size_t frame_len,
void OnInvalidHeaders() override;
// Http::MultiplexedStreamImplBase
bool hasPendingData() override;
void onStreamError(absl::optional<bool> should_close_connection,
quic::QuicRstStreamErrorCode rst_code) override;
private:
QuicFilterManagerConnectionImpl* filterManagerConnection();
// Deliver awaiting trailers if body has been delivered.
void maybeDecodeTrailers();
// Makes the QUIC stream use Capsule Protocol. Once this method is called, any calls to encodeData
// are expected to contain capsules which will be sent along as HTTP Datagrams. Also, the stream
// starts to receive HTTP/3 Datagrams and decode into Capsules.
void useCapsuleProtocol();
// Returns nullptr if the response decoder has already been destructed.
Http::ResponseDecoder* getResponseDecoder();
void onResponseDecoderDead() const;
Http::ResponseDecoderHandlePtr response_decoder_handle_;
Http::ResponseDecoder* response_decoder_{nullptr};
bool decoded_1xx_{false};
// When an HTTP Upgrade is requested, this contains the protocol upgrade type, e.g. "websocket".
// It will be empty, when no such request is active.
std::string upgrade_protocol_;
};
} // namespace Quic
} // namespace Envoy