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