1
0
mirror of https://github.com/facebook/proxygen.git synced 2026-10-24 01:33:54 +03:00

Don't generate or accept SETTINGS with ENABLE_PUSH for servers

Summary: This is a violation of the spec.  Reported by Apple

Test Plan: New unit test

Reviewed By: xiaosophiawang@fb.com

Subscribers: xiaosophiawang, noamler, bmatheny

FB internal diff: D2160494

Tasks: 7431234
This commit is contained in:
Alan Frindell
2015-06-16 15:37:14 -07:00
committed by Praveen Kumar Ramakrishnan
parent 9a9c7539ed
commit 2174ac22d2
3 changed files with 33 additions and 4 deletions

View File

@@ -534,7 +534,9 @@ ErrorCode HTTP2Codec::parseSettings(Cursor& cursor) {
headerCodec_.setEncoderHeaderTableSize(setting.second);
break;
case SettingsId::ENABLE_PUSH:
if (setting.second != 0 && setting.second != 1) {
if ((setting.second != 0 && setting.second != 1) ||
(setting.second == 1 &&
transportDirection_ == TransportDirection::UPSTREAM)) {
VLOG(4) << "Invalid ENABLE_PUSH setting=" << setting.second;
return ErrorCode::PROTOCOL_ERROR;
}
@@ -934,12 +936,19 @@ size_t HTTP2Codec::generateSettings(folly::IOBufQueue& writeBuf) {
std::deque<SettingPair> settings;
for (auto& setting: egressSettings_.getAllSettings()) {
if (setting.isSet) {
settings.push_back(SettingPair(setting.id, setting.value));
if (setting.id == SettingsId::HEADER_TABLE_SIZE) {
headerCodec_.setDecoderHeaderTableMaxSize(setting.value);
} else if (setting.id == SettingsId::MAX_HEADER_LIST_SIZE) {
headerCodec_.setMaxUncompressed(setting.value);
} else if (setting.id == SettingsId::ENABLE_PUSH) {
if (transportDirection_ == TransportDirection::DOWNSTREAM) {
// HTTP/2 spec says downstream must not enable push
CHECK_EQ(setting.value, 0);
} else {
CHECK(setting.value == 0 || setting.value == 1);
}
}
settings.push_back(SettingPair(setting.id, setting.value));
}
}
VLOG(4) << "generating " << (unsigned)settings.size() << " settings";

View File

@@ -194,7 +194,7 @@ public:
};
HTTPSettings egressSettings_{
{ SettingsId::HEADER_TABLE_SIZE, 4096 },
{ SettingsId::ENABLE_PUSH, 1 },
{ SettingsId::ENABLE_PUSH, 0 },
{ SettingsId::MAX_FRAME_SIZE, 16384 },
{ SettingsId::MAX_HEADER_LIST_SIZE, 1 << 17 }, // same as SPDYCodec
};

View File

@@ -722,6 +722,24 @@ TEST_F(HTTP2CodecTest, BadSettings) {
EXPECT_EQ(callbacks_.sessionErrors, 1);
}
TEST_F(HTTP2CodecTest, BadPushSettings) {
auto settings = downstreamCodec_.getEgressSettings();
settings->clearSettings();
settings->setSetting(SettingsId::ENABLE_PUSH, 0);
SetUpUpstreamTest();
parseUpstream([&] (IOBuf* ingress) {
// set ENABLE_PUSH to 1
folly::io::RWPrivateCursor c(ingress);
c.skip(http2::kFrameHeaderSize + sizeof(uint16_t));
c.writeBE<uint32_t>(1);
});
EXPECT_EQ(callbacks_.settings, 0);
EXPECT_EQ(callbacks_.streamErrors, 0);
EXPECT_EQ(callbacks_.sessionErrors, 1);
}
TEST_F(HTTP2CodecTest, SettingsTableSize) {
auto settings = upstreamCodec_.getEgressSettings();
settings->setSetting(SettingsId::HEADER_TABLE_SIZE, 8192);
@@ -789,6 +807,8 @@ TEST_F(HTTP2CodecTest, BasicPriority) {
}
TEST_F(HTTP2CodecTest, BasicPushPromise) {
auto settings = upstreamCodec_.getEgressSettings();
settings->setSetting(SettingsId::ENABLE_PUSH, 1);
SetUpUpstreamTest();
HTTPMessage req = getGetRequest();
req.getHeaders().add("user-agent", "coolio");
@@ -802,12 +822,12 @@ TEST_F(HTTP2CodecTest, BasicPushPromise) {
}
TEST_F(HTTP2CodecTest, BadPushPromise) {
// ENABLE_PUSH is now 0 by default
SetUpUpstreamTest();
HTTPMessage req = getGetRequest();
req.getHeaders().add("user-agent", "coolio");
downstreamCodec_.generateHeader(output_, 2, req, 1);
upstreamCodec_.getEgressSettings()->setSetting(SettingsId::ENABLE_PUSH, 0);
parseUpstream();
EXPECT_EQ(callbacks_.messageBegin, 0);
EXPECT_EQ(callbacks_.headersComplete, 0);