Coverage Report

Created: 2023-11-12 09:30

/proc/self/cwd/source/server/api_listener_impl.h
Line
Count
Source (jump to first uncovered line)
1
#pragma once
2
3
#include <memory>
4
#include <ostream>
5
6
#include "envoy/config/core/v3/base.pb.h"
7
#include "envoy/config/listener/v3/listener.pb.h"
8
#include "envoy/event/dispatcher.h"
9
#include "envoy/network/connection.h"
10
#include "envoy/network/filter.h"
11
#include "envoy/network/socket.h"
12
#include "envoy/server/api_listener.h"
13
#include "envoy/server/filter_config.h"
14
#include "envoy/server/instance.h"
15
#include "envoy/server/listener_manager.h"
16
#include "envoy/stats/scope.h"
17
18
#include "source/common/common/empty_string.h"
19
#include "source/common/common/logger.h"
20
#include "source/common/http/conn_manager_impl.h"
21
#include "source/common/init/manager_impl.h"
22
#include "source/common/network/socket_impl.h"
23
#include "source/common/stream_info/stream_info_impl.h"
24
#include "source/server/factory_context_impl.h"
25
26
namespace Envoy {
27
namespace Server {
28
29
/**
30
 * Base class all ApiListeners.
31
 */
32
class ApiListenerImplBase : public ApiListener,
33
                            public Network::DrainDecision,
34
                            Logger::Loggable<Logger::Id::http> {
35
public:
36
  // TODO(junr03): consider moving Envoy Mobile's SyntheticAddressImpl to Envoy in order to return
37
  // that rather than this semi-real one.
38
0
  const Network::Address::InstanceConstSharedPtr& address() const { return address_; }
39
40
  // ApiListener
41
0
  absl::string_view name() const override { return name_; }
42
43
  // Network::DrainDecision
44
  // TODO(junr03): hook up draining to listener state management.
45
0
  bool drainClose() const override { return false; }
46
0
  Common::CallbackHandlePtr addOnDrainCloseCb(DrainCloseCb) const override {
47
0
    IS_ENVOY_BUG("Unexpected call to addOnDrainCloseCb");
48
0
    return nullptr;
49
0
  }
50
51
protected:
52
  ApiListenerImplBase(const envoy::config::listener::v3::Listener& config, Server::Instance& server,
53
                      const std::string& name);
54
55
  // Synthetic class that acts as a stub Network::ReadFilterCallbacks.
56
  // TODO(junr03): if we are able to separate the Network Filter aspects of the
57
  // Http::ConnectionManagerImpl from the http management aspects of it, it is possible we would not
58
  // need this and the SyntheticConnection stub anymore.
59
  class SyntheticReadCallbacks : public Network::ReadFilterCallbacks {
60
  public:
61
    SyntheticReadCallbacks(ApiListenerImplBase& parent, Event::Dispatcher& dispatcher)
62
0
        : parent_(parent), connection_(SyntheticConnection(*this, dispatcher)) {}
Unexecuted instantiation: Envoy::Server::ApiListenerImplBase::SyntheticReadCallbacks::SyntheticReadCallbacks(Envoy::Server::ApiListenerImplBase&, Envoy::Event::Dispatcher&)
Unexecuted instantiation: Envoy::Server::ApiListenerImplBase::SyntheticReadCallbacks::SyntheticReadCallbacks(Envoy::Server::ApiListenerImplBase&, Envoy::Event::Dispatcher&)
63
64
    // Network::ReadFilterCallbacks
65
0
    void continueReading() override { IS_ENVOY_BUG("Unexpected call to continueReading"); }
66
0
    void injectReadDataToFilterChain(Buffer::Instance&, bool) override {
67
0
      IS_ENVOY_BUG("Unexpected call to injectReadDataToFilterChain");
68
0
    }
69
0
    bool startUpstreamSecureTransport() override {
70
0
      IS_ENVOY_BUG("Unexpected call to startUpstreamSecureTransport");
71
0
      return false;
72
0
    }
73
0
    Upstream::HostDescriptionConstSharedPtr upstreamHost() override { return nullptr; }
74
0
    void upstreamHost(Upstream::HostDescriptionConstSharedPtr) override {
75
0
      IS_ENVOY_BUG("Unexpected call to upstreamHost");
76
0
    }
77
0
    Network::Connection& connection() override { return connection_; }
78
0
    const Network::Socket& socket() override { PANIC("not implemented"); }
79
80
    // Synthetic class that acts as a stub for the connection backing the
81
    // Network::ReadFilterCallbacks.
82
    class SyntheticConnection : public Network::Connection {
83
    public:
84
      SyntheticConnection(SyntheticReadCallbacks& parent, Event::Dispatcher& dispatcher)
85
          : parent_(parent), dispatcher_(dispatcher),
86
            connection_info_provider_(std::make_shared<Network::ConnectionInfoSetterImpl>(
87
                parent.parent_.address_, parent.parent_.address_)),
88
            stream_info_(parent_.parent_.factory_context_.timeSource(), connection_info_provider_),
89
0
            options_(std::make_shared<std::vector<Network::Socket::OptionConstSharedPtr>>()) {}
90
91
      void raiseConnectionEvent(Network::ConnectionEvent event);
92
93
      // Network::FilterManager
94
0
      void addWriteFilter(Network::WriteFilterSharedPtr) override {
95
0
        IS_ENVOY_BUG("Unexpected function call");
96
0
      }
97
0
      void addFilter(Network::FilterSharedPtr) override {
98
0
        IS_ENVOY_BUG("Unexpected function call");
99
0
      }
100
0
      void addReadFilter(Network::ReadFilterSharedPtr) override {
101
0
        IS_ENVOY_BUG("Unexpected function call");
102
0
      }
103
0
      void removeReadFilter(Network::ReadFilterSharedPtr) override {
104
0
        IS_ENVOY_BUG("Unexpected function call");
105
0
      }
106
0
      bool initializeReadFilters() override { return true; }
107
108
      // Network::Connection
109
0
      void addConnectionCallbacks(Network::ConnectionCallbacks& cb) override {
110
0
        callbacks_.push_back(&cb);
111
0
      }
112
0
      void removeConnectionCallbacks(Network::ConnectionCallbacks& cb) override {
113
0
        callbacks_.remove(&cb);
114
0
      }
115
0
      void addBytesSentCallback(Network::Connection::BytesSentCb) override {
116
0
        IS_ENVOY_BUG("Unexpected function call");
117
0
      }
118
0
      void enableHalfClose(bool) override { IS_ENVOY_BUG("Unexpected function call"); }
119
0
      bool isHalfCloseEnabled() const override {
120
0
        IS_ENVOY_BUG("Unexpected function call");
121
0
        return false;
122
0
      }
123
0
      void close(Network::ConnectionCloseType) override {}
124
0
      void close(Network::ConnectionCloseType, absl::string_view) override {}
125
0
      Network::DetectedCloseType detectedCloseType() const override {
126
0
        return Network::DetectedCloseType::Normal;
127
0
      };
128
0
      Event::Dispatcher& dispatcher() const override { return dispatcher_; }
129
0
      uint64_t id() const override { return 12345; }
130
0
      void hashKey(std::vector<uint8_t>&) const override {}
131
0
      std::string nextProtocol() const override { return EMPTY_STRING; }
132
0
      void noDelay(bool) override { IS_ENVOY_BUG("Unexpected function call"); }
133
0
      ReadDisableStatus readDisable(bool) override { return ReadDisableStatus::NoTransition; }
134
0
      void detectEarlyCloseWhenReadDisabled(bool) override {
135
0
        IS_ENVOY_BUG("Unexpected function call");
136
0
      }
137
0
      bool readEnabled() const override { return true; }
138
0
      Network::ConnectionInfoSetter& connectionInfoSetter() override {
139
0
        return *connection_info_provider_;
140
0
      }
141
0
      const Network::ConnectionInfoProvider& connectionInfoProvider() const override {
142
0
        return *connection_info_provider_;
143
0
      }
144
0
      Network::ConnectionInfoProviderSharedPtr connectionInfoProviderSharedPtr() const override {
145
0
        return connection_info_provider_;
146
0
      }
147
      absl::optional<Network::Connection::UnixDomainSocketPeerCredentials>
148
0
      unixSocketPeerCredentials() const override {
149
0
        return absl::nullopt;
150
0
      }
151
0
      void setConnectionStats(const Network::Connection::ConnectionStats&) override {}
152
0
      Ssl::ConnectionInfoConstSharedPtr ssl() const override { return nullptr; }
153
0
      absl::string_view requestedServerName() const override { return EMPTY_STRING; }
154
0
      State state() const override { return Network::Connection::State::Open; }
155
0
      bool connecting() const override { return false; }
156
0
      void write(Buffer::Instance&, bool) override { IS_ENVOY_BUG("Unexpected function call"); }
157
0
      void setBufferLimits(uint32_t) override { IS_ENVOY_BUG("Unexpected function call"); }
158
0
      uint32_t bufferLimit() const override { return 65000; }
159
0
      bool aboveHighWatermark() const override { return false; }
160
0
      const Network::ConnectionSocket::OptionsSharedPtr& socketOptions() const override {
161
0
        return options_;
162
0
      }
163
0
      StreamInfo::StreamInfo& streamInfo() override { return stream_info_; }
164
0
      const StreamInfo::StreamInfo& streamInfo() const override { return stream_info_; }
165
0
      void setDelayedCloseTimeout(std::chrono::milliseconds) override {}
166
0
      absl::string_view transportFailureReason() const override { return EMPTY_STRING; }
167
0
      absl::string_view localCloseReason() const override { return EMPTY_STRING; }
168
0
      bool startSecureTransport() override {
169
0
        IS_ENVOY_BUG("Unexpected function call");
170
0
        return false;
171
0
      }
172
0
      absl::optional<std::chrono::milliseconds> lastRoundTripTime() const override { return {}; }
173
0
      void configureInitialCongestionWindow(uint64_t, std::chrono::microseconds) override {}
174
0
      absl::optional<uint64_t> congestionWindowInBytes() const override { return {}; }
175
      // ScopeTrackedObject
176
0
      void dumpState(std::ostream& os, int) const override { os << "SyntheticConnection"; }
177
178
      SyntheticReadCallbacks& parent_;
179
      Event::Dispatcher& dispatcher_;
180
      Network::ConnectionInfoSetterSharedPtr connection_info_provider_;
181
      StreamInfo::StreamInfoImpl stream_info_;
182
      Network::ConnectionSocket::OptionsSharedPtr options_;
183
      std::list<Network::ConnectionCallbacks*> callbacks_;
184
    };
185
186
    ApiListenerImplBase& parent_;
187
    SyntheticConnection connection_;
188
  };
189
190
  const envoy::config::listener::v3::Listener& config_;
191
  const std::string name_;
192
  Network::Address::InstanceConstSharedPtr address_;
193
  Stats::ScopeSharedPtr global_scope_;
194
  Stats::ScopeSharedPtr listener_scope_;
195
  FactoryContextImpl factory_context_;
196
};
197
198
/**
199
 * ApiListener that provides a handle to inject HTTP calls into Envoy via an
200
 * Http::ConnectionManager. Thus, it provides full access to Envoy's L7 features, e.g HTTP filters.
201
 */
202
class HttpApiListener : public ApiListenerImplBase {
203
public:
204
  // Class to wrap an Http::ApiListener and the associated SyntheticReadCallbacks to ensure that
205
  // both objects have the same lifetime.
206
  //
207
  // Public for testing.
208
  class ApiListenerWrapper : public Http::ApiListener {
209
  public:
210
    ApiListenerWrapper(HttpApiListener& parent, Event::Dispatcher& dispatcher)
211
        : read_callbacks_(parent, dispatcher),
212
0
          http_connection_manager_(parent.http_connection_manager_factory_(read_callbacks_)) {}
213
    ~ApiListenerWrapper() override;
214
215
    Http::RequestDecoderHandlePtr newStreamHandle(Http::ResponseEncoder& response_encoder,
216
                                                  bool is_internally_created = false) override;
217
218
0
    SyntheticReadCallbacks& readCallbacks() { return read_callbacks_; }
219
220
  private:
221
    SyntheticReadCallbacks read_callbacks_;
222
    Http::ApiListenerPtr http_connection_manager_;
223
  };
224
225
  HttpApiListener(const envoy::config::listener::v3::Listener& config, Server::Instance& server,
226
                  const std::string& name);
227
228
  // ApiListener
229
0
  ApiListener::Type type() const override { return ApiListener::Type::HttpApiListener; }
230
  Http::ApiListenerPtr createHttpApiListener(Event::Dispatcher& dispatcher) override;
231
232
private:
233
  // Need to store the factory due to the shared_ptrs that need to be kept alive: date provider,
234
  // route config manager, scoped route config manager.
235
  std::function<Http::ApiListenerPtr(Network::ReadFilterCallbacks&)>
236
      http_connection_manager_factory_;
237
};
238
239
} // namespace Server
240
} // namespace Envoy