36 using namespace folly;
47 std::vector<int64_t> flowControl = { -1, -1, -1 },
48 bool startImmediately =
true)
52 flowControl_(flowControl) {
53 EXPECT_CALL(mockController_, getGracefulShutdownTimeout())
54 .WillRepeatedly(
Return(std::chrono::milliseconds(0)));
59 HTTPSession::setDefaultReadBufferLimit(65536);
61 rawCodec_ =
codec.get();
65 if (rawCodec_->getProtocol() == CodecProtocol::HTTP_2) {
66 EXPECT_CALL(mockController_, getHeaderIndexingStrategy())
68 Return(&testH2IndexingStrat_)
73 transactionTimeouts_.get(),
80 for (
auto& param: flowControl) {
82 param = rawCodec_->getDefaultWindowSize();
87 if (rawCodec_->getProtocol() == CodecProtocol::HTTP_2) {
93 httpSession_->setFlowControl(flowControl[0], flowControl[1],
95 httpSession_->setEgressSettings({{ SettingsId::MAX_CONCURRENT_STREAMS, 80 },
96 { SettingsId::HEADER_TABLE_SIZE, 5555 },
97 { SettingsId::ENABLE_PUSH, 1 },
98 { SettingsId::ENABLE_EX_HEADERS, 1 }});
99 if (startImmediately) {
100 httpSession_->startNow();
102 clientCodec_ = makeClientCodec<typename C::Codec>(
C::version);
103 if (clientCodec_->getProtocol() == CodecProtocol::HTTP_2) {
104 clientCodec_->getEgressSettings()->setSetting(
105 SettingsId::ENABLE_EX_HEADERS, 1);
107 clientCodec_->generateConnectionPreface(requests_);
108 clientCodec_->setCallback(&callbacks_);
116 req.setPriority(priority);
117 return sendRequest(req, eom);
121 auto streamID = clientCodec_->createStream();
122 clientCodec_->generateHeader(requests_,
streamID, req, eom);
127 return sendRequest(
"/", 0,
false);
134 transport_->addReadEvent(requests_, milliseconds(0));
144 HTTPSession::setDefaultWriteBufferLimit(65536);
145 HTTP2PriorityQueue::setNodeLifetime(std::chrono::milliseconds(2));
150 httpSession_->dropConnection();
154 std::unique_ptr<testing::StrictMock<MockHTTPHandler>>
156 std::unique_ptr<testing::StrictMock<MockHTTPHandler>>
handler =
157 std::make_unique<testing::StrictMock<MockHTTPHandler>>();
161 auto rawHandler = handler.get();
164 .RetiresOnSaturation();
167 .WillOnce(testing::SaveArg<0>(&handler->txn_));
172 std::unique_ptr<testing::NiceMock<MockHTTPHandler>>
174 std::unique_ptr<testing::NiceMock<MockHTTPHandler>>
handler =
175 std::make_unique<testing::NiceMock<MockHTTPHandler>>();
178 auto rawHandler = handler.get();
181 .RetiresOnSaturation();
184 .WillOnce(testing::SaveArg<0>(&handler->txn_));
192 expectDetachSession();
200 for (
const char* p = data; *p !=
'\0'; ++p) {
206 bool eof=
false, milliseconds eofDelay=milliseconds(0),
207 milliseconds initialDelay=milliseconds(0),
208 std::function<
void()> extraEventsFn = std::function<
void()>()) {
209 flushRequests(eof, eofDelay, initialDelay, extraEventsFn);
214 bool eof=
false, milliseconds eofDelay=milliseconds(0),
215 milliseconds initialDelay=milliseconds(0),
216 std::function<
void()> extraEventsFn = std::function<
void()>()) {
217 flushRequests(eof, eofDelay, initialDelay, extraEventsFn);
219 eventBase_.loopOnce();
224 bool eof=
false, milliseconds eofDelay=milliseconds(0),
225 milliseconds initialDelay=milliseconds(0),
226 std::function<
void()> extraEventsFn = std::function<
void()>()) {
227 transport_->addReadEvent(requests_, initialDelay);
237 void testSimpleUpgrade(
244 clientCodec_->generateGoaway(this->requests_, 0, ErrorCode::NO_ERROR);
245 expectDetachSession();
246 flushRequestsAndLoop(
true);
249 void testPriorities(
uint32_t numPriorities);
251 void testChunks(
bool trailers);
255 bool expect100 =
false) {
271 breakParseOutput_ =
true;
277 .RetiresOnSaturation();
280 std::shared_ptr<HTTPMessage> msg) {
281 LOG(
INFO) <<
"100 headers";
284 .RetiresOnSaturation();
286 .RetiresOnSaturation();
288 clientCodec_->setCallback(&callbacks);
289 parseOutput(*clientCodec_);
291 TransportDirection::UPSTREAM);
294 ErrorCode errorCode = ErrorCode::NO_ERROR,
295 bool expect100 =
false,
bool expectGoaway =
false) {
296 expectResponses(1, code, errorCode, expect100, expectGoaway);
299 ErrorCode errorCode = ErrorCode::NO_ERROR,
300 bool expect100 =
false,
bool expectGoaway =
false) {
301 clientCodec_->setCallback(&callbacks_);
305 if (flowControl_[0] > 0) {
306 bool foundInitialWindow =
false;
307 for (
const auto& setting: settings) {
308 if (setting.id == SettingsId::INITIAL_WINDOW_SIZE) {
309 EXPECT_EQ(flowControl_[0], setting.value);
310 foundInitialWindow = true;
317 if (flowControl_[2] > 0) {
319 flowControl_[2] - clientCodec_->getDefaultWindowSize();
320 if (clientCodec_->supportsSessionFlowControl() && sessionDelta) {
321 EXPECT_CALL(callbacks_, onWindowUpdate(0, sessionDelta));
324 if (flowControl_[1] > 0) {
325 size_t initWindow = flowControl_[0] > 0 ?
326 flowControl_[0] : clientCodec_->getDefaultWindowSize();
327 int64_t streamDelta = flowControl_[1] - initWindow;
328 if (clientCodec_->supportsStreamFlowControl() && streamDelta) {
329 EXPECT_CALL(callbacks_, onWindowUpdate(1, streamDelta));
335 ErrorCode::NO_ERROR,
_));
341 .Times(times).RetiresOnSaturation();
344 std::shared_ptr<HTTPMessage> msg) {
350 std::shared_ptr<HTTPMessage> msg) {
353 .RetiresOnSaturation();
355 if (errorCode != ErrorCode::NO_ERROR) {
363 EXPECT_CALL(callbacks_, onMessageComplete(
_,
_)).RetiresOnSaturation();
365 parseOutput(*clientCodec_);
369 auto writeEvents =
transport_->getWriteEvents();
370 while (!breakParseOutput_ &&
371 (!writeEvents->empty() || !parseOutputStream_.empty())) {
372 if (!writeEvents->empty()) {
373 auto event = writeEvents->front();
374 auto vec =
event->getIoVec();
375 for (
size_t i = 0;
i <
event->getCount();
i++) {
376 parseOutputStream_.append(
379 writeEvents->pop_front();
382 parseOutputStream_.split(consumed);
384 if (!breakParseOutput_) {
385 EXPECT_EQ(parseOutputStream_.chainLength(), 0);
387 breakParseOutput_ =
false;
391 eventBase_.runInLoop([
this] {
transport_->resumeWrites(); });
395 eventBase_.runAfterDelay([
this] {
transport_->resumeWrites(); },
401 httpSession_->setByteEventTracker(
402 std::unique_ptr<ByteEventTracker>(byteEventTracker));
404 .WillRepeatedly(
Return(0));
406 .WillRepeatedly(
Return(0));
409 (std::shared_ptr<ByteEventTracker>
self,
411 return self->ByteEventTracker::processByteEvents(
416 return byteEventTracker;
430 bool breakParseOutput_{
false};
431 typename C::Codec* rawCodec_{
nullptr};
441 HTTP2DownstreamSessionTest()
444 void SetUp()
override {
450 clientCodec_->getEgressSettings()->setSetting(
451 SettingsId::ENABLE_EX_HEADERS, 1);
452 clientCodec_->generateSettings(requests_);
454 clientCodec_->generateHeader(requests_, cStreamId,
getGetRequest(
"/cc"),
458 void TearDown()
override {
464 class HTTP2DownstreamSessionEarlyShutdownTest :
467 HTTP2DownstreamSessionEarlyShutdownTest()
470 void SetUp()
override {
474 void TearDown()
override {
479 TEST_F(HTTP2DownstreamSessionEarlyShutdownTest, EarlyShutdown) {
486 clientCodec_->setCallback(&callbacks);
490 expectDetachSession();
491 httpSession_->notifyPendingShutdown();
492 httpSession_->startNow();
494 parseOutput(*clientCodec_);
499 EXPECT_CALL(mockController_, getRequestHandler(
_,
_)).Times(0);
500 expectDetachSession();
502 flushRequestsAndLoop(
true, milliseconds(0));
508 auto handler = addSimpleNiceHandler();
509 handler->expectHeaders([&] (std::shared_ptr<HTTPMessage> msg) {
515 EXPECT_EQ(1, msg->getHTTPVersion().first);
516 EXPECT_EQ(0, msg->getHTTPVersion().second);
518 onEOMTerminateHandlerExpectShutdown(*
handler);
521 req.setHTTPVersion(1, 0);
523 flushRequestsAndLoop();
529 auto handler = addSimpleNiceHandler();
530 handler->expectHeaders([&] (std::shared_ptr<HTTPMessage> msg) {
533 EXPECT_EQ(
"http://example.com/foo?bar", msg->getURL());
536 EXPECT_EQ(1, msg->getHTTPVersion().first);
537 EXPECT_EQ(0, msg->getHTTPVersion().second);
539 onEOMTerminateHandlerExpectShutdown(*
handler);
541 const char *req =
"GET http://example.com/foo?bar HTTP/1.0\r\n\r\n";
542 requests_.append(req, strlen(req));
543 flushRequestsAndLoop(
true, milliseconds(0));
549 auto handler = addSimpleNiceHandler();
550 handler->expectHeaders([&] (std::shared_ptr<HTTPMessage> msg) {
558 EXPECT_EQ(
"/somepath.php?param=foo", msg->getURL());
559 EXPECT_EQ(
"/somepath.php", msg->getPath());
560 EXPECT_EQ(
"param=foo", msg->getQueryString());
561 EXPECT_EQ(1, msg->getHTTPVersion().first);
562 EXPECT_EQ(1, msg->getHTTPVersion().second);
564 onEOMTerminateHandlerExpectShutdown(*
handler);
566 addSingleByteReads(
"GET /somepath.php?param=foo HTTP/1.1\r\n" 567 "Host: example.com\r\n" 568 "Connection: close\r\n" 578 auto handler = addSimpleNiceHandler();
579 handler->expectHeaders([&] (std::shared_ptr<HTTPMessage> msg) {
588 EXPECT_EQ(
"/somepath.php?param=foo", msg->getURL());
589 EXPECT_EQ(
"/somepath.php", msg->getPath());
590 EXPECT_EQ(
"param=foo", msg->getQueryString());
591 EXPECT_EQ(1, msg->getHTTPVersion().first);
592 EXPECT_EQ(1, msg->getHTTPVersion().second);
595 .WillOnce(ExpectString(
"1"))
596 .WillOnce(ExpectString(
"2"))
597 .WillOnce(ExpectString(
"3"))
598 .WillOnce(ExpectString(
"4"))
599 .WillOnce(ExpectString(
"5"));
600 onEOMTerminateHandlerExpectShutdown(*
handler);
602 addSingleByteReads(
"POST /somepath.php?param=foo HTTP/1.1\r\n" 603 "Host: example.com\r\n" 604 "MyHeader: FooBar\r\n" 605 "Content-Length: 5\r\n" 616 auto handler = addSimpleNiceHandler();
617 handler->expectHeaders([&] (std::shared_ptr<HTTPMessage> msg) {
622 .WillOnce(ExpectString(
"12345"))
623 .WillOnce(ExpectString(
"abcde"));
624 onEOMTerminateHandlerExpectShutdown(*
handler);
626 transport_->addReadEvent(
"POST / HTTP/1.1\r\n" 627 "Host: example.com\r\n" 628 "Content-Length: 10\r\n" 630 "12345", milliseconds(0));
631 transport_->addReadEvent(
"abcde", milliseconds(5));
640 auto handler = addSimpleNiceHandler();
641 handler->expectHeaders([&] (std::shared_ptr<HTTPMessage> msg) {
649 EXPECT_EQ(
"http://example.com/cgi-bin/foo.aspx?abc&def",
651 EXPECT_EQ(
"/cgi-bin/foo.aspx", msg->getPath());
652 EXPECT_EQ(
"abc&def", msg->getQueryString());
653 EXPECT_EQ(1, msg->getHTTPVersion().first);
654 EXPECT_EQ(1, msg->getHTTPVersion().second);
658 .WillOnce(ExpectString(
"bar"));
662 .WillOnce(ExpectString(
"0123456789abcdef\nfedcba9876543210\n"));
666 .WillOnce(ExpectString(
"foo"));
668 onEOMTerminateHandlerExpectShutdown(*
handler);
670 transport_->addReadEvent(
"POST http://example.com/cgi-bin/foo.aspx?abc&def " 672 "Host: example.com\r\n" 673 "Content-Type: text/pla", milliseconds(0));
674 transport_->addReadEvent(
"in; charset=utf-8\r\n" 675 "Transfer-encoding: chunked\r\n" 676 "\r", milliseconds(2));
684 "3\r", milliseconds(3));
687 "0\r\n\r\n", milliseconds(1));
695 auto handler1 = addSimpleNiceHandler();
696 handler1->expectHeaders();
698 .WillOnce(ExpectString(
"foo"))
699 .WillOnce(ExpectString(
"bar9876"));
700 handler1->expectEOM([&] { handler1->sendReply(); });
701 handler1->expectDetachTransaction();
703 auto handler2 = addSimpleNiceHandler();
704 handler2->expectHeaders();
707 .WillOnce(ExpectString(
"some "))
708 .WillOnce(ExpectString(
"data\n"));
710 onEOMTerminateHandlerExpectShutdown(*handler2);
712 transport_->addReadEvent(
"POST / HTTP/1.1\r\n" 713 "Host: example.com\r\n" 714 "Content-Length: 10\r\n" 716 "foo", milliseconds(0));
718 "POST /foo HTTP/1.1\r\n" 719 "Host: exa", milliseconds(2));
721 "Connection: close\r\n" 722 "Trans", milliseconds(0));
723 transport_->addReadEvent(
"fer-encoding: chunked\r\n" 724 "\r\n", milliseconds(2));
725 transport_->addReadEvent(
"a\r\nsome ", milliseconds(0));
726 transport_->addReadEvent(
"data\n\r\n0\r\n\r\n", milliseconds(2));
735 auto handler = addSimpleStrictHandler();
738 handler->sendHeaders(200, 100);
745 .WillOnce(ExpectString(
"12345"))
746 .WillOnce(ExpectString(
"abcde"));
747 onEOMTerminateHandlerExpectShutdown(*
handler);
749 transport_->addReadEvent(
"CONNECT test HTTP/1.1\r\n" 751 "12345", milliseconds(0));
752 transport_->addReadEvent(
"abcde", milliseconds(5));
761 auto handler = addSimpleStrictHandler();
767 onEOMTerminateHandlerExpectShutdown(*
handler);
769 transport_->addReadEvent(
"CONNECT test HTTP/1.1\r\n" 771 "12345", milliseconds(0));
772 transport_->addReadEvent(
"abcde", milliseconds(5));
781 auto handler = addSimpleStrictHandler();
784 handler->sendHeaders(101, 100);
793 onEOMTerminateHandlerExpectShutdown(*
handler);
799 flushRequestsAndLoop(
true, milliseconds(0));
815 .WillRepeatedly(SaveArg<0>(&codecCallback));
820 bool transportGood =
true;
823 .WillRepeatedly(ReturnPointee(&transportGood));
825 .WillRepeatedly(
Assign(&transportGood,
false));
836 transactionTimeouts.get(),
843 HTTPException ex(HTTPException::Direction::INGRESS_AND_EGRESS,
"foo");
849 session->dropConnection();
865 transactionTimeouts.get(),
872 std::unique_ptr<ByteEventTracker>(byteEventTracker));
885 session->dropConnection();
892 auto byteEventTracker = setMockByteEventTracker();
895 auto handler1 = addSimpleStrictHandler();
896 handler1->expectHeaders();
897 handler1->expectEOM([&handler1] () {
898 handler1->sendChunkedReplyWithBody(200, 100, 100,
false);
907 flushRequestsAndLoop();
912 auto handler2 = addSimpleStrictHandler();
913 handler2->expectHeaders();
914 handler2->expectEOM([&handler2] () {
915 handler2->sendChunkedReplyWithBody(200, 100, 100,
false);
919 handler2->expectDetachTransaction();
922 flushRequestsAndLoop();
927 handler1->expectDetachTransaction();
928 handler1->txn_->decrementPendingByteEvents();
939 auto handler1 = addSimpleNiceHandler();
940 handler1->expectHeaders();
941 handler1->expectEOM([&handler1] () {
943 handler1->sendHeaders(200, 105);
944 handler1->sendBody(100);
945 handler1->txn_->sendEOM();
948 flushRequestsAndLoop();
950 auto handler2 = addSimpleNiceHandler();
951 handler2->expectHeaders();
952 handler2->expectEOM([&handler2] () {
954 handler2->sendHeaders(200, 95);
955 handler2->sendBody(100);
956 handler2->txn_->sendEOM();
959 flushRequestsAndLoop();
966 auto byteEventTracker = setMockByteEventTracker();
969 auto handler1 = addSimpleStrictHandler();
970 handler1->expectHeaders();
971 handler1->expectEOM([&handler1] () {
972 handler1->sendChunkedReplyWithBody(200, 100, 100,
false);
980 auto handler2 = addSimpleStrictHandler();
981 handler2->expectHeaders();
982 handler2->expectEOM([&handler2] () {
983 handler2->sendChunkedReplyWithBody(200, 100, 100,
false);
986 handler2->expectDetachTransaction();
990 auto handler3 = addSimpleStrictHandler();
991 handler3->expectHeaders();
992 handler3->expectEOM([&handler3] () {
993 handler3->sendChunkedReplyWithBody(200, 100, 100,
false);
996 handler3->expectDetachTransaction();
997 flushRequestsAndLoop();
999 handler1->expectDetachTransaction();
1000 handler1->txn_->decrementPendingByteEvents();
1012 TEST_F(HTTP2DownstreamSessionTest, ExheaderFromServer) {
1014 SetupControlStream(cStreamId);
1022 auto cHandler = addSimpleStrictHandler();
1025 cHandler->expectHeaders([&] {
1026 cHandler->txn_->pauseIngress();
1029 cHandler->txn_->sendBody(
makeBuf(100));
1031 auto* pubTxn = cHandler->txn_->newExTransaction(&pubHandler);
1033 pubTxn->sendHeaders(pub);
1034 pubTxn->sendBody(
makeBuf(200));
1040 EXPECT_CALL(callbacks_, onHeadersComplete(cStreamId,
_));
1052 transport_->addReadEvent(requests_, milliseconds(0));
1055 eventBase_.runAfterDelay([&] {
1056 parseOutput(*clientCodec_);
1058 clientCodec_->generateExHeader(requests_, 2,
getResponse(200, 0),
1061 transport_->addReadEvent(requests_, milliseconds(0));
1063 parseOutput(*clientCodec_);
1064 cHandler->txn_->resumeIngress();
1065 cHandler->txn_->sendEOM();
1069 HTTPSession::DestructorGuard
g(httpSession_);
1070 expectDetachSession();
1082 TEST_F(HTTP2DownstreamSessionTest, ExheaderFromClient) {
1084 SetupControlStream(cStreamId);
1087 auto exStreamId = cStreamId + 2;
1088 clientCodec_->generateExHeader(requests_, exStreamId,
getGetRequest(
"/pub"),
1092 auto cHandler = addSimpleStrictHandler();
1093 cHandler->expectHeaders([&] {
1103 pubHandler.txn_ = exTxn;
1108 pubHandler.expectHeaders([&] {
1110 pubHandler.txn_->sendHeadersWithEOM(
getResponse(200, 0));
1114 cHandler->expectDetachTransaction();
1117 EXPECT_CALL(callbacks_, onHeadersComplete(cStreamId,
_));
1119 EXPECT_CALL(callbacks_, onHeadersComplete(exStreamId,
_));
1120 EXPECT_CALL(callbacks_, onMessageComplete(exStreamId,
_));
1121 EXPECT_CALL(callbacks_, onMessageComplete(cStreamId,
_));
1123 transport_->addReadEvent(requests_, milliseconds(0));
1128 HTTPSession::DestructorGuard
g(httpSession_);
1129 expectDetachSession();
1130 cHandler->txn_->sendEOM();
1132 parseOutput(*clientCodec_);
1141 TEST_F(HTTP2DownstreamSessionTest, UnidirectionalExTransaction) {
1143 SetupControlStream(cStreamId);
1145 auto cHandler = addSimpleStrictHandler();
1148 cHandler->expectHeaders([&] {
1149 auto* uniTxn = cHandler->txn_->newExTransaction(&uniHandler,
true);
1155 cHandler->txn_->sendHeadersWithEOM(
getResponse(200, 0));
1163 transport_->addReadEvent(requests_, milliseconds(0));
1165 eventBase_.runAfterDelay([&] {
1169 HTTPSession::DestructorGuard
g(httpSession_);
1170 expectDetachSession();
1174 TEST_F(HTTP2DownstreamSessionTest, PauseResumeControlStream) {
1176 SetupControlStream(cStreamId);
1179 clientCodec_->generateExHeader(requests_, cStreamId + 2,
getGetRequest(),
1183 auto cHandler = addSimpleStrictHandler();
1184 cHandler->expectHeaders([&] {
1185 cHandler->txn_->pauseIngress();
1195 pubHandler.txn_ = exTxn;
1200 pubHandler.expectHeaders([&] {
1202 pubHandler.txn_->sendHeadersWithEOM(
getResponse(200, 0));
1206 cHandler->expectDetachTransaction();
1209 EXPECT_CALL(callbacks_, onHeadersComplete(cStreamId,
_));
1210 EXPECT_CALL(callbacks_, onHeadersComplete(cStreamId + 2,
_));
1211 EXPECT_CALL(callbacks_, onMessageComplete(cStreamId + 2,
_));
1212 EXPECT_CALL(callbacks_, onMessageComplete(cStreamId,
_));
1214 HTTPSession::DestructorGuard
g(httpSession_);
1215 transport_->addReadEvent(requests_, milliseconds(0));
1220 cHandler->txn_->resumeIngress();
1221 cHandler->txn_->sendEOM();
1224 expectDetachSession();
1225 parseOutput(*clientCodec_);
1228 TEST_F(HTTP2DownstreamSessionTest, InvalidControlStream) {
1230 SetupControlStream(cStreamId);
1233 clientCodec_->generateExHeader(requests_, cStreamId + 2,
getGetRequest(),
1237 auto cHandler = addSimpleStrictHandler();
1239 cHandler->expectHeaders([&] {
1245 cHandler->expectDetachTransaction();
1248 EXPECT_CALL(callbacks_, onHeadersComplete(cStreamId,
_));
1251 HTTPSession::DestructorGuard
g(httpSession_);
1252 transport_->addReadEvent(requests_, milliseconds(0));
1257 cHandler->txn_->sendEOM();
1260 expectDetachSession();
1261 parseOutput(*clientCodec_);
1264 TEST_F(HTTP2DownstreamSessionTest, SetByteEventTracker) {
1271 auto handler1 = addSimpleStrictHandler();
1272 handler1->expectHeaders();
1273 handler1->expectEOM([&handler1] () {
1274 handler1->sendReplyWithBody(200, 100);
1276 auto handler2 = addSimpleStrictHandler();
1277 handler2->expectHeaders();
1278 handler2->expectEOM([&handler2] () {
1279 handler2->sendReplyWithBody(200, 100);
1285 eventBase_.runInLoop([
this] {
1290 EXPECT_CALL(*handler1, onGoaway(ErrorCode::NO_ERROR));
1291 EXPECT_CALL(*handler2, onGoaway(ErrorCode::NO_ERROR));
1294 handler1->expectDetachTransaction([
this] {
1295 auto tracker = std::make_unique<ByteEventTracker>(httpSession_);
1296 httpSession_->setByteEventTracker(
std::move(tracker));
1300 handler2->expectDetachTransaction();
1305 auto byteEventTracker = setMockByteEventTracker();
1308 auto handler1 = addSimpleStrictHandler();
1309 size_t bytesToSend = 200;
1310 size_t expectedTrackedByteOffset = bytesToSend + 99;
1311 handler1->expectHeaders();
1312 handler1->expectEOM([&handler1, &bytesToSend] () {
1313 handler1->sendHeaders(200, 200);
1314 handler1->sendBodyWithLastByteTracking(bytesToSend);
1315 handler1->txn_->sendEOM();
1319 addTrackedByteEvent(
_, expectedTrackedByteOffset))
1325 flushRequestsAndLoop();
1326 handler1->expectDetachTransaction();
1327 handler1->txn_->decrementPendingByteEvents();
1331 TEST_F(HTTP2DownstreamSessionTest, Trailers) {
1334 auto handler = addSimpleStrictHandler();
1338 200, 100,
true ,
true ,
true );
1340 handler->expectDetachTransaction();
1342 HTTPSession::DestructorGuard
g(httpSession_);
1344 flushRequestsAndLoop(
true, milliseconds(0));
1346 EXPECT_CALL(callbacks_, onMessageBegin(1,
_)).Times(1);
1347 EXPECT_CALL(callbacks_, onHeadersComplete(1,
_)).Times(1);
1352 parseOutput(*clientCodec_);
1353 expectDetachSession();
1368 auto handler = addSimpleStrictHandler();
1371 handler->sendChunkedReplyWithBody(200, 100, 17, trailers);
1373 handler->expectDetachTransaction();
1375 HTTPSession::DestructorGuard
g(httpSession_);
1377 flushRequestsAndLoop(
true, milliseconds(0));
1383 for (
int i = 0;
i < 6;
i++) {
1393 parseOutput(*clientCodec_);
1394 expectDetachSession();
1400 auto handler1 = addSimpleStrictHandler();
1401 handler1->expectHeaders([
this, &handler1] {
1402 handler1->sendHeaders(200, 100);
1403 httpSession_->notifyPendingShutdown();
1405 handler1->expectEOM([&handler1] {
1406 handler1->sendBody(100);
1407 handler1->txn_->sendEOM();
1409 handler1->expectDetachTransaction();
1411 auto handler2 = addSimpleStrictHandler();
1412 handler2->expectHeaders([&handler2] {
1413 handler2->sendHeaders(200, 100);
1415 handler2->expectEOM([&handler2] {
1416 handler2->sendBody(100);
1417 handler2->txn_->sendEOM();
1419 handler2->expectDetachTransaction();
1421 expectDetachSession();
1425 flushRequestsAndLoop();
1435 auto handler = addSimpleStrictHandler();
1437 httpSession_->notifyPendingShutdown();
1438 eventBase_.tryRunAfterDelay([
this] {
1440 httpSession_->timeoutExpired();
1442 eventBase_.tryRunAfterDelay([&
handler] {
1443 handler->sendReplyWithBody(200, 100);
1447 handler->expectDetachTransaction();
1449 expectDetachSession();
1452 flushRequestsAndLoop();
1460 .WillOnce(
Return(&handler));
1465 handler.txn_->sendAbort();
1467 handler.expectDetachTransaction();
1468 expectDetachSession();
1470 addSingleByteReads(
"GET /somepath.php?param=foo HTTP/1.1\r\n" 1471 "Host: example.com\r\n" 1472 "Connection: close\r\n" 1481 auto s = sendRequest();
1482 clientCodec_->generateRstStream(rst,
s, ErrorCode::CANCEL);
1486 auto handler1 = addSimpleNiceHandler();
1487 handler1->expectHeaders();
1488 handler1->expectEOM([&handler1,
this] {
1490 handler1->sendHeaders(200, 65536 * 2);
1491 handler1->sendBody(65536 * 2);
1493 handler1->expectEgressPaused();
1494 auto handler2 = addSimpleNiceHandler();
1495 handler2->expectEgressPaused();
1496 handler2->expectHeaders();
1497 handler2->expectEOM([&] {
1498 eventBase_.runInLoop([&] {
1499 transport_->addReadEvent(rst, milliseconds(0)); });
1503 resumeWritesInLoop();
1505 handler1->expectDetachTransaction();
1506 handler2->expectEgressResumed([&] {
1507 handler2->sendReplyWithBody(200, 32768);
1509 handler2->expectDetachTransaction([
this] {
1510 eventBase_.runInLoop([&] {
transport_->addReadEOF(milliseconds(0)); });
1512 expectDetachSession();
1514 flushRequestsAndLoop();
1522 auto handler1 = addSimpleNiceHandler();
1523 handler1->expectHeaders();
1524 handler1->expectEOM([&handler1,
this] {
1526 handler1->sendHeaders(200, 1000);
1531 folly::to<std::string>(
"WriteTimeout on transaction id: ",
1532 handler1->txn_->getID()),
1534 handler1->txn_->sendAbort();
1536 handler1->expectDetachTransaction();
1537 expectDetachSession();
1539 flushRequestsAndLoop();
1553 auto handler1 = addSimpleNiceHandler();
1554 handler1->expectHeaders([&] {
1556 handler1->txn_->setEgressRateLimit(rateLimit_kbps * 1024);
1559 handler1->expectEOM([&handler1] {
1562 handler1->sendHeaders(200, rspLengthBytes);
1563 handler1->sendBody(rspLengthBytes);
1564 handler1->txn_->sendEOM();
1566 handler1->expectDetachTransaction();
1570 HTTPSession::DestructorGuard
g(httpSession_);
1571 flushRequestsAndLoop();
1574 transport_->getWriteEvents()->front()->getTime();
1576 transport_->getWriteEvents()->back()->getTime();
1589 clientCodec_->getEgressSettings()->setSetting(SettingsId::INITIAL_WINDOW_SIZE,
1591 clientCodec_->generateSettings(requests_);
1595 auto handler1 = addSimpleNiceHandler();
1596 handler1->expectHeaders([&] {
1598 handler1->txn_->setEgressRateLimit(rateLimit_kbps * 1024);
1601 handler1->expectEOM([&handler1] {
1604 handler1->sendHeaders(200, rspLengthBytes);
1605 handler1->sendBody(rspLengthBytes);
1606 handler1->txn_->sendEOM();
1608 handler1->expectDetachTransaction();
1612 HTTPSession::DestructorGuard
g(httpSession_);
1613 flushRequestsAndLoop(
true, milliseconds(50));
1616 transport_->getWriteEvents()->front()->getTime();
1618 transport_->getWriteEvents()->back()->getTime();
1622 expectDetachSession();
1635 clientCodec_->getEgressSettings()->setSetting(SettingsId::INITIAL_WINDOW_SIZE,
1637 clientCodec_->generateSettings(requests_);
1639 clientCodec_->generateRstStream(rst,
streamID, ErrorCode::CANCEL);
1642 auto handler1 = addSimpleNiceHandler();
1643 handler1->expectHeaders([&] {
1645 handler1->txn_->setEgressRateLimit(rateLimit_kbps * 1024);
1647 handler1->expectEOM([&handler1] {
1649 handler1->sendHeaders(200, rspLengthBytes);
1650 handler1->sendBody(rspLengthBytes);
1651 handler1->txn_->sendEOM();
1653 handler1->expectError();
1654 handler1->expectDetachTransaction();
1655 expectDetachSession();
1657 flushRequestsAndLoop(
true, milliseconds(50), milliseconds(0), [&] {
1658 transport_->addReadEvent(rst, milliseconds(10));
1671 auto handler1 = addSimpleNiceHandler();
1672 handler1->expectHeaders();
1673 handler1->expectEOM([&handler1,
this] {
1674 handler1->sendHeaders(200, 100);
1675 eventBase_.tryRunAfterDelay([&handler1,
this] {
1677 handler1->sendBody(100);
1678 handler1->txn_->sendEOM();
1683 ASSERT_EQ(folly::to<std::string>(
"WriteTimeout on transaction id: ",
1684 handler1->txn_->getID()),
1687 handler1->expectDetachTransaction();
1689 expectDetachSession();
1691 flushRequestsAndLoop();
1696 const char* buf =
"GET / HTTP/1.1\r\nHost: localhost\r\n\r\n" 1697 "GET / HTTP/1.1\r\nHost: localhost\r\n\r\n";
1698 requests_.append(buf, strlen(buf));
1701 auto handler1 = addSimpleNiceHandler();
1702 handler1->expectHeaders();
1703 handler1->expectEOM([&handler1,
this] {
1704 handler1->sendHeaders(200, 100);
1705 eventBase_.tryRunAfterDelay([&handler1,
this] {
1707 handler1->sendBody(100);
1708 handler1->txn_->sendEOM();
1711 auto handler2 = addSimpleNiceHandler();
1712 handler2->expectHeaders();
1713 handler2->expectEOM();
1716 ASSERT_EQ(folly::to<std::string>(
"WriteTimeout on transaction id: ",
1717 handler1->txn_->getID()),
1719 handler1->txn_->sendAbort();
1723 ASSERT_EQ(folly::to<std::string>(
"WriteTimeout on transaction id: ",
1724 handler2->txn_->getID()),
1726 handler2->txn_->sendAbort();
1728 handler2->expectDetachTransaction();
1729 handler1->expectDetachTransaction();
1730 expectDetachSession();
1732 flushRequestsAndLoop();
1742 auto handler1 = addSimpleNiceHandler();
1743 handler1->expectHeaders();
1744 handler1->expectEOM([&handler1] {
1745 handler1->sendReplyWithBody(200, 32768);
1747 handler1->expectDetachTransaction();
1749 expectDetachSession();
1753 HTTPSession::DestructorGuard
g(httpSession_);
1754 flushRequestsAndLoop();
1762 requests_.append(data.data(), data.length());
1764 expectDetachSession();
1766 flushRequestsAndLoop(
true, milliseconds(0));
1774 auto handler = addSimpleNiceHandler();
1776 handler->sendHeaders(200, 100,
false);
1777 size_t len = 16 * 1024 * 1024;
1778 handler->txn_->sendChunkHeader(len);
1781 handler->txn_->sendChunkTerminator();
1784 handler->expectDetachTransaction();
1786 expectDetachSession();
1790 HTTPSession::DestructorGuard
g(httpSession_);
1791 flushRequestsAndLoop();
1801 auto handler = addSimpleStrictHandler();
1804 handler->sendHeaders(101, 0,
true, {{
"Upgrade",
"blarf"}});
1810 handler->expectDetachTransaction();
1813 expectDetachSession();
1814 flushRequestsAndLoop(
true);
1820 auto handler = addSimpleStrictHandler();
1823 handler->sendReplyWithBody(200, 100);
1826 handler->expectDetachTransaction();
1830 expectDetachSession();
1831 flushRequestsAndLoop(
true);
1837 auto handler1 = addSimpleStrictHandler();
1839 handler1->expectHeaders([&handler1] (std::shared_ptr<HTTPMessage> msg) {
1842 handler1->sendReplyWithBody(200, 100);
1844 handler1->expectEOM();
1845 handler1->expectDetachTransaction();
1847 auto handler2 = addSimpleStrictHandler();
1848 handler2->expectHeaders([&handler2] {
1849 handler2->sendReplyWithBody(200, 100);
1851 handler2->expectEOM();
1852 handler2->expectDetachTransaction();
1855 transport_->addReadEvent(
"GET / HTTP/1.1\r\n" 1857 expectDetachSession();
1858 flushRequestsAndLoop(
true);
1868 this->rawCodec_->setAllowedUpgradeProtocols({expectedUpgradeHeader});
1870 auto handler = addSimpleStrictHandler();
1874 EXPECT_CALL(mockController_, onSessionCodecChange(httpSession_));
1876 [&
handler, expectedProtocol, expectedUpgradeHeader, &testH2IndexingStrat] {
1879 expectedUpgradeHeader);
1880 if (expectedProtocol == CodecProtocol::HTTP_2) {
1882 &
handler->txn_->getTransport().getCodec());
1886 handler->sendReplyWithBody(200, 100);
1888 handler->expectDetachTransaction();
1890 if (expectedProtocol == CodecProtocol::HTTP_2) {
1891 EXPECT_CALL(mockController_, getHeaderIndexingStrategy())
1893 Return(&testH2IndexingStrat)
1899 HTTP2Codec::requestUpgrade(req);
1902 flushRequestsAndLoop();
1904 expect101(expectedProtocol, expectedUpgradeHeader);
1912 testSimpleUpgrade(
"spdy/3", CodecProtocol::SPDY_3,
"spdy/3");
1917 testSimpleUpgrade(
"spdy/3.1", CodecProtocol::SPDY_3_1,
"spdy/3.1");
1922 testSimpleUpgrade(
"h2c", CodecProtocol::HTTP_2,
"h2c");
1934 testSimpleUpgrade(
"h2c", CodecProtocol::HTTP_2,
"h2c");
1941 testSimpleUpgrade(
"blarf, spdy/3.1, spdy/3",
1942 CodecProtocol::SPDY_3_1,
"spdy/3.1");
1947 testSimpleUpgrade(
" \tspdy/3.1\t , spdy/3",
1948 CodecProtocol::SPDY_3_1,
"spdy/3.1");
1953 testSimpleUpgrade(
",,,, ,,\t~^%$(*&@(@$^^*(,spdy/3",
1954 CodecProtocol::SPDY_3,
"spdy/3");
1959 this->rawCodec_->setAllowedUpgradeProtocols({
"spdy/3"});
1960 auto handler1 = addSimpleStrictHandler();
1961 handler1->expectHeaders();
1962 handler1->expectEOM([&handler1] {
1963 handler1->sendReplyWithBody(200, 100);
1965 handler1->expectDetachTransaction();
1967 flushRequestsAndLoop();
1970 auto handler2 = addSimpleStrictHandler();
1971 handler2->expectHeaders();
1972 handler2->expectEOM([&handler2] {
1973 handler2->sendReplyWithBody(200, 100);
1975 handler2->expectDetachTransaction();
1978 flushRequestsAndLoop();
1985 this->rawCodec_->setAllowedUpgradeProtocols({
"spdy/3"});
1986 auto handler = addSimpleStrictHandler();
1989 EXPECT_CALL(mockController_, onSessionCodecChange(httpSession_));
1991 handler->sendReplyWithBody(200, 100);
1993 handler->expectDetachTransaction();
1996 auto streamID = sendRequest(req,
false);
1998 HTTPCodec::NoPadding,
true);
2000 flushRequestsAndLoop();
2001 expect101(CodecProtocol::SPDY_3,
"spdy/3");
2008 this->rawCodec_->setAllowedUpgradeProtocols({
"spdy/3"});
2009 auto handler = addSimpleStrictHandler();
2011 handler->sendReplyWithBody(200, 100);
2015 handler->expectDetachTransaction();
2018 auto streamID = sendRequest(req,
false);
2020 HTTPCodec::NoPadding,
true);
2021 flushRequestsAndLoop();
2027 this->rawCodec_->setAllowedUpgradeProtocols({
"spdy/3"});
2028 auto handler = addSimpleStrictHandler();
2030 handler->sendHeaders(200, 100);
2037 handler->expectDetachTransaction();
2040 auto streamID = sendRequest(req,
false);
2042 HTTPCodec::NoPadding,
true);
2043 flushRequestsAndLoop();
2051 this->rawCodec_->setAllowedUpgradeProtocols({
"spdy/3"});
2052 auto handler = addSimpleStrictHandler();
2054 EXPECT_CALL(mockController_, onSessionCodecChange(httpSession_));
2056 handler->sendReplyWithBody(200, 100);
2058 handler->expectDetachTransaction();
2062 transport_->addReadEvent(
"GET / HTTP/1.1\r\n" 2063 "Upgrade: spdy/3\r\n" 2065 flushRequestsAndLoop();
2066 expect101(CodecProtocol::SPDY_3,
"spdy/3");
2067 expectResponse(200, ErrorCode::_SPDY_INVALID_STREAM);
2077 this->rawCodec_->setAllowedUpgradeProtocols({
"spdy/3"});
2078 auto handler = addSimpleStrictHandler();
2083 EXPECT_CALL(mockController_, onSessionCodecChange(httpSession_));
2085 handler->sendReplyWithBody(200, 100);
2087 handler->expectDetachTransaction();
2091 auto streamID = sendRequest(req,
false);
2093 HTTPCodec::NoPadding,
true);
2094 flushRequestsAndLoop();
2095 expect101(CodecProtocol::SPDY_3,
"spdy/3",
true );
2101 this->rawCodec_->setAllowedUpgradeProtocols({
"spdy/3"});
2102 auto handler = addSimpleStrictHandler();
2105 EXPECT_CALL(mockController_, onSessionCodecChange(httpSession_));
2108 handler->sendReplyWithBody(200, 100);
2110 handler->expectDetachTransaction();
2114 auto streamID = sendRequest(req,
false);
2116 HTTPCodec::NoPadding,
true);
2117 flushRequestsAndLoop();
2118 expect101(CodecProtocol::SPDY_3,
"spdy/3");
2119 expectResponse(200, ErrorCode::NO_ERROR,
true );
2134 this->rawCodec_->setAllowedUpgradeProtocols({
"h2c"});
2135 auto handler = addSimpleStrictHandler();
2138 EXPECT_CALL(mockController_, onSessionCodecChange(httpSession_));
2141 handler->expectDetachTransaction();
2143 EXPECT_CALL(mockController_, getHeaderIndexingStrategy())
2145 Return(&testH2IndexingStrat_)
2149 HTTP2Codec::requestUpgrade(req);
2150 auto streamID = sendRequest(req,
false);
2152 HTTPCodec::NoPadding,
true);
2155 flushRequestsAndLoop();
2156 expect101(CodecProtocol::HTTP_2,
"h2c");
2157 clientCodec_->generateConnectionPreface(requests_);
2158 clientCodec_->generateGoaway(requests_, 0, ErrorCode::NO_ERROR);
2159 flushRequestsAndLoop();
2160 eventBase_.runInLoop([&
handler] {
2161 handler->sendReplyWithBody(200, 100);
2163 HTTPSession::DestructorGuard
g(httpSession_);
2165 expectResponse(200, ErrorCode::NO_ERROR,
false,
true);
2166 expectDetachSession();
2172 uint32_t maxPriority = numPriorities - 1;
2173 std::vector<std::unique_ptr<testing::NiceMock<MockHTTPHandler>>> handlers;
2174 for (
int pri = numPriorities - 1; pri >= 0; pri--) {
2176 sendRequest(
"/", pri * (8 / numPriorities));
2178 auto handler = addSimpleNiceHandler();
2179 auto rawHandler =
handler.get();
2181 rawHandler->expectHeaders();
2182 rawHandler->expectEOM([rawHandler] {
2183 rawHandler->sendReplyWithBody(200, 1000);
2185 rawHandler->expectDetachTransaction([] { });
2189 auto buf = requests_.move();
2193 flushRequestsAndLoop();
2195 std::list<HTTPCodec::StreamID> streams;
2197 .Times(iterations * numPriorities);
2199 .Times(iterations * numPriorities);
2202 .Times(iterations * numPriorities)
2204 streams.push_back(stream);
2207 parseOutput(*clientCodec_);
2210 EXPECT_EQ(streams.size(), iterations * numPriorities);
2211 auto txn = streams.begin();
2212 for (
int band = maxPriority; band >= 0; band--) {
2213 auto upperID = iterations * 2 * (band + 1);
2214 auto lowerID = iterations * 2 * band;
2229 httpSession_->setWriteBufferLimit(512);
2232 auto handler1 = addSimpleStrictHandler();
2233 handler1->expectHeaders([
this] {
transport_->pauseWrites(); });
2234 handler1->expectEOM([&] {
2235 handler1->sendHeaders(200, 1000);
2236 handler1->sendBody(1000);
2238 handler1->expectEgressPaused();
2239 auto handler2 = addSimpleStrictHandler();
2241 handler2->expectEgressPaused();
2242 handler2->expectHeaders();
2243 handler2->expectEOM([
this] {
2247 resumeWritesAfterDelay(milliseconds(400));
2249 handler1->expectEgressResumed([&handler1] { handler1->txn_->sendEOM(); });
2250 handler2->expectEgressResumed([&handler2,
this] {
2253 eventBase_.tryRunAfterDelay([&handler2] {
2254 handler2->sendReplyWithBody(200, 400); }, 200
2257 handler1->expectDetachTransaction();
2258 handler2->expectDetachTransaction();
2260 flushRequestsAndLoop(
false, milliseconds(0), milliseconds(10));
2268 clientCodec_->getEgressSettings()->setSetting(SettingsId::INITIAL_WINDOW_SIZE,
2270 clientCodec_->generateSettings(requests_);
2274 auto handler = addSimpleStrictHandler();
2277 handler->sendReplyWithBody(200, 1000);
2279 handler->expectEgressPaused();
2283 folly::to<std::string>(
"ingress timeout, streamID=",
streamID),
2287 handler->expectDetachTransaction();
2289 flushRequestsAndLoop();
2299 this->sendRequest();
2300 badCodec->generatePushPromise(this->requests_, 2 ,
getGetRequest(),
2303 this->expectDetachSession();
2306 auto handler1 = this->addSimpleNiceHandler();
2307 handler1->expectHeaders();
2308 handler1->expectEOM();
2315 handler1->expectDetachTransaction();
2317 this->flushRequestsAndLoop();
2321 this->clientCodec_->generateWindowUpdate(this->requests_, 0, 65536);
2322 this->sendRequest();
2323 this->sendRequest();
2326 auto handler1 = this->addSimpleNiceHandler();
2327 handler1->expectHeaders();
2328 handler1->expectEOM();
2329 auto handler2 = this->addSimpleNiceHandler();
2330 handler2->expectHeaders();
2331 handler2->expectEOM([&] {
2332 handler1->sendReplyWithBody(200, 33000);
2333 handler2->sendReplyWithBody(200, 33000);
2335 handler1->expectDetachTransaction();
2336 handler2->expectDetachTransaction();
2338 this->flushRequestsAndLoop();
2340 std::list<HTTPCodec::StreamID> streams;
2342 EXPECT_CALL(this->callbacks_, onHeadersComplete(1,
_));
2344 EXPECT_CALL(this->callbacks_, onHeadersComplete(3,
_));
2350 EXPECT_CALL(this->callbacks_, onMessageComplete(1,
_));
2352 EXPECT_CALL(this->callbacks_, onMessageComplete(3,
_));
2354 this->parseOutput(*this->clientCodec_);
2359 #define IF_HTTP2(X) \ 2360 if (this->clientCodec_->getProtocol() == CodecProtocol::HTTP_2) { X; } 2363 this->httpSession_->setWriteBufferLimit(12000);
2364 this->clientCodec_->getEgressSettings()->setSetting(
2365 SettingsId::INITIAL_WINDOW_SIZE, 1000000);
2366 this->clientCodec_->generateSettings(this->requests_);
2367 this->clientCodec_->generateWindowUpdate(this->requests_, 0, 1000000);
2368 this->sendRequest(
"/", 1);
2369 this->sendRequest(
"/", 1);
2370 this->sendRequest(
"/", 2);
2373 auto handler1 = this->addSimpleStrictHandler();
2374 handler1->expectHeaders();
2375 handler1->expectEOM();
2376 auto handler2 = this->addSimpleStrictHandler();
2377 handler2->expectHeaders();
2378 handler2->expectEOM([&] {
2379 handler1->sendHeaders(200, 24002);
2383 this->resumeWritesAfterDelay(milliseconds(50));
2385 handler1->expectEgressPaused();
2386 handler2->expectEgressPaused();
2387 auto handler3 = this->addSimpleStrictHandler();
2388 handler3->expectEgressPaused();
2389 handler3->expectHeaders();
2390 handler3->expectEOM();
2392 handler1->expectEgressResumed([&] {
2398 handler2->expectEgressResumed();
2399 IF_HTTP2(handler3->expectEgressResumed());
2400 handler1->expectEgressPaused();
2401 handler2->expectEgressPaused();
2402 IF_HTTP2(handler3->expectEgressPaused());
2404 handler1->expectEgressResumed();
2405 handler2->expectEgressResumed([&] {
2406 handler2->sendHeaders(200, 12001);
2409 this->resumeWritesAfterDelay(milliseconds(50));
2412 IF_HTTP2(handler3->expectEgressResumed());
2414 handler1->expectEgressPaused();
2415 handler2->expectEgressPaused();
2416 IF_HTTP2(handler3->expectEgressPaused());
2418 handler1->expectEgressResumed();
2419 handler2->expectEgressResumed([&] {
2420 handler1->txn_->sendEOM();
2421 handler2->txn_->sendEOM();
2423 handler3->expectEgressResumed([&] {
2424 handler3->txn_->sendAbort();
2427 handler3->expectDetachTransaction();
2428 handler1->expectDetachTransaction();
2429 handler2->expectDetachTransaction();
2431 this->flushRequestsAndLoop();
2439 auto settings = this->rawCodec_->getEgressSettings();
2440 auto maxTxns =
settings->getSetting(SettingsId::MAX_CONCURRENT_STREAMS,
2442 std::list<unique_ptr<StrictMock<MockHTTPHandler>>> handlers;
2445 for (
auto i = 0U;
i < maxTxns;
i++) {
2446 this->sendRequest();
2447 auto handler = this->addSimpleStrictHandler();
2452 auto streamID = this->sendRequest();
2453 this->clientCodec_->generateGoaway(this->requests_, 0, ErrorCode::NO_ERROR);
2455 for (
auto&
handler: handlers) {
2459 this->flushRequestsAndLoop();
2464 this->parseOutput(*this->clientCodec_);
2467 for (
auto&
handler: handlers) {
2468 handler->sendReplyWithBody(200, 100);
2469 handler->expectDetachTransaction();
2471 this->expectDetachSession();
2472 this->eventBase_.loop();
2485 auto req2p = sendRequestLater(req,
true);
2487 httpSession_->setEgressSettings({{
2488 SettingsId::MAX_CONCURRENT_STREAMS, 1}});
2491 auto handler1 = addSimpleStrictHandler();
2492 handler1->expectHeaders();
2493 handler1->expectEOM([&handler1, req,
this, &req2p] {
2495 handler1->sendReplyWithBody(200, 100);
2498 auto handler2 = addSimpleStrictHandler();
2499 handler2->expectHeaders();
2500 handler2->expectEOM([&handler2,
this] {
2501 handler2->sendReplyWithBody(200, 100);
2502 resumeWritesInLoop();
2504 handler1->expectDetachTransaction();
2505 handler2->expectDetachTransaction();
2507 expectDetachSession();
2509 flushRequestsAndLoop();
2513 TestWritesDraining, TestBodySizeLimit,
2514 TestUniformPauseState, TestMaxTxns);
2530 eventBase_.loopOnce();
2535 parseOutput(*clientCodec_);
2543 auto handler1 = addSimpleStrictHandler();
2546 handler1->expectHeaders();
2547 handler1->expectEOM([&handler1] {
2548 handler1->sendReplyWithBody(200, 80000);
2550 handler1->expectEgressPaused();
2558 handler1->expectDetachTransaction();
2560 expectDetachSession();
2562 flushRequestsAndLoop(
true, milliseconds(10));
2570 auto handler1 = addSimpleStrictHandler();
2571 handler1->expectHeaders();
2572 handler1->expectEOM([&handler1] {
2573 handler1->sendHeaders(200, 40000);
2574 handler1->sendBody(32769);
2576 auto handler2 = addSimpleStrictHandler();
2577 handler2->expectHeaders();
2578 handler2->expectEOM([&handler2,
this] {
2579 handler2->sendHeaders(200, 40000);
2580 handler2->sendBody(32768);
2581 eventBase_.runInLoop([
this] {
transport_->addReadEOF(milliseconds(0)); });
2584 handler1->expectEgressPaused();
2585 handler2->expectEgressPaused();
2586 handler1->expectEgressResumed();
2587 handler2->expectEgressResumed();
2590 HTTPException::Direction::INGRESS_AND_EGRESS);
2592 handler1->expectDetachTransaction();
2595 HTTPException::Direction::INGRESS_AND_EGRESS);
2597 handler2->expectDetachTransaction();
2599 expectDetachSession();
2601 flushRequestsAndLoop();
2614 sendRequest(
"/", 0);
2616 req2.setPriority(1);
2617 auto req2p = sendRequestLater(req2,
true);
2619 unique_ptr<StrictMock<MockHTTPHandler>> handler1;
2620 unique_ptr<StrictMock<MockHTTPHandler>> handler2;
2622 httpSession_->setWriteBufferLimit(200);
2625 handler1 = addSimpleStrictHandler();
2626 handler1->expectHeaders();
2627 handler1->expectEOM([&handler1,
this, &req2p] {
2629 handler1->sendHeaders(200, 1000);
2630 handler1->sendBody(100);
2633 handler1->expectEgressPaused([] { LOG(
INFO) <<
"paused 1"; });
2635 handler2 = addSimpleStrictHandler();
2636 handler2->expectEgressPaused();
2637 handler2->expectHeaders();
2638 handler2->expectEOM([&] {
2640 handler1->sendBody(900);
2641 handler1->txn_->sendEOM();
2642 handler2->sendReplyWithBody(200, 1000);
2643 resumeWritesInLoop();
2645 handler1->expectDetachTransaction();
2646 handler2->expectDetachTransaction();
2648 HTTPSession::DestructorGuard
g(httpSession_);
2649 flushRequestsAndLoop();
2651 std::list<HTTPCodec::StreamID> streams;
2659 streams.push_back(stream);
2661 parseOutput(*clientCodec_);
2666 TEST_F(HTTP2DownstreamSessionTest, ZeroDeltaWindowUpdate) {
2671 clientCodec_->generateWindowUpdate(requests_,
streamID, 1);
2676 auto handler = addSimpleStrictHandler();
2679 handler->expectHeaders();
2683 "streamID=1 with HTTP2Codec stream error: window update delta=0",
2686 handler->expectDetachTransaction();
2687 expectDetachSession();
2689 flushRequestsAndLoop();
2692 TEST_F(HTTP2DownstreamSessionTest, PaddingFlowControl) {
2697 for (
auto i = 0;
i < 129;
i++) {
2698 clientCodec_->generateBody(requests_,
streamID,
makeBuf(1), 255,
false);
2701 auto handler = addSimpleStrictHandler();
2705 handler->txn_->pauseIngress();
2706 eventBase_.runAfterDelay([&] {
handler->txn_->resumeIngress(); },
2712 handler->expectDetachTransaction();
2714 HTTPSession::DestructorGuard
g(httpSession_);
2715 flushRequestsAndLoop(
false, milliseconds(0), milliseconds(0), [&] {
2716 clientCodec_->generateRstStream(requests_,
streamID, ErrorCode::CANCEL);
2717 clientCodec_->generateGoaway(requests_, 0, ErrorCode::NO_ERROR);
2718 transport_->addReadEvent(requests_, milliseconds(110));
2721 std::list<HTTPCodec::StreamID> streams;
2724 parseOutput(*clientCodec_);
2725 expectDetachSession();
2728 TEST_F(HTTP2DownstreamSessionTest, GracefulDrainOnTimeout) {
2730 std::chrono::milliseconds gracefulTimeout(200);
2731 httpSession_->enableDoubleGoawayDrain();
2732 EXPECT_CALL(mockController_, getGracefulShutdownTimeout())
2736 eventBase_.runInLoop([&] {
2739 ErrorCode::NO_ERROR,
_));
2740 parseOutput(*clientCodec_);
2742 return gracefulTimeout;
2747 eventBase_.runAfterDelay([&] { httpSession_->timeoutExpired(); },
2748 transactionTimeouts_->getDefaultTimeout().count());
2749 HTTPSession::DestructorGuard
g(httpSession_);
2754 gracefulTimeout + transactionTimeouts_->getDefaultTimeout();
2756 EXPECT_CALL(callbacks_, onGoaway(0, ErrorCode::NO_ERROR,
_));
2757 parseOutput(*clientCodec_);
2758 expectDetachSession();
2769 TEST_F(HTTP2DownstreamSessionTest, ServerPush) {
2773 req.
setURL(
"https://www.foo.com/");
2778 clientCodec_->getEgressSettings()->setSetting(SettingsId::ENABLE_PUSH, 1);
2779 clientCodec_->generateSettings(requests_);
2782 clientCodec_->generateHeader(requests_, assocStreamId,
getGetRequest(),
2785 auto handler = addSimpleStrictHandler();
2791 handler->txn_->sendHeaders(res);
2793 handler->txn_->pauseIngress();
2795 auto* pushTxn =
handler->txn_->newPushedTransaction(&pushHandler);
2798 auto outgoingStreams = httpSession_->getNumOutgoingStreams();
2799 pushTxn->sendHeaders(req);
2800 EXPECT_EQ(httpSession_->getNumOutgoingStreams(), outgoingStreams);
2802 auto pri =
handler->txn_->getPriority();
2804 pri.exclusive, pri.weight));
2805 pushTxn->sendHeaders(res);
2806 EXPECT_EQ(httpSession_->getNumOutgoingStreams(), outgoingStreams + 1);
2807 pushTxn->sendBody(
makeBuf(200));
2810 eventBase_.runAfterDelay([&] {
handler->txn_->resumeIngress(); },
2815 pushHandler.txn_ = txn; }));
2818 handler->expectDetachTransaction();
2820 transport_->addReadEvent(requests_, milliseconds(0));
2821 clientCodec_->generateRstStream(requests_, assocStreamId, ErrorCode::CANCEL);
2822 clientCodec_->generateGoaway(requests_, 2, ErrorCode::NO_ERROR);
2823 transport_->addReadEvent(requests_, milliseconds(200));
2825 HTTPSession::DestructorGuard
g(httpSession_);
2836 parseOutput(*clientCodec_);
2837 expectDetachSession();
2840 TEST_F(HTTP2DownstreamSessionTest, ServerPushAbortPaused) {
2844 req.
setURL(
"https://www.foo.com/");
2849 clientCodec_->getEgressSettings()->setSetting(SettingsId::ENABLE_PUSH, 1);
2850 clientCodec_->generateSettings(requests_);
2853 clientCodec_->generateHeader(requests_, assocStreamId,
getGetRequest(),
2856 auto handler = addSimpleStrictHandler();
2863 handler->txn_->sendHeaders(res);
2865 handler->txn_->pauseIngress();
2867 auto* pushTxn =
handler->txn_->newPushedTransaction(&pushHandler);
2870 pushTxn->sendHeaders(req);
2874 pushHandler.txn_ = txn; }));
2878 handler->expectDetachTransaction();
2880 transport_->addReadEvent(requests_, milliseconds(0));
2882 clientCodec_->generateRstStream(requests_, assocStreamId, ErrorCode::CANCEL);
2883 transport_->addReadEvent(requests_, milliseconds(10));
2885 HTTPSession::DestructorGuard
g(httpSession_);
2888 parseOutput(*clientCodec_);
2889 expectDetachSession();
2892 TEST_F(HTTP2DownstreamSessionTest, TestPriorityWeightsTinyRatio) {
2908 auto id2 = sendRequest(req2);
2914 auto handler1 = addSimpleStrictHandler();
2915 handler1->expectHeaders();
2916 handler1->expectEOM([&] {
2917 handler1->sendReplyWithBody(200, 4 * 1024);
2919 auto handler2 = addSimpleStrictHandler();
2920 handler2->expectHeaders();
2921 handler2->expectEOM();
2922 auto handler3 = addSimpleStrictHandler();
2923 handler3->expectHeaders();
2924 handler3->expectEOM([&] {
2925 handler3->sendReplyWithBody(200, 15);
2927 auto handler4 = addSimpleStrictHandler();
2928 handler4->expectHeaders();
2929 handler4->expectEOM([&] {
2930 handler4->sendReplyWithBody(200, 1);
2933 handler1->expectDetachTransaction([&] {
2935 EXPECT_EQ(handler1->txn_->getPrioritySampleSummary(summary),
true);
2936 EXPECT_EQ(handler1->txn_->getTransport().getHTTP2PrioritiesEnabled(),
2956 handler3->expectDetachTransaction([&] {
2958 EXPECT_EQ(handler3->txn_->getPrioritySampleSummary(summary),
true);
2959 EXPECT_EQ(handler3->txn_->getTransport().getHTTP2PrioritiesEnabled(),
2981 handler4->expectDetachTransaction([&] {
2983 EXPECT_EQ(handler4->txn_->getPrioritySampleSummary(summary),
true);
2984 EXPECT_EQ(handler4->txn_->getTransport().getHTTP2PrioritiesEnabled(),
3020 handler2->txn_->sendAbort();
3022 handler2->expectDetachTransaction();
3023 flushRequestsAndLoop();
3024 httpSession_->closeWhenIdle();
3025 expectDetachSession();
3029 TEST_F(HTTP2DownstreamSessionTest, TestPriorityDependentTransactions) {
3041 auto id1 = sendRequest(req1);
3047 auto handler1 = addSimpleStrictHandler();
3048 handler1->expectHeaders();
3049 handler1->expectEOM([&] {
3050 handler1->sendReplyWithBody(200, 1024);
3052 auto handler2 = addSimpleStrictHandler();
3053 handler2->expectHeaders();
3054 handler2->expectEOM([&] {
3055 handler2->sendReplyWithBody(200, 1024);
3058 handler1->expectDetachTransaction([&] {
3060 EXPECT_EQ(handler1->txn_->getPrioritySampleSummary(summary),
true);
3061 EXPECT_EQ(handler1->txn_->getTransport().getHTTP2PrioritiesEnabled(),
3077 handler2->expectDetachTransaction([&] {
3079 EXPECT_EQ(handler2->txn_->getPrioritySampleSummary(summary),
true);
3080 EXPECT_EQ(handler2->txn_->getTransport().getHTTP2PrioritiesEnabled(),
3099 handler2->txn_->sendAbort();
3101 flushRequestsAndLoop();
3102 httpSession_->closeWhenIdle();
3103 expectDetachSession();
3107 TEST_F(HTTP2DownstreamSessionTest, TestDisablePriorities) {
3109 httpSession_->setHTTP2PrioritiesEnabled(
false);
3120 auto handler1 = addSimpleStrictHandler();
3121 handler1->expectHeaders();
3122 handler1->expectEOM([&] {
3123 handler1->sendReplyWithBody(200, 4 * 1024);
3126 auto handler2 = addSimpleStrictHandler();
3127 handler2->expectHeaders();
3128 handler2->expectEOM([&] {
3129 handler2->sendReplyWithBody(200, 4 * 1024);
3134 handler1->expectDetachTransaction();
3135 handler2->expectDetachTransaction();
3137 flushRequestsAndLoop();
3138 httpSession_->closeWhenIdle();
3139 expectDetachSession();
3143 TEST_F(HTTP2DownstreamSessionTest, TestPriorityWeights) {
3145 auto priGroupID = clientCodec_->createStream();
3146 clientCodec_->generatePriority(
3149 auto id1 = sendRequest();
3150 auto id2 = sendRequest();
3152 auto handler1 = addSimpleStrictHandler();
3154 handler1->expectHeaders();
3155 handler1->expectEOM([&] {
3156 handler1->sendHeaders(200, 12 * 1024);
3157 handler1->txn_->sendBody(
makeBuf(4 * 1024));
3159 auto handler2 = addSimpleStrictHandler();
3160 handler2->expectHeaders();
3161 handler2->expectEOM([&] {
3162 handler2->sendHeaders(200, 12 * 1024);
3163 handler2->txn_->sendBody(
makeBuf(4 * 1024));
3167 flushRequestsAndLoopN(2);
3174 .WillOnce(ExpectBodyLen(4 * 1024));
3176 .WillOnce(ExpectBodyLen(4 * 1024));
3177 parseOutput(*clientCodec_);
3180 clientCodec_->generatePriority(
3183 eventBase_.runInLoop([&] {
3184 handler1->txn_->sendBody(
makeBuf(4 * 1024));
3185 handler2->txn_->sendBody(
makeBuf(4 * 1024));
3187 flushRequestsAndLoopN(2);
3190 .WillOnce(ExpectBodyLen(4 * 1024));
3192 .WillOnce(ExpectBodyLen(1 * 1024))
3193 .WillOnce(ExpectBodyLen(3 * 1024));
3194 parseOutput(*clientCodec_);
3197 clientCodec_->generatePriority(requests_, priGroupID,
3199 eventBase_.runInLoop([&] {
3200 handler1->txn_->sendBody(
makeBuf(4 * 1024));
3201 handler1->txn_->sendEOM();
3202 handler2->txn_->sendBody(
makeBuf(4 * 1024));
3203 handler2->txn_->sendEOM();
3205 handler1->expectDetachTransaction();
3206 handler2->expectDetachTransaction();
3207 flushRequestsAndLoopN(2);
3211 .WillOnce(ExpectBodyLen(4 * 1024));
3214 .WillOnce(ExpectBodyLen(4 * 1024));
3216 parseOutput(*clientCodec_);
3218 httpSession_->closeWhenIdle();
3219 expectDetachSession();
3220 this->eventBase_.loop();
3223 TEST_F(HTTP2DownstreamSessionTest, TestPriorityWeightsTinyWindow) {
3224 httpSession_->setWriteBufferLimit(2 * 65536);
3226 auto id1 = sendRequest();
3227 auto id2 = sendRequest();
3229 auto handler1 = addSimpleStrictHandler();
3231 handler1->expectHeaders();
3232 handler1->expectEOM([&] {
3233 handler1->sendReplyWithBody(200, 32 * 1024);
3235 auto handler2 = addSimpleStrictHandler();
3236 handler2->expectHeaders();
3237 handler2->expectEOM([&] {
3238 handler2->sendReplyWithBody(200, 32 * 1024);
3241 handler1->expectDetachTransaction();
3244 flushRequestsAndLoopN(2);
3250 for (
auto i = 0;
i < 7;
i++) {
3252 .WillOnce(ExpectBodyLen(4 * 1024));
3254 .WillOnce(ExpectBodyLen(4 * 1024));
3257 .WillOnce(ExpectBodyLen(4 * 1024 - 1));
3259 .WillOnce(ExpectBodyLen(4 * 1024 - 1));
3261 .WillOnce(ExpectBodyLen(1));
3263 parseOutput(*clientCodec_);
3266 clientCodec_->generateWindowUpdate(requests_, 0, 100);
3267 handler2->expectDetachTransaction();
3268 flushRequestsAndLoopN(2);
3271 .WillOnce(ExpectBodyLen(1));
3273 parseOutput(*clientCodec_);
3275 httpSession_->closeWhenIdle();
3276 expectDetachSession();
3277 this->eventBase_.loop();
3280 TEST_F(HTTP2DownstreamSessionTest, TestShortContentLength) {
3282 auto streamID = sendRequest(req,
false);
3284 HTTPCodec::NoPadding,
true);
3285 auto handler1 = addSimpleStrictHandler();
3288 handler1->expectHeaders();
3289 handler1->expectError([&handler1] (
const HTTPException& ex) {
3291 handler1->txn_->sendAbort();
3293 handler1->expectDetachTransaction();
3294 flushRequestsAndLoop();
3303 TEST_F(HTTP2DownstreamSessionTest, TestBadContentLengthUntieHandler) {
3305 auto streamID = sendRequest(req,
false);
3306 clientCodec_->generateBody(
3310 HTTPCodec::NoPadding,
3312 auto handler1 = addSimpleStrictHandler();
3315 handler1->expectHeaders();
3317 if (handler1->txn_) {
3318 handler1->txn_->setHandler(nullptr);
3320 handler1->txn_ =
nullptr;
3322 flushRequestsAndLoop();
3327 TEST_F(HTTP2DownstreamSessionTest, TestLongContentLength) {
3329 auto streamID = sendRequest(req,
false);
3331 HTTPCodec::NoPadding,
true);
3332 auto handler1 = addSimpleStrictHandler();
3335 handler1->expectHeaders();
3336 handler1->expectBody();
3337 handler1->expectError([&handler1] (
const HTTPException& ex) {
3339 handler1->txn_->sendAbort();
3341 handler1->expectDetachTransaction();
3342 flushRequestsAndLoop();
3347 TEST_F(HTTP2DownstreamSessionTest, TestMalformedContentLength) {
3350 auto streamID = sendRequest(req,
false);
3352 HTTPCodec::NoPadding,
true);
3353 auto handler1 = addSimpleStrictHandler();
3356 handler1->expectHeaders();
3357 handler1->expectBody();
3358 handler1->expectEOM([&handler1] {
3359 handler1->sendReplyWithBody(200, 100);
3361 handler1->expectDetachTransaction();
3362 flushRequestsAndLoop();
3367 TEST_F(HTTP2DownstreamSessionTest, TestHeadContentLength) {
3370 req.setMethod(HTTPMethod::HEAD);
3372 auto handler1 = addSimpleStrictHandler();
3374 handler1->expectHeaders();
3375 handler1->expectEOM([&handler1] {
3376 handler1->sendHeaders(200, 100);
3378 handler1->txn_->sendEOM();
3380 handler1->expectDetachTransaction();
3381 flushRequestsAndLoop();
3386 TEST_F(HTTP2DownstreamSessionTest, Test304ContentLength) {
3389 req.setMethod(HTTPMethod::HEAD);
3391 auto handler1 = addSimpleStrictHandler();
3393 handler1->expectHeaders();
3394 handler1->expectEOM([&handler1] {
3395 handler1->sendHeaders(304, 100);
3396 handler1->txn_->sendEOM();
3398 handler1->expectDetachTransaction();
3399 flushRequestsAndLoop();
3408 req.setIsChunked(
true);
3410 auto streamID = sendRequest(req,
false);
3411 clientCodec_->generateChunkHeader(requests_,
streamID, 20);
3413 HTTPCodec::NoPadding,
false);
3414 clientCodec_->generateChunkTerminator(requests_,
streamID);
3415 clientCodec_->generateEOM(requests_,
streamID);
3416 auto handler1 = addSimpleStrictHandler();
3418 handler1->expectHeaders();
3421 handler1->expectError([&handler1] (
const HTTPException& ex) {
3423 handler1->txn_->sendAbort();
3425 handler1->expectDetachTransaction();
3426 expectDetachSession();
3427 flushRequestsAndLoop();
3431 TEST_F(HTTP2DownstreamSessionTest, TestSessionStallByFlowControl) {
3439 httpSession_->setWriteBufferLimit(128 * 1024);
3440 httpSession_->setSessionStats(&stats);
3446 auto handler1 = addSimpleStrictHandler();
3448 handler1->expectHeaders();
3449 handler1->expectEOM([&] {
3450 handler1->sendReplyWithBody(200, 32 * 1024);
3453 auto handler2 = addSimpleStrictHandler();
3454 handler2->expectHeaders();
3455 handler2->expectEOM([&] {
3456 handler2->sendReplyWithBody(200, 32 * 1024);
3459 EXPECT_CALL(stats, recordSessionStalled()).Times(1);
3461 handler1->expectDetachTransaction();
3464 flushRequestsAndLoopN(2);
3467 clientCodec_->generateWindowUpdate(requests_, 0, 100);
3468 handler2->expectDetachTransaction();
3469 flushRequestsAndLoopN(2);
3471 httpSession_->closeWhenIdle();
3472 expectDetachSession();
3473 flushRequestsAndLoop();
3476 TEST_F(HTTP2DownstreamSessionTest, TestTransactionStallByFlowControl) {
3479 httpSession_->setSessionStats(&stats);
3484 clientCodec_->getEgressSettings()->setSetting(SettingsId::INITIAL_WINDOW_SIZE,
3486 clientCodec_->generateSettings(requests_);
3493 auto handler = addSimpleStrictHandler();
3496 handler->sendReplyWithBody(200, 1000);
3500 handler->expectEgressPaused();
3505 folly::to<std::string>(
"ingress timeout, streamID=",
streamID),
3510 handler->expectDetachTransaction();
3514 flushRequestsAndLoop();
3518 TEST_F(HTTP2DownstreamSessionTest, TestTransactionNotStallByFlowControl) {
3521 httpSession_->setSessionStats(&stats);
3523 clientCodec_->getEgressSettings()->setSetting(SettingsId::INITIAL_WINDOW_SIZE,
3525 clientCodec_->generateSettings(requests_);
3532 auto handler = addSimpleStrictHandler();
3535 handler->sendReplyWithBody(200, 500);
3541 handler->expectEgressPaused();
3543 handler->expectDetachTransaction();
3547 flushRequestsAndLoop();
3551 TEST_F(HTTP2DownstreamSessionTest, TestSetEgressSettings) {
3553 { SettingsId::MAX_FRAME_SIZE, 16384 },
3554 { SettingsId::ENABLE_PUSH, 1 }};
3556 const HTTPSettings* codecSettings = rawCodec_->getEgressSettings();
3557 for (
const auto& setting: settings) {
3564 flushRequestsAndLoop();
WeightedAverage contentions_
void expect101(CodecProtocol expectedProtocol, const std::string &expectedUpgrade, bool expect100=false)
folly::HHWheelTimer::UniquePtr makeInternalTimeoutSet(EventBase *evb)
#define EXPECT_LE(val1, val2)
virtual void setHandler(Handler *handler)
StrictMock< MockController > mockController_
std::unique_ptr< testing::NiceMock< MockHTTPCodec > > makeDownstreamParallelCodec()
virtual size_t onIngress(const folly::IOBuf &buf)=0
std::chrono::milliseconds millisecondsBetween(std::chrono::time_point< ClockType > finish, std::chrono::time_point< ClockType > start)
const uint32_t kInitialWindow
void parseOutput(HTTPCodec &clientCodec)
virtual void onError(StreamID stream, const HTTPException &error, bool newTxn=false)=0
GTEST_API_ Cardinality AtLeast(int n)
HTTPCodec::StreamID sendRequest(const std::string &url="/", int8_t priority=0, bool eom=true)
void setWantsKeepalive(bool wantsKeepaliveVal)
ProxygenError getProxygenError() const
#define ASSERT_EQ(val1, val2)
const SocketAddress peerAddr
void testSimpleUpgrade(const std::string &upgradeHeader, CodecProtocol expectedProtocol, const std::string &expectedUpgradeHeader)
const std::string & getStatusMessage() const
void setEventBase(EventBase *eventBase, bool takeOwnership)
const std::string kProtocolCleartextString
std::vector< int64_t > flowControl_
void setStatusMessage(T &&msg)
uint16_t getStatusCode() const
#define EXPECT_EQ(val1, val2)
void onEOMTerminateHandlerExpectShutdown(MockHTTPHandler &handler)
TestAsyncTransport * transport_
constexpr detail::Map< Move > move
::testing::Types< SPDY3CodecPair, SPDY3_1CodecPair, HTTP2CodecPair > ParallelCodecs
void resumeWritesAfterDelay(milliseconds delay)
void setProxygenError(ProxygenError proxygenError)
static http_parser_settings settings
—— Concurrent Priority Queue Implementation ——
void setCodecStatusCode(ErrorCode statusCode)
void setByteEventTracker(std::shared_ptr< ByteEventTracker > byteEventTracker)
const wangle::TransportInfo mockTransportInfo
MockByteEventTracker * setMockByteEventTracker()
#define EXPECT_GE(val1, val2)
INSTANTIATE_TYPED_TEST_CASE_P(ParallelCodecs, HTTPDownstreamTest, ParallelCodecs)
requires And< SemiMovable< VN >... > &&SemiMovable< E > auto error(E e)
PolymorphicAction< internal::InvokeWithoutArgsAction< FunctionImpl > > InvokeWithoutArgs(FunctionImpl function_impl)
const HeaderIndexingStrategy * getHeaderIndexingStrategy() const
static EventBaseManager * get()
void testPriorities(uint32_t numPriorities)
void handler(int, siginfo_t *, void *)
std::unique_ptr< folly::IOBuf > makeBuf(uint32_t size)
HTTPCodec::StreamID sendRequest(const HTTPMessage &req, bool eom=true)
void flushRequestsAndLoop(bool eof=false, milliseconds eofDelay=milliseconds(0), milliseconds initialDelay=milliseconds(0), std::function< void()> extraEventsFn=std::function< void()>())
std::unique_ptr< AsyncTransportWrapper, Destructor > UniquePtr
folly::HHWheelTimer::UniquePtr transactionTimeouts_
static Options cacheChainLength()
void setHTTP2Priority(HTTPPriority h2Pri)
folly::HHWheelTimer::UniquePtr makeTimeoutSet(EventBase *evb)
Direction getDirection() const
PolymorphicAction< internal::InvokeAction< FunctionImpl > > Invoke(FunctionImpl function_impl)
void setPrioritySampled(bool sampled)
NiceMock< MockHTTPCodecCallback > callbacks_
const uint32_t kFrameWindowUpdateSize
constexpr auto data(C &c) -> decltype(c.data())
void incrementPendingByteEvents()
HTTPDownstreamSessionUpgradeFlowControlTest()
HTTPCodec::StreamID sendHeader()
ErrorCode getCodecStatusCode() const
void resumeWritesInLoop()
void expectEOM(std::function< void()> callback=std::function< void()>())
REGISTER_TYPED_TEST_CASE_P(HTTPDownstreamTest, TestWritesDraining, TestBodySizeLimit, TestUniformPauseState, TestMaxTxns)
HTTPMessage getResponse(uint32_t code, uint32_t bodyLen)
void expectResponse(uint32_t code=200, ErrorCode errorCode=ErrorCode::NO_ERROR, bool expect100=false, bool expectGoaway=false)
TYPED_TEST_P(HTTPDownstreamTest, TestWritesDraining)
void addSingleByteReads(const char *data, milliseconds delay={})
HTTPHeaders & getHeaders()
void expectDetachTransaction(std::function< void()> callback=std::function< void()>())
std::unique_ptr< HHWheelTimer, Destructor > UniquePtr
TEST_F(AsyncSSLSocketWriteTest, write_coalescing1)
std::tuple< uint32_t, bool, uint8_t > HTTPPriority
#define EXPECT_TRUE(condition)
SteadyClock::time_point TimePoint
std::vector< HTTPSetting > SettingsList
HeaderIndexingStrategy testH2IndexingStrat_
bool isParallelCodecProtocol(CodecProtocol protocol)
HTTPMessage getGetRequest(const std::string &url)
unique_ptr< HTTPCodec > clientCodec_
void flushRequests(bool eof=false, milliseconds eofDelay=milliseconds(0), milliseconds initialDelay=milliseconds(0), std::function< void()> extraEventsFn=std::function< void()>())
AsyncFizzClient::UniquePtr transport_
HTTPMessage getPostRequest(uint32_t contentLength)
std::chrono::time_point< ClockType > getCurrentTime()
const SocketAddress localAddr
testing::NiceMock< MockAsyncTransport > * newMockTransport(EventBase *evb)
void setHTTPVersion(uint8_t major, uint8_t minor)
PolymorphicAction< internal::AssignAction< T1, T2 > > Assign(T1 *ptr, T2 val)
void flushRequestsAndLoopN(uint64_t n, bool eof=false, milliseconds eofDelay=milliseconds(0), milliseconds initialDelay=milliseconds(0), std::function< void()> extraEventsFn=std::function< void()>())
Promise< Unit > sendRequestLater(HTTPMessage req, bool eof=false)
std::unique_ptr< testing::NiceMock< MockHTTPHandler > > addSimpleNiceHandler()
#define EXPECT_CALL(obj, call)
double byTransactionBytes_
const internal::AnythingMatcher _
virtual void writeSuccess() noexcept=0
std::unique_ptr< testing::StrictMock< MockHTTPHandler > > addSimpleStrictHandler()
void expectDetachSession()
#define ASSERT_NE(val1, val2)
HTTPDownstreamSession * httpSession_
HTTPMessage getUpgradeRequest(const std::string &upgradeHeader, HTTPMethod method, uint32_t bodyLen)
#define EXPECT_FALSE(condition)
void expectResponses(uint32_t n, uint32_t code=200, ErrorCode errorCode=ErrorCode::NO_ERROR, bool expect100=false, bool expectGoaway=false)
#define EXPECT_LT(val1, val2)
TYPED_TEST_CASE_P(HTTPDownstreamTest)
Future< Unit > times(const int n, F &&thunk)
static std::unique_ptr< IOBuf > copyBuffer(const void *buf, std::size_t size, std::size_t headroom=0, std::size_t minTailroom=0)
const char * what(void) const noexceptoverride
#define ASSERT_TRUE(condition)
std::unique_ptr< Codec > getCodec(CodecType type, int level)
TEST(SequencedExecutor, CPUThreadPoolExecutor)
HTTPDownstreamTest(std::vector< int64_t > flowControl={-1,-1,-1}, bool startImmediately=true)
internal::ReturnAction< R > Return(R value)
const HTTPSetting * getSetting(SettingsId id) const
void testChunks(bool trailers)
#define EXPECT_GT(val1, val2)
void setStatusCode(uint16_t status)