proxygen
HTTPServer.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-present, Facebook, Inc.
3  * All rights reserved.
4  *
5  * This source code is licensed under the BSD-style license found in the
6  * LICENSE file in the root directory of this source tree. An additional grant
7  * of patent rights can be found in the PATENTS file in the same directory.
8  *
9  */
10 
12 
21 
23 using folly::EventBase;
28 
29 namespace proxygen {
30 
32  public:
33  AcceptorFactory(std::shared_ptr<HTTPServerOptions> options,
34  std::shared_ptr<HTTPCodecFactory> codecFactory,
36  HTTPSession::InfoCallback* sessionInfoCb) :
37  options_(options),
38  codecFactory_(codecFactory),
39  config_(config),
40  sessionInfoCb_(sessionInfoCb) {}
41  std::shared_ptr<wangle::Acceptor> newAcceptor(
42  folly::EventBase* eventBase) override {
43  auto acc = std::shared_ptr<HTTPServerAcceptor>(
45  if (sessionInfoCb_) {
46  acc->setSessionInfoCallback(sessionInfoCb_);
47  }
48  acc->init(nullptr, eventBase);
49  return acc;
50  }
51 
52  private:
53  std::shared_ptr<HTTPServerOptions> options_;
54  std::shared_ptr<HTTPCodecFactory> codecFactory_;
57 };
58 
60  options_(std::make_shared<HTTPServerOptions>(std::move(options))) {
61 
62  // Insert a filter to fail all the CONNECT request, if required
63  if (!options_->supportsConnect) {
64  options_->handlerFactories.insert(
65  options_->handlerFactories.begin(),
66  std::make_unique<RejectConnectFilterFactory>());
67  }
68 
69  // Add Content Compression filter (gzip), if needed. Should be
70  // final filter
71  if (options_->enableContentCompression) {
72  options_->handlerFactories.insert(
73  options_->handlerFactories.begin(),
74  std::make_unique<ZlibServerFilterFactory>(
75  options_->contentCompressionLevel,
76  options_->contentCompressionMinimumSize,
77  options_->contentCompressionTypes));
78  }
79 }
80 
82  CHECK(!mainEventBase_) << "Forgot to stop() server?";
83 }
84 
85 void HTTPServer::bind(std::vector<IPConfig>&& addrs) {
86  addresses_ = std::move(addrs);
87 }
88 
89 void HTTPServer::bind(std::vector<IPConfig> const& addrs) {
90  addresses_ = addrs;
91 }
92 
93 class HandlerCallbacks : public ThreadPoolExecutor::Observer {
94  public:
95  explicit HandlerCallbacks(std::shared_ptr<HTTPServerOptions> options) : options_(options) {}
96 
97  void threadStarted(ThreadPoolExecutor::ThreadHandle* h) override {
99  CHECK(evb) << "Invariant violated - started thread must have an EventBase";
100  evb->runInEventBaseThread([=](){
101  for (auto& factory: options_->handlerFactories) {
102  factory->onServerStart(evb);
103  }
104  });
105  }
106  void threadStopped(ThreadPoolExecutor::ThreadHandle* h) override {
108  for (auto& factory: options_->handlerFactories) {
109  factory->onServerStop();
110  }
111  });
112  }
113 
114  private:
115  std::shared_ptr<HTTPServerOptions> options_;
116 };
117 
118 
119 void HTTPServer::start(std::function<void()> onSuccess,
120  std::function<void(std::exception_ptr)> onError) {
121  mainEventBase_ = EventBaseManager::get()->getEventBase();
122 
123  auto accExe = std::make_shared<IOThreadPoolExecutor>(1);
124  auto exe = std::make_shared<IOThreadPoolExecutor>(options_->threads,
125  std::make_shared<folly::NamedThreadFactory>("HTTPSrvExec"));
126  auto exeObserver = std::make_shared<HandlerCallbacks>(options_);
127  // Observer has to be set before bind(), so onServerStart() callbacks run
128  exe->addObserver(exeObserver);
129 
130  try {
131  FOR_EACH_RANGE (i, 0, addresses_.size()) {
132  auto codecFactory = addresses_[i].codecFactory;
134  auto factory = std::make_shared<AcceptorFactory>(
135  options_,
136  codecFactory,
137  accConfig,
139  bootstrap_.push_back(
141  bootstrap_[i].childHandler(factory);
142  if (accConfig.enableTCPFastOpen) {
143  // We need to do this because wangle's bootstrap has 2 acceptor configs
144  // and the socketConfig gets passed to the SocketFactory. The number of
145  // configs should really be one, and when that happens, we can remove
146  // this code path.
147  bootstrap_[i].socketConfig.enableTCPFastOpen = true;
148  bootstrap_[i].socketConfig.fastOpenQueueSize =
149  accConfig.fastOpenQueueSize;
150  }
151  bootstrap_[i].group(accExe, exe);
152  if (options_->preboundSockets_.size() > 0) {
153  bootstrap_[i].bind(std::move(options_->preboundSockets_[i]));
154  } else {
155  bootstrap_[i].bind(addresses_[i].address);
156  }
157  }
158  } catch (const std::exception& ex) {
159  stop();
160 
161  if (onError) {
162  onError(std::current_exception());
163  return;
164  }
165 
166  throw;
167  }
168 
169  // Install signal handler if required
170  if (!options_->shutdownOn.empty()) {
171  signalHandler_ = std::make_unique<SignalHandler>(this);
172  signalHandler_->install(options_->shutdownOn);
173  }
174 
175  // Start the main event loop.
176  if (onSuccess) {
177  mainEventBase_->runInLoop([onSuccess(std::move(onSuccess))]() {
178  // IMPORTANT: Since we may be racing with stop(), we must assume that
179  // mainEventBase_ can become null the moment that onSuccess is called,
180  // so this **has** to be queued to run from inside loopForever().
181  onSuccess();
182  });
183  }
185 }
186 
188  for (auto& bootstrap : bootstrap_) {
189  bootstrap.stop();
190  }
191 }
192 
194  stopListening();
195 
196  for (auto& bootstrap : bootstrap_) {
197  bootstrap.join();
198  }
199 
200  if (signalHandler_) {
201  signalHandler_.reset();
202  }
203 
204  if (mainEventBase_) {
206  mainEventBase_ = nullptr;
207  }
208 }
209 
210 const std::vector<const folly::AsyncSocketBase*>
212 
213  std::vector<const folly::AsyncSocketBase*> sockets;
214  FOR_EACH_RANGE(i, 0, bootstrap_.size()) {
215  auto& bootstrapSockets = bootstrap_[i].getSockets();
216  FOR_EACH_RANGE(j, 0, bootstrapSockets.size()) {
217  sockets.push_back(bootstrapSockets[j].get());
218  }
219  }
220 
221  return sockets;
222 }
223 
225  if (bootstrap_.size() == 0) {
226  return -1;
227  }
228 
229  auto& bootstrapSockets = bootstrap_[0].getSockets();
230  if (bootstrapSockets.size() == 0) {
231  return -1;
232  }
233 
234  auto serverSocket =
235  std::dynamic_pointer_cast<folly::AsyncServerSocket>(bootstrapSockets[0]);
236  auto socketFds = serverSocket->getSockets();
237  if (socketFds.size() == 0) {
238  return -1;
239  }
240 
241  return socketFds[0];
242 }
243 
244 
246  for (auto& bootstrap : bootstrap_) {
247  bootstrap.forEachWorker([&](wangle::Acceptor* acceptor) {
248  if (!acceptor || !acceptor->isSSL()) {
249  return;
250  }
251  auto evb = acceptor->getEventBase();
252  if (!evb) {
253  return;
254  }
255  evb->runInEventBaseThread([acceptor] {
256  acceptor->resetSSLContextConfigs();
257  });
258  });
259  }
260 }
261 
263  for (auto& bootstrap : bootstrap_) {
264  bootstrap.forEachWorker([&](wangle::Acceptor* acceptor) {
265  if (!acceptor || !acceptor->isSSL()) {
266  return;
267  }
268  auto evb = acceptor->getEventBase();
269  if (!evb) {
270  return;
271  }
272  evb->runInEventBaseThread([acceptor, seeds] {
273  acceptor->setTLSTicketSecrets(
274  seeds.oldSeeds, seeds.currentSeeds, seeds.newSeeds);
275  });
276  });
277  }
278 }
279 
280 }
std::vector< std::string > newSeeds
*than *hazptr_holder h
Definition: Hazptr.h:116
static AcceptorConfiguration makeConfig(const HTTPServer::IPConfig &ipConfig, const HTTPServerOptions &opts)
std::vector< std::string > currentSeeds
void threadStarted(ThreadPoolExecutor::ThreadHandle *h) override
Definition: HTTPServer.cpp:97
AcceptorFactory(std::shared_ptr< HTTPServerOptions > options, std::shared_ptr< HTTPCodecFactory > codecFactory, AcceptorConfiguration config, HTTPSession::InfoCallback *sessionInfoCb)
Definition: HTTPServer.cpp:33
void start(std::function< void()> onSuccess=nullptr, std::function< void(std::exception_ptr)> onError=nullptr)
Definition: HTTPServer.cpp:119
std::vector< int > getSockets() const
virtual void setTLSTicketSecrets(const std::vector< std::string > &oldSecrets, const std::vector< std::string > &currentSecrets, const std::vector< std::string > &newSecrets)
Definition: Acceptor.cpp:195
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
EventBase * getEventBase()
STL namespace.
void bind(std::vector< IPConfig > &&addrs)
Definition: HTTPServer.cpp:85
std::shared_ptr< HTTPServerOptions > options_
Definition: HTTPServer.cpp:115
int getListenSocket() const
Definition: HTTPServer.cpp:224
AHArrayT::Config config
#define FOR_EACH_RANGE(i, begin, end)
Definition: Foreach.h:313
void runInLoop(LoopCallback *callback, bool thisIteration=false)
Definition: EventBase.cpp:520
bool isSSL() const
Definition: Acceptor.h:195
std::shared_ptr< wangle::Acceptor > newAcceptor(folly::EventBase *eventBase) override
Definition: HTTPServer.cpp:41
void terminateLoopSoon()
Definition: EventBase.cpp:493
HandlerCallbacks(std::shared_ptr< HTTPServerOptions > options)
Definition: HTTPServer.cpp:95
AcceptorConfiguration config_
Definition: HTTPServer.cpp:55
bool runInEventBaseThread(void(*fn)(T *), T *arg)
Definition: EventBase.h:794
void threadStopped(ThreadPoolExecutor::ThreadHandle *h) override
Definition: HTTPServer.cpp:106
std::shared_ptr< HTTPCodecFactory > codecFactory_
Definition: HTTPServer.cpp:54
std::shared_ptr< HTTPServerOptions > options_
Definition: HTTPServer.cpp:53
std::vector< IPConfig > addresses_
Definition: HTTPServer.h:183
std::unique_ptr< SignalHandler > signalHandler_
Definition: HTTPServer.h:178
HTTPSession::InfoCallback * sessionInfoCb_
Definition: HTTPServer.cpp:56
folly::EventBase * mainEventBase_
Definition: HTTPServer.h:173
HTTPSession::InfoCallback * sessionInfoCb_
Definition: HTTPServer.h:189
std::shared_ptr< HTTPServerOptions > options_
Definition: HTTPServer.h:168
static std::unique_ptr< HTTPServerAcceptor > make(const AcceptorConfiguration &conf, const HTTPServerOptions &opts, const std::shared_ptr< HTTPCodecFactory > &codecFactory=nullptr)
void updateTicketSeeds(wangle::TLSTicketKeySeeds seeds)
Definition: HTTPServer.cpp:262
InlineExecutor exe
Definition: Benchmark.cpp:337
std::vector< std::string > oldSeeds
std::vector< wangle::ServerBootstrap< wangle::DefaultPipeline > > bootstrap_
Definition: HTTPServer.h:184
HTTPServer(HTTPServerOptions options)
Definition: HTTPServer.cpp:59
PUSHMI_INLINE_VAR constexpr detail::get_fn< T > get
Definition: submit.h:391
virtual void resetSSLContextConfigs()
Definition: Acceptor.cpp:162
virtual folly::EventBase * getEventBase() const
Definition: Acceptor.h:127
const std::vector< const folly::AsyncSocketBase * > getSockets() const
Definition: HTTPServer.cpp:211