proxygen
HTTPServerTest.cpp File Reference

Go to the source code of this file.

Classes

class  ServerThread
 
class  Cb
 
class  DummyFilterFactory
 
class  DummyFilterFactory::DummyFilter
 
class  TestHandlerFactory
 
class  TestHandlerFactory::TestHandler
 
class  ScopedServerTest
 
class  ConnectionFilterTest
 

Functions

 TEST (MultiBind, HandlesListenFailures)
 
 TEST (HttpServerStartStop, TestRepeatStopCalls)
 
 TEST (SSL, SSLTest)
 
std::pair< std::unique_ptr< HTTPServer >, std::unique_ptr< ServerThread > > setupServer (bool allowInsecureConnectionsOnSecureServer=false, folly::Optional< wangle::TLSTicketKeySeeds > seeds=folly::none)
 
 TEST (SSL, TestAllowInsecureOnSecureServer)
 
 TEST (SSL, DisallowInsecureOnSecureServer)
 
 TEST (SSL, TestResumptionWithTickets)
 
 TEST (SSL, TestResumptionAfterUpdateFails)
 
 TEST (SSL, TestUpdateTLSCredentials)
 
 TEST (GetListenSocket, TestNoBootstrap)
 
 TEST (GetListenSocket, TestBootstrapWithNoBinding)
 
 TEST (GetListenSocket, TestBootstrapWithBinding)
 
 TEST (UseExistingSocket, TestWithExistingAsyncServerSocket)
 
 TEST (UseExistingSocket, TestWithSocketFd)
 
 TEST (UseExistingSocket, TestWithMultipleSocketFds)
 
 TEST_F (ScopedServerTest, Start)
 
 TEST_F (ScopedServerTest, StartStrictSSL)
 
 TEST_F (ScopedServerTest, StartNotStrictSSL)
 
 TEST_F (ScopedServerTest, StartSSLWithInsecure)
 
 TEST_F (ConnectionFilterTest, Test)
 

Function Documentation

std::pair<std::unique_ptr<HTTPServer>, std::unique_ptr<ServerThread> > setupServer ( bool  allowInsecureConnectionsOnSecureServer = false,
folly::Optional< wangle::TLSTicketKeySeeds seeds = folly::none 
)

Definition at line 241 of file HTTPServerTest.cpp.

References proxygen::RequestHandlerChain::addThen(), EXPECT_TRUE, proxygen::HTTPServerOptions::handlerFactories, wangle::SSLContextConfig::isDefault, folly::gen::move, wangle::SSLContextConfig::setCertificate(), and proxygen::HTTPServerOptions::threads.

Referenced by TEST().

