proxygen
HTTPSessionAcceptorTest.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  */
16 
17 using namespace proxygen;
18 using namespace testing;
19 
20 using folly::AsyncSocket;
25 
26 namespace {
27 
28 const std::string kTestDir = getContainingDirectory(__FILE__).str();
29 
30 }
31 
33  public:
35  : HTTPSessionAcceptor(accConfig) {
36  }
37 
39  HTTPMessage* /*msg*/) noexcept override {
40  return new MockHTTPHandler();
41  }
42 
43  void onCreate(const HTTPSessionBase& session) override{
44  EXPECT_EQ(expectedProto_,
46  sessionsCreated_++;
47  }
48 
49  void connectionReady(AsyncSocket::UniquePtr sock,
50  const SocketAddress& clientAddr,
51  const std::string& nextProtocolName,
52  SecureTransportType secureTransportType,
53  wangle::TransportInfo& tinfo) {
55  clientAddr,
56  nextProtocolName,
57  secureTransportType,
58  tinfo);
59  }
60 
61  void onSessionCreationError(ProxygenError /*error*/) override {
62  sessionCreationErrors_++;
63  }
64 
65  uint32_t sessionsCreated_{0};
66  uint32_t sessionCreationErrors_{0};
68 };
69 
71  public ::testing::TestWithParam<const char*> {
72  public:
73 
74  virtual void setupSSL() {
75  sslCtxConfig_.setCertificate(
76  kTestDir + "test_cert1.pem",
77  kTestDir + "test_cert1.key",
78  "");
79 
80  sslCtxConfig_.isDefault = true;
81  config_->sslContextConfigs.emplace_back(sslCtxConfig_);
82  }
83 
84  void SetUp() override {
85  config_ = std::make_unique<AcceptorConfiguration>();
86  SocketAddress address("127.0.0.1", 0);
87  config_->bindAddress = address;
88  setupSSL();
89  newAcceptor();
90  }
91 
92  void newAcceptor() {
93  acceptor_ = std::make_unique<HTTPTargetSessionAcceptor>(*config_);
94  EXPECT_CALL(mockServerSocket_, addAcceptCallback(_, _, _));
95  acceptor_->init(&mockServerSocket_, &eventBase_);
96  }
97 
98  protected:
99  std::unique_ptr<AcceptorConfiguration> config_;
101  std::unique_ptr<HTTPTargetSessionAcceptor> acceptor_;
104 };
105 
107  public HTTPSessionAcceptorTestBase {};
109  public HTTPSessionAcceptorTestBase {};
111  public HTTPSessionAcceptorTestBase {};
112 
113 // Verify HTTPSessionAcceptor creates the correct codec based on NPN
115  std::string proto(GetParam());
116  if (proto == "") {
117  acceptor_->expectedProto_ = "http/1.1";
118  } else if (proto.find("h2") != std::string::npos) {
119  acceptor_->expectedProto_ = "http/2";
120  } else {
121  acceptor_->expectedProto_ = proto;
122  }
123 
124  auto ctx = std::make_shared<folly::SSLContext>();
125  AsyncSSLSocket::UniquePtr sock(new AsyncSSLSocket(ctx, &eventBase_));
126  SocketAddress clientAddress;
127  wangle::TransportInfo tinfo;
128  acceptor_->connectionReady(
129  std::move(sock),
130  clientAddress,
131  proto,
132  SecureTransportType::TLS,
133  tinfo);
134  EXPECT_EQ(acceptor_->sessionsCreated_, 1);
135  EXPECT_EQ(acceptor_->sessionCreationErrors_, 0);
136 }
137 
138 char const* protos1[] = { "h2-14", "h2", "spdy/3.1", "spdy/3",
139  "http/1.1", "" };
140 INSTANTIATE_TEST_CASE_P(NPNPositive,
142  ::testing::ValuesIn(protos1));
143 
144 // Verify HTTPSessionAcceptor creates the correct plaintext codec
146  std::string proto(GetParam());
147  config_->plaintextProtocol = proto;
148  newAcceptor();
149  if (proto == "h2c") {
150  acceptor_->expectedProto_ = "http/2";
151  } else {
152  acceptor_->expectedProto_ = proto;
153  }
154  AsyncSocket::UniquePtr sock(new AsyncSocket(&eventBase_));
155  SocketAddress clientAddress;
156  wangle::TransportInfo tinfo;
157  acceptor_->connectionReady(
158  std::move(sock),
159  clientAddress,
160  "",
162  tinfo);
163  EXPECT_EQ(acceptor_->sessionsCreated_, 1);
164  EXPECT_EQ(acceptor_->sessionCreationErrors_, 0);
165 }
166 
167 char const* protos2[] = { "spdy/3", "h2c" };
168 INSTANTIATE_TEST_CASE_P(NPNPlaintext,
170  ::testing::ValuesIn(protos2));
171 
172 // Verify HTTPSessionAcceptor closes the socket on invalid NPN
174  std::string proto("/http/1.1");
175  MockAsyncSocket::UniquePtr sock(new MockAsyncSocket(&eventBase_));
176  SocketAddress clientAddress;
177  wangle::TransportInfo tinfo;
178  EXPECT_CALL(*sock.get(), closeNow());
179  acceptor_->connectionReady(
180  std::move(sock),
181  clientAddress,
182  proto,
184  tinfo);
185  EXPECT_EQ(acceptor_->sessionsCreated_, 0);
186  EXPECT_EQ(acceptor_->sessionCreationErrors_, 1);
187 }
188 
189 TEST_F(HTTPSessionAcceptorTestNPN, AcceptorConfigCapture) {
190  newAcceptor();
191  config_.reset();
192  acceptor_->expectedProto_ = "http/1.1";
193  AsyncSocket::UniquePtr sock(new AsyncSocket(&eventBase_));
194  SocketAddress clientAddress;
195  wangle::TransportInfo tinfo;
196  acceptor_->connectionReady(
197  std::move(sock), clientAddress, "", SecureTransportType::NONE, tinfo);
198 }
void connectionReady(folly::AsyncTransportWrapper::UniquePtr sock, const folly::SocketAddress &clientAddr, const std::string &nextProtocolName, SecureTransportType secureTransportType, TransportInfo &tinfo)
Definition: Acceptor.cpp:365
std::string str() const
Definition: Range.h:591
void onSessionCreationError(ProxygenError) override
void onCreate(const HTTPSessionBase &session) override
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::unique_ptr< AcceptorConfiguration > config_
HTTPTargetSessionAcceptor(const AcceptorConfiguration &accConfig)
void connectionReady(AsyncSocket::UniquePtr sock, const SocketAddress &clientAddr, const std::string &nextProtocolName, SecureTransportType secureTransportType, wangle::TransportInfo &tinfo)
requires E e noexcept(noexcept(s.error(std::move(e))))
FizzServerAcceptor * acceptor_
TEST_P(RFC1867CR, Test)
HTTPTransaction::Handler * newHandler(HTTPTransaction &, HTTPMessage *) noexceptoverride
const std::string & getCodecProtocolString(CodecProtocol proto)
virtual CodecProtocol getCodecProtocol() const
const char * string
Definition: Conv.cpp:212
folly::StringPiece getContainingDirectory(folly::StringPiece input)
Definition: TestUtils.h:33
wangle::SSLContextConfig sslCtxConfig_
#define EXPECT_CALL(obj, call)
const internal::AnythingMatcher _
TEST_F(HeaderTableTests, IndexTranslation)
char const * protos1[]
char const * protos2[]
***std::atomic< Config * > config_
Definition: Hazptr.h:80
INSTANTIATE_TEST_CASE_P(ValueTest, RFC1867CR,::testing::Values(string("zyx\r\nwvu", 8), string("\rzyxwvut", 8), string("zyxwvut\r", 8), string("\nzyxwvut", 8), string("zyxwvut\n", 8), string("\r\n\r\n\r\n\r\n", 8), string("\r\r\r\r\r\r\r\r", 8)))
std::unique_ptr< HTTPTargetSessionAcceptor > acceptor_
folly::test::MockAsyncServerSocket mockServerSocket_