Coverage Report

Created: 2023-11-12 09:30

/proc/self/cwd/source/common/http/http1/conn_pool.cc
Line
Count
Source (jump to first uncovered line)
1
#include "source/common/http/http1/conn_pool.h"
2
3
#include <cstdint>
4
#include <list>
5
#include <memory>
6
7
#include "envoy/event/dispatcher.h"
8
#include "envoy/event/schedulable_cb.h"
9
#include "envoy/event/timer.h"
10
#include "envoy/http/codec.h"
11
#include "envoy/http/header_map.h"
12
#include "envoy/upstream/upstream.h"
13
14
#include "source/common/http/codec_client.h"
15
#include "source/common/http/codes.h"
16
#include "source/common/http/header_utility.h"
17
#include "source/common/http/headers.h"
18
#include "source/common/runtime/runtime_features.h"
19
20
#include "absl/strings/match.h"
21
22
namespace Envoy {
23
namespace Http {
24
namespace Http1 {
25
26
ActiveClient::StreamWrapper::StreamWrapper(ResponseDecoder& response_decoder, ActiveClient& parent)
27
    : RequestEncoderWrapper(&parent.codec_client_->newStream(*this)),
28
44
      ResponseDecoderWrapper(response_decoder), parent_(parent) {
29
44
  RequestEncoderWrapper::inner_encoder_->getStream().addCallbacks(*this);
30
44
}
Unexecuted instantiation: Envoy::Http::Http1::ActiveClient::StreamWrapper::StreamWrapper(Envoy::Http::ResponseDecoder&, Envoy::Http::Http1::ActiveClient&)
Envoy::Http::Http1::ActiveClient::StreamWrapper::StreamWrapper(Envoy::Http::ResponseDecoder&, Envoy::Http::Http1::ActiveClient&)
Line
Count
Source
28
44
      ResponseDecoderWrapper(response_decoder), parent_(parent) {
29
44
  RequestEncoderWrapper::inner_encoder_->getStream().addCallbacks(*this);
30
44
}
31
32
44
ActiveClient::StreamWrapper::~StreamWrapper() {
33
  // Upstream connection might be closed right after response is complete. Setting delay=true
34
  // here to attach pending requests in next dispatcher loop to handle that case.
35
  // https://github.com/envoyproxy/envoy/issues/2715
36
44
  parent_.parent_.onStreamClosed(parent_, true);
37
44
}
38
39
15
void ActiveClient::StreamWrapper::onEncodeComplete() { encode_complete_ = true; }
40
41
7
void ActiveClient::StreamWrapper::decodeHeaders(ResponseHeaderMapPtr&& headers, bool end_stream) {
42
7
  close_connection_ =
43
7
      HeaderUtility::shouldCloseConnection(parent_.codec_client_->protocol(), *headers);
44
7
  if (close_connection_) {
45
5
    parent_.parent().host()->cluster().trafficStats()->upstream_cx_close_notify_.inc();
46
5
  }
47
7
  ResponseDecoderWrapper::decodeHeaders(std::move(headers), end_stream);
48
7
}
49
50
4
void ActiveClient::StreamWrapper::onDecodeComplete() {
51
4
  ASSERT(!decode_complete_);
52
4
  decode_complete_ = encode_complete_;
53
4
  ENVOY_CONN_LOG(debug, "response complete", *parent_.codec_client_);
54
55
4
  if (!parent_.stream_wrapper_->encode_complete_) {
56
3
    ENVOY_CONN_LOG(debug, "response before request complete", *parent_.codec_client_);
57
3
    parent_.codec_client_->close();
58
3
  } else if (parent_.stream_wrapper_->close_connection_ || parent_.codec_client_->remoteClosed()) {
59
0
    ENVOY_CONN_LOG(debug, "saw upstream close connection", *parent_.codec_client_);
60
0
    parent_.codec_client_->close();
61
1
  } else {
62
1
    auto* pool = &parent_.parent();
63
1
    pool->scheduleOnUpstreamReady();
64
1
    parent_.stream_wrapper_.reset();
65
66
1
    pool->checkForIdleAndCloseIdleConnsIfDraining();
67
1
  }
68
4
}
69
70
40
void ActiveClient::StreamWrapper::onResetStream(StreamResetReason, absl::string_view) {
71
40
  parent_.codec_client_->close();
72
40
}
73
74
ActiveClient::ActiveClient(HttpConnPoolImplBase& parent,
75
                           OptRef<Upstream::Host::CreateConnectionData> data)
76
    : Envoy::Http::ActiveClient(parent, parent.host()->cluster().maxRequestsPerConnection(),
77
                                /* effective_concurrent_stream_limit */ 1,
78
53
                                /* configured_concurrent_stream_limit */ 1, data) {
79
53
  parent.host()->cluster().trafficStats()->upstream_cx_http1_total_.inc();
80
53
}
81
82
53
ActiveClient::~ActiveClient() { ASSERT(!stream_wrapper_.get()); }
83
84
53
bool ActiveClient::closingWithIncompleteStream() const {
85
53
  return (stream_wrapper_ != nullptr) && (!stream_wrapper_->decode_complete_);
86
53
}
87
88
44
RequestEncoder& ActiveClient::newStreamEncoder(ResponseDecoder& response_decoder) {
89
44
  ASSERT(!stream_wrapper_);
90
44
  stream_wrapper_ = std::make_unique<StreamWrapper>(response_decoder, *this);
91
44
  return *stream_wrapper_;
92
44
}
93
94
ConnectionPool::InstancePtr
95
allocateConnPool(Event::Dispatcher& dispatcher, Random::RandomGenerator& random_generator,
96
                 Upstream::HostConstSharedPtr host, Upstream::ResourcePriority priority,
97
                 const Network::ConnectionSocket::OptionsSharedPtr& options,
98
                 const Network::TransportSocketOptionsConstSharedPtr& transport_socket_options,
99
53
                 Upstream::ClusterConnectivityState& state) {
100
53
  return std::make_unique<FixedHttpConnPoolImpl>(
101
53
      std::move(host), std::move(priority), dispatcher, options, transport_socket_options,
102
53
      random_generator, state,
103
53
      [](HttpConnPoolImplBase* pool) {
104
53
        return std::make_unique<ActiveClient>(*pool, absl::nullopt);
105
53
      },
106
53
      [](Upstream::Host::CreateConnectionData& data, HttpConnPoolImplBase* pool) {
107
53
        CodecClientPtr codec{new CodecClientProd(
108
53
            CodecType::HTTP1, std::move(data.connection_), data.host_description_,
109
53
            pool->dispatcher(), pool->randomGenerator(), pool->transportSocketOptions())};
110
53
        return codec;
111
53
      },
112
53
      std::vector<Protocol>{Protocol::Http11}, absl::nullopt, nullptr);
113
53
}
114
115
} // namespace Http1
116
} // namespace Http
117
} // namespace Envoy