242  {
243  HTTPServer::IPConfig cfg{folly::SocketAddress("127.0.0.1", 0),
244  HTTPServer::Protocol::HTTP};
246  sslCfg.isDefault = true;
247  sslCfg.setCertificate(
248  kTestDir + "certs/test_cert1.pem", kTestDir + "certs/test_key1.pem", "");
249  cfg.sslConfigs.push_back(sslCfg);
250  cfg.allowInsecureConnectionsOnSecureServer =
251  allowInsecureConnectionsOnSecureServer;
252  cfg.ticketSeeds = seeds;
253 
254  HTTPServerOptions options;
255  options.threads = 4;
256  options.handlerFactories =
258 
259  auto server = std::make_unique<HTTPServer>(std::move(options));
260 
261  std::vector<HTTPServer::IPConfig> ips{cfg};
262  server->bind(ips);
263 
264  auto st = std::make_unique<ServerThread>(server.get());
265  EXPECT_TRUE(st->start());
266  return std::make_pair(std::move(server), std::move(st));
267 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
RequestHandlerChain & addThen(Args &&...args)
std::vector< std::unique_ptr< RequestHandlerFactory > > handlerFactories
void setCertificate(const std::string &certPath, const std::string &keyPath, const std::string &passwordPath)
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
TEST ( MultiBind  ,
HandlesListenFailures   
)

Definition at line 76 of file HTTPServerTest.cpp.

References addr, EXPECT_FALSE, folly::EventBaseManager::get(), folly::EventBaseManager::getEventBase(), folly::SocketAddress::getPort(), folly::gen::move, folly::netops::socket(), and proxygen::HTTPServerOptions::threads.

76  {
77  SocketAddress addr("127.0.0.1", 0);
78 
79  auto evb = EventBaseManager::get()->getEventBase();
81  socket->bind(addr);
82 
83  // Get the ephemeral port
84  socket->getAddress(&addr);
85  int port = addr.getPort();
86 
87  std::vector<HTTPServer::IPConfig> ips = {
88  {
89  folly::SocketAddress("127.0.0.1", port),
90  HTTPServer::Protocol::HTTP
91  }
92  };
93 
94  HTTPServerOptions options;
95  options.threads = 4;
96 
97  auto server = std::make_unique<HTTPServer>(std::move(options));
98 
99  // We have to bind both the sockets before listening on either
100  server->bind(ips);
101 
102  // On kernel 2.6 trying to listen on a FD that another socket
103  // has bound to fails. While in kernel 3.2 only when one socket tries
104  // to listen on a FD that another socket is listening on fails.
105  try {
106  socket->listen(1024);
107  } catch (const std::exception& ex) {
108  return;
109  }
110 
111  ServerThread st(server.get());
112  EXPECT_FALSE(st.start());
113 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
NetworkSocket socket(int af, int type, int protocol)
Definition: NetOps.cpp:412
std::unique_ptr< AsyncServerSocket, Destructor > UniquePtr
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
PUSHMI_INLINE_VAR constexpr detail::get_fn< T > get
Definition: submit.h:391
ThreadPoolListHook * addr
TEST ( HttpServerStartStop  ,
TestRepeatStopCalls   
)

Definition at line 115 of file HTTPServerTest.cpp.

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

115  {
116  HTTPServerOptions options;
117  auto server = std::make_unique<HTTPServer>(std::move(options));
118  auto st = std::make_unique<ServerThread>(server.get());
119  EXPECT_TRUE(st->start());
120 
121  server->stop();
122  // Calling stop again should be benign.
123  server->stop();
124 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
TEST ( SSL  ,
SSLTest   
)

Definition at line 154 of file HTTPServerTest.cpp.

References EXPECT_TRUE, wangle::SSLContextConfig::isDefault, folly::gen::move, wangle::SSLContextConfig::setCertificate(), and proxygen::HTTPServerOptions::threads.

154  {
156  folly::SocketAddress("127.0.0.1", 0),
157  HTTPServer::Protocol::HTTP};
159  sslCfg.isDefault = true;
160  sslCfg.setCertificate(
161  kTestDir + "certs/test_cert1.pem",
162  kTestDir + "certs/test_key1.pem",
163  "");
164  cfg.sslConfigs.push_back(sslCfg);
165 
166  HTTPServerOptions options;
167  options.threads = 4;
168 
169  auto server = std::make_unique<HTTPServer>(std::move(options));
170 
171  std::vector<HTTPServer::IPConfig> ips{cfg};
172  server->bind(ips);
173 
174  ServerThread st(server.get());
175  EXPECT_TRUE(st.start());
176 
177  folly::EventBase evb;
178  auto ctx = std::make_shared<SSLContext>();
180  Cb cb(sock.get());
181  sock->connect(&cb, server->addresses().front().address, 1000);
182  evb.loop();
183  EXPECT_TRUE(cb.success);
184 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::unique_ptr< AsyncSSLSocket, Destructor > UniquePtr
void setCertificate(const std::string &certPath, const std::string &keyPath, const std::string &passwordPath)
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
TEST ( SSL  ,
TestAllowInsecureOnSecureServer   
)

Definition at line 269 of file HTTPServerTest.cpp.

References proxygen::HTTPServer::addresses(), proxygen::HTTPConnector::connect(), folly::HHWheelTimer::DEFAULT_TICK_INTERVAL, EXPECT_EQ, CurlService::CurlClient::getResponse(), folly::EventBase::loop(), folly::TimeoutManager::NORMAL, CurlService::CurlClient::setFlowControlSettings(), CurlService::CurlClient::setLogging(), and setupServer().

269  {
270  std::unique_ptr<HTTPServer> server;
271  std::unique_ptr<ServerThread> st;
272  std::tie(server, st) = setupServer(true);
273 
274  folly::EventBase evb;
275  URL url(folly::to<std::string>(
276  "http://localhost:", server->addresses().front().address.getPort()));
277  HTTPHeaders headers;
278  CurlClient curl(&evb, HTTPMethod::GET, url, nullptr, headers, "");
279  curl.setFlowControlSettings(64 * 1024);
280  curl.setLogging(false);
282  &evb,
283  std::chrono::milliseconds(HHWheelTimer::DEFAULT_TICK_INTERVAL),
284  AsyncTimeout::InternalEnum::NORMAL,
285  std::chrono::milliseconds(1000))};
286  HTTPConnector connector(&curl, timer.get());
287  connector.connect(&evb,
288  server->addresses().front().address,
289  std::chrono::milliseconds(1000));
290  evb.loop();
291  auto response = curl.getResponse();
292  EXPECT_EQ(200, response->getStatusCode());
293 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
std::pair< std::unique_ptr< HTTPServer >, std::unique_ptr< ServerThread > > setupServer(bool allowInsecureConnectionsOnSecureServer=false, folly::Optional< wangle::TLSTicketKeySeeds > seeds=folly::none)
std::vector< IPConfig > addresses() const
Definition: HTTPServer.h:139
std::unique_ptr< HHWheelTimer, Destructor > UniquePtr
Definition: HHWheelTimer.h:57
void connect(folly::EventBase *eventBase, const folly::SocketAddress &connectAddr, std::chrono::milliseconds timeoutMs=std::chrono::milliseconds(0), const folly::AsyncSocket::OptionMap &socketOptions=folly::AsyncSocket::emptyOptionMap, const folly::SocketAddress &bindAddr=folly::AsyncSocket::anyAddress())
TEST ( SSL  ,
DisallowInsecureOnSecureServer   
)

Definition at line 295 of file HTTPServerTest.cpp.

References proxygen::HTTPServer::addresses(), proxygen::HTTPConnector::connect(), folly::HHWheelTimer::DEFAULT_TICK_INTERVAL, EXPECT_EQ, CurlService::CurlClient::getResponse(), folly::EventBase::loop(), folly::TimeoutManager::NORMAL, CurlService::CurlClient::setFlowControlSettings(), CurlService::CurlClient::setLogging(), and setupServer().

295  {
296  std::unique_ptr<HTTPServer> server;
297  std::unique_ptr<ServerThread> st;
298  std::tie(server, st) = setupServer(false);
299 
300  folly::EventBase evb;
301  URL url(folly::to<std::string>(
302  "http://localhost:", server->addresses().front().address.getPort()));
303  HTTPHeaders headers;
304  CurlClient curl(&evb, HTTPMethod::GET, url, nullptr, headers, "");
305  curl.setFlowControlSettings(64 * 1024);
306  curl.setLogging(false);
308  &evb,
309  std::chrono::milliseconds(HHWheelTimer::DEFAULT_TICK_INTERVAL),
310  AsyncTimeout::InternalEnum::NORMAL,
311  std::chrono::milliseconds(1000))};
312  HTTPConnector connector(&curl, timer.get());
313  connector.connect(&evb,
314  server->addresses().front().address,
315  std::chrono::milliseconds(1000));
316  evb.loop();
317  auto response = curl.getResponse();
318  EXPECT_EQ(nullptr, response);
319 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
std::pair< std::unique_ptr< HTTPServer >, std::unique_ptr< ServerThread > > setupServer(bool allowInsecureConnectionsOnSecureServer=false, folly::Optional< wangle::TLSTicketKeySeeds > seeds=folly::none)
std::vector< IPConfig > addresses() const
Definition: HTTPServer.h:139
std::unique_ptr< HHWheelTimer, Destructor > UniquePtr
Definition: HHWheelTimer.h:57
void connect(folly::EventBase *eventBase, const folly::SocketAddress &connectAddr, std::chrono::milliseconds timeoutMs=std::chrono::milliseconds(0), const folly::AsyncSocket::OptionMap &socketOptions=folly::AsyncSocket::emptyOptionMap, const folly::SocketAddress &bindAddr=folly::AsyncSocket::anyAddress())
TEST ( SSL  ,
TestResumptionWithTickets   
)

Definition at line 321 of file HTTPServerTest.cpp.

References proxygen::HTTPServer::addresses(), ASSERT_FALSE, ASSERT_NE, ASSERT_TRUE, wangle::TLSTicketKeySeeds::currentSeeds, folly::hexlify(), folly::EventBase::loop(), and setupServer().

321  {
322  std::unique_ptr<HTTPServer> server;
323  std::unique_ptr<ServerThread> st;
325  seeds.currentSeeds.push_back(hexlify("hello"));
326  std::tie(server, st) = setupServer(false, seeds);
327 
328  folly::EventBase evb;
329  auto ctx = std::make_shared<SSLContext>();
331  Cb cb(sock.get());
332  sock->connect(&cb, server->addresses().front().address, 1000);
333  evb.loop();
334  ASSERT_TRUE(cb.success);
335  ASSERT_NE(nullptr, cb.session.get());
336  ASSERT_FALSE(cb.reusedSession);
337 
339  sock2->setSSLSession(cb.session.get());
340  Cb cb2(sock2.get());
341  sock2->connect(&cb2, server->addresses().front().address, 1000);
342  evb.loop();
343  ASSERT_TRUE(cb2.success);
344  ASSERT_NE(nullptr, cb2.session.get());
345  ASSERT_TRUE(cb2.reusedSession);
346 }
std::vector< std::string > currentSeeds
std::unique_ptr< AsyncSSLSocket, Destructor > UniquePtr
std::pair< std::unique_ptr< HTTPServer >, std::unique_ptr< ServerThread > > setupServer(bool allowInsecureConnectionsOnSecureServer=false, folly::Optional< wangle::TLSTicketKeySeeds > seeds=folly::none)
std::vector< IPConfig > addresses() const
Definition: HTTPServer.h:139
#define ASSERT_NE(val1, val2)
Definition: gtest.h:1960
#define ASSERT_FALSE(condition)
Definition: gtest.h:1868
bool hexlify(const InputString &input, OutputString &output, bool append_output)
Definition: String-inl.h:596
#define ASSERT_TRUE(condition)
Definition: gtest.h:1865
TEST ( SSL  ,
TestResumptionAfterUpdateFails   
)

Definition at line 348 of file HTTPServerTest.cpp.

References proxygen::HTTPServer::addresses(), ASSERT_FALSE, ASSERT_NE, ASSERT_TRUE, wangle::TLSTicketKeySeeds::currentSeeds, folly::hexlify(), folly::EventBase::loop(), setupServer(), and proxygen::HTTPServer::updateTicketSeeds().

348  {
349  std::unique_ptr<HTTPServer> server;
350  std::unique_ptr<ServerThread> st;
352  seeds.currentSeeds.push_back(hexlify("hello"));
353  std::tie(server, st) = setupServer(false, seeds);
354 
355  folly::EventBase evb;
356  auto ctx = std::make_shared<SSLContext>();
358  Cb cb(sock.get());
359  sock->connect(&cb, server->addresses().front().address, 1000);
360  evb.loop();
361  ASSERT_TRUE(cb.success);
362  ASSERT_NE(nullptr, cb.session.get());
363  ASSERT_FALSE(cb.reusedSession);
364 
365  wangle::TLSTicketKeySeeds newSeeds;
366  newSeeds.currentSeeds.push_back(hexlify("goodbyte"));
367  server->updateTicketSeeds(newSeeds);
368 
370  sock2->setSSLSession(cb.session.get());
371  Cb cb2(sock2.get());
372  sock2->connect(&cb2, server->addresses().front().address, 1000);
373  evb.loop();
374  ASSERT_TRUE(cb2.success);
375  ASSERT_NE(nullptr, cb2.session.get());
376  ASSERT_FALSE(cb2.reusedSession);
377 
379  sock3->setSSLSession(cb2.session.get());
380  Cb cb3(sock3.get());
381  sock3->connect(&cb3, server->addresses().front().address, 1000);
382  evb.loop();
383  ASSERT_TRUE(cb3.success);
384  ASSERT_NE(nullptr, cb3.session.get());
385  ASSERT_TRUE(cb3.reusedSession);
386 }
std::vector< std::string > currentSeeds
std::unique_ptr< AsyncSSLSocket, Destructor > UniquePtr
std::pair< std::unique_ptr< HTTPServer >, std::unique_ptr< ServerThread > > setupServer(bool allowInsecureConnectionsOnSecureServer=false, folly::Optional< wangle::TLSTicketKeySeeds > seeds=folly::none)
std::vector< IPConfig > addresses() const
Definition: HTTPServer.h:139
void updateTicketSeeds(wangle::TLSTicketKeySeeds seeds)
Definition: HTTPServer.cpp:262
#define ASSERT_NE(val1, val2)
Definition: gtest.h:1960
#define ASSERT_FALSE(condition)
Definition: gtest.h:1868
bool hexlify(const InputString &input, OutputString &output, bool append_output)
Definition: String-inl.h:596
#define ASSERT_TRUE(condition)
Definition: gtest.h:1865
TEST ( SSL  ,
TestUpdateTLSCredentials   
)

Definition at line 388 of file HTTPServerTest.cpp.

References EXPECT_EQ, EXPECT_NE, EXPECT_TRUE, wangle::SSLContextConfig::isDefault, folly::gen::move, folly::test::TemporaryFile::path(), folly::readFile(), wangle::SSLContextConfig::setCertificate(), string, proxygen::HTTPServerOptions::threads, folly::writeFile(), and x.

388  {
389  // Set up a temporary file with credentials that we will update
391  auto copyCreds = [path = credFile.path()](const std::string& certFile,
392  const std::string& keyFile) {
393  std::string certData, keyData;
394  folly::readFile(certFile.c_str(), certData);
395  folly::writeFile(certData, path.c_str(), O_WRONLY | O_CREAT | O_TRUNC);
396  folly::writeFile(std::string("\n"), path.c_str(), O_WRONLY | O_APPEND);
397  folly::readFile(keyFile.c_str(), keyData);
398  folly::writeFile(keyData, path.c_str(), O_WRONLY | O_APPEND);
399  };
400 
401  auto getCertDigest = [&](const X509* x) -> std::string {
402  unsigned int n;
403  unsigned char md[EVP_MAX_MD_SIZE];
404  const EVP_MD* dig = EVP_sha256();
405 
406  if (!X509_digest(x, dig, md, &n)) {
407  throw std::runtime_error("Cannot calculate digest");
408  }
409  return std::string((const char*)md, n);
410  };
411 
412  HTTPServer::IPConfig cfg{folly::SocketAddress("127.0.0.1", 0),
413  HTTPServer::Protocol::HTTP};
415  sslCfg.isDefault = true;
416  copyCreds(kTestDir + "certs/test_cert1.pem",
417  kTestDir + "certs/test_key1.pem");
418  sslCfg.setCertificate(credFile.path().string(), credFile.path().string(), "");
419  cfg.sslConfigs.push_back(sslCfg);
420 
421  HTTPServer::IPConfig insecureCfg{folly::SocketAddress("127.0.0.1", 0),
422  HTTPServer::Protocol::HTTP};
423 
424  HTTPServerOptions options;
425  options.threads = 4;
426 
427  auto server = std::make_unique<HTTPServer>(std::move(options));
428 
429  std::vector<HTTPServer::IPConfig> ips{cfg, insecureCfg};
430  server->bind(ips);
431 
432  ServerThread st(server.get());
433  EXPECT_TRUE(st.start());
434 
435  // First connection which should return old cert
436  folly::EventBase evb;
437  auto ctx = std::make_shared<SSLContext>();
438  std::string certDigest1, certDigest2;
439 
440  // Connect and store digest of server cert
441  auto connectAndFetchServerCert = [&]() -> std::string {
443  Cb cb(sock.get());
444  sock->connect(&cb, server->addresses().front().address, 1000);
445  evb.loop();
446  EXPECT_TRUE(cb.success);
447 
448  auto x509 = cb.getPeerCert();
449  EXPECT_NE(x509, nullptr);
450  return getCertDigest(x509);
451  };
452 
453  // Original cert
454  auto cert1 = connectAndFetchServerCert();
455  EXPECT_EQ(cert1.length(), SHA256_DIGEST_LENGTH);
456 
457  // Update cert/key
458  copyCreds(kTestDir + "certs/test_cert2.pem",
459  kTestDir + "certs/test_key2.pem");
460  server->updateTLSCredentials();
461  evb.loop();
462 
463  // Should get new cert
464  auto cert2 = connectAndFetchServerCert();
465  EXPECT_EQ(cert2.length(), SHA256_DIGEST_LENGTH);
466  EXPECT_NE(cert1, cert2);
467 }
Definition: InvokeTest.cpp:58
bool readFile(int fd, Container &out, size_t num_bytes=std::numeric_limits< size_t >::max())
Definition: FileUtil.h:125
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
const int x
std::unique_ptr< AsyncSSLSocket, Destructor > UniquePtr
const fs::path & path() const
Definition: TestUtil.cpp:85
void setCertificate(const std::string &certPath, const std::string &keyPath, const std::string &passwordPath)
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
const char * string
Definition: Conv.cpp:212
#define EXPECT_NE(val1, val2)
Definition: gtest.h:1926
bool writeFile(const Container &data, const char *filename, int flags=O_WRONLY|O_CREAT|O_TRUNC, mode_t mode=0666)
Definition: FileUtil.h:211
TEST ( GetListenSocket  ,
TestNoBootstrap   
)

Definition at line 469 of file HTTPServerTest.cpp.

References ASSERT_EQ, EXPECT_TRUE, and folly::gen::move.

469  {
470  HTTPServerOptions options;
471  auto server = std::make_unique<HTTPServer>(std::move(options));
472  auto st = std::make_unique<ServerThread>(server.get());
473  EXPECT_TRUE(st->start());
474 
475  auto socketFd = server->getListenSocket();
476  ASSERT_EQ(-1, socketFd);
477 }
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
TEST ( GetListenSocket  ,
TestBootstrapWithNoBinding   
)

Definition at line 479 of file HTTPServerTest.cpp.

References ASSERT_EQ, wangle::TLSTicketKeySeeds::currentSeeds, proxygen::HTTPServer::getListenSocket(), folly::hexlify(), setupServer(), and proxygen::HTTPServer::stopListening().

479  {
480  std::unique_ptr<HTTPServer> server;
481  std::unique_ptr<ServerThread> st;
483  seeds.currentSeeds.push_back(hexlify("hello"));
484  std::tie(server, st) = setupServer(false, seeds);
485 
486  // Stop listening on socket
487  server->stopListening();
488 
489  auto socketFd = server->getListenSocket();
490  ASSERT_EQ(-1, socketFd);
491 }
std::vector< std::string > currentSeeds
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
int getListenSocket() const
Definition: HTTPServer.cpp:224
std::pair< std::unique_ptr< HTTPServer >, std::unique_ptr< ServerThread > > setupServer(bool allowInsecureConnectionsOnSecureServer=false, folly::Optional< wangle::TLSTicketKeySeeds > seeds=folly::none)
bool hexlify(const InputString &input, OutputString &output, bool append_output)
Definition: String-inl.h:596
TEST ( GetListenSocket  ,
TestBootstrapWithBinding   
)

Definition at line 493 of file HTTPServerTest.cpp.

References ASSERT_NE, wangle::TLSTicketKeySeeds::currentSeeds, proxygen::HTTPServer::getListenSocket(), folly::hexlify(), and setupServer().

493  {
494  std::unique_ptr<HTTPServer> server;
495  std::unique_ptr<ServerThread> st;
497  seeds.currentSeeds.push_back(hexlify("hello"));
498  std::tie(server, st) = setupServer(false, seeds);
499 
500  auto socketFd = server->getListenSocket();
501  ASSERT_NE(-1, socketFd);
502 }
std::vector< std::string > currentSeeds
int getListenSocket() const
Definition: HTTPServer.cpp:224
std::pair< std::unique_ptr< HTTPServer >, std::unique_ptr< ServerThread > > setupServer(bool allowInsecureConnectionsOnSecureServer=false, folly::Optional< wangle::TLSTicketKeySeeds > seeds=folly::none)
#define ASSERT_NE(val1, val2)
Definition: gtest.h:1960
bool hexlify(const InputString &input, OutputString &output, bool append_output)
Definition: String-inl.h:596
TEST ( UseExistingSocket  ,
TestWithExistingAsyncServerSocket   
)

Definition at line 504 of file HTTPServerTest.cpp.

References proxygen::RequestHandlerChain::addThen(), ASSERT_EQ, EXPECT_TRUE, proxygen::HTTPServerOptions::handlerFactories, folly::gen::move, and proxygen::HTTPServerOptions::useExistingSocket().

504  {
506  serverSocket->bind(0);
507 
508  HTTPServer::IPConfig cfg{folly::SocketAddress("127.0.0.1", 0),
509  HTTPServer::Protocol::HTTP};
510  std::vector<HTTPServer::IPConfig> ips{cfg};
511 
512  HTTPServerOptions options;
513  options.handlerFactories =
515  // Use the existing AsyncServerSocket for binding
516  auto existingFd = serverSocket->getSocket();
517  options.useExistingSocket(std::move(serverSocket));
518 
519  auto server = std::make_unique<HTTPServer>(std::move(options));
520  auto st = std::make_unique<ServerThread>(server.get());
521  server->bind(ips);
522 
523  EXPECT_TRUE(st->start());
524 
525  auto socketFd = server->getListenSocket();
526  ASSERT_EQ(existingFd, socketFd);
527 }
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
void useExistingSocket(folly::AsyncServerSocket::UniquePtr socket)
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
RequestHandlerChain & addThen(Args &&...args)
std::vector< std::unique_ptr< RequestHandlerFactory > > handlerFactories
std::unique_ptr< AsyncServerSocket, Destructor > UniquePtr
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
TEST ( UseExistingSocket  ,
TestWithSocketFd   
)

Definition at line 529 of file HTTPServerTest.cpp.

References proxygen::RequestHandlerChain::addThen(), ASSERT_EQ, EXPECT_TRUE, proxygen::HTTPServerOptions::handlerFactories, folly::gen::move, and proxygen::HTTPServerOptions::useExistingSocket().

529  {
531  serverSocket->bind(0);
532 
533  HTTPServer::IPConfig cfg{folly::SocketAddress("127.0.0.1", 0),
534  HTTPServer::Protocol::HTTP};
535  HTTPServerOptions options;
536  options.handlerFactories =
538  // Use the socket fd from the existing AsyncServerSocket for binding
539  auto existingFd = serverSocket->getSocket();
540  options.useExistingSocket(existingFd);
541 
542  auto server = std::make_unique<HTTPServer>(std::move(options));
543  auto st = std::make_unique<ServerThread>(server.get());
544  std::vector<HTTPServer::IPConfig> ips{cfg};
545  server->bind(ips);
546 
547 
548  EXPECT_TRUE(st->start());
549 
550  auto socketFd = server->getListenSocket();
551  ASSERT_EQ(existingFd, socketFd);
552 }
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
void useExistingSocket(folly::AsyncServerSocket::UniquePtr socket)
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
RequestHandlerChain & addThen(Args &&...args)
std::vector< std::unique_ptr< RequestHandlerFactory > > handlerFactories
std::unique_ptr< AsyncServerSocket, Destructor > UniquePtr
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
TEST ( UseExistingSocket  ,
TestWithMultipleSocketFds   
)

Definition at line 554 of file HTTPServerTest.cpp.

References proxygen::RequestHandlerChain::addThen(), ASSERT_EQ, EXPECT_TRUE, proxygen::HTTPServerOptions::handlerFactories, folly::gen::move, and proxygen::HTTPServerOptions::useExistingSockets().

554  {
556  serverSocket->bind(0);
557  try {
558  serverSocket->bind(1024);
559  } catch (const std::exception& ex) {
560  // This is fine because we are trying to bind to multiple ports
561  }
562 
563  HTTPServer::IPConfig cfg{folly::SocketAddress("127.0.0.1", 0),
564  HTTPServer::Protocol::HTTP};
565  HTTPServerOptions options;
566  options.handlerFactories =
568  // Use the socket fd from the existing AsyncServerSocket for binding
569  auto existingFds = serverSocket->getSockets();
570  options.useExistingSockets(existingFds);
571 
572  auto server = std::make_unique<HTTPServer>(std::move(options));
573  auto st = std::make_unique<ServerThread>(server.get());
574  std::vector<HTTPServer::IPConfig> ips{cfg};
575  server->bind(ips);
576 
577 
578  EXPECT_TRUE(st->start());
579 
580  auto socketFd = server->getListenSocket();
581  ASSERT_EQ(existingFds[0], socketFd);
582 }
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
RequestHandlerChain & addThen(Args &&...args)
std::vector< std::unique_ptr< RequestHandlerFactory > > handlerFactories
void useExistingSockets(const std::vector< int > &socketFds)
std::unique_ptr< AsyncServerSocket, Destructor > UniquePtr
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
TEST_F ( ScopedServerTest  ,
Start   
)

Definition at line 658 of file HTTPServerTest.cpp.

References EXPECT_EQ.

658  {
659  auto server = createScopedServer();
660  auto client = connectPlainText();
661  auto resp = client->getResponse();
662  EXPECT_EQ(200, resp->getStatusCode());
663 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
TEST_F ( ScopedServerTest  ,
StartStrictSSL   
)

Definition at line 665 of file HTTPServerTest.cpp.

References EXPECT_THROW, wangle::SSLContextConfig::isDefault, and wangle::SSLContextConfig::setCertificate().

665  {
667  sslCfg.isDefault = true;
668  sslCfg.setCertificate(
669  "/path/should/not/exist",
670  "/path/should/not/exist",
671  "");
672  cfg_.sslConfigs.push_back(sslCfg);
673  EXPECT_THROW(createScopedServer(), std::exception);
674 }
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
void setCertificate(const std::string &certPath, const std::string &keyPath, const std::string &passwordPath)
TEST_F ( ScopedServerTest  ,
StartNotStrictSSL   
)

Definition at line 676 of file HTTPServerTest.cpp.

References EXPECT_EQ, wangle::SSLContextConfig::isDefault, and wangle::SSLContextConfig::setCertificate().

676  {
678  sslCfg.isDefault = true;
679  sslCfg.setCertificate(
680  "/path/should/not/exist",
681  "/path/should/not/exist",
682  "");
683  cfg_.strictSSL = false;
684  cfg_.sslConfigs.push_back(sslCfg);
685  auto server = createScopedServer();
686  auto client = connectPlainText();
687  auto resp = client->getResponse();
688  EXPECT_EQ(200, resp->getStatusCode());
689 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
void setCertificate(const std::string &certPath, const std::string &keyPath, const std::string &passwordPath)
TEST_F ( ScopedServerTest  ,
StartSSLWithInsecure   
)

Definition at line 691 of file HTTPServerTest.cpp.

References EXPECT_EQ, wangle::SSLContextConfig::isDefault, and wangle::SSLContextConfig::setCertificate().

691  {
693  sslCfg.isDefault = true;
694  sslCfg.setCertificate(
695  kTestDir + "certs/test_cert1.pem",
696  kTestDir + "certs/test_key1.pem",
697  "");
698  cfg_.sslConfigs.push_back(sslCfg);
699  cfg_.allowInsecureConnectionsOnSecureServer = true;
700  auto server = createScopedServer();
701  auto client = connectPlainText();
702  auto resp = client->getResponse();
703  EXPECT_EQ(200, resp->getStatusCode());
704 
705  client = connectSSL();
706  resp = client->getResponse();
707  EXPECT_EQ(200, resp->getStatusCode());
708 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
void setCertificate(const std::string &certPath, const std::string &keyPath, const std::string &passwordPath)
TEST_F ( ConnectionFilterTest  ,
Test   
)

Definition at line 737 of file HTTPServerTest.cpp.

References wangle::SSLContextConfig::clientCAFile, wangle::SSLContextConfig::clientVerification, EXPECT_EQ, wangle::SSLContextConfig::isDefault, and wangle::SSLContextConfig::setCertificate().

737  {
739  sslCfg.isDefault = true;
740  sslCfg.setCertificate(
741  kTestDir + "certs/test_cert1.pem", kTestDir + "certs/test_key1.pem", "");
742  sslCfg.clientCAFile = kTestDir + "certs/client_ca_cert.pem";
743  // Permissive client auth.
744  sslCfg.clientVerification = folly::SSLContext::SSLVerifyPeerEnum::VERIFY;
745  cfg_.sslConfigs.push_back(sslCfg);
746 
747  auto server = createScopedServer();
748  auto insecureClient = connectPlainText();
749  auto certlessClient = connectSSL();
750  auto certlessClient2 = connectSSL(kTestDir + "certs/ca_cert.pem");
751  auto secureClient = connectSSL(kTestDir + "certs/ca_cert.pem",
752  kTestDir + "certs/client_cert.pem",
753  kTestDir + "certs/client_key.pem");
754 
755  // The following clients fail newConnectionFilter.
756  EXPECT_EQ(nullptr, insecureClient->getResponse());
757  EXPECT_EQ(nullptr, certlessClient->getResponse());
758  EXPECT_EQ(nullptr, certlessClient2->getResponse());
759 
760  // Only secureClient passes.
761  auto response = secureClient->getResponse();
762  EXPECT_EQ(200, response->getStatusCode());
763 
764  // Check the header set by TestHandler.
765  auto headers = response->getHeaders();
766  EXPECT_EQ("testuser1", headers.getSingleOrEmpty("X-Client-CN"));
767 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
folly::SSLContext::SSLVerifyPeerEnum clientVerification
void setCertificate(const std::string &certPath, const std::string &keyPath, const std::string &passwordPath)