Coverage Report

Created: 2023-11-12 09:30

/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