proxygen
proxygen::HTTPServer Class Referencefinal

#include <HTTPServer.h>

Classes

struct  IPConfig
 

Public Types

enum  Protocol : uint8_t { Protocol::HTTP, Protocol::SPDY, Protocol::HTTP2 }
 

Public Member Functions

 HTTPServer (HTTPServerOptions options)
 
 ~HTTPServer ()
 
void bind (std::vector< IPConfig > &&addrs)
 
void bind (std::vector< IPConfig > const &addrs)
 
void start (std::function< void()> onSuccess=nullptr, std::function< void(std::exception_ptr)> onError=nullptr)
 
void stopListening ()
 
void stop ()
 
std::vector< IPConfigaddresses () const
 
const std::vector< const folly::AsyncSocketBase * > getSockets () const
 
void setSessionInfoCallback (HTTPSession::InfoCallback *cb)
 
int getListenSocket () const
 
void updateTLSCredentials ()
 
void updateTicketSeeds (wangle::TLSTicketKeySeeds seeds)
 

Private Attributes

std::shared_ptr< HTTPServerOptionsoptions_
 
folly::EventBasemainEventBase_ {nullptr}
 
std::unique_ptr< SignalHandlersignalHandler_
 
std::vector< IPConfigaddresses_
 
std::vector< wangle::ServerBootstrap< wangle::DefaultPipeline > > bootstrap_
 
HTTPSession::InfoCallbacksessionInfoCb_ {nullptr}
 

Detailed Description

HTTPServer based on proxygen http libraries

Definition at line 28 of file HTTPServer.h.

Member Enumeration Documentation

For each IP you can specify HTTP protocol to use. You can use plain old HTTP/1.1 protocol or SPDY/3.1 for now.

Enumerator
HTTP 
SPDY 
HTTP2 

Definition at line 34 of file HTTPServer.h.

34  : uint8_t {
35  HTTP,
36  SPDY,
37  HTTP2,
38  };

Constructor & Destructor Documentation

proxygen::HTTPServer::HTTPServer ( HTTPServerOptions  options)
explicit

Create a new HTTPServer

Definition at line 59 of file HTTPServer.cpp.

References options_.

59  :
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 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::shared_ptr< HTTPServerOptions > options_
Definition: HTTPServer.h:168
proxygen::HTTPServer::~HTTPServer ( )

Definition at line 81 of file HTTPServer.cpp.

References mainEventBase_.

81  {
82  CHECK(!mainEventBase_) << "Forgot to stop() server?";
83 }
folly::EventBase * mainEventBase_
Definition: HTTPServer.h:173

Member Function Documentation

std::vector<IPConfig> proxygen::HTTPServer::addresses ( ) const
inline

Get the list of addresses server is listening on. Empty if sockets are not bound yet.

Definition at line 139 of file HTTPServer.h.

References addresses_, and getSockets().

Referenced by TEST().

139  {
140  return addresses_;
141  }
std::vector< IPConfig > addresses_
Definition: HTTPServer.h:183
void proxygen::HTTPServer::bind ( std::vector< IPConfig > &&  addrs)

Configure server to bind to the following addresses.

Actual bind happens in start function.

Can be called from any thread.

Definition at line 85 of file HTTPServer.cpp.

References addresses_, and folly::gen::move.

Referenced by main().

