24 using namespace folly;
29 TEST(HTTP2CodecConstantsTest, HTTPContantsAreCommonHeaders) {
57 void testHeaderListSize(
bool oversized);
58 void testFrameSizeLimit(
bool oversized);
66 auto numSettings = downstreamCodec_.getIngressSettings()->getNumSettings();
77 downstreamCodec_.getIngressSettings()->getNumSettings());
86 EXPECT_EQ(
false, downstreamCodec_.supportsExTransactions());
93 EXPECT_EQ(
false, downstreamCodec_.supportsExTransactions());
98 downstreamCodec_.getEgressSettings()->setSetting(
100 auto ptr = downstreamCodec_.getEgressSettings()->getSetting(
104 ptr = downstreamCodec_.getIngressSettings()->getSetting(
107 EXPECT_EQ(
false, downstreamCodec_.supportsExTransactions());
116 ptr = downstreamCodec_.getIngressSettings()->getSetting(
119 EXPECT_EQ(
false, downstreamCodec_.supportsExTransactions());
129 ptr = downstreamCodec_.getIngressSettings()->getSetting(
132 EXPECT_EQ(
false, downstreamCodec_.supportsExTransactions());
137 downstreamCodec_.getEgressSettings()->setSetting(
140 auto ptr = downstreamCodec_.getEgressSettings()->getSetting(
144 ptr = downstreamCodec_.getIngressSettings()->getSetting(
147 EXPECT_EQ(
false, downstreamCodec_.supportsExTransactions());
156 ptr = downstreamCodec_.getIngressSettings()->getSetting(
159 EXPECT_EQ(
true, downstreamCodec_.supportsExTransactions());
169 ptr = downstreamCodec_.getIngressSettings()->getSetting(
172 EXPECT_EQ(
false, downstreamCodec_.supportsExTransactions());
177 downstreamCodec_.getEgressSettings()->setSetting(
195 upstreamCodec_.generateHeader(output_, 1, req,
true );
198 callbacks_.expectMessage(
true, 3,
"/guacamole");
200 const auto& headers = callbacks_.msg->getHeaders();
202 EXPECT_EQ(
"coolio\tv2", headers.getSingleOrEmpty(
"tab-hdr"));
209 upstreamCodec_.getEgressSettings()->setSetting(
217 req.getHeaders().add(
"tab-hdr",
"coolio\tv2");
224 upstreamCodec_.generateExHeader(output_, stream, req,
229 EXPECT_EQ(controlStream, callbacks_.controlStreamId);
231 callbacks_.expectMessage(
true, 3,
"/guacamole");
233 const auto& headers = callbacks_.msg->getHeaders();
235 EXPECT_EQ(
"coolio\tv2", headers.getSingleOrEmpty(
"tab-hdr"));
242 downstreamCodec_.getEgressSettings()->setSetting(
249 resp.setStatusMessage(
"nifty-nice");
254 downstreamCodec_.generateExHeader(output_, stream, resp,
258 EXPECT_EQ(controlStream, callbacks_.controlStreamId);
260 EXPECT_EQ(
"OK", callbacks_.msg->getStatusMessage());
261 callbacks_.expectMessage(
true, 2, 200);
262 const auto& headers = callbacks_.msg->getHeaders();
263 EXPECT_EQ(
"OK", callbacks_.msg->getStatusMessage());
269 downstreamCodec_.getEgressSettings()->setSetting(
276 req.setHTTP2Priority(pri);
277 upstreamCodec_.generateExHeader(output_, 3, req,
281 EXPECT_EQ(callbacks_.msg->getHTTP2Priority(), pri);
287 downstreamCodec_.getEgressSettings()->setSetting(
291 downstreamCodec_.generateExHeader(output_, 3, req,
304 static const vector<proxygen::compress::Header> reqHeaders = {
314 for (
size_t i = 0;
i < reqHeaders.size();
i++, stream += 2) {
315 std::vector<proxygen::compress::Header> allHeaders = reqHeaders;
316 allHeaders.erase(allHeaders.begin() +
i);
317 auto encodedHeaders = headerCodec.
encode(allHeaders);
328 for (
size_t i = 0;
i < reqHeaders.size();
i++, stream += 2) {
329 std::vector<proxygen::compress::Header> allHeaders = reqHeaders;
330 auto h = allHeaders[
i];
332 allHeaders.push_back(
h);
333 auto encodedHeaders = headerCodec.
encode(allHeaders);
345 EXPECT_EQ(callbacks_.headersComplete, 1);
346 EXPECT_EQ(callbacks_.messageComplete, 1);
357 static const vector<proxygen::compress::Header> reqHeaders = {
366 std::vector<proxygen::compress::Header> allHeaders = reqHeaders;
367 auto encodedHeaders = headerCodec.
encode(allHeaders);
378 EXPECT_EQ(callbacks_.headersComplete, 0);
379 EXPECT_EQ(callbacks_.messageComplete, 0);
386 static const std::string v2(
"\13\10protocol-attack");
389 static const vector<proxygen::compress::Header> reqHeaders = {
398 for (
size_t i = 0;
i < reqHeaders.size();
i++, stream += 2) {
399 std::vector<proxygen::compress::Header> allHeaders;
400 allHeaders.push_back(reqHeaders[
i]);
401 auto encodedHeaders = headerCodec.
encode(allHeaders);
413 EXPECT_EQ(callbacks_.headersComplete, 0);
414 EXPECT_EQ(callbacks_.messageComplete, 0);
423 0x00, 0x00, 0x1d, 0x01, 0x04, 0x00, 0x00, 0x00, 0x01, 0x82,
424 0x87, 0x44, 0x87, 0x62, 0x6b, 0x46, 0x41, 0xd2, 0x7a, 0x0b,
425 0x41, 0x89, 0xf1, 0xe3, 0xc2, 0xf2, 0x9c, 0xeb, 0x90, 0xf4,
426 0xff, 0x40, 0x80, 0x84, 0x2d, 0x35, 0xa7, 0xd7
433 EXPECT_EQ(callbacks_.headersComplete, 0);
434 EXPECT_EQ(callbacks_.messageComplete, 0);
444 upstreamCodec_.generateHeader(output_, 1, request,
false );
447 callbacks_.expectMessage(
false, 1,
"");
449 const auto& headers = callbacks_.msg->getHeaders();
456 std::vector<proxygen::compress::Header> goodHeaders = {
463 std::vector<proxygen::compress::Header> badHeaders = {
471 for (
size_t i = 0;
i < badHeaders.size();
i++, stream += 2) {
472 auto allHeaders = goodHeaders;
473 allHeaders.push_back(badHeaders[
i]);
474 auto encodedHeaders = headerCodec.
encode(allHeaders);
486 EXPECT_EQ(callbacks_.headersComplete, 0);
487 EXPECT_EQ(callbacks_.messageComplete, 0);
488 EXPECT_EQ(callbacks_.streamErrors, badHeaders.size());
494 auto settings = downstreamCodec_.getEgressSettings();
501 "supercalafragalisticexpialadoshus");
502 upstreamCodec_.generateHeader(output_, 1, req,
true );
506 EXPECT_EQ(callbacks_.messageBegin, oversized ? 0 : 1);
507 EXPECT_EQ(callbacks_.headersComplete, oversized ? 0 : 1);
508 EXPECT_EQ(callbacks_.messageComplete, oversized ? 0 : 1);
510 EXPECT_EQ(callbacks_.sessionErrors, oversized ? 1 : 0);
515 auto settings = downstreamCodec_.getEgressSettings();
522 downstreamCodec_.generateSettings(output_);
528 upstreamCodec_.generateHeader(output_, 1, req,
true );
532 EXPECT_EQ(callbacks_.messageBegin, oversized ? 0 : 1);
533 EXPECT_EQ(callbacks_.headersComplete, oversized ? 0 : 1);
534 EXPECT_EQ(callbacks_.messageComplete, oversized ? 0 : 1);
536 EXPECT_EQ(callbacks_.sessionErrors, oversized ? 1 : 0);
540 testHeaderListSize(
false);
544 testHeaderListSize(
true);
548 testFrameSizeLimit(
false);
552 testFrameSizeLimit(
true);
557 auto settings = downstreamCodec_.getEgressSettings();
559 downstreamCodec_.generateSettings(output_);
565 upstreamCodec_.generateHeader(output_, 1, req,
true );
570 EXPECT_EQ(callbacks_.headersComplete, 0);
571 EXPECT_EQ(callbacks_.messageComplete, 0);
583 downstreamCodec_.generateHeader(output_, 1, resp);
584 downstreamCodec_.generateEOM(output_, 1);
587 callbacks_.expectMessage(
true, 2, 200);
588 const auto& headers = callbacks_.msg->getHeaders();
590 EXPECT_EQ(
"OK", callbacks_.msg->getStatusMessage());
597 static const vector<proxygen::compress::Header> respHeaders = {
604 for (
size_t i = 0;
i < respHeaders.size();
i++, stream += 2) {
605 std::vector<proxygen::compress::Header> allHeaders = respHeaders;
606 allHeaders.erase(allHeaders.begin() +
i);
607 auto encodedHeaders = headerCodec.
encode(allHeaders);
618 for (
size_t i = 0;
i < respHeaders.size();
i++, stream += 2) {
619 std::vector<proxygen::compress::Header> allHeaders = respHeaders;
620 auto h = allHeaders[
i];
622 allHeaders.push_back(
h);
623 auto encodedHeaders = headerCodec.
encode(allHeaders);
635 EXPECT_EQ(callbacks_.headersComplete, 0);
636 EXPECT_EQ(callbacks_.messageComplete, 0);
648 upstreamCodec_.generateHeader(output_, 1, req);
651 callbacks_.expectMessage(
false, 2,
"/guacamole");
652 EXPECT_EQ(callbacks_.msg->getCookie(
"chocolate-chip"),
"1");
653 EXPECT_EQ(callbacks_.msg->getCookie(
"rainbow-chip"),
"2");
654 EXPECT_EQ(callbacks_.msg->getCookie(
"butterscotch"),
"3");
655 EXPECT_EQ(callbacks_.msg->getCookie(
"oatmeal-raisin"),
"4");
660 upstreamCodec_.generateHeader(output_, 1, req);
663 callbacks_.expectMessage(
false, -1,
"/");
665 EXPECT_GT(downstreamCodec_.getReceivedFrameCount(), 1);
667 const auto& headers = callbacks_.msg->getHeaders();
670 EXPECT_EQ(callbacks_.headersComplete, 1);
671 EXPECT_EQ(callbacks_.messageComplete, 0);
679 upstreamCodec_.generateHeader(output_, 1, req,
true );
682 callbacks_.expectMessage(
true, -1,
"/");
684 EXPECT_GT(downstreamCodec_.getReceivedFrameCount(), 1);
686 const auto& headers = callbacks_.msg->getHeaders();
689 EXPECT_EQ(callbacks_.headersComplete, 1);
690 EXPECT_EQ(callbacks_.messageComplete, 1);
702 EXPECT_EQ(callbacks_.headersComplete, 0);
703 EXPECT_EQ(callbacks_.messageComplete, 0);
712 upstreamCodec_.generateHeader(output_, 1, req);
721 EXPECT_EQ(callbacks_.headersComplete, 0);
722 EXPECT_EQ(callbacks_.messageComplete, 0);
726 EXPECT_EQ(downstreamCodec_.getReceivedFrameCount(), 2);
733 upstreamCodec_.generateHeader(output_, 1, req);
740 *((
uint32_t *)frame->writableData()) = 0xfa000000;
745 EXPECT_EQ(callbacks_.headersComplete, 0);
746 EXPECT_EQ(callbacks_.messageComplete, 0);
750 EXPECT_EQ(downstreamCodec_.getReceivedFrameCount(), 2);
756 upstreamCodec_.generateHeader(output_, 1, req);
760 auto fakeHeaders =
makeBuf(4134);
765 EXPECT_EQ(callbacks_.headersComplete, 0);
766 EXPECT_EQ(callbacks_.messageComplete, 0);
770 EXPECT_EQ(downstreamCodec_.getReceivedFrameCount(), 2);
779 EXPECT_EQ(callbacks_.headersComplete, 0);
780 EXPECT_EQ(callbacks_.messageComplete, 0);
783 EXPECT_TRUE(callbacks_.lastParseError->hasCodecStatusCode());
784 EXPECT_EQ(callbacks_.lastParseError->getCodecStatusCode(),
794 output_.append(
"wicked awesome!!!");
795 upstreamCodec_.generateHeader(output_, 1, req);
798 callbacks_.expectMessage(
false, 2,
"");
808 upstreamCodec_.generateHeader(output_, 1, req);
812 EXPECT_EQ(callbacks_.headersComplete, 0);
813 EXPECT_EQ(callbacks_.messageComplete, 0);
819 string data(
"abcde");
821 upstreamCodec_.generateBody(output_, 2,
std::move(buf),
826 EXPECT_EQ(callbacks_.headersComplete, 0);
827 EXPECT_EQ(callbacks_.messageComplete, 1);
845 EXPECT_EQ(callbacks_.headersComplete, 0);
846 EXPECT_EQ(callbacks_.messageComplete, 1);
851 EXPECT_EQ(callbacks_.data.move()->moveToFbString(), buf->moveToFbString());
855 const uint8_t badInput[] = {0x50, 0x52, 0x49, 0x20, 0x2a, 0x20, 0x48, 0x54,
856 0x54, 0x50, 0x2f, 0x32, 0x2e, 0x30, 0x0d, 0x0a,
857 0x0d, 0x0a, 0x53, 0x4d, 0x0d, 0x0a, 0x0d, 0x0a,
858 0x00, 0x00, 0x7e, 0x00, 0x6f, 0x6f, 0x6f, 0x6f,
862 0x01, 0x82, 0x87, 0x44, 0x87, 0x92, 0x97, 0x92,
863 0x92, 0x92, 0x7a, 0x0b, 0x41, 0x89, 0xf1, 0xe3,
864 0xc0, 0xf2, 0x9c, 0xdd, 0x90, 0xf4, 0xff, 0x40,
865 0x80, 0x84, 0x2d, 0x35, 0xa7, 0xd7};
867 output_.append(badInput,
sizeof(badInput));
868 EXPECT_EQ(output_.chainLength(),
sizeof(badInput));
875 0x00, 0x00, 0x0d, 0x01, 0xbe, 0x63, 0x0d, 0x0a, 0x0d, 0x0a, 0x00, 0x73,
876 0x00, 0x00, 0x06, 0x08, 0x72, 0x00, 0x24, 0x00, 0xfa, 0x4d, 0x0d
878 output_.append(badInput,
sizeof(badInput));
884 const uint8_t noAppByte[] = {0x50, 0x52, 0x49, 0x20, 0x2a, 0x20, 0x48, 0x54,
885 0x54, 0x50, 0x2f, 0x32, 0x2e, 0x30, 0x0d, 0x0a,
886 0x0d, 0x0a, 0x53, 0x4d, 0x0d, 0x0a, 0x0d, 0x0a,
887 0x00, 0x00, 0x56, 0x00, 0x5d, 0x00, 0x00, 0x00,
890 output_.append(noAppByte,
sizeof(noAppByte));
891 EXPECT_EQ(output_.chainLength(),
sizeof(noAppByte));
895 EXPECT_EQ(callbacks_.headersComplete, 0);
896 EXPECT_EQ(callbacks_.messageComplete, 0);
908 const size_t bufSize = 10;
910 const size_t padding = 10;
911 upstreamCodec_.generateBody(output_, 1, buf->clone(), padding,
true);
914 downstreamCodec_.setCallback(&mockCallback);
916 auto ingress = output_.move();
920 downstreamCodec_.onIngress(*ingress1);
924 const size_t bufSize = 10;
926 const size_t padding = 10;
927 upstreamCodec_.generateBody(output_, 1, buf->clone(), padding,
true);
930 auto ingress = output_.move();
934 size_t parsed = downstreamCodec_.onIngress(*ingress1);
939 parsed = downstreamCodec_.onIngress(*ingress2);
945 EXPECT_EQ(callbacks_.headersComplete, 0);
946 EXPECT_EQ(callbacks_.messageComplete, 1);
948 EXPECT_EQ(callbacks_.bodyLength, bufSize);
950 EXPECT_EQ(callbacks_.paddingBytes, padding + 1);
953 EXPECT_EQ(callbacks_.data.move()->moveToFbString(), buf->moveToFbString());
960 EXPECT_EQ(callbacks_.headersComplete, 0);
961 EXPECT_EQ(callbacks_.messageComplete, 0);
972 EXPECT_EQ(callbacks_.headersComplete, 0);
973 EXPECT_EQ(callbacks_.messageComplete, 0);
981 upstreamCodec_.generatePingRequest(output_);
982 upstreamCodec_.generatePingReply(output_, 17);
992 EXPECT_EQ(callbacks_.headersComplete, 0);
993 EXPECT_EQ(callbacks_.messageComplete, 0);
995 EXPECT_EQ(callbacks_.recvPingRequest, pingReq);
1003 upstreamCodec_.generateWindowUpdate(output_, 0, 10);
1005 upstreamCodec_.generateWindowUpdate(output_, 1, 12);
1009 EXPECT_EQ(callbacks_.windowUpdateCalls, 4);
1011 std::vector<uint32_t>({10, http2::kMaxWindowUpdateSize}));
1013 std::vector<uint32_t>({12, http2::kMaxWindowUpdateSize}));
1022 upstreamCodec_.generateWindowUpdate(output_,
streamID, 1);
1029 EXPECT_EQ(callbacks_.windowUpdateCalls, 0);
1031 EXPECT_EQ(callbacks_.lastParseError->getCodecStatusCode(),
1036 std::unique_ptr<folly::IOBuf> debugData =
1043 EXPECT_EQ(callbacks_.data.move()->moveToFbString(),
"debugData");
1049 std::unique_ptr<folly::IOBuf> debugData =
1059 SetUpUpstreamTest();
1064 EXPECT_TRUE(downstreamCodec_.isStreamIngressEgressAllowed(0));
1065 EXPECT_TRUE(downstreamCodec_.isStreamIngressEgressAllowed(1));
1066 EXPECT_TRUE(downstreamCodec_.isStreamIngressEgressAllowed(2));
1070 EXPECT_TRUE(downstreamCodec_.isStreamIngressEgressAllowed(0));
1071 EXPECT_FALSE(downstreamCodec_.isStreamIngressEgressAllowed(1));
1072 EXPECT_TRUE(downstreamCodec_.isStreamIngressEgressAllowed(2));
1074 EXPECT_TRUE(upstreamCodec_.isStreamIngressEgressAllowed(0));
1075 EXPECT_TRUE(upstreamCodec_.isStreamIngressEgressAllowed(1));
1076 EXPECT_TRUE(upstreamCodec_.isStreamIngressEgressAllowed(2));
1078 EXPECT_TRUE(upstreamCodec_.isStreamIngressEgressAllowed(0));
1079 EXPECT_FALSE(upstreamCodec_.isStreamIngressEgressAllowed(1));
1080 EXPECT_TRUE(upstreamCodec_.isStreamIngressEgressAllowed(2));
1086 EXPECT_TRUE(upstreamCodec_.isStreamIngressEgressAllowed(0));
1087 EXPECT_FALSE(upstreamCodec_.isStreamIngressEgressAllowed(1));
1088 EXPECT_FALSE(upstreamCodec_.isStreamIngressEgressAllowed(2));
1090 EXPECT_TRUE(downstreamCodec_.isStreamIngressEgressAllowed(0));
1091 EXPECT_FALSE(downstreamCodec_.isStreamIngressEgressAllowed(1));
1092 EXPECT_FALSE(downstreamCodec_.isStreamIngressEgressAllowed(2));
1096 SetUpUpstreamTest();
1097 std::unique_ptr<folly::IOBuf> debugData =
1104 auto ret = downstreamCodec_.generateGoaway(output_, 0,
1110 EXPECT_EQ(callbacks_.data.move()->moveToFbString(),
"debugData");
1116 auto settings = upstreamCodec_.getEgressSettings();
1118 upstreamCodec_.generateSettings(output_);
1124 upstreamCodec_.generateHeader(output_, 1, req,
true, &size);
1127 callbacks_.expectMessage(
true, 1,
"/");
1130 SetUpUpstreamTest();
1135 upstreamCodec_.generateHeader(output_, 3, req,
false, &size);
1137 upstreamCodec_.generateWindowUpdate(output_, 3, 100);
1140 upstreamCodec_.generatePriority(output_, 3,
1142 upstreamCodec_.generateEOM(output_, 3);
1148 downstreamCodec_.generatePushPromise(output_, 2, req, 1,
false, &size);
1153 downstreamCodec_.generateHeader(output_, 2, resp,
false, &size);
1155 downstreamCodec_.generateWindowUpdate(output_, 2, 100);
1167 downstreamCodec_.generatePriority(output_, 2,
1169 downstreamCodec_.generateEOM(output_, 2);
1173 downstreamCodec_.generateHeader(output_, 1, resp,
true, &size);
1178 callbacks_.expectMessage(
true, 1, 200);
1189 SetUpUpstreamTest();
1193 downstreamCodec_.generateHeader(output_, 1, resp);
1194 downstreamCodec_.generateEOM(output_, 1);
1196 callbacks_.expectMessage(
true, 1, 200);
1201 auto settings = upstreamCodec_.getEgressSettings();
1204 upstreamCodec_.generateSettings(output_);
1209 EXPECT_EQ(callbacks_.windowSize, 12345);
1215 upstreamCodec_.generateSettingsAck(output_);
1225 auto settings = upstreamCodec_.getEgressSettings();
1227 upstreamCodec_.generateSettings(output_);
1236 auto settings = downstreamCodec_.getEgressSettings();
1239 SetUpUpstreamTest();
1241 parseUpstream([&] (
IOBuf* ingress) {
1244 EXPECT_FALSE(upstreamCodec_.supportsPushTransactions());
1247 EXPECT_TRUE(downstreamCodec_.supportsPushTransactions());
1255 auto settings = upstreamCodec_.getEgressSettings();
1257 upstreamCodec_.generateSettings(output_);
1270 SetUpUpstreamTest();
1271 downstreamCodec_.generateHeader(output_, 1, resp);
1274 callbacks_.expectMessage(
false, 2, 200);
1275 const auto& headers = callbacks_.msg->getHeaders();
1281 auto settings = upstreamCodec_.getEgressSettings();
1284 upstreamCodec_.generateSettings(output_);
1297 upstreamCodec_.generateSettings(output_);
1303 SetUpUpstreamTest();
1304 downstreamCodec_.generateHeader(output_, 1, resp);
1310 EXPECT_EQ(callbacks_.headersComplete, 0);
1315 upstreamCodec_.generatePriority(output_, 1, pri);
1326 upstreamCodec_.generateHeader(output_, 1, req,
true );
1341 upstreamCodec_.generatePriority(output_, 1, pri);
1359 nodes_.push_back(
id);
1368 upstreamCodec_.addPriorityNodes(queue, output_, level);
1371 for (
int i = 0;
i < level;
i++) {
1377 upstreamCodec_.mapPriorityToDependency(level));
1379 upstreamCodec_.mapPriorityToDependency(level + 1));
1383 upstreamCodec_.generateSettings(output_);
1385 EXPECT_FALSE(upstreamCodec_.supportsPushTransactions());
1386 EXPECT_FALSE(downstreamCodec_.supportsPushTransactions());
1388 auto settings = upstreamCodec_.getEgressSettings();
1390 upstreamCodec_.generateSettings(output_);
1392 EXPECT_TRUE(upstreamCodec_.supportsPushTransactions());
1393 EXPECT_TRUE(downstreamCodec_.supportsPushTransactions());
1395 SetUpUpstreamTest();
1398 for (
auto i = 0;
i < 2;
i++) {
1403 downstreamCodec_.generatePushPromise(output_, pushStream, req, assocStream);
1406 callbacks_.expectMessage(
false, 2,
"/");
1407 EXPECT_EQ(callbacks_.assocStreamId, assocStream);
1408 EXPECT_EQ(callbacks_.headersCompleteId, pushStream);
1409 auto& headers = callbacks_.msg->getHeaders();
1417 downstreamCodec_.generateHeader(output_, pushStream, resp);
1420 callbacks_.expectMessage(
false, 2, 200);
1421 EXPECT_EQ(callbacks_.headersCompleteId, pushStream);
1424 EXPECT_EQ(
"text/plain", callbacks_.msg->getHeaders().getSingleOrEmpty(
1432 SetUpUpstreamTest();
1435 downstreamCodec_.generatePushPromise(output_, 2, req, 1);
1439 EXPECT_EQ(callbacks_.headersComplete, 0);
1440 EXPECT_EQ(callbacks_.messageComplete, 0);
1448 std::unique_ptr<folly::IOBuf> authRequest =
1450 upstreamCodec_.generateCertificateRequest(
1451 output_, requestId,
std::move(authRequest));
1454 EXPECT_EQ(callbacks_.certificateRequests, 1);
1455 EXPECT_EQ(callbacks_.lastCertRequestId, requestId);
1456 EXPECT_EQ(callbacks_.data.move()->moveToFbString(),
"authRequestData");
1463 std::unique_ptr<folly::IOBuf> authenticator =
1465 upstreamCodec_.generateCertificate(output_, certId,
std::move(authenticator));
1469 EXPECT_EQ(callbacks_.lastCertId, certId);
1470 EXPECT_EQ(callbacks_.data.move()->moveToFbString(),
"authenticatorData");
1477 downstreamCodec_.generateWindowUpdate(output_, 0, 10);
1480 EXPECT_EQ(callbacks_.headersComplete, 0);
1481 EXPECT_EQ(callbacks_.messageComplete, 0);
1489 string bigval(8691,
'!');
1490 bigval.append(8691,
' ');
1493 upstreamCodec_.generateHeader(output_, 1, req);
1496 callbacks_.expectMessage(
false, -1,
"/");
1497 const auto& headers = callbacks_.msg->getHeaders();
1498 EXPECT_EQ(bigval, headers.getSingleOrEmpty(
"x-headr"));
1500 EXPECT_EQ(callbacks_.headersComplete, 1);
1501 EXPECT_EQ(callbacks_.messageComplete, 0);
1505 upstreamCodec_.generateSettingsAck(output_);
1528 upstreamCodec_.generateHeader(output_, 1, req,
true );
1533 EXPECT_EQ(callbacks_.headersComplete, 0);
1534 EXPECT_EQ(callbacks_.lastParseError->getHttpStatusCode(), 400);
1544 upstreamCodec_.generateHeader(output_, 1, req,
true );
1549 EXPECT_EQ(callbacks_.headersComplete, 1);
1572 EXPECT_TRUE(downstreamCodec_.onIngressUpgradeMessage(req));
1576 EXPECT_TRUE(downstreamCodec_.onIngressUpgradeMessage(req));
1582 EXPECT_FALSE(downstreamCodec_.onIngressUpgradeMessage(req));
1588 EXPECT_FALSE(downstreamCodec_.onIngressUpgradeMessage(req));
1590 EXPECT_FALSE(downstreamCodec_.onIngressUpgradeMessage(req));
1595 EXPECT_FALSE(downstreamCodec_.onIngressUpgradeMessage(req));
1599 EXPECT_FALSE(downstreamCodec_.onIngressUpgradeMessage(req));
1604 EXPECT_FALSE(downstreamCodec_.onIngressUpgradeMessage(req));
1608 SetUpUpstreamTest();
1610 auto ws_enable = upstreamCodec_.getEgressSettings()->getSetting(
1613 upstreamCodec_.getEgressSettings()->setSetting(
1615 ws_enable = upstreamCodec_.getEgressSettings()->getSetting(
1620 upstreamCodec_.generateSettings(output_);
1622 EXPECT_EQ(1, upstreamCodec_.peerHasWebsockets());
1630 upstreamCodec_.generateHeader(output_, 1, req,
false);
1633 EXPECT_TRUE(callbacks_.msg->isIngressWebsocketUpgrade());
1634 EXPECT_NE(
nullptr, callbacks_.msg->getUpgradeProtocol());
1642 vector<proxygen::compress::Header> reqHeaders = {
1646 vector<proxygen::compress::Header> optionalHeaders = {
1653 for (
size_t i = 0;
i < optionalHeaders.size(); ++
i, stream += 2) {
1654 auto headers = reqHeaders;
1655 headers.push_back(optionalHeaders[
i]);
1656 auto encodedHeaders = headerCodec.
encode(headers);
1668 EXPECT_EQ(callbacks_.headersComplete, 0);
1669 EXPECT_EQ(callbacks_.messageComplete, 0);
1670 EXPECT_EQ(callbacks_.streamErrors, optionalHeaders.size());
1678 vector<proxygen::compress::Header> headers = {
1686 auto encodedHeaders = headerCodec.
encode(headers);
1696 EXPECT_EQ(callbacks_.headersComplete, 0);
1697 EXPECT_EQ(callbacks_.messageComplete, 0);
1704 SetUpUpstreamTest();
1711 upstreamCodec_.generateHeader(output_, 1, req,
false);
1718 downstreamCodec_.generateHeader(output_, 1, resp);
1724 class CallbackTypeTracker {
1725 std::set<uint8_t> types;
1731 bool isAllFrameTypesReceived() {
1747 EXPECT_TRUE(types.find(static_cast<uint8_t>(type)) != types.end())
1748 <<
"callback missing for type " << static_cast<uint8_t>(type);
1754 CallbackTypeTracker callbackTypeTracker;
1757 upstreamCodec_.setCallback(&mockCallback);
1758 downstreamCodec_.setCallback(&mockCallback);
1763 string data(
"abcde");
1765 upstreamCodec_.generateBody(output_, 2,
std::move(buf),
1771 upstreamCodec_.generateHeader(output_, 1, req,
true, &size);
1773 upstreamCodec_.generatePriority(output_, 3,
1776 upstreamCodec_.generateSettings(output_);
1777 downstreamCodec_.generatePushPromise(output_, 2, req, 1);
1778 upstreamCodec_.generatePingRequest(output_);
1780 std::unique_ptr<folly::IOBuf> debugData =
1785 upstreamCodec_.generateWindowUpdate(output_, 0, 10);
1789 downstreamCodec_.generateExHeader(output_, stream, req,
1794 upstreamCodec_.generateHeader(output_, 1, req,
true );
1796 EXPECT_TRUE(callbackTypeTracker.isAllFrameTypesReceived());
1802 upstreamCodec_.generateHeader(output_, 1, req);
1804 string data(
"abcde");
1806 upstreamCodec_.generateBody(
1810 trailers.
add(
"x-trailer-1",
"pico-de-gallo");
1811 upstreamCodec_.generateTrailers(output_, 1, trailers);
1816 EXPECT_EQ(callbacks_.headersComplete, 1);
1820 EXPECT_NE(
nullptr, callbacks_.msg->getTrailers());
1822 callbacks_.msg->getTrailers()->getSingleOrEmpty(
"x-trailer-1"));
1823 EXPECT_EQ(callbacks_.messageComplete, 1);
1827 EXPECT_EQ(downstreamCodec_.getReceivedFrameCount(), 3);
1834 upstreamCodec_.generateHeader(output_, 1, req);
1836 string data(
"abcde");
1838 upstreamCodec_.generateBody(
1843 std::vector<proxygen::compress::Header> trailers = {
1845 auto encodedTrailers = headerCodec.
encode(trailers);
1857 EXPECT_EQ(callbacks_.headersComplete, 1);
1861 EXPECT_EQ(
nullptr, callbacks_.msg->getTrailers());
1862 EXPECT_EQ(callbacks_.messageComplete, 0);
1869 upstreamCodec_.generateHeader(output_, 1, req);
1872 trailers.
add(
"x-trailer-1",
"pico-de-gallo");
1873 upstreamCodec_.generateTrailers(output_, 1, trailers);
1878 EXPECT_EQ(callbacks_.headersComplete, 1);
1882 EXPECT_NE(
nullptr, callbacks_.msg->getTrailers());
1884 callbacks_.msg->getTrailers()->getSingleOrEmpty(
"x-trailer-1"));
1885 EXPECT_EQ(callbacks_.messageComplete, 1);
1889 EXPECT_EQ(downstreamCodec_.getReceivedFrameCount(), 2);
1895 upstreamCodec_.generateHeader(output_, 1, req);
1898 trailers.
add(
"x-trailer-1",
"pico-de-gallo");
1899 trailers.
add(
"x-huge-trailer",
1901 upstreamCodec_.generateTrailers(output_, 1, trailers);
1906 EXPECT_EQ(callbacks_.headersComplete, 1);
1907 EXPECT_EQ(callbacks_.messageComplete, 1);
1912 EXPECT_NE(callbacks_.msg->getTrailers(),
nullptr);
1914 callbacks_.msg->getTrailers()->getSingleOrEmpty(
"x-trailer-1"));
1916 callbacks_.msg->getTrailers()->getSingleOrEmpty(
"x-huge-trailer"));
1918 EXPECT_EQ(downstreamCodec_.getReceivedFrameCount(), 3);
1923 SetUpUpstreamTest();
1928 downstreamCodec_.generateHeader(output_, 1, resp);
1930 string data(
"abcde");
1932 downstreamCodec_.generateBody(
1936 trailers.
add(
"x-trailer-1",
"pico-de-gallo");
1937 trailers.
add(
"x-trailer-2",
"chicken-kyiv");
1938 downstreamCodec_.generateTrailers(output_, 1, trailers);
1942 callbacks_.expectMessage(
true, 2, 200);
1945 const auto& headers = callbacks_.msg->getHeaders();
1949 EXPECT_NE(
nullptr, callbacks_.msg->getTrailers());
1951 callbacks_.msg->getTrailers()->getSingleOrEmpty(
"x-trailer-1"));
1953 callbacks_.msg->getTrailers()->getSingleOrEmpty(
"x-trailer-2"));
1955 EXPECT_EQ(upstreamCodec_.getReceivedFrameCount(), 4);
1960 SetUpUpstreamTest();
1965 downstreamCodec_.generateHeader(output_, 1, resp);
1968 trailers.
add(
"x-trailer-1",
"pico-de-gallo");
1969 downstreamCodec_.generateTrailers(output_, 1, trailers);
1973 callbacks_.expectMessage(
true, 2, 200);
1976 const auto& headers = callbacks_.msg->getHeaders();
1980 EXPECT_NE(
nullptr, callbacks_.msg->getTrailers());
1982 callbacks_.msg->getTrailers()->getSingleOrEmpty(
"x-trailer-1"));
1984 EXPECT_EQ(upstreamCodec_.getReceivedFrameCount(), 3);
1989 SetUpUpstreamTest();
1994 downstreamCodec_.generateHeader(output_, 1, resp);
1996 string data(
"abcde");
1998 downstreamCodec_.generateBody(
2003 std::vector<proxygen::compress::Header> trailers = {
2005 auto encodedTrailers = headerCodec.
encode(trailers);
2016 EXPECT_EQ(callbacks_.headersComplete, 1);
2018 EXPECT_EQ(
nullptr, callbacks_.msg->getTrailers());
2024 SetUpUpstreamTest();
2027 downstreamCodec_.generateHeader(output_, 1, resp);
2030 trailers.
add(
"x-trailer-1",
"pico-de-gallo");
2031 trailers.
add(
"x-huge-trailer",
2033 downstreamCodec_.generateTrailers(output_, 1, trailers);
2038 EXPECT_EQ(callbacks_.headersComplete, 1);
2039 EXPECT_EQ(callbacks_.messageComplete, 1);
2043 EXPECT_EQ(callbacks_.msg->getStatusCode(), 200);
2045 EXPECT_NE(
nullptr, callbacks_.msg->getTrailers());
2047 callbacks_.msg->getTrailers()->getSingleOrEmpty(
"x-trailer-1"));
2049 callbacks_.msg->getTrailers()->getSingleOrEmpty(
"x-huge-trailer"));
2051 EXPECT_EQ(upstreamCodec_.getReceivedFrameCount(), 4);
2056 SetUpUpstreamTest();
2059 downstreamCodec_.generateHeader(output_, 1, resp);
2062 trailers.
add(
"x-trailer-1",
"pico-de-gallo");
2063 trailers.
add(
"x-huge-trailer",
2065 downstreamCodec_.generateTrailers(output_, 1, trailers);
2075 EXPECT_EQ(callbacks_.headersComplete, 1);
2076 EXPECT_EQ(callbacks_.messageComplete, 0);
2080 EXPECT_EQ(upstreamCodec_.getReceivedFrameCount(), 4);
std::unique_ptr< folly::IOBuf > makeBuf(uint32_t size)
static const folly::Optional< uint8_t > NoPadding
void writeFrameHeaderManual(IOBufQueue &queue, uint32_t length, uint8_t type, uint8_t flags, uint32_t stream)
const uint32_t kFrameHeaderSize
const uint8_t kBufEmptyHeader[]
size_t writeHeaders(IOBufQueue &queue, std::unique_ptr< IOBuf > headers, uint32_t stream, folly::Optional< PriorityUpdate > priority, folly::Optional< uint8_t > padding, bool endStream, bool endHeaders) noexcept
void setStatusMessage(T &&msg)
#define EXPECT_DEATH_NO_CORE(token, regex)
#define EXPECT_EQ(val1, val2)
constexpr detail::Map< Move > move
HTTPMessage getBigGetRequest(const std::string &url)
void testHeaderListSize(bool oversized)
const uint32_t kMaxFramePayloadLength
void setNextEgressStreamId(StreamID nextEgressStreamID)
static http_parser_settings settings
—— Concurrent Priority Queue Implementation ——
void addPriorityNode(HTTPCodec::StreamID id, HTTPCodec::StreamID) override
std::vector< HTTPCodec::StreamID > nodes_
bool isReusable() const override
void testFrameSizeLimit(bool oversized)
size_t writeContinuation(IOBufQueue &queue, uint32_t stream, bool endHeaders, std::unique_ptr< IOBuf > headers) noexcept
size_t writeSettings(IOBufQueue &queue, const std::deque< SettingPair > &settings)
const uint32_t kMaxWindowUpdateSize
static void requestUpgrade(HTTPMessage &request)
const uint32_t kMaxFramePayloadLengthMin
constexpr auto size(C const &c) -> decltype(c.size())
bool checkForHeaderToken(const HTTPHeaderCode headerCode, char const *token, bool caseSensitive) const
void setSecure(bool secure)
void setHTTP2Priority(HTTPPriority h2Pri)
PolymorphicAction< internal::InvokeAction< FunctionImpl > > Invoke(FunctionImpl function_impl)
const uint32_t kFrameWindowUpdateSize
StreamID createStream() override
TEST(HTTP2CodecConstantsTest, HTTPContantsAreCommonHeaders)
std::pair< SettingsId, uint32_t > SettingPair
HTTPHeaders & getHeaders()
const std::string kProtocolSettingsHeader
void setMethod(HTTPMethod method)
std::size_t computeChainDataLength() const
std::unique_ptr< IOBuf > copyBuffer(const folly::IOBuf &buf)
std::tuple< uint32_t, bool, uint8_t > HTTPPriority
#define EXPECT_TRUE(condition)
HTTPMessage getGetRequest(const std::string &url)
size_t writeGoaway(IOBufQueue &queue, uint32_t lastStreamID, ErrorCode errorCode, std::unique_ptr< IOBuf > debugData) noexcept
#define EXPECT_NE(val1, val2)
HTTPMessage getPostRequest(uint32_t contentLength)
#define EXPECT_CALL(obj, call)
const std::string kConnectionPreface
const internal::AnythingMatcher _
TEST_F(HeaderTableTests, IndexTranslation)
size_t parse(T *codec, const uint8_t *inputData, uint32_t length, int32_t atOnce=0, std::function< bool()> stopFn=[]{return false;})
#define EXPECT_FALSE(condition)
std::unique_ptr< folly::IOBuf > encode(std::vector< compress::Header > &headers) noexcept
void setEgressWebsocketUpgrade()
static std::unique_ptr< IOBuf > copyBuffer(const void *buf, std::size_t size, std::size_t headroom=0, std::size_t minTailroom=0)
static constexpr uint64_t data[1]
#define EXPECT_GT(val1, val2)
void setSetting(SettingsId id, SettingsValue val)
void setStatusCode(uint16_t status)