summaryrefslogtreecommitdiff
path: root/chromium/net/third_party/quiche/src/quiche/http2/adapter/nghttp2_adapter_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/third_party/quiche/src/quiche/http2/adapter/nghttp2_adapter_test.cc')
-rw-r--r--chromium/net/third_party/quiche/src/quiche/http2/adapter/nghttp2_adapter_test.cc163
1 files changed, 161 insertions, 2 deletions
diff --git a/chromium/net/third_party/quiche/src/quiche/http2/adapter/nghttp2_adapter_test.cc b/chromium/net/third_party/quiche/src/quiche/http2/adapter/nghttp2_adapter_test.cc
index 8647b027895..9bf5bd219fe 100644
--- a/chromium/net/third_party/quiche/src/quiche/http2/adapter/nghttp2_adapter_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/http2/adapter/nghttp2_adapter_test.cc
@@ -4744,6 +4744,81 @@ TEST(NgHttp2AdapterTest, ServerSubmitResponse) {
EXPECT_GT(adapter->GetHpackEncoderDynamicTableSize(), 0);
}
+TEST(NgHttp2AdapterTest, ServerSubmitResponseWithResetFromClient) {
+ DataSavingVisitor visitor;
+ auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+ EXPECT_FALSE(adapter->want_write());
+
+ const std::string frames = TestFrameSequence()
+ .ClientPreface()
+ .Headers(1,
+ {{":method", "GET"},
+ {":scheme", "https"},
+ {":authority", "example.com"},
+ {":path", "/this/is/request/one"}},
+ /*fin=*/true)
+ .Serialize();
+ testing::InSequence s;
+
+ // Client preface (empty SETTINGS)
+ EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+ EXPECT_CALL(visitor, OnSettingsStart());
+ EXPECT_CALL(visitor, OnSettingsEnd());
+ // Stream 1
+ EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+ EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+ EXPECT_CALL(visitor, OnHeaderForStream).Times(4);
+ EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+ EXPECT_CALL(visitor, OnEndStream(1));
+
+ const int64_t result = adapter->ProcessBytes(frames);
+ EXPECT_EQ(frames.size(), result);
+
+ EXPECT_EQ(1, adapter->GetHighestReceivedStreamId());
+
+ // Server will want to send a SETTINGS ack.
+ EXPECT_TRUE(adapter->want_write());
+
+ EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+ EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+ int send_result = adapter->Send();
+ EXPECT_EQ(0, send_result);
+ EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
+ visitor.Clear();
+
+ EXPECT_FALSE(adapter->want_write());
+ const absl::string_view kBody = "This is an example response body.";
+ auto body1 = absl::make_unique<TestDataFrameSource>(visitor, true);
+ body1->AppendPayload(kBody);
+ int submit_result = adapter->SubmitResponse(
+ 1,
+ ToHeaders({{":status", "404"},
+ {"x-comment", "I have no idea what you're talking about."}}),
+ std::move(body1));
+ EXPECT_EQ(submit_result, 0);
+ EXPECT_TRUE(adapter->want_write());
+
+ // Client resets the stream before the server can send the response.
+ const std::string reset =
+ TestFrameSequence().RstStream(1, Http2ErrorCode::CANCEL).Serialize();
+ EXPECT_CALL(visitor, OnFrameHeader(1, 4, RST_STREAM, 0));
+ EXPECT_CALL(visitor, OnRstStream(1, Http2ErrorCode::CANCEL));
+ EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::CANCEL));
+ const int64_t reset_result = adapter->ProcessBytes(reset);
+ EXPECT_EQ(reset.size(), static_cast<size_t>(reset_result));
+
+ // Outbound HEADERS and DATA are dropped.
+ EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, _)).Times(0);
+ EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, _, _)).Times(0);
+ EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, _, _)).Times(0);
+
+ send_result = adapter->Send();
+ EXPECT_EQ(0, send_result);
+
+ EXPECT_THAT(visitor.data(), testing::IsEmpty());
+}
+
// Should also test: client attempts shutdown, server attempts shutdown after an
// explicit GOAWAY.
TEST(NgHttp2AdapterTest, ServerSendsShutdown) {
@@ -5883,12 +5958,12 @@ TEST(NgHttp2AdapterTest, AutomaticPingAcksDisabled) {
EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
}
-TEST(NgHttp2AdapterTest, InvalidMaxFrameSize) {
+TEST(NgHttp2AdapterTest, InvalidMaxFrameSizeSetting) {
DataSavingVisitor visitor;
auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
const std::string frames =
- TestFrameSequence().ClientPreface({{MAX_FRAME_SIZE, 3}}).Serialize();
+ TestFrameSequence().ClientPreface({{MAX_FRAME_SIZE, 3u}}).Serialize();
testing::InSequence s;
// Client preface
@@ -5912,6 +5987,90 @@ TEST(NgHttp2AdapterTest, InvalidMaxFrameSize) {
EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
}
+TEST(OgHttp2AdapterTest, InvalidPushSetting) {
+ DataSavingVisitor visitor;
+ auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+ const std::string frames =
+ TestFrameSequence().ClientPreface({{ENABLE_PUSH, 3u}}).Serialize();
+ testing::InSequence s;
+
+ // Client preface
+ EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
+ EXPECT_CALL(visitor, OnInvalidFrame(0, _));
+
+ const int64_t read_result = adapter->ProcessBytes(frames);
+ EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
+
+ EXPECT_TRUE(adapter->want_write());
+
+ EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+ EXPECT_CALL(visitor,
+ OnFrameSent(GOAWAY, 0, _, 0x0,
+ static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+
+ int send_result = adapter->Send();
+ EXPECT_EQ(0, send_result);
+ EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
+}
+
+TEST(NgHttp2AdapterTest, InvalidConnectProtocolSetting) {
+ DataSavingVisitor visitor;
+ auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+ const std::string frames = TestFrameSequence()
+ .ClientPreface({{ENABLE_CONNECT_PROTOCOL, 3u}})
+ .Serialize();
+ testing::InSequence s;
+
+ EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
+ EXPECT_CALL(
+ visitor,
+ OnInvalidFrame(0, Http2VisitorInterface::InvalidFrameError::kProtocol));
+
+ int64_t read_result = adapter->ProcessBytes(frames);
+ EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
+
+ EXPECT_TRUE(adapter->want_write());
+
+ EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+ EXPECT_CALL(visitor,
+ OnFrameSent(GOAWAY, 0, _, 0x0,
+ static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+
+ int send_result = adapter->Send();
+ EXPECT_EQ(0, send_result);
+ EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
+
+ auto adapter2 = NgHttp2Adapter::CreateServerAdapter(visitor);
+ const std::string frames2 = TestFrameSequence()
+ .ClientPreface({{ENABLE_CONNECT_PROTOCOL, 1}})
+ .Settings({{ENABLE_CONNECT_PROTOCOL, 0}})
+ .Serialize();
+
+ EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
+ EXPECT_CALL(visitor, OnSettingsStart());
+ EXPECT_CALL(visitor, OnSetting(Http2Setting{ENABLE_CONNECT_PROTOCOL, 1u}));
+ EXPECT_CALL(visitor, OnSettingsEnd());
+ EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
+ EXPECT_CALL(visitor, OnSettingsStart());
+ // Surprisingly, nghttp2 allows this behavior, which is prohibited in RFC
+ // 8441.
+ EXPECT_CALL(visitor, OnSetting(Http2Setting{ENABLE_CONNECT_PROTOCOL, 0u}));
+ EXPECT_CALL(visitor, OnSettingsEnd());
+
+ read_result = adapter2->ProcessBytes(frames2);
+ EXPECT_EQ(static_cast<size_t>(read_result), frames2.size());
+
+ EXPECT_TRUE(adapter2->want_write());
+
+ EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+ EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+ EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+ EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+ adapter2->Send();
+}
+
TEST(NgHttp2AdapterTest, ServerForbidsProtocolPseudoheaderBeforeAck) {
DataSavingVisitor visitor;
auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);