blob: c9ccd0f7853d924d6aaef33ccdaa089cf6d31dfb [file] [log] [blame]
#include "third_party/nghttp2/src/lib/includes/nghttp2/nghttp2.h"
#include "http2/adapter/mock_nghttp2_callbacks.h"
#include "http2/adapter/test_frame_sequence.h"
#include "http2/adapter/test_utils.h"
#include "common/platform/api/quiche_test.h"
namespace http2 {
namespace adapter {
namespace test {
namespace {
using testing::_;
enum FrameType {
DATA,
HEADERS,
PRIORITY,
RST_STREAM,
SETTINGS,
PUSH_PROMISE,
PING,
GOAWAY,
WINDOW_UPDATE,
};
nghttp2_option* GetOptions() {
nghttp2_option* options;
nghttp2_option_new(&options);
// Set some common options for compatibility.
nghttp2_option_set_no_closed_streams(options, 1);
nghttp2_option_set_no_auto_window_update(options, 1);
nghttp2_option_set_max_send_header_block_length(options, 0x2000000);
nghttp2_option_set_max_outbound_ack(options, 10000);
return options;
}
// Verifies nghttp2 behavior when acting as a client.
TEST(Nghttp2ClientTest, ClientReceivesUnexpectedHeaders) {
testing::StrictMock<MockNghttp2Callbacks> mock_callbacks;
auto nghttp2_callbacks = MockNghttp2Callbacks::GetCallbacks();
nghttp2_option* options = GetOptions();
nghttp2_session* ptr;
nghttp2_session_client_new2(&ptr, nghttp2_callbacks.get(), &mock_callbacks,
options);
auto client_session = MakeSessionPtr(ptr);
const std::string initial_frames = TestFrameSequence()
.ServerPreface()
.Ping(42)
.WindowUpdate(0, 1000)
.Serialize();
testing::InSequence seq;
EXPECT_CALL(mock_callbacks, OnBeginFrame(HasFrameHeader(0, SETTINGS, 0)));
EXPECT_CALL(mock_callbacks, OnFrameRecv(IsSettings(testing::IsEmpty())));
EXPECT_CALL(mock_callbacks, OnBeginFrame(HasFrameHeader(0, PING, 0)));
EXPECT_CALL(mock_callbacks, OnFrameRecv(IsPing(42)));
EXPECT_CALL(mock_callbacks,
OnBeginFrame(HasFrameHeader(0, WINDOW_UPDATE, 0)));
EXPECT_CALL(mock_callbacks, OnFrameRecv(IsWindowUpdate(1000)));
nghttp2_session_mem_recv(client_session.get(),
ToUint8Ptr(initial_frames.data()),
initial_frames.size());
const std::string unexpected_stream_frames =
TestFrameSequence()
.Headers(1,
{{":status", "200"},
{"server", "my-fake-server"},
{"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
/*fin=*/false)
.Data(1, "This is the response body.")
.RstStream(3, Http2ErrorCode::INTERNAL_ERROR)
.GoAway(5, Http2ErrorCode::ENHANCE_YOUR_CALM, "calm down!!")
.Serialize();
EXPECT_CALL(mock_callbacks, OnBeginFrame(HasFrameHeader(1, HEADERS, _)));
EXPECT_CALL(mock_callbacks, OnInvalidFrameRecv(IsHeaders(1, _, _), _));
// No events from the DATA, RST_STREAM or GOAWAY.
nghttp2_session_mem_recv(client_session.get(),
ToUint8Ptr(unexpected_stream_frames.data()),
unexpected_stream_frames.size());
nghttp2_option_del(options);
}
} // namespace
} // namespace test
} // namespace adapter
} // namespace http2