Coverage Report

Created: 2023-11-12 09:30

/proc/self/cwd/test/common/http/conn_manager_impl_test_base.h
Line
Count
Source (jump to first uncovered line)
1
#pragma once
2
3
#include "source/common/http/conn_manager_impl.h"
4
#include "source/common/http/context_impl.h"
5
#include "source/common/http/date_provider_impl.h"
6
#include "source/common/network/address_impl.h"
7
#include "source/common/tracing/custom_tag_impl.h"
8
#include "source/extensions/access_loggers/common/file_access_log_impl.h"
9
#include "source/extensions/http/header_validators/envoy_default/http1_header_validator.h"
10
11
#include "test/mocks/access_log/mocks.h"
12
#include "test/mocks/event/mocks.h"
13
#include "test/mocks/http/header_validator.h"
14
#include "test/mocks/http/mocks.h"
15
#include "test/mocks/local_info/mocks.h"
16
#include "test/mocks/network/mocks.h"
17
#include "test/mocks/router/mocks.h"
18
#include "test/mocks/runtime/mocks.h"
19
#include "test/mocks/server/factory_context.h"
20
#include "test/mocks/ssl/mocks.h"
21
#include "test/test_common/delegating_route_utility.h"
22
#include "test/test_common/simulated_time_system.h"
23
24
#include "gmock/gmock.h"
25
#include "gtest/gtest.h"
26
27
using testing::NiceMock;
28
29
namespace Envoy {
30
namespace Http {
31
32
// Base class for HttpConnectionManagerImpl related tests. This base class is used by tests under
33
// common/http as well as test/extensions/filters/http/ext_proc/, to reuse the many mocks/default
34
// impls of ConnectionManagerConfig that we need to provide to HttpConnectionManagerImpl.
35
class HttpConnectionManagerImplMixin : public ConnectionManagerConfig {
36
public:
37
  HttpConnectionManagerImplMixin();
38
  ~HttpConnectionManagerImplMixin() override;
39
  Tracing::CustomTagConstSharedPtr requestHeaderCustomTag(const std::string& header);
40
  void setup(bool ssl, const std::string& server_name, bool tracing = true, bool use_srds = false);
41
  void setupFilterChain(int num_decoder_filters, int num_encoder_filters, int num_requests = 1);
42
  void setUpBufferLimits();
43
44
  // If request_with_data_and_trailers is true, includes data and trailers in the request. If
45
  // decode_headers_stop_all is true, decoder_filters_[0]'s callback decodeHeaders() returns
46
  // StopAllIterationAndBuffer.
47
  void setUpEncoderAndDecoder(bool request_with_data_and_trailers, bool decode_headers_stop_all);
48
49
  // Sends request headers, and stashes the new stream in decoder_;
50
  void startRequest(bool end_stream = false, absl::optional<std::string> body = absl::nullopt);
51
52
  Event::MockTimer* setUpTimer();
53
  void sendRequestHeadersAndData();
54
  ResponseHeaderMap*
55
  sendResponseHeaders(ResponseHeaderMapPtr&& response_headers,
56
                      absl::optional<StreamInfo::ResponseFlag> response_flag = absl::nullopt,
57
                      std::string response_code_details = "details");
58
  void expectOnDestroy(bool deferred = true);
59
  void doRemoteClose(bool deferred = true);
60
  void testPathNormalization(const RequestHeaderMap& request_headers,
61
                             const ResponseHeaderMap& expected_response);
62
63
  // Http::ConnectionManagerConfig
64
7
  const std::list<AccessLog::InstanceSharedPtr>& accessLogs() override { return access_logs_; }
65
7
  bool flushAccessLogOnNewRequest() override { return flush_access_log_on_new_request_; }
66
0
  bool flushAccessLogOnTunnelSuccessfullyEstablished() const override {
67
0
    return flush_log_on_tunnel_successfully_established_;
68
0
  }
69
7
  const absl::optional<std::chrono::milliseconds>& accessLogFlushInterval() override {
70
7
    return access_log_flush_interval_;
71
7
  }
72
  ServerConnectionPtr createCodec(Network::Connection&, const Buffer::Instance&,
73
0
                                  ServerConnectionCallbacks&, Server::OverloadManager&) override {
74
0
    return ServerConnectionPtr{codec_};
75
0
  }
76
1
  DateProvider& dateProvider() override { return date_provider_; }
77
0
  std::chrono::milliseconds drainTimeout() const override { return std::chrono::milliseconds(100); }
78
7
  FilterChainFactory& filterFactory() override { return filter_factory_; }
79
7
  bool generateRequestId() const override { return true; }
80
7
  bool preserveExternalRequestId() const override { return false; }
81
1
  bool alwaysSetRequestIdInResponse() const override { return false; }
82
0
  uint32_t maxRequestHeadersKb() const override { return max_request_headers_kb_; }
83
0
  uint32_t maxRequestHeadersCount() const override { return max_request_headers_count_; }
84
18
  absl::optional<std::chrono::milliseconds> idleTimeout() const override { return idle_timeout_; }
85
28
  bool isRoutable() const override { return true; }
86
18
  absl::optional<std::chrono::milliseconds> maxConnectionDuration() const override {
87
18
    return max_connection_duration_;
88
18
  }
89
7
  std::chrono::milliseconds streamIdleTimeout() const override { return stream_idle_timeout_; }
90
7
  std::chrono::milliseconds requestTimeout() const override { return request_timeout_; }
91
7
  std::chrono::milliseconds requestHeadersTimeout() const override {
92
7
    return request_headers_timeout_;
93
7
  }
94
18
  std::chrono::milliseconds delayedCloseTimeout() const override { return delayed_close_timeout_; }
95
14
  absl::optional<std::chrono::milliseconds> maxStreamDuration() const override {
96
14
    return max_stream_duration_;
97
14
  }
98
  bool use_srds_{};
99
42
  Router::RouteConfigProvider* routeConfigProvider() override {
100
42
    if (use_srds_) {
101
0
      return nullptr;
102
0
    }
103
42
    return &route_config_provider_;
104
42
  }
105
14
  Config::ConfigProvider* scopedRouteConfigProvider() override {
106
14
    if (use_srds_) {
107
0
      return &scoped_route_config_provider_;
108
0
    }
109
14
    return nullptr;
110
14
  }
111
7
  OptRef<const Router::ScopeKeyBuilder> scopeKeyBuilder() override {
112
7
    if (use_srds_) {
113
0
      return scope_key_builder_;
114
0
    }
115
7
    return {};
116
7
  }
117
19
  const std::string& serverName() const override { return server_name_; }
118
  HttpConnectionManagerProto::ServerHeaderTransformation
119
1
  serverHeaderTransformation() const override {
120
1
    return server_transformation_;
121
1
  }
122
7
  const absl::optional<std::string>& schemeToSet() const override { return scheme_; }
123
18
  ConnectionManagerStats& stats() override { return stats_; }
124
0
  ConnectionManagerTracingStats& tracingStats() override { return tracing_stats_; }
125
7
  bool useRemoteAddress() const override { return use_remote_address_; }
126
7
  const Http::InternalAddressConfig& internalAddressConfig() const override {
127
7
    return internal_address_config_;
128
7
  }
129
7
  uint32_t xffNumTrustedHops() const override { return 0; }
130
7
  bool skipXffAppend() const override { return false; }
131
8
  const std::string& via() const override { return EMPTY_STRING; }
132
14
  Http::ForwardClientCertType forwardClientCert() const override { return forward_client_cert_; }
133
0
  const std::vector<Http::ClientCertDetailsType>& setCurrentClientCertDetails() const override {
134
0
    return set_current_client_cert_details_;
135
0
  }
136
0
  const Network::Address::Instance& localAddress() override { return local_address_; }
137
7
  const absl::optional<std::string>& userAgent() override { return user_agent_; }
138
0
  Tracing::TracerSharedPtr tracer() override { return tracer_; }
139
14
  const TracingConnectionManagerConfig* tracingConfig() override { return tracing_config_.get(); }
140
18
  ConnectionManagerListenerStats& listenerStats() override { return listener_stats_; }
141
14
  bool proxy100Continue() const override { return proxy_100_continue_; }
142
0
  bool streamErrorOnInvalidHttpMessaging() const override {
143
0
    return stream_error_on_invalid_http_messaging_;
144
0
  }
145
0
  const Http::Http1Settings& http1Settings() const override { return http1_settings_; }
146
7
  bool shouldNormalizePath() const override { return normalize_path_; }
147
7
  bool shouldMergeSlashes() const override { return merge_slashes_; }
148
7
  bool shouldStripTrailingHostDot() const override { return strip_trailing_host_dot_; }
149
14
  Http::StripPortType stripPortType() const override { return strip_port_type_; }
150
7
  const RequestIDExtensionSharedPtr& requestIDExtension() override { return request_id_extension_; }
151
  envoy::config::core::v3::HttpProtocolOptions::HeadersWithUnderscoresAction
152
0
  headersWithUnderscoresAction() const override {
153
0
    return headers_with_underscores_action_;
154
0
  }
155
7
  const LocalReply::LocalReply& localReply() const override { return *local_reply_; }
156
  envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager::
157
      PathWithEscapedSlashesAction
158
7
      pathWithEscapedSlashesAction() const override {
159
7
    return path_with_escaped_slashes_action_;
160
7
  }
161
  const std::vector<Http::OriginalIPDetectionSharedPtr>&
162
0
  originalIpDetectionExtensions() const override {
163
0
    return ip_detection_extensions_;
164
0
  }
165
7
  const std::vector<Http::EarlyHeaderMutationPtr>& earlyHeaderMutationExtensions() const override {
166
7
    return early_header_mutations_;
167
7
  }
168
7
  uint64_t maxRequestsPerConnection() const override { return max_requests_per_connection_; }
169
19
  const HttpConnectionManagerProto::ProxyStatusConfig* proxyStatusConfig() const override {
170
19
    return proxy_status_config_.get();
171
19
  }
172
7
  ServerHeaderValidatorPtr makeHeaderValidator(Protocol protocol) override {
173
7
    return header_validator_factory_.createServerHeaderValidator(protocol, header_validator_stats_);
174
7
  }
175
14
  bool appendXForwardedPort() const override { return false; }
176
18
  bool addProxyProtocolConnectionState() const override {
177
18
    return add_proxy_protocol_connection_state_;
178
18
  }
179
180
  // Simple helper to wrapper filter to the factory function.
181
0
  FilterFactoryCb createDecoderFilterFactoryCb(StreamDecoderFilterSharedPtr filter) {
182
0
    return [filter](FilterChainFactoryCallbacks& callbacks) {
183
0
      callbacks.addStreamDecoderFilter(filter);
184
0
    };
185
0
  }
186
0
  FilterFactoryCb createEncoderFilterFactoryCb(StreamEncoderFilterSharedPtr filter) {
187
0
    return [filter](FilterChainFactoryCallbacks& callbacks) {
188
0
      callbacks.addStreamEncoderFilter(filter);
189
0
    };
190
0
  }
191
0
  FilterFactoryCb createStreamFilterFactoryCb(StreamFilterSharedPtr filter) {
192
0
    return [filter](FilterChainFactoryCallbacks& callbacks) { callbacks.addStreamFilter(filter); };
193
0
  }
194
0
  FilterFactoryCb createLogHandlerFactoryCb(AccessLog::InstanceSharedPtr handler) {
195
0
    return [handler](FilterChainFactoryCallbacks& callbacks) {
196
0
      callbacks.addAccessLogHandler(handler);
197
0
    };
198
0
  }
199
  void expectUhvHeaderCheck(
200
      HeaderValidator::ValidationResult validation_result,
201
      ServerHeaderValidator::RequestHeadersTransformationResult transformation_result);
202
  void expectUhvTrailerCheck(HeaderValidator::ValidationResult validation_result,
203
                             HeaderValidator::TransformationResult transformation_result,
204
                             bool expect_response = true);
205
  // This method sets-up expectation that UHV will be called and provides real default UHV to
206
  // validate headers.
207
  void expectCheckWithDefaultUhv();
208
209
  Event::MockSchedulableCallback* enableStreamsPerIoLimit(uint32_t limit);
210
211
  Envoy::Event::SimulatedTimeSystem test_time_;
212
  NiceMock<Router::MockRouteConfigProvider> route_config_provider_;
213
  std::shared_ptr<Router::MockConfig> route_config_{new NiceMock<Router::MockConfig>()};
214
  NiceMock<Router::MockScopedRouteConfigProvider> scoped_route_config_provider_;
215
  Router::MockScopeKeyBuilder scope_key_builder_;
216
  Stats::TestUtil::TestSymbolTable symbol_table_;
217
  Stats::IsolatedStoreImpl fake_stats_;
218
  Http::ContextImpl http_context_;
219
  NiceMock<Runtime::MockLoader> runtime_;
220
  NiceMock<Envoy::AccessLog::MockAccessLogManager> log_manager_;
221
  std::string access_log_path_;
222
  std::list<AccessLog::InstanceSharedPtr> access_logs_;
223
  bool flush_access_log_on_new_request_ = false;
224
  bool flush_log_on_tunnel_successfully_established_ = false;
225
  absl::optional<std::chrono::milliseconds> access_log_flush_interval_;
226
  NiceMock<Network::MockReadFilterCallbacks> filter_callbacks_;
227
  MockServerConnection* codec_;
228
  NiceMock<MockFilterChainFactory> filter_factory_;
229
  ConnectionManagerStats stats_;
230
  ConnectionManagerTracingStats tracing_stats_{CONN_MAN_TRACING_STATS(POOL_COUNTER(fake_stats_))};
231
  NiceMock<Network::MockDrainDecision> drain_close_;
232
  std::unique_ptr<ConnectionManagerImpl> conn_manager_;
233
  std::string server_name_;
234
  HttpConnectionManagerProto::ServerHeaderTransformation server_transformation_{
235
      HttpConnectionManagerProto::OVERWRITE};
236
  absl::optional<std::string> scheme_;
237
  Network::Address::Ipv4Instance local_address_{"127.0.0.1"};
238
  bool use_remote_address_{true};
239
  Http::DefaultInternalAddressConfig internal_address_config_;
240
  Http::ForwardClientCertType forward_client_cert_{Http::ForwardClientCertType::Sanitize};
241
  std::vector<Http::ClientCertDetailsType> set_current_client_cert_details_;
242
  absl::optional<std::string> user_agent_;
243
  uint32_t max_request_headers_kb_{Http::DEFAULT_MAX_REQUEST_HEADERS_KB};
244
  uint32_t max_request_headers_count_{Http::DEFAULT_MAX_HEADERS_COUNT};
245
  uint64_t max_requests_per_connection_{};
246
  absl::optional<std::chrono::milliseconds> idle_timeout_;
247
  absl::optional<std::chrono::milliseconds> max_connection_duration_;
248
  std::chrono::milliseconds stream_idle_timeout_{};
249
  std::chrono::milliseconds request_timeout_{};
250
  std::chrono::milliseconds request_headers_timeout_{};
251
  std::chrono::milliseconds delayed_close_timeout_{};
252
  absl::optional<std::chrono::milliseconds> max_stream_duration_{};
253
  NiceMock<Random::MockRandomGenerator> random_;
254
  NiceMock<LocalInfo::MockLocalInfo> local_info_;
255
  NiceMock<Server::Configuration::MockFactoryContext> factory_context_;
256
  RequestDecoder* decoder_{};
257
  std::shared_ptr<Ssl::MockConnectionInfo> ssl_connection_;
258
  std::shared_ptr<NiceMock<Tracing::MockTracer>> tracer_{
259
      std::make_shared<NiceMock<Tracing::MockTracer>>()};
260
  TracingConnectionManagerConfigPtr tracing_config_;
261
  SlowDateProviderImpl date_provider_{test_time_.timeSystem()};
262
  Http::StreamCallbacks* stream_callbacks_{nullptr};
263
  NiceMock<Upstream::MockClusterManager> cluster_manager_;
264
  NiceMock<Server::MockOverloadManager> overload_manager_;
265
  uint32_t initial_buffer_limit_{};
266
  bool streaming_filter_{false};
267
  Stats::IsolatedStoreImpl fake_listener_stats_;
268
  ConnectionManagerListenerStats listener_stats_;
269
  bool proxy_100_continue_ = false;
270
  bool stream_error_on_invalid_http_messaging_ = false;
271
  bool preserve_external_request_id_ = false;
272
  Http::Http1Settings http1_settings_;
273
  bool normalize_path_ = false;
274
  bool merge_slashes_ = false;
275
  Http::StripPortType strip_port_type_ = Http::StripPortType::None;
276
  envoy::config::core::v3::HttpProtocolOptions::HeadersWithUnderscoresAction
277
      headers_with_underscores_action_ = envoy::config::core::v3::HttpProtocolOptions::ALLOW;
278
  NiceMock<Network::MockClientConnection> upstream_conn_; // for websocket tests
279
  NiceMock<Tcp::ConnectionPool::MockInstance> conn_pool_; // for websocket tests
280
  RequestIDExtensionSharedPtr request_id_extension_;
281
  std::vector<Http::OriginalIPDetectionSharedPtr> ip_detection_extensions_{};
282
  std::vector<Http::EarlyHeaderMutationPtr> early_header_mutations_{};
283
  bool add_proxy_protocol_connection_state_ = true;
284
285
  const LocalReply::LocalReplyPtr local_reply_;
286
287
  NiceMock<MockResponseEncoder> response_encoder_;
288
  std::vector<MockStreamDecoderFilter*> decoder_filters_;
289
  std::vector<MockStreamEncoderFilter*> encoder_filters_;
290
  std::shared_ptr<AccessLog::MockInstance> log_handler_;
291
  envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager::
292
      PathWithEscapedSlashesAction path_with_escaped_slashes_action_{
293
          envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager::
294
              KEEP_UNCHANGED};
295
  bool strip_trailing_host_dot_ = false;
296
  std::unique_ptr<HttpConnectionManagerProto::ProxyStatusConfig> proxy_status_config_;
297
  NiceMock<MockHeaderValidatorFactory> header_validator_factory_;
298
  NiceMock<MockHeaderValidatorStats> header_validator_stats_;
299
  envoy::extensions::http::header_validators::envoy_default::v3::HeaderValidatorConfig
300
      header_validator_config_;
301
  Extensions::Http::HeaderValidators::EnvoyDefault::ConfigOverrides
302
      header_validator_config_overrides_;
303
};
304
305
class HttpConnectionManagerImplTest : public HttpConnectionManagerImplMixin,
306
                                      public testing::Test {};
307
} // namespace Http
308
} // namespace Envoy