1
#include "source/common/http/http2/conn_pool.h"
2

            
3
#include <cstdint>
4

            
5
#include "envoy/event/dispatcher.h"
6
#include "envoy/server/overload/overload_manager.h"
7
#include "envoy/upstream/upstream.h"
8

            
9
#include "source/common/http/http2/codec_impl.h"
10
#include "source/common/runtime/runtime_features.h"
11

            
12
namespace Envoy {
13
namespace Http {
14

            
15
namespace Http2 {
16

            
17
uint32_t ActiveClient::calculateInitialStreamsLimit(
18
    Http::HttpServerPropertiesCacheSharedPtr http_server_properties_cache,
19
    absl::optional<HttpServerPropertiesCache::Origin>& origin,
20
6136
    Upstream::HostDescriptionConstSharedPtr host) {
21
6136
  uint32_t initial_streams =
22
6136
      host->cluster().httpProtocolOptions().http2Options().max_concurrent_streams().value();
23
6136
  if (http_server_properties_cache && origin.has_value()) {
24
175
    uint32_t cached_concurrency =
25
175
        http_server_properties_cache->getConcurrentStreams(origin.value());
26
175
    if (cached_concurrency != 0 && cached_concurrency < initial_streams) {
27
      // Only use the cached concurrency if lowers the streams below the
28
      // configured max_concurrent_streams as Envoy should never send more
29
      // than max_concurrent_streams at once.
30
9
      initial_streams = cached_concurrency;
31
9
    }
32
175
  }
33
6136
  uint32_t max_requests = MultiplexedActiveClientBase::maxStreamsPerConnection(
34
6136
      host->cluster().maxRequestsPerConnection());
35
6136
  if (max_requests < initial_streams) {
36
24
    initial_streams = max_requests;
37
24
  }
38
6136
  return initial_streams;
39
6136
}
40

            
41
ActiveClient::ActiveClient(HttpConnPoolImplBase& parent,
42
                           OptRef<Upstream::Host::CreateConnectionData> data)
43
6066
    : MultiplexedActiveClientBase(
44
6066
          parent, calculateInitialStreamsLimit(parent.cache(), parent.origin(), parent.host()),
45
6066
          parent.host()
46
6066
              ->cluster()
47
6066
              .httpProtocolOptions()
48
6066
              .http2Options()
49
6066
              .max_concurrent_streams()
50
6066
              .value(),
51
6066
          parent.host()->cluster().trafficStats()->upstream_cx_http2_total_, data) {}
52

            
53
ConnectionPool::InstancePtr
54
allocateConnPool(Event::Dispatcher& dispatcher, Random::RandomGenerator& random_generator,
55
                 Upstream::HostConstSharedPtr host, Upstream::ResourcePriority priority,
56
                 const Network::ConnectionSocket::OptionsSharedPtr& options,
57
                 const Network::TransportSocketOptionsConstSharedPtr& transport_socket_options,
58
                 Upstream::ClusterConnectivityState& state,
59
                 Server::OverloadManager& overload_manager,
60
                 absl::optional<HttpServerPropertiesCache::Origin> origin,
61
5921
                 Http::HttpServerPropertiesCacheSharedPtr cache) {
62
5921
  return std::make_unique<FixedHttpConnPoolImpl>(
63
5921
      host, priority, dispatcher, options, transport_socket_options, random_generator, state,
64
5949
      [](HttpConnPoolImplBase* pool) {
65
5949
        return std::make_unique<ActiveClient>(*pool, absl::nullopt);
66
5949
      },
67
5949
      [](Upstream::Host::CreateConnectionData& data, HttpConnPoolImplBase* pool) {
68
5949
        CodecClientPtr codec{new CodecClientProd(
69
5949
            CodecType::HTTP2, std::move(data.connection_), data.host_description_,
70
5949
            pool->dispatcher(), pool->randomGenerator(), pool->transportSocketOptions())};
71
5949
        return codec;
72
5949
      },
73
5921
      std::vector<Protocol>{Protocol::Http2}, overload_manager, origin, cache);
74
5921
}
75

            
76
} // namespace Http2
77
} // namespace Http
78
} // namespace Envoy