/proc/self/cwd/source/common/router/upstream_codec_filter.h
Line | Count | Source (jump to first uncovered line) |
1 | | #pragma once |
2 | | |
3 | | #include <chrono> |
4 | | #include <cstdint> |
5 | | #include <functional> |
6 | | #include <memory> |
7 | | #include <string> |
8 | | |
9 | | #include "envoy/extensions/filters/http/upstream_codec/v3/upstream_codec.pb.h" |
10 | | #include "envoy/extensions/filters/http/upstream_codec/v3/upstream_codec.pb.validate.h" |
11 | | #include "envoy/http/conn_pool.h" |
12 | | #include "envoy/http/filter.h" |
13 | | |
14 | | #include "source/common/common/logger.h" |
15 | | #include "source/common/config/well_known_names.h" |
16 | | #include "source/extensions/filters/http/common/factory_base.h" |
17 | | |
18 | | namespace Envoy { |
19 | | namespace Router { |
20 | | |
21 | | // This is the last filter in the upstream HTTP filter chain. |
22 | | // It takes request headers/body/data from the filter manager and encodes them to the upstream |
23 | | // codec. It also registers the CodecBridge with the upstream stream, and takes response |
24 | | // headers/body/data from the upstream stream and sends them to the filter manager. |
25 | | class UpstreamCodecFilter : public Http::StreamDecoderFilter, |
26 | | public Logger::Loggable<Logger::Id::router>, |
27 | | public Http::DownstreamWatermarkCallbacks, |
28 | | public Http::UpstreamCallbacks { |
29 | | public: |
30 | 2.40k | UpstreamCodecFilter() : bridge_(*this), calling_encode_headers_(false), deferred_reset_(false) {} |
31 | | |
32 | | // Http::DownstreamWatermarkCallbacks |
33 | | void onBelowWriteBufferLowWatermark() override; |
34 | | void onAboveWriteBufferHighWatermark() override; |
35 | | |
36 | | // UpstreamCallbacks |
37 | | void onUpstreamConnectionEstablished() override; |
38 | | |
39 | | // Http::StreamFilterBase |
40 | 2.40k | void onDestroy() override { callbacks_->removeDownstreamWatermarkCallbacks(*this); } |
41 | | |
42 | | // Http::StreamDecoderFilter |
43 | | Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap& headers, |
44 | | bool end_stream) override; |
45 | | Http::FilterDataStatus decodeData(Buffer::Instance& data, bool end_stream) override; |
46 | | Http::FilterTrailersStatus decodeTrailers(Http::RequestTrailerMap& trailers) override; |
47 | | Http::FilterMetadataStatus decodeMetadata(Http::MetadataMap& metadata_map) override; |
48 | | void setDecoderFilterCallbacks(Http::StreamDecoderFilterCallbacks& callbacks) override; |
49 | | |
50 | | // This bridge connects the upstream stream to the filter manager. |
51 | | class CodecBridge : public UpstreamToDownstream { |
52 | | public: |
53 | 2.40k | CodecBridge(UpstreamCodecFilter& filter) : filter_(filter) {} Envoy::Router::UpstreamCodecFilter::CodecBridge::CodecBridge(Envoy::Router::UpstreamCodecFilter&) Line | Count | Source | 53 | 2.40k | CodecBridge(UpstreamCodecFilter& filter) : filter_(filter) {} |
Unexecuted instantiation: Envoy::Router::UpstreamCodecFilter::CodecBridge::CodecBridge(Envoy::Router::UpstreamCodecFilter&) |
54 | | void decode1xxHeaders(Http::ResponseHeaderMapPtr&& headers) override; |
55 | | void decodeHeaders(Http::ResponseHeaderMapPtr&& headers, bool end_stream) override; |
56 | | void decodeData(Buffer::Instance& data, bool end_stream) override; |
57 | | void decodeTrailers(Http::ResponseTrailerMapPtr&& trailers) override; |
58 | | void decodeMetadata(Http::MetadataMapPtr&&) override; |
59 | | void dumpState(std::ostream& os, int indent_level) const override; |
60 | | |
61 | | void onResetStream(Http::StreamResetReason reason, |
62 | 74 | absl::string_view transport_failure_reason) override { |
63 | 74 | if (filter_.calling_encode_headers_) { |
64 | 0 | filter_.deferred_reset_ = true; |
65 | 0 | return; |
66 | 0 | } |
67 | 74 | if (reason == Http::StreamResetReason::LocalReset) { |
68 | 0 | ASSERT(transport_failure_reason.empty()); |
69 | | // Use this to communicate to the upstream request to not force-terminate. |
70 | 0 | transport_failure_reason = "codec_error"; |
71 | 0 | } |
72 | 74 | filter_.callbacks_->resetStream(reason, transport_failure_reason); |
73 | 74 | } |
74 | 0 | void onAboveWriteBufferHighWatermark() override { |
75 | 0 | filter_.callbacks_->onDecoderFilterAboveWriteBufferHighWatermark(); |
76 | 0 | } |
77 | 0 | void onBelowWriteBufferLowWatermark() override { |
78 | 0 | filter_.callbacks_->onDecoderFilterBelowWriteBufferLowWatermark(); |
79 | 0 | } |
80 | | // UpstreamToDownstream |
81 | 0 | const Route& route() const override { return *filter_.callbacks_->route(); } |
82 | 0 | OptRef<const Network::Connection> connection() const override { |
83 | 0 | return filter_.callbacks_->connection(); |
84 | 0 | } |
85 | 2.39k | const Http::ConnectionPool::Instance::StreamOptions& upstreamStreamOptions() const override { |
86 | 2.39k | return filter_.callbacks_->upstreamCallbacks()->upstreamStreamOptions(); |
87 | 2.39k | } |
88 | | |
89 | | private: |
90 | | void maybeEndDecode(bool end_stream); |
91 | | bool seen_1xx_headers_{}; |
92 | | UpstreamCodecFilter& filter_; |
93 | | }; |
94 | | Http::StreamDecoderFilterCallbacks* callbacks_; |
95 | | CodecBridge bridge_; |
96 | | OptRef<Http::RequestHeaderMap> latched_headers_; |
97 | | // Keep small members (bools and enums) at the end of class, to reduce alignment overhead. |
98 | | bool calling_encode_headers_ : 1; |
99 | | bool deferred_reset_ : 1; |
100 | | absl::optional<bool> latched_end_stream_; |
101 | | |
102 | | private: |
103 | 7.88k | StreamInfo::UpstreamTiming& upstreamTiming() { |
104 | 7.88k | return callbacks_->upstreamCallbacks()->upstreamStreamInfo().upstreamInfo()->upstreamTiming(); |
105 | 7.88k | } |
106 | | }; |
107 | | |
108 | | class UpstreamCodecFilterFactory |
109 | | : public Extensions::HttpFilters::Common::CommonFactoryBase< |
110 | | envoy::extensions::filters::http::upstream_codec::v3::UpstreamCodec>, |
111 | | public Server::Configuration::UpstreamHttpFilterConfigFactory { |
112 | | public: |
113 | 110 | UpstreamCodecFilterFactory() : CommonFactoryBase("envoy.filters.http.upstream_codec") {} Unexecuted instantiation: Envoy::Router::UpstreamCodecFilterFactory::UpstreamCodecFilterFactory() Envoy::Router::UpstreamCodecFilterFactory::UpstreamCodecFilterFactory() Line | Count | Source | 113 | 110 | UpstreamCodecFilterFactory() : CommonFactoryBase("envoy.filters.http.upstream_codec") {} |
|
114 | | |
115 | 220 | std::string category() const override { return "envoy.filters.http.upstream"; } |
116 | | Http::FilterFactoryCb |
117 | | createFilterFactoryFromProto(const Protobuf::Message&, const std::string&, |
118 | 3.26k | Server::Configuration::UpstreamFactoryContext&) override { |
119 | 3.26k | return [](Http::FilterChainFactoryCallbacks& callbacks) -> void { |
120 | 2.39k | callbacks.addStreamDecoderFilter(std::make_shared<UpstreamCodecFilter>()); |
121 | 2.39k | }; |
122 | 3.26k | } |
123 | | bool isTerminalFilterByProtoTyped( |
124 | | const envoy::extensions::filters::http::upstream_codec::v3::UpstreamCodec&, |
125 | 3.26k | Server::Configuration::ServerFactoryContext&) override { |
126 | 3.26k | return true; |
127 | 3.26k | } |
128 | | }; |
129 | | |
130 | | DECLARE_FACTORY(UpstreamCodecFilterFactory); |
131 | | |
132 | | } // namespace Router |
133 | | } // namespace Envoy |