1
#pragma once
2

            
3
#include <array>
4
#include <cstdint>
5
#include <list>
6
#include <memory>
7
#include <string>
8

            
9
#include "envoy/common/optref.h"
10
#include "envoy/common/scope_tracker.h"
11
#include "envoy/config/core/v3/protocol.pb.h"
12
#include "envoy/http/codec.h"
13
#include "envoy/network/connection.h"
14
#include "envoy/server/overload/overload_manager.h"
15

            
16
#include "source/common/buffer/watermark_buffer.h"
17
#include "source/common/common/assert.h"
18
#include "source/common/common/statusor.h"
19
#include "source/common/http/codec_helper.h"
20
#include "source/common/http/codes.h"
21
#include "source/common/http/header_map_impl.h"
22
#include "source/common/http/http1/codec_stats.h"
23
#include "source/common/http/http1/header_formatter.h"
24
#include "source/common/http/http1/parser.h"
25
#include "source/common/http/status.h"
26

            
27
namespace Envoy {
28
namespace Http {
29
namespace Http1 {
30

            
31
// The default limit of 80 KiB is the vanilla http_parser behaviour.
32
inline constexpr uint32_t MAX_RESPONSE_HEADERS_KB = 80;
33

            
34
class ConnectionImpl;
35

            
36
/**
37
 * Base class for HTTP/1.1 request and response encoders.
38
 */
39
class StreamEncoderImpl : public virtual StreamEncoder,
40
                          public Stream,
41
                          public Logger::Loggable<Logger::Id::http>,
42
                          public StreamCallbackHelper,
43
                          public Http1StreamEncoderOptions {
44
public:
45
85018
  ~StreamEncoderImpl() override {
46
    // When the stream goes away, undo any read blocks to resume reading.
47
85075
    while (read_disable_calls_ != 0) {
48
57
      StreamEncoderImpl::readDisable(false);
49
57
    }
50
85018
  }
51
  // Http::StreamEncoder
52
  void encodeData(Buffer::Instance& data, bool end_stream) override;
53
  void encodeMetadata(const MetadataMapVector&) override;
54
1869217
  Stream& getStream() override { return *this; }
55
2
  Http1StreamEncoderOptionsOptRef http1StreamEncoderOptions() override { return *this; }
56

            
57
  // Http::Http1StreamEncoderOptions
58
456
  void disableChunkEncoding() override { disable_chunk_encoding_ = true; }
59

            
60
  // Http::Stream
61
151876
  void addCallbacks(StreamCallbacks& callbacks) override { addCallbacksHelper(callbacks); }
62
57962
  void removeCallbacks(StreamCallbacks& callbacks) override { removeCallbacksHelper(callbacks); }
63
  CodecEventCallbacks* registerCodecEventCallbacks(CodecEventCallbacks* codec_callbacks) override;
64
  // After this is called, for the HTTP/1 codec, the connection should be closed, i.e. no further
65
  // progress may be made with the codec.
66
  void resetStream(StreamResetReason reason) override;
67
  void readDisable(bool disable) override;
68
  uint32_t bufferLimit() const override;
69
2129
  absl::string_view responseDetails() override { return details_; }
70
  const Network::ConnectionInfoProvider& connectionInfoProvider() override;
71
16462
  void setFlushTimeout(std::chrono::milliseconds) override {
72
    // HTTP/1 has one stream per connection, thus any data encoded is immediately written to the
73
    // connection, invoking any watermarks as necessary. There is no internal buffering that would
74
    // require a flush timeout not already covered by other timeouts.
75
16462
  }
76

            
77
16462
  Buffer::BufferMemoryAccountSharedPtr account() const override { return buffer_memory_account_; }
78

            
79
41818
  void setAccount(Buffer::BufferMemoryAccountSharedPtr account) override {
80
    // TODO(kbaichoo): implement account tracking for H1. Particularly, binding
81
    // the account to the buffers used. The current wiring is minimal, and used
82
    // to ensure the memory_account gets notified that the downstream request is
83
    // closing.
84
41818
    buffer_memory_account_ = account;
85
41818
  }
86

            
87
41502
  void setIsResponseToHeadRequest(bool value) { is_response_to_head_request_ = value; }
88
41502
  void setIsResponseToConnectRequest(bool value) { is_response_to_connect_request_ = value; }
89
1639
  void setDetails(absl::string_view details) { details_ = details; }
90

            
91
1448057
  const StreamInfo::BytesMeterSharedPtr& bytesMeter() override { return bytes_meter_; }
92

            
93
  // http1 doesn't have a codec level stream id.
94
16463
  absl::optional<uint32_t> codecStreamId() const override { return absl::nullopt; }
95

            
96
protected:
97
  StreamEncoderImpl(ConnectionImpl& connection, StreamInfo::BytesMeterSharedPtr&& bytes_meter);
98
  void encodeHeadersBase(const RequestOrResponseHeaderMap& headers, absl::optional<uint64_t> status,
99
                         bool end_stream, bool bodiless_request);
100
  void encodeTrailersBase(const HeaderMap& headers);
101

            
102
  Buffer::BufferMemoryAccountSharedPtr buffer_memory_account_;
103
  ConnectionImpl& connection_;
104
  uint32_t read_disable_calls_{};
105
  bool disable_chunk_encoding_ : 1;
106
  bool chunk_encoding_ : 1;
107
  bool connect_request_ : 1;
108
  bool is_tcp_tunneling_ : 1;
109
  bool is_response_to_head_request_ : 1;
110
  bool is_response_to_connect_request_ : 1;
111

            
112
private:
113
  /**
114
   * Called to encode an individual header.
115
   * @param key supplies the header to encode as a string_view.
116
   * @param value supplies the value to encode as a string_view.
117
   */
118
  void encodeHeader(absl::string_view key, absl::string_view value);
119

            
120
  /**
121
   * Called to finalize a stream encode.
122
   */
123
  void endEncode();
124

            
125
  /**
126
   * Encapsulates notification to various objects that the encode completed.
127
   */
128
  void notifyEncodeComplete();
129

            
130
  void encodeFormattedHeader(absl::string_view key, absl::string_view value,
131
                             HeaderKeyFormatterOptConstRef formatter);
132

            
133
  void flushOutput(bool end_encode = false);
134

            
135
  absl::string_view details_;
136
  StreamInfo::BytesMeterSharedPtr bytes_meter_;
137
  CodecEventCallbacks* codec_callbacks_{nullptr};
138
};
139

            
140
/**
141
 * HTTP/1.1 response encoder.
142
 */
143
class ResponseEncoderImpl : public StreamEncoderImpl, public ResponseEncoder {
144
public:
145
  ResponseEncoderImpl(ConnectionImpl& connection, StreamInfo::BytesMeterSharedPtr&& bytes_meter,
146
                      bool stream_error_on_invalid_http_message)
147
43054
      : StreamEncoderImpl(connection, std::move(bytes_meter)),
148
43054
        stream_error_on_invalid_http_message_(stream_error_on_invalid_http_message) {}
149

            
150
43054
  ~ResponseEncoderImpl() override {
151
    // Only the downstream stream should clear the downstream of the
152
    // memory account.
153
    //
154
    // There are cases where a corresponding upstream stream dtor might
155
    // be called, but the downstream stream isn't going to terminate soon
156
    // such as StreamDecoderFilterCallbacks::recreateStream().
157
43054
    if (buffer_memory_account_) {
158
4
      buffer_memory_account_->clearDownstream();
159
4
    }
160
43054
  }
161

            
162
1535
  bool startedResponse() { return started_response_; }
163

            
164
  // Http::ResponseEncoder
165
  void encode1xxHeaders(const ResponseHeaderMap& headers) override;
166
  void encodeHeaders(const ResponseHeaderMap& headers, bool end_stream) override;
167
4908
  void encodeTrailers(const ResponseTrailerMap& trailers) override { encodeTrailersBase(trailers); }
168

            
169
2378
  bool streamErrorOnInvalidHttpMessage() const override {
170
2378
    return stream_error_on_invalid_http_message_;
171
2378
  }
172
  void setDeferredLoggingHeadersAndTrailers(Http::RequestHeaderMapConstSharedPtr,
173
                                            Http::ResponseHeaderMapConstSharedPtr,
174
                                            Http::ResponseTrailerMapConstSharedPtr,
175
                                            StreamInfo::StreamInfo&) override {}
176

            
177
  // For H/1, ResponseEncoder doesn't hold a pointer to RequestDecoder.
178
  // TODO(paulsohn): Enable H/1 codec to get a pointer to the new
179
  // request decoder on recreateStream, here or elsewhere.
180
145
  void setRequestDecoder(Http::RequestDecoder& /*decoder*/) override {}
181

            
182
  // Http1::StreamEncoderImpl
183
  void resetStream(StreamResetReason reason) override;
184

            
185
private:
186
  bool started_response_{};
187
  const bool stream_error_on_invalid_http_message_;
188
};
189

            
190
/**
191
 * HTTP/1.1 request encoder.
192
 */
193
class RequestEncoderImpl : public StreamEncoderImpl, public RequestEncoder {
194
public:
195
  RequestEncoderImpl(ConnectionImpl& connection, StreamInfo::BytesMeterSharedPtr&& bytes_meter)
196
41964
      : StreamEncoderImpl(connection, std::move(bytes_meter)) {}
197
67
  bool upgradeRequest() const { return upgrade_request_; }
198
82113
  bool headRequest() const { return head_request_; }
199
35291
  bool connectRequest() const { return connect_request_; }
200

            
201
  // Http::RequestEncoder
202
  Status encodeHeaders(const RequestHeaderMap& headers, bool end_stream) override;
203
175
  void encodeTrailers(const RequestTrailerMap& trailers) override { encodeTrailersBase(trailers); }
204
271
  void enableTcpTunneling() override { is_tcp_tunneling_ = true; }
205

            
206
private:
207
  bool upgrade_request_{};
208
  bool head_request_{};
209
};
210

            
211
/**
212
 * Base class for HTTP/1.1 client and server connections.
213
 * Handles the callbacks of http_parser with its own base routine and then
214
 * virtual dispatches to its subclasses.
215
 */
216
class ConnectionImpl : public virtual Connection,
217
                       protected Logger::Loggable<Logger::Id::http>,
218
                       public ParserCallbacks,
219
                       public ScopeTrackedObject {
220
public:
221
  /**
222
   * @return Network::Connection& the backing network connection.
223
   */
224
341368
  Network::Connection& connection() { return connection_; }
225
9
  const Network::Connection& connection() const { return connection_; }
226

            
227
  /**
228
   * Called when the active encoder has completed encoding the outbound half of the stream.
229
   */
230
  virtual void onEncodeComplete() PURE;
231

            
232
  virtual StreamInfo::BytesMeter& getBytesMeter() PURE;
233

            
234
  /**
235
   * Called when resetStream() has been called on an active stream. In HTTP/1.1 the only
236
   * valid operation after this point is for the connection to get blown away, but we will not
237
   * fire any more callbacks in case some stack has to unwind.
238
   */
239
  void onResetStreamBase(StreamResetReason reason);
240

            
241
  /**
242
   * Flush all pending output from encoding.
243
   */
244
  uint64_t flushOutput(bool end_encode = false);
245

            
246
850961
  Buffer::Instance& buffer() { return *output_buffer_; }
247

            
248
24456
  void readDisable(bool disable) {
249
24456
    if (connection_.state() == Network::Connection::State::Open) {
250
24452
      connection_.readDisable(disable);
251
24452
    }
252
24456
  }
253
16462
  uint32_t bufferLimit() { return connection_.bufferLimit(); }
254
  virtual bool supportsHttp10() { return false; }
255
  bool maybeDirectDispatch(Buffer::Instance& data);
256
40679
  virtual void maybeAddSentinelBufferFragment(Buffer::Instance&) {}
257
323
  CodecStats& stats() { return stats_; }
258
74696
  bool enableTrailers() const { return codec_settings_.enable_trailers_; }
259
41936
  virtual bool sendFullyQualifiedUrl() const { return codec_settings_.send_fully_qualified_url_; }
260
84489
  HeaderKeyFormatterOptConstRef formatter() const {
261
84489
    return makeOptRefFromPtr(encode_only_header_key_formatter_.get());
262
84489
  }
263

            
264
  // Http::Connection
265
  Http::Status dispatch(Buffer::Instance& data) override;
266
24
  void goAway() override {} // Called during connection manager drain flow
267
445042
  Protocol protocol() override { return protocol_; }
268
46
  void shutdownNotice() override {} // Called during connection manager drain flow
269
2299
  bool wantsToWrite() override { return false; }
270
31291
  void onUnderlyingConnectionAboveWriteBufferHighWatermark() override { onAboveHighWatermark(); }
271
31290
  void onUnderlyingConnectionBelowWriteBufferLowWatermark() override { onBelowLowWatermark(); }
272

            
273
  // Codec errors found in callbacks are overridden within the http_parser library. This holds those
274
  // errors to propagate them through to dispatch() where we can handle the error.
275
  Envoy::Http::Status codec_status_;
276

            
277
  // ScopeTrackedObject
278
  OptRef<const StreamInfo::StreamInfo> trackedStream() const override;
279
  void dumpState(std::ostream& os, int indent_level) const override;
280

            
281
protected:
282
  ConnectionImpl(Network::Connection& connection, CodecStats& stats, const Http1Settings& settings,
283
                 MessageType type, uint32_t max_headers_kb, const uint32_t max_headers_count);
284

            
285
44594
  bool resetStreamCalled() { return reset_stream_called_; }
286

            
287
  // This must be protected because it is called through ServerConnectionImpl::sendProtocolError.
288
  Status onMessageBeginImpl();
289

            
290
  /**
291
   * Get memory used to represent HTTP headers or trailers currently being parsed.
292
   * Computed by adding the partial header field and value that is currently being parsed and the
293
   * estimated header size for previous header lines provided by HeaderMap::byteSize().
294
   */
295
  virtual uint32_t getHeadersSize();
296

            
297
  /**
298
   * Called from onUrl, onHeaderFields and onHeaderValue to verify that the headers do not exceed
299
   * the configured max header size limit.
300
   * @return A codecProtocolError status if headers exceed the size limit.
301
   */
302
  Status checkMaxHeadersSize();
303

            
304
  Network::Connection& connection_;
305
  CodecStats& stats_;
306
  const Http1Settings codec_settings_;
307
  std::unique_ptr<Parser> parser_;
308
  Buffer::Instance* current_dispatching_buffer_{};
309
  Buffer::Instance* output_buffer_ = nullptr; // Not owned
310
  Http::Code error_code_{Http::Code::BadRequest};
311
  const HeaderKeyFormatterConstPtr encode_only_header_key_formatter_;
312
  HeaderString current_header_field_;
313
  HeaderString current_header_value_;
314
  bool processing_trailers_ : 1;
315
  bool handling_upgrade_ : 1;
316
  bool reset_stream_called_ : 1;
317
  // Deferred end stream headers indicate that we are not going to raise headers until the full
318
  // HTTP/1 message has been flushed from the parser. This allows raising an HTTP/2 style headers
319
  // block with end stream set to true with no further protocol data remaining.
320
  bool deferred_end_stream_headers_ : 1;
321
  bool dispatching_ : 1;
322
  bool dispatching_slice_already_drained_ : 1;
323
  StreamInfo::BytesMeterSharedPtr bytes_meter_before_stream_;
324
  const uint32_t max_headers_kb_;
325
  const uint32_t max_headers_count_;
326

            
327
private:
328
  enum class HeaderParsingState { Field, Value, Done };
329
3
  friend std::ostream& operator<<(std::ostream& os, HeaderParsingState parsing_state) {
330
3
    switch (parsing_state) {
331
1
    case ConnectionImpl::HeaderParsingState::Field:
332
1
      return os << "Field";
333
    case ConnectionImpl::HeaderParsingState::Value:
334
      return os << "Value";
335
2
    case ConnectionImpl::HeaderParsingState::Done:
336
2
      return os << "Done";
337
3
    }
338
    return os;
339
3
  }
340

            
341
  virtual HeaderMap& headersOrTrailers() PURE;
342
  virtual RequestOrResponseHeaderMap& requestOrResponseHeaders() PURE;
343
  virtual void allocHeaders(StatefulHeaderKeyFormatterPtr&& formatter) PURE;
344
  virtual void allocTrailers() PURE;
345

            
346
  /**
347
   * Called for each header in order to complete an in progress header decode.
348
   * @return A status representing success.
349
   */
350
  Status completeCurrentHeader();
351

            
352
  /**
353
   * Dispatch a memory span.
354
   * @param slice supplies the start address.
355
   * @len supplies the length of the span.
356
   */
357
  Envoy::StatusOr<size_t> dispatchSlice(const char* slice, size_t len);
358

            
359
  void onDispatch(const Buffer::Instance& data);
360

            
361
  // ParserCallbacks.
362
  CallbackResult onMessageBegin() override;
363
  CallbackResult onUrl(const char* data, size_t length) override;
364
  CallbackResult onStatus(const char* data, size_t length) override;
365
  CallbackResult onHeaderField(const char* data, size_t length) override;
366
  CallbackResult onHeaderValue(const char* data, size_t length) override;
367
  CallbackResult onHeadersComplete() override;
368
  void bufferBody(const char* data, size_t length) override;
369
  CallbackResult onMessageComplete() override;
370
  void onChunkHeader(bool is_final_chunk) override;
371

            
372
  // Internal implementations of ParserCallbacks methods,
373
  // and virtual methods for connection-specific implementations.
374
  virtual Status onMessageBeginBase() PURE;
375
  virtual Status onUrlBase(const char* data, size_t length) PURE;
376
  virtual Status onStatusBase(const char* data, size_t length) PURE;
377
  Status onHeaderFieldImpl(const char* data, size_t length);
378
  Status onHeaderValueImpl(const char* data, size_t length);
379
  StatusOr<CallbackResult> onHeadersCompleteImpl();
380
  virtual StatusOr<CallbackResult> onHeadersCompleteBase() PURE;
381
  StatusOr<CallbackResult> onMessageCompleteImpl();
382
  virtual CallbackResult onMessageCompleteBase() PURE;
383

            
384
  // These helpers wrap *Impl() calls in the overrides of non-void
385
  // ParserCallbacks methods.
386
  CallbackResult setAndCheckCallbackStatus(Status&& status);
387
  CallbackResult setAndCheckCallbackStatusOr(StatusOr<CallbackResult>&& statusor);
388

            
389
  /**
390
   * Push the accumulated body through the filter pipeline.
391
   */
392
  void dispatchBufferedBody();
393

            
394
  /**
395
   * Called to see if upgrade transition is allowed.
396
   */
397
  virtual bool upgradeAllowed() const PURE;
398

            
399
  /**
400
   * Called with body data is available for processing when either:
401
   * - There is an accumulated partial body after the parser is done processing bytes read from the
402
   * socket
403
   * - The parser encounters the last byte of the body
404
   * - The codec does a direct dispatch from the read buffer
405
   * For performance reasons there is at most one call to onBody per call to HTTP/1
406
   * ConnectionImpl::dispatch call.
407
   * @param data supplies the body data
408
   */
409
  virtual void onBody(Buffer::Instance& data) PURE;
410

            
411
  /**
412
   * @see onResetStreamBase().
413
   */
414
  virtual void onResetStream(StreamResetReason reason) PURE;
415

            
416
  /**
417
   * Send a protocol error response to remote.
418
   */
419
  virtual Status sendProtocolError(absl::string_view details) PURE;
420

            
421
  /**
422
   * Called when output_buffer_ or the underlying connection go from below a low watermark to over
423
   * a high watermark.
424
   */
425
  virtual void onAboveHighWatermark() PURE;
426

            
427
  /**
428
   * Called when output_buffer_ or the underlying connection  go from above a high watermark to
429
   * below a low watermark.
430
   */
431
  virtual void onBelowLowWatermark() PURE;
432

            
433
  /**
434
   * Check if header name contains underscore character.
435
   * The ServerConnectionImpl may drop header or reject request based on configuration.
436
   * @return A status representing whether the request is rejected.
437
   */
438
106550
  virtual Status checkHeaderNameForUnderscores() { return okStatus(); }
439

            
440
  /**
441
   * Additional state to dump on crash.
442
   */
443
  virtual void dumpAdditionalState(std::ostream& os, int indent_level) const PURE;
444

            
445
  HeaderParsingState header_parsing_state_{HeaderParsingState::Field};
446
  // Used to accumulate the HTTP message body during the current dispatch call. The accumulated body
447
  // is pushed through the filter pipeline either at the end of the current dispatch call, or when
448
  // the last byte of the body is processed (whichever happens first).
449
  Buffer::OwnedImpl buffered_body_;
450
  Protocol protocol_{Protocol::Http11};
451
};
452

            
453
/**
454
 * Implementation of Http::ServerConnection for HTTP/1.1.
455
 */
456
class ServerConnectionImpl : public ServerConnection, public ConnectionImpl {
457
public:
458
  ServerConnectionImpl(Network::Connection& connection, CodecStats& stats,
459
                       ServerConnectionCallbacks& callbacks, const Http1Settings& settings,
460
                       uint32_t max_request_headers_kb, const uint32_t max_request_headers_count,
461
                       envoy::config::core::v3::HttpProtocolOptions::HeadersWithUnderscoresAction
462
                           headers_with_underscores_action,
463
                       Server::OverloadManager& overload_manager);
464
19
  bool supportsHttp10() override { return codec_settings_.accept_http_10_; }
465

            
466
protected:
467
  /**
468
   * An active HTTP/1.1 request.
469
   */
470
  struct ActiveRequest : public Event::DeferredDeletable {
471
    ActiveRequest(ServerConnectionImpl& connection, StreamInfo::BytesMeterSharedPtr&& bytes_meter)
472
43054
        : response_encoder_(connection, std::move(bytes_meter),
473
43054
                            connection.codec_settings_.stream_error_on_invalid_http_message_) {}
474
43054
    ~ActiveRequest() override = default;
475

            
476
    void dumpState(std::ostream& os, int indent_level) const;
477
    HeaderString request_url_;
478
    RequestDecoder* request_decoder_{};
479
    ResponseEncoderImpl response_encoder_;
480
    bool remote_complete_{};
481
  };
482
  // ConnectionImpl
483
  CallbackResult onMessageCompleteBase() override;
484
  // Add the size of the request_url to the reported header size when processing request headers.
485
  uint32_t getHeadersSize() override;
486

            
487
private:
488
  /**
489
   * Manipulate the request's first line, parsing the url and converting to a relative path if
490
   * necessary. Compute Host / :authority headers based on 7230#5.7 and 7230#6
491
   *
492
   * @param is_connect true if the request has the CONNECT method
493
   * @param headers the request's headers
494
   * @return Status representing success or failure. This will fail if there is an invalid url in
495
   * the request line.
496
   */
497
  Status handlePath(RequestHeaderMap& headers, absl::string_view method);
498

            
499
  // ParserCallbacks.
500
  Status onUrlBase(const char* data, size_t length) override;
501
  Status onStatusBase(const char*, size_t) override { return okStatus(); }
502
  // ConnectionImpl
503
  Http::Status dispatch(Buffer::Instance& data) override;
504
  void onEncodeComplete() override;
505
993611
  StreamInfo::BytesMeter& getBytesMeter() override {
506
993611
    if (active_request_) {
507
950552
      return *(active_request_->response_encoder_.getStream().bytesMeter());
508
950552
    }
509
43059
    if (bytes_meter_before_stream_ == nullptr) {
510
43056
      bytes_meter_before_stream_ = std::make_shared<StreamInfo::BytesMeter>();
511
43056
    }
512
43059
    return *bytes_meter_before_stream_;
513
993611
  }
514
  Status onMessageBeginBase() override;
515
  Envoy::StatusOr<CallbackResult> onHeadersCompleteBase() override;
516
  // If upgrade behavior is not allowed, the HCM will have sanitized the headers out.
517
135
  bool upgradeAllowed() const override { return true; }
518
  void onBody(Buffer::Instance& data) override;
519
  void onResetStream(StreamResetReason reason) override;
520
  Status sendProtocolError(absl::string_view details) override;
521
  Status sendOverloadError();
522
  void onAboveHighWatermark() override;
523
  void onBelowLowWatermark() override;
524
852363
  HeaderMap& headersOrTrailers() override {
525
852363
    if (absl::holds_alternative<RequestHeaderMapPtr>(headers_or_trailers_)) {
526
729762
      return *absl::get<RequestHeaderMapPtr>(headers_or_trailers_);
527
849006
    } else {
528
122601
      return *absl::get<RequestTrailerMapPtr>(headers_or_trailers_);
529
122601
    }
530
852363
  }
531
41520
  RequestOrResponseHeaderMap& requestOrResponseHeaders() override {
532
41520
    return *absl::get<RequestHeaderMapPtr>(headers_or_trailers_);
533
41520
  }
534
43055
  void allocHeaders(StatefulHeaderKeyFormatterPtr&& formatter) override {
535
43055
    ASSERT(!processing_trailers_);
536
43055
    auto headers = RequestHeaderMapImpl::create(max_headers_kb_, max_headers_count_);
537
43055
    headers->setFormatter(std::move(formatter));
538
43055
    headers_or_trailers_.emplace<RequestHeaderMapPtr>(std::move(headers));
539
43055
  }
540
67
  void allocTrailers() override {
541
67
    ASSERT(processing_trailers_);
542
67
    if (!absl::holds_alternative<RequestTrailerMapPtr>(headers_or_trailers_)) {
543
67
      headers_or_trailers_.emplace<RequestTrailerMapPtr>(
544
67
          RequestTrailerMapImpl::create(max_headers_kb_, max_headers_count_));
545
67
    }
546
67
  }
547
  void dumpAdditionalState(std::ostream& os, int indent_level) const override;
548

            
549
  void releaseOutboundResponse(const Buffer::OwnedBufferFragmentImpl* fragment);
550
  void maybeAddSentinelBufferFragment(Buffer::Instance& output_buffer) override;
551

            
552
  Status doFloodProtectionChecks() const;
553
  Status checkHeaderNameForUnderscores() override;
554
  Status checkProtocolVersion(RequestHeaderMap& headers);
555

            
556
  ServerConnectionCallbacks& callbacks_;
557
  std::unique_ptr<ActiveRequest> active_request_;
558
  const Buffer::OwnedBufferFragmentImpl::Releasor response_buffer_releasor_;
559
  uint32_t outbound_responses_{};
560
  // Buffer used to encode the HTTP message before moving it to the network connection's output
561
  // buffer. This buffer is always allocated, never nullptr.
562
  Buffer::InstancePtr owned_output_buffer_;
563
  // TODO(mattklein123): This should be a member of ActiveRequest but this change needs dedicated
564
  // thought as some of the reset and no header code paths make this difficult. Headers are
565
  // populated on message begin. Trailers are populated on the first parsed trailer field (if
566
  // trailers are enabled). The variant is reset to null headers on message complete for assertion
567
  // purposes.
568
  absl::variant<RequestHeaderMapPtr, RequestTrailerMapPtr> headers_or_trailers_;
569
  // The action to take when a request header name contains underscore characters.
570
  const envoy::config::core::v3::HttpProtocolOptions::HeadersWithUnderscoresAction
571
      headers_with_underscores_action_;
572
  Server::LoadShedPoint* abort_dispatch_{nullptr};
573
};
574

            
575
/**
576
 * Implementation of Http::ClientConnection for HTTP/1.1.
577
 */
578
class ClientConnectionImpl : public ClientConnection, public ConnectionImpl {
579
public:
580
  ClientConnectionImpl(Network::Connection& connection, CodecStats& stats,
581
                       ConnectionCallbacks& callbacks, const Http1Settings& settings,
582
                       absl::optional<uint16_t> max_response_headers_kb,
583
                       const uint32_t max_response_headers_count,
584
                       bool passing_through_proxy = false);
585
  // Http::ClientConnection
586
  RequestEncoder& newStream(ResponseDecoder& response_decoder) override;
587

            
588
private:
589
  struct PendingResponse {
590
    PendingResponse(ConnectionImpl& connection, StreamInfo::BytesMeterSharedPtr&& bytes_meter,
591
                    ResponseDecoder* decoder)
592
41964
        : encoder_(connection, std::move(bytes_meter)), decoder_(decoder) {}
593
    RequestEncoderImpl encoder_;
594
    ResponseDecoder* decoder_;
595
  };
596

            
597
  bool cannotHaveBody();
598

            
599
41936
  bool sendFullyQualifiedUrl() const override {
600
    // Send fully qualified URLs either if the parent connection is configured to do so or this
601
    // stream is passing through a proxy and the underlying transport is plaintext.
602
41936
    return ConnectionImpl::sendFullyQualifiedUrl() ||
603
41936
           (passing_through_proxy_ && !connection().ssl());
604
41936
  }
605

            
606
  // ParserCallbacks.
607
  Status onUrlBase(const char*, size_t) override { return okStatus(); }
608
  Status onStatusBase(const char* data, size_t length) override;
609
  // ConnectionImpl
610
  Http::Status dispatch(Buffer::Instance& data) override;
611
40792
  void onEncodeComplete() override { encode_complete_ = true; }
612
455584
  StreamInfo::BytesMeter& getBytesMeter() override {
613
455584
    if (pending_response_.has_value()) {
614
455549
      return *(pending_response_->encoder_.getStream().bytesMeter());
615
455549
    }
616
35
    if (bytes_meter_before_stream_ == nullptr) {
617
14
      bytes_meter_before_stream_ = std::make_shared<StreamInfo::BytesMeter>();
618
14
    }
619
35
    return *bytes_meter_before_stream_;
620
455584
  }
621
41221
  Status onMessageBeginBase() override { return okStatus(); }
622
  Envoy::StatusOr<CallbackResult> onHeadersCompleteBase() override;
623
  bool upgradeAllowed() const override;
624
  void onBody(Buffer::Instance& data) override;
625
  CallbackResult onMessageCompleteBase() override;
626
  void onResetStream(StreamResetReason reason) override;
627
  Status sendProtocolError(absl::string_view details) override;
628
  void onAboveHighWatermark() override;
629
  void onBelowLowWatermark() override;
630
318966
  HeaderMap& headersOrTrailers() override {
631
318966
    if (absl::holds_alternative<ResponseHeaderMapPtr>(headers_or_trailers_)) {
632
317787
      return *absl::get<ResponseHeaderMapPtr>(headers_or_trailers_);
633
317787
    } else {
634
1179
      return *absl::get<ResponseTrailerMapPtr>(headers_or_trailers_);
635
1179
    }
636
318966
  }
637
41180
  RequestOrResponseHeaderMap& requestOrResponseHeaders() override {
638
41180
    return *absl::get<ResponseHeaderMapPtr>(headers_or_trailers_);
639
41180
  }
640
41221
  void allocHeaders(StatefulHeaderKeyFormatterPtr&& formatter) override {
641
41221
    ASSERT(nullptr == absl::get<ResponseHeaderMapPtr>(headers_or_trailers_));
642
41221
    ASSERT(!processing_trailers_);
643
41221
    auto headers = ResponseHeaderMapImpl::create(max_headers_kb_, max_headers_count_);
644
41221
    headers->setFormatter(std::move(formatter));
645
41221
    headers_or_trailers_.emplace<ResponseHeaderMapPtr>(std::move(headers));
646
41221
  }
647
213
  void allocTrailers() override {
648
213
    ASSERT(processing_trailers_);
649
213
    if (!absl::holds_alternative<ResponseTrailerMapPtr>(headers_or_trailers_)) {
650
213
      headers_or_trailers_.emplace<ResponseTrailerMapPtr>(
651
213
          ResponseTrailerMapImpl::create(max_headers_kb_, max_headers_count_));
652
213
    }
653
213
  }
654
  void dumpAdditionalState(std::ostream& os, int indent_level) const override;
655

            
656
  // Buffer used to encode the HTTP message before moving it to the network connection's output
657
  // buffer. This buffer is always allocated, never nullptr.
658
  Buffer::InstancePtr owned_output_buffer_;
659

            
660
  absl::optional<PendingResponse> pending_response_;
661
  // TODO(mattklein123): The following bool tracks whether a pending response is complete before
662
  // dispatching callbacks. This is needed so that pending_response_ stays valid during callbacks
663
  // in order to access the stream, but to avoid invoking callbacks that shouldn't be called once
664
  // the response is complete. The existence of this variable is hard to reason about and it should
665
  // be combined with pending_response_ somehow in a follow up cleanup.
666
  bool pending_response_done_{true};
667
  // Set true between receiving non-101 1xx headers and receiving the spurious onMessageComplete.
668
  bool ignore_message_complete_for_1xx_{};
669
  // TODO(mattklein123): This should be a member of PendingResponse but this change needs dedicated
670
  // thought as some of the reset and no header code paths make this difficult. Headers are
671
  // populated on message begin. Trailers are populated when the switch to trailer processing is
672
  // detected while parsing the first trailer field (if trailers are enabled). The variant is reset
673
  // to null headers on message complete for assertion purposes.
674
  absl::variant<ResponseHeaderMapPtr, ResponseTrailerMapPtr> headers_or_trailers_;
675

            
676
  // True if the upstream connection is pointed at an HTTP/1.1 proxy, and
677
  // plaintext HTTP should be sent with fully qualified URLs.
678
  bool passing_through_proxy_ = false;
679

            
680
  const bool force_reset_on_premature_upstream_half_close_{};
681
  bool encode_complete_{false};
682
};
683

            
684
} // namespace Http1
685
} // namespace Http
686
} // namespace Envoy