/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 |