85  {
86  addresses_ = std::move(addrs);
87 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::vector< IPConfig > addresses_
Definition: HTTPServer.h:183
void proxygen::HTTPServer::bind ( std::vector< IPConfig > const &  addrs)

Definition at line 89 of file HTTPServer.cpp.

References addresses_.

89  {
90  addresses_ = addrs;
91 }
std::vector< IPConfig > addresses_
Definition: HTTPServer.h:183
int proxygen::HTTPServer::getListenSocket ( ) const

Returns a file descriptor associated with the listening socket

Definition at line 224 of file HTTPServer.cpp.

References bootstrap_, and folly::AsyncServerSocket::getSockets().

Referenced by setSessionInfoCallback(), and TEST().

224  {
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 }
std::vector< int > getSockets() const
std::vector< wangle::ServerBootstrap< wangle::DefaultPipeline > > bootstrap_
Definition: HTTPServer.h:184
const std::vector< const folly::AsyncSocketBase * > proxygen::HTTPServer::getSockets ( ) const

Get the sockets the server is currently bound to.

Definition at line 211 of file HTTPServer.cpp.

References bootstrap_, FOR_EACH_RANGE, and i.

Referenced by addresses().

211  {
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 }
#define FOR_EACH_RANGE(i, begin, end)
Definition: Foreach.h:313
std::vector< wangle::ServerBootstrap< wangle::DefaultPipeline > > bootstrap_
Definition: HTTPServer.h:184
void proxygen::HTTPServer::setSessionInfoCallback ( HTTPSession::InfoCallback cb)
inline

Definition at line 148 of file HTTPServer.h.

References getListenSocket(), sessionInfoCb_, updateTicketSeeds(), and updateTLSCredentials().

148  {
149  sessionInfoCb_ = cb;
150  }
HTTPSession::InfoCallback * sessionInfoCb_
Definition: HTTPServer.h:189
void proxygen::HTTPServer::start ( std::function< void()>  onSuccess = nullptr,
std::function< void(std::exception_ptr)>  onError = nullptr 
)

Start HTTPServer.

Note this is a blocking call and the current thread will be used to listen for incoming connections. Throws exception if something goes wrong (say somebody else is already listening on that socket).

onSuccess callback will be invoked from the event loop which shows that all the setup was successfully done.

onError callback will be invoked if some errors occurs while starting the server instead of throwing exception.

Definition at line 119 of file HTTPServer.cpp.

References addresses_, bootstrap_, exe, FOR_EACH_RANGE, folly::pushmi::operators::get, i, folly::EventBase::loopForever(), mainEventBase_, proxygen::HTTPServerAcceptor::makeConfig(), folly::gen::move, options_, folly::EventBase::runInLoop(), sessionInfoCb_, signalHandler_, and stop().

Referenced by main().

120  {
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 }
static AcceptorConfiguration makeConfig(const HTTPServer::IPConfig &ipConfig, const HTTPServerOptions &opts)
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
#define FOR_EACH_RANGE(i, begin, end)
Definition: Foreach.h:313
void runInLoop(LoopCallback *callback, bool thisIteration=false)
Definition: EventBase.cpp:520
std::vector< IPConfig > addresses_
Definition: HTTPServer.h:183
std::unique_ptr< SignalHandler > signalHandler_
Definition: HTTPServer.h:178
folly::EventBase * mainEventBase_
Definition: HTTPServer.h:173
HTTPSession::InfoCallback * sessionInfoCb_
Definition: HTTPServer.h:189
std::shared_ptr< HTTPServerOptions > options_
Definition: HTTPServer.h:168
InlineExecutor exe
Definition: Benchmark.cpp:337
std::vector< wangle::ServerBootstrap< wangle::DefaultPipeline > > bootstrap_
Definition: HTTPServer.h:184
PUSHMI_INLINE_VAR constexpr detail::get_fn< T > get
Definition: submit.h:391
void proxygen::HTTPServer::stop ( )

Stop HTTPServer.

Can be called from any thread, but only after start() has called onSuccess. Server will stop listening for new connections and will wait for running requests to finish.

TODO: Separate method to do hard shutdown?

Definition at line 193 of file HTTPServer.cpp.

References bootstrap_, mainEventBase_, signalHandler_, stopListening(), and folly::EventBase::terminateLoopSoon().

Referenced by proxygen::SignalHandler::signalReceived(), and start().

193  {
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 }
void terminateLoopSoon()
Definition: EventBase.cpp:493
std::unique_ptr< SignalHandler > signalHandler_
Definition: HTTPServer.h:178
folly::EventBase * mainEventBase_
Definition: HTTPServer.h:173
std::vector< wangle::ServerBootstrap< wangle::DefaultPipeline > > bootstrap_
Definition: HTTPServer.h:184
void proxygen::HTTPServer::stopListening ( )

Stop listening on bound ports. (Stop accepting new work). It does not wait for pending work to complete. You must still invoke stop() before destroying the server. You do NOT need to invoke this before calling stop(). This can be called from any thread, and it is idempotent. However, it may only be called after start() has called onSuccess.

Definition at line 187 of file HTTPServer.cpp.

References bootstrap_.

Referenced by stop(), and TEST().

187  {
188  for (auto& bootstrap : bootstrap_) {
189  bootstrap.stop();
190  }
191 }
std::vector< wangle::ServerBootstrap< wangle::DefaultPipeline > > bootstrap_
Definition: HTTPServer.h:184
void proxygen::HTTPServer::updateTicketSeeds ( wangle::TLSTicketKeySeeds  seeds)

Updates ticket seeds for the HTTPServer for all the VIPs.

Definition at line 262 of file HTTPServer.cpp.

References bootstrap_, wangle::TLSTicketKeySeeds::currentSeeds, wangle::Acceptor::getEventBase(), wangle::Acceptor::isSSL(), wangle::TLSTicketKeySeeds::newSeeds, wangle::TLSTicketKeySeeds::oldSeeds, folly::EventBase::runInEventBaseThread(), and wangle::Acceptor::setTLSTicketSecrets().

Referenced by setSessionInfoCallback(), and TEST().

262  {
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 }
std::vector< std::string > newSeeds
std::vector< std::string > currentSeeds
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
bool isSSL() const
Definition: Acceptor.h:195
bool runInEventBaseThread(void(*fn)(T *), T *arg)
Definition: EventBase.h:794
std::vector< std::string > oldSeeds
std::vector< wangle::ServerBootstrap< wangle::DefaultPipeline > > bootstrap_
Definition: HTTPServer.h:184
virtual folly::EventBase * getEventBase() const
Definition: Acceptor.h:127
void proxygen::HTTPServer::updateTLSCredentials ( )

Re-reads the certificate / key pair for all SSL vips on all acceptors

Definition at line 245 of file HTTPServer.cpp.

References bootstrap_, wangle::Acceptor::getEventBase(), wangle::Acceptor::isSSL(), wangle::Acceptor::resetSSLContextConfigs(), and folly::EventBase::runInEventBaseThread().

Referenced by setSessionInfoCallback().

245  {
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 }
bool isSSL() const
Definition: Acceptor.h:195
bool runInEventBaseThread(void(*fn)(T *), T *arg)
Definition: EventBase.h:794
std::vector< wangle::ServerBootstrap< wangle::DefaultPipeline > > bootstrap_
Definition: HTTPServer.h:184
virtual void resetSSLContextConfigs()
Definition: Acceptor.cpp:162
virtual folly::EventBase * getEventBase() const
Definition: Acceptor.h:127

Member Data Documentation

std::vector<IPConfig> proxygen::HTTPServer::addresses_
private

Addresses we are listening on

Definition at line 183 of file HTTPServer.h.

Referenced by addresses(), bind(), and start().

std::vector<wangle::ServerBootstrap<wangle::DefaultPipeline> > proxygen::HTTPServer::bootstrap_
private
folly::EventBase* proxygen::HTTPServer::mainEventBase_ {nullptr}
private

Event base in which we binded server sockets.

Definition at line 173 of file HTTPServer.h.

Referenced by start(), stop(), and ~HTTPServer().

std::shared_ptr<HTTPServerOptions> proxygen::HTTPServer::options_
private
HTTPSession::InfoCallback* proxygen::HTTPServer::sessionInfoCb_ {nullptr}
private

Callback for session create/destruction

Definition at line 189 of file HTTPServer.h.

Referenced by setSessionInfoCallback(), and start().

std::unique_ptr<SignalHandler> proxygen::HTTPServer::signalHandler_
private

Optional signal handlers on which we should shutdown server

Definition at line 178 of file HTTPServer.h.

Referenced by start(), and stop().


The documentation for this class was generated from the following files: