blob: 25423114fabc54fe8f93dd402a9d50a8f89369da [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
QUICHE team5be974e2020-12-29 18:35:24 -05005#include "quic/tools/quic_simple_server_stream.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -05006
7#include <list>
8#include <memory>
9#include <utility>
10
vasilvv035fe3d2020-10-20 08:38:37 -070011#include "absl/base/macros.h"
bnc38b5aed2021-04-02 10:57:41 -070012#include "absl/memory/memory.h"
vasilvv6c9e9c32020-10-08 08:16:57 -070013#include "absl/strings/string_view.h"
vasilvv7df418b2020-10-13 13:47:09 -070014#include "absl/types/optional.h"
QUICHE team5be974e2020-12-29 18:35:24 -050015#include "quic/core/crypto/null_encrypter.h"
16#include "quic/core/http/http_encoder.h"
17#include "quic/core/http/spdy_utils.h"
18#include "quic/core/quic_error_codes.h"
19#include "quic/core/quic_types.h"
20#include "quic/core/quic_utils.h"
21#include "quic/platform/api/quic_expect_bug.h"
QUICHE team5be974e2020-12-29 18:35:24 -050022#include "quic/platform/api/quic_socket_address.h"
23#include "quic/platform/api/quic_test.h"
24#include "quic/test_tools/crypto_test_utils.h"
25#include "quic/test_tools/quic_config_peer.h"
26#include "quic/test_tools/quic_connection_peer.h"
27#include "quic/test_tools/quic_session_peer.h"
28#include "quic/test_tools/quic_spdy_session_peer.h"
29#include "quic/test_tools/quic_stream_peer.h"
30#include "quic/test_tools/quic_test_utils.h"
31#include "quic/tools/quic_backend_response.h"
32#include "quic/tools/quic_memory_cache_backend.h"
33#include "quic/tools/quic_simple_server_session.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050034
35using testing::_;
36using testing::AnyNumber;
37using testing::InSequence;
38using testing::Invoke;
QUICHE teama6ef0a62019-03-07 20:34:33 -050039using testing::StrictMock;
QUICHE teama6ef0a62019-03-07 20:34:33 -050040
41namespace quic {
42namespace test {
43
44const size_t kFakeFrameLen = 60;
45const size_t kErrorLength = strlen(QuicSimpleServerStream::kErrorResponseBody);
46const size_t kDataFrameHeaderLength = 2;
47
48class TestStream : public QuicSimpleServerStream {
49 public:
50 TestStream(QuicStreamId stream_id,
51 QuicSpdySession* session,
52 StreamType type,
53 QuicSimpleServerBackend* quic_simple_server_backend)
54 : QuicSimpleServerStream(stream_id,
55 session,
56 type,
57 quic_simple_server_backend) {}
58
59 ~TestStream() override = default;
60
wub713afae2020-04-27 07:48:31 -070061 MOCK_METHOD(void, WriteHeadersMock, (bool fin), ());
QUICHE teamb0aaa822021-03-15 16:49:08 -070062 MOCK_METHOD(void, WriteEarlyHintsHeadersMock, (bool fin), ());
QUICHE teama6ef0a62019-03-07 20:34:33 -050063
QUICHE teamb0aaa822021-03-15 16:49:08 -070064 size_t WriteHeaders(spdy::Http2HeaderBlock header_block,
QUICHE teama6ef0a62019-03-07 20:34:33 -050065 bool fin,
66 QuicReferenceCountedPointer<QuicAckListenerInterface>
dschinazi17d42422019-06-18 16:35:07 -070067 /*ack_listener*/) override {
QUICHE teamb0aaa822021-03-15 16:49:08 -070068 if (header_block[":status"] == "103") {
69 WriteEarlyHintsHeadersMock(fin);
70 } else {
71 WriteHeadersMock(fin);
72 }
QUICHE teama6ef0a62019-03-07 20:34:33 -050073 return 0;
74 }
75
76 // Expose protected QuicSimpleServerStream methods.
77 void DoSendResponse() { SendResponse(); }
78 void DoSendErrorResponse() { SendErrorResponse(); }
79
QUICHE team82103522020-10-22 08:15:09 -070080 spdy::Http2HeaderBlock* mutable_headers() { return &request_headers_; }
vasilvvc48c8712019-03-11 13:38:16 -070081 void set_body(std::string body) { body_ = std::move(body); }
82 const std::string& body() const { return body_; }
QUICHE teama6ef0a62019-03-07 20:34:33 -050083 int content_length() const { return content_length_; }
dschinazi9a630bf2020-11-25 11:34:29 -080084 bool send_response_was_called() const { return send_response_was_called_; }
dschinazi8d63c922021-03-01 14:31:49 -080085 bool send_error_response_was_called() const {
86 return send_error_response_was_called_;
87 }
QUICHE teama6ef0a62019-03-07 20:34:33 -050088
vasilvv6c9e9c32020-10-08 08:16:57 -070089 absl::string_view GetHeader(absl::string_view key) const {
QUICHE teama6ef0a62019-03-07 20:34:33 -050090 auto it = request_headers_.find(key);
vasilvvf8035162021-02-01 14:49:14 -080091 QUICHE_DCHECK(it != request_headers_.end());
QUICHE teama6ef0a62019-03-07 20:34:33 -050092 return it->second;
93 }
dschinazi9a630bf2020-11-25 11:34:29 -080094
95 protected:
96 void SendResponse() override {
97 send_response_was_called_ = true;
98 QuicSimpleServerStream::SendResponse();
99 }
100
dschinazi8d63c922021-03-01 14:31:49 -0800101 void SendErrorResponse() override {
102 send_error_response_was_called_ = true;
103 QuicSimpleServerStream::SendErrorResponse();
104 }
105
dschinazi9a630bf2020-11-25 11:34:29 -0800106 private:
107 bool send_response_was_called_ = false;
dschinazi8d63c922021-03-01 14:31:49 -0800108 bool send_error_response_was_called_ = false;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500109};
110
111namespace {
112
113class MockQuicSimpleServerSession : public QuicSimpleServerSession {
114 public:
115 const size_t kMaxStreamsForTest = 100;
116
117 MockQuicSimpleServerSession(
118 QuicConnection* connection,
119 MockQuicSessionVisitor* owner,
120 MockQuicCryptoServerStreamHelper* helper,
121 QuicCryptoServerConfig* crypto_config,
122 QuicCompressedCertsCache* compressed_certs_cache,
123 QuicSimpleServerBackend* quic_simple_server_backend)
124 : QuicSimpleServerSession(DefaultQuicConfig(),
125 CurrentSupportedVersions(),
126 connection,
127 owner,
128 helper,
129 crypto_config,
130 compressed_certs_cache,
131 quic_simple_server_backend) {
fkastenholz305e1732019-06-18 05:01:22 -0700132 if (VersionHasIetfQuicFrames(connection->transport_version())) {
fkastenholzd3a1de92019-05-15 07:00:07 -0700133 QuicSessionPeer::SetMaxOpenIncomingUnidirectionalStreams(
134 this, kMaxStreamsForTest);
135 QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(
136 this, kMaxStreamsForTest);
137 } else {
138 QuicSessionPeer::SetMaxOpenIncomingStreams(this, kMaxStreamsForTest);
139 QuicSessionPeer::SetMaxOpenOutgoingStreams(this, kMaxStreamsForTest);
140 }
renjietang41a1b412020-02-27 15:05:14 -0800141 ON_CALL(*this, WritevData(_, _, _, _, _, _))
renjietang7c239172020-02-21 13:50:39 -0800142 .WillByDefault(Invoke(this, &MockQuicSimpleServerSession::ConsumeData));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500143 }
144
145 MockQuicSimpleServerSession(const MockQuicSimpleServerSession&) = delete;
146 MockQuicSimpleServerSession& operator=(const MockQuicSimpleServerSession&) =
147 delete;
148 ~MockQuicSimpleServerSession() override = default;
149
wub713afae2020-04-27 07:48:31 -0700150 MOCK_METHOD(void,
151 OnConnectionClosed,
152 (const QuicConnectionCloseFrame& frame,
153 ConnectionCloseSource source),
154 (override));
155 MOCK_METHOD(QuicSpdyStream*,
156 CreateIncomingStream,
157 (QuicStreamId id),
158 (override));
159 MOCK_METHOD(QuicConsumedData,
160 WritevData,
161 (QuicStreamId id,
162 size_t write_length,
163 QuicStreamOffset offset,
164 StreamSendingState state,
165 TransmissionType type,
vasilvv7df418b2020-10-13 13:47:09 -0700166 absl::optional<EncryptionLevel> level),
wub713afae2020-04-27 07:48:31 -0700167 (override));
168 MOCK_METHOD(void,
169 OnStreamHeaderList,
170 (QuicStreamId stream_id,
171 bool fin,
172 size_t frame_len,
173 const QuicHeaderList& header_list),
174 (override));
175 MOCK_METHOD(void,
176 OnStreamHeadersPriority,
177 (QuicStreamId stream_id,
178 const spdy::SpdyStreamPrecedence& precedence),
179 (override));
180 MOCK_METHOD(void,
renjietang052df7c2020-10-13 14:46:09 -0700181 MaybeSendRstStreamFrame,
182 (QuicStreamId stream_id,
183 QuicRstStreamErrorCode error,
184 QuicStreamOffset bytes_written),
185 (override));
186 MOCK_METHOD(void,
187 MaybeSendStopSendingFrame,
188 (QuicStreamId stream_id, QuicRstStreamErrorCode error),
189 (override));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500190
191 using QuicSession::ActivateStream;
192
vasilvv7df418b2020-10-13 13:47:09 -0700193 QuicConsumedData ConsumeData(QuicStreamId id,
194 size_t write_length,
195 QuicStreamOffset offset,
196 StreamSendingState state,
197 TransmissionType /*type*/,
198 absl::optional<EncryptionLevel> /*level*/) {
renjietang7c239172020-02-21 13:50:39 -0800199 if (write_length > 0) {
200 auto buf = std::make_unique<char[]>(write_length);
201 QuicStream* stream = GetOrCreateStream(id);
vasilvvf8035162021-02-01 14:49:14 -0800202 QUICHE_DCHECK(stream);
renjietang7c239172020-02-21 13:50:39 -0800203 QuicDataWriter writer(write_length, buf.get(), quiche::HOST_BYTE_ORDER);
204 stream->WriteStreamData(offset, write_length, &writer);
205 } else {
vasilvvf8035162021-02-01 14:49:14 -0800206 QUICHE_DCHECK(state != NO_FIN);
renjietang7c239172020-02-21 13:50:39 -0800207 }
208 return QuicConsumedData(write_length, state != NO_FIN);
209 }
210
QUICHE team82103522020-10-22 08:15:09 -0700211 spdy::Http2HeaderBlock original_request_headers_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500212};
213
214class QuicSimpleServerStreamTest : public QuicTestWithParam<ParsedQuicVersion> {
215 public:
216 QuicSimpleServerStreamTest()
217 : connection_(
218 new StrictMock<MockQuicConnection>(&helper_,
219 &alarm_factory_,
220 Perspective::IS_SERVER,
221 SupportedVersions(GetParam()))),
222 crypto_config_(new QuicCryptoServerConfig(
223 QuicCryptoServerConfig::TESTING,
224 QuicRandom::GetInstance(),
225 crypto_test_utils::ProofSourceForTesting(),
nharper6ebe83b2019-06-13 17:43:52 -0700226 KeyExchangeSource::Default())),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500227 compressed_certs_cache_(
228 QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
229 session_(connection_,
230 &session_owner_,
231 &session_helper_,
232 crypto_config_.get(),
233 &compressed_certs_cache_,
234 &memory_cache_backend_),
235 quic_response_(new QuicBackendResponse),
236 body_("hello world") {
237 connection_->set_visitor(&session_);
238 header_list_.OnHeaderBlockStart();
239 header_list_.OnHeader(":authority", "www.google.com");
240 header_list_.OnHeader(":path", "/");
241 header_list_.OnHeader(":method", "POST");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500242 header_list_.OnHeader("content-length", "11");
243
244 header_list_.OnHeaderBlockEnd(128, 128);
245
246 // New streams rely on having the peer's flow control receive window
247 // negotiated in the config.
248 session_.config()->SetInitialStreamFlowControlWindowToSend(
249 kInitialStreamFlowControlWindowForTest);
250 session_.config()->SetInitialSessionFlowControlWindowToSend(
251 kInitialSessionFlowControlWindowForTest);
renjietang8513ffe2019-08-12 10:08:57 -0700252 session_.Initialize();
fayang9c41f8b2020-10-30 13:13:06 -0700253 connection_->SetEncrypter(
254 quic::ENCRYPTION_FORWARD_SECURE,
255 std::make_unique<quic::NullEncrypter>(connection_->perspective()));
fayang6a258412020-05-28 08:57:12 -0700256 if (connection_->version().SupportsAntiAmplificationLimit()) {
257 QuicConnectionPeer::SetAddressValidated(connection_);
258 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500259 stream_ = new StrictMock<TestStream>(
260 GetNthClientInitiatedBidirectionalStreamId(
261 connection_->transport_version(), 0),
262 &session_, BIDIRECTIONAL, &memory_cache_backend_);
263 // Register stream_ in dynamic_stream_map_ and pass ownership to session_.
bnc38b5aed2021-04-02 10:57:41 -0700264 session_.ActivateStream(absl::WrapUnique(stream_));
renjietangbb2e22a2019-09-12 15:46:39 -0700265 QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
266 session_.config(), kMinimumFlowControlSendWindow);
dschinazi18cdf132019-10-09 16:08:18 -0700267 QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
268 session_.config(), kMinimumFlowControlSendWindow);
269 QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
270 session_.config(), kMinimumFlowControlSendWindow);
271 QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
272 session_.config(), kMinimumFlowControlSendWindow);
renjietange6d94672020-01-07 10:30:10 -0800273 QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(session_.config(), 10);
renjietangbb2e22a2019-09-12 15:46:39 -0700274 session_.OnConfigNegotiated();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500275 connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
276 }
277
vasilvvc48c8712019-03-11 13:38:16 -0700278 const std::string& StreamBody() { return stream_->body(); }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500279
vasilvvc48c8712019-03-11 13:38:16 -0700280 std::string StreamHeadersValue(const std::string& key) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500281 return (*stream_->mutable_headers())[key].as_string();
282 }
283
renjietanga29a96a2019-10-10 12:47:50 -0700284 bool UsesHttp3() const {
285 return VersionUsesHttp3(connection_->transport_version());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500286 }
287
QUICHE team82103522020-10-22 08:15:09 -0700288 spdy::Http2HeaderBlock response_headers_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500289 MockQuicConnectionHelper helper_;
290 MockAlarmFactory alarm_factory_;
291 StrictMock<MockQuicConnection>* connection_;
292 StrictMock<MockQuicSessionVisitor> session_owner_;
293 StrictMock<MockQuicCryptoServerStreamHelper> session_helper_;
294 std::unique_ptr<QuicCryptoServerConfig> crypto_config_;
295 QuicCompressedCertsCache compressed_certs_cache_;
296 QuicMemoryCacheBackend memory_cache_backend_;
297 StrictMock<MockQuicSimpleServerSession> session_;
298 StrictMock<TestStream>* stream_; // Owned by session_.
299 std::unique_ptr<QuicBackendResponse> quic_response_;
vasilvvc48c8712019-03-11 13:38:16 -0700300 std::string body_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500301 QuicHeaderList header_list_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500302};
303
304INSTANTIATE_TEST_SUITE_P(Tests,
305 QuicSimpleServerStreamTest,
dschinazi88bd5b02019-10-10 00:52:20 -0700306 ::testing::ValuesIn(AllSupportedVersions()),
307 ::testing::PrintToStringParamName());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500308
309TEST_P(QuicSimpleServerStreamTest, TestFraming) {
renjietang41a1b412020-02-27 15:05:14 -0800310 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
renjietang7c239172020-02-21 13:50:39 -0800311 .WillRepeatedly(
312 Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500313 stream_->OnStreamHeaderList(false, kFakeFrameLen, header_list_);
314 std::unique_ptr<char[]> buffer;
315 QuicByteCount header_length =
bnc46942722019-10-29 11:56:21 -0700316 HttpEncoder::SerializeDataFrameHeader(body_.length(), &buffer);
vasilvvc48c8712019-03-11 13:38:16 -0700317 std::string header = std::string(buffer.get(), header_length);
renjietanga29a96a2019-10-10 12:47:50 -0700318 std::string data = UsesHttp3() ? header + body_ : body_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500319 stream_->OnStreamFrame(
320 QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
321 EXPECT_EQ("11", StreamHeadersValue("content-length"));
322 EXPECT_EQ("/", StreamHeadersValue(":path"));
323 EXPECT_EQ("POST", StreamHeadersValue(":method"));
324 EXPECT_EQ(body_, StreamBody());
325}
326
327TEST_P(QuicSimpleServerStreamTest, TestFramingOnePacket) {
renjietang41a1b412020-02-27 15:05:14 -0800328 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
renjietang7c239172020-02-21 13:50:39 -0800329 .WillRepeatedly(
330 Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500331
332 stream_->OnStreamHeaderList(false, kFakeFrameLen, header_list_);
333 std::unique_ptr<char[]> buffer;
334 QuicByteCount header_length =
bnc46942722019-10-29 11:56:21 -0700335 HttpEncoder::SerializeDataFrameHeader(body_.length(), &buffer);
vasilvvc48c8712019-03-11 13:38:16 -0700336 std::string header = std::string(buffer.get(), header_length);
renjietanga29a96a2019-10-10 12:47:50 -0700337 std::string data = UsesHttp3() ? header + body_ : body_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500338 stream_->OnStreamFrame(
339 QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
340 EXPECT_EQ("11", StreamHeadersValue("content-length"));
341 EXPECT_EQ("/", StreamHeadersValue(":path"));
342 EXPECT_EQ("POST", StreamHeadersValue(":method"));
343 EXPECT_EQ(body_, StreamBody());
344}
345
346TEST_P(QuicSimpleServerStreamTest, SendQuicRstStreamNoErrorInStopReading) {
renjietang41a1b412020-02-27 15:05:14 -0800347 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
renjietang7c239172020-02-21 13:50:39 -0800348 .WillRepeatedly(
349 Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500350
351 EXPECT_FALSE(stream_->fin_received());
352 EXPECT_FALSE(stream_->rst_received());
353
fayang3a51d1a2020-04-16 13:42:08 -0700354 QuicStreamPeer::SetFinSent(stream_);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500355 stream_->CloseWriteSide();
356
renjietang861766b2021-02-02 09:59:04 -0800357 if (session_.version().UsesHttp3()) {
358 EXPECT_CALL(session_, MaybeSendStopSendingFrame(_, QUIC_STREAM_NO_ERROR))
renjietang052df7c2020-10-13 14:46:09 -0700359 .Times(1);
360 } else {
renjietang861766b2021-02-02 09:59:04 -0800361 EXPECT_CALL(session_, MaybeSendRstStreamFrame(_, QUIC_STREAM_NO_ERROR, _))
362 .Times(1);
renjietang052df7c2020-10-13 14:46:09 -0700363 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500364 stream_->StopReading();
365}
366
367TEST_P(QuicSimpleServerStreamTest, TestFramingExtraData) {
368 InSequence seq;
vasilvvc48c8712019-03-11 13:38:16 -0700369 std::string large_body = "hello world!!!!!!";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500370
371 // We'll automatically write out an error (headers + body)
372 EXPECT_CALL(*stream_, WriteHeadersMock(false));
renjietanga29a96a2019-10-10 12:47:50 -0700373 if (UsesHttp3()) {
renjietang41a1b412020-02-27 15:05:14 -0800374 EXPECT_CALL(session_,
375 WritevData(_, kDataFrameHeaderLength, _, NO_FIN, _, _));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500376 }
renjietang41a1b412020-02-27 15:05:14 -0800377 EXPECT_CALL(session_, WritevData(_, kErrorLength, _, FIN, _, _));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500378
QUICHE teama6ef0a62019-03-07 20:34:33 -0500379 stream_->OnStreamHeaderList(false, kFakeFrameLen, header_list_);
380 std::unique_ptr<char[]> buffer;
381 QuicByteCount header_length =
bnc46942722019-10-29 11:56:21 -0700382 HttpEncoder::SerializeDataFrameHeader(body_.length(), &buffer);
vasilvvc48c8712019-03-11 13:38:16 -0700383 std::string header = std::string(buffer.get(), header_length);
renjietanga29a96a2019-10-10 12:47:50 -0700384 std::string data = UsesHttp3() ? header + body_ : body_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500385
386 stream_->OnStreamFrame(
387 QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
388 // Content length is still 11. This will register as an error and we won't
389 // accept the bytes.
390 header_length =
bnc46942722019-10-29 11:56:21 -0700391 HttpEncoder::SerializeDataFrameHeader(large_body.length(), &buffer);
vasilvvc48c8712019-03-11 13:38:16 -0700392 header = std::string(buffer.get(), header_length);
renjietanga29a96a2019-10-10 12:47:50 -0700393 std::string data2 = UsesHttp3() ? header + large_body : large_body;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500394 stream_->OnStreamFrame(
395 QuicStreamFrame(stream_->id(), /*fin=*/true, data.size(), data2));
396 EXPECT_EQ("11", StreamHeadersValue("content-length"));
397 EXPECT_EQ("/", StreamHeadersValue(":path"));
398 EXPECT_EQ("POST", StreamHeadersValue(":method"));
399}
400
401TEST_P(QuicSimpleServerStreamTest, SendResponseWithIllegalResponseStatus) {
402 // Send an illegal response with response status not supported by HTTP/2.
QUICHE team82103522020-10-22 08:15:09 -0700403 spdy::Http2HeaderBlock* request_headers = stream_->mutable_headers();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500404 (*request_headers)[":path"] = "/bar";
405 (*request_headers)[":authority"] = "www.google.com";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500406 (*request_headers)[":method"] = "GET";
407
QUICHE teama6ef0a62019-03-07 20:34:33 -0500408 // HTTP/2 only supports integer responsecode, so "200 OK" is illegal.
409 response_headers_[":status"] = "200 OK";
410 response_headers_["content-length"] = "5";
vasilvvc48c8712019-03-11 13:38:16 -0700411 std::string body = "Yummm";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500412 std::unique_ptr<char[]> buffer;
413 QuicByteCount header_length =
bnc46942722019-10-29 11:56:21 -0700414 HttpEncoder::SerializeDataFrameHeader(body.length(), &buffer);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500415
416 memory_cache_backend_.AddResponse("www.google.com", "/bar",
417 std::move(response_headers_), body);
418
fayang3a51d1a2020-04-16 13:42:08 -0700419 QuicStreamPeer::SetFinReceived(stream_);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500420
421 InSequence s;
422 EXPECT_CALL(*stream_, WriteHeadersMock(false));
renjietanga29a96a2019-10-10 12:47:50 -0700423 if (UsesHttp3()) {
renjietang41a1b412020-02-27 15:05:14 -0800424 EXPECT_CALL(session_, WritevData(_, header_length, _, NO_FIN, _, _));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500425 }
renjietang41a1b412020-02-27 15:05:14 -0800426 EXPECT_CALL(session_, WritevData(_, kErrorLength, _, FIN, _, _));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500427
428 stream_->DoSendResponse();
429 EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
430 EXPECT_TRUE(stream_->write_side_closed());
431}
432
433TEST_P(QuicSimpleServerStreamTest, SendResponseWithIllegalResponseStatus2) {
434 // Send an illegal response with response status not supported by HTTP/2.
QUICHE team82103522020-10-22 08:15:09 -0700435 spdy::Http2HeaderBlock* request_headers = stream_->mutable_headers();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500436 (*request_headers)[":path"] = "/bar";
437 (*request_headers)[":authority"] = "www.google.com";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500438 (*request_headers)[":method"] = "GET";
439
QUICHE teama6ef0a62019-03-07 20:34:33 -0500440 // HTTP/2 only supports 3-digit-integer, so "+200" is illegal.
441 response_headers_[":status"] = "+200";
442 response_headers_["content-length"] = "5";
vasilvvc48c8712019-03-11 13:38:16 -0700443 std::string body = "Yummm";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500444
445 std::unique_ptr<char[]> buffer;
446 QuicByteCount header_length =
bnc46942722019-10-29 11:56:21 -0700447 HttpEncoder::SerializeDataFrameHeader(body.length(), &buffer);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500448
449 memory_cache_backend_.AddResponse("www.google.com", "/bar",
450 std::move(response_headers_), body);
451
fayang3a51d1a2020-04-16 13:42:08 -0700452 QuicStreamPeer::SetFinReceived(stream_);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500453
454 InSequence s;
455 EXPECT_CALL(*stream_, WriteHeadersMock(false));
renjietanga29a96a2019-10-10 12:47:50 -0700456 if (UsesHttp3()) {
renjietang41a1b412020-02-27 15:05:14 -0800457 EXPECT_CALL(session_, WritevData(_, header_length, _, NO_FIN, _, _));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500458 }
renjietang41a1b412020-02-27 15:05:14 -0800459 EXPECT_CALL(session_, WritevData(_, kErrorLength, _, FIN, _, _));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500460
461 stream_->DoSendResponse();
462 EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
463 EXPECT_TRUE(stream_->write_side_closed());
464}
465
466TEST_P(QuicSimpleServerStreamTest, SendPushResponseWith404Response) {
467 // Create a new promised stream with even id().
468 auto promised_stream = new StrictMock<TestStream>(
469 GetNthServerInitiatedUnidirectionalStreamId(
renjietang87cd7de2019-08-16 08:35:10 -0700470 connection_->transport_version(), 3),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500471 &session_, WRITE_UNIDIRECTIONAL, &memory_cache_backend_);
bnc38b5aed2021-04-02 10:57:41 -0700472 session_.ActivateStream(absl::WrapUnique(promised_stream));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500473
474 // Send a push response with response status 404, which will be regarded as
475 // invalid server push response.
QUICHE team82103522020-10-22 08:15:09 -0700476 spdy::Http2HeaderBlock* request_headers = promised_stream->mutable_headers();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500477 (*request_headers)[":path"] = "/bar";
478 (*request_headers)[":authority"] = "www.google.com";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500479 (*request_headers)[":method"] = "GET";
480
QUICHE teama6ef0a62019-03-07 20:34:33 -0500481 response_headers_[":status"] = "404";
482 response_headers_["content-length"] = "8";
vasilvvc48c8712019-03-11 13:38:16 -0700483 std::string body = "NotFound";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500484
485 memory_cache_backend_.AddResponse("www.google.com", "/bar",
486 std::move(response_headers_), body);
487
488 InSequence s;
renjietang861766b2021-02-02 09:59:04 -0800489 if (session_.version().UsesHttp3()) {
490 EXPECT_CALL(session_, MaybeSendStopSendingFrame(promised_stream->id(),
491 QUIC_STREAM_CANCELLED));
renjietang052df7c2020-10-13 14:46:09 -0700492 }
renjietang861766b2021-02-02 09:59:04 -0800493 EXPECT_CALL(session_, MaybeSendRstStreamFrame(promised_stream->id(),
494 QUIC_STREAM_CANCELLED, 0));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500495
496 promised_stream->DoSendResponse();
497}
498
499TEST_P(QuicSimpleServerStreamTest, SendResponseWithValidHeaders) {
500 // Add a request and response with valid headers.
QUICHE team82103522020-10-22 08:15:09 -0700501 spdy::Http2HeaderBlock* request_headers = stream_->mutable_headers();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500502 (*request_headers)[":path"] = "/bar";
503 (*request_headers)[":authority"] = "www.google.com";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500504 (*request_headers)[":method"] = "GET";
505
QUICHE teama6ef0a62019-03-07 20:34:33 -0500506 response_headers_[":status"] = "200";
507 response_headers_["content-length"] = "5";
vasilvvc48c8712019-03-11 13:38:16 -0700508 std::string body = "Yummm";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500509
510 std::unique_ptr<char[]> buffer;
511 QuicByteCount header_length =
bnc46942722019-10-29 11:56:21 -0700512 HttpEncoder::SerializeDataFrameHeader(body.length(), &buffer);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500513
514 memory_cache_backend_.AddResponse("www.google.com", "/bar",
515 std::move(response_headers_), body);
fayang3a51d1a2020-04-16 13:42:08 -0700516 QuicStreamPeer::SetFinReceived(stream_);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500517
518 InSequence s;
519 EXPECT_CALL(*stream_, WriteHeadersMock(false));
renjietanga29a96a2019-10-10 12:47:50 -0700520 if (UsesHttp3()) {
renjietang41a1b412020-02-27 15:05:14 -0800521 EXPECT_CALL(session_, WritevData(_, header_length, _, NO_FIN, _, _));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500522 }
renjietang41a1b412020-02-27 15:05:14 -0800523 EXPECT_CALL(session_, WritevData(_, body.length(), _, FIN, _, _));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500524
525 stream_->DoSendResponse();
526 EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
527 EXPECT_TRUE(stream_->write_side_closed());
528}
529
QUICHE teamb0aaa822021-03-15 16:49:08 -0700530TEST_P(QuicSimpleServerStreamTest, SendResponseWithEarlyHints) {
531 std::string host = "www.google.com";
532 std::string request_path = "/foo";
533 std::string body = "Yummm";
534
535 // Add a request and response with early hints.
536 spdy::Http2HeaderBlock* request_headers = stream_->mutable_headers();
537 (*request_headers)[":path"] = request_path;
538 (*request_headers)[":authority"] = host;
539 (*request_headers)[":method"] = "GET";
540
541 std::unique_ptr<char[]> buffer;
542 QuicByteCount header_length =
543 HttpEncoder::SerializeDataFrameHeader(body.length(), &buffer);
544 std::vector<spdy::Http2HeaderBlock> early_hints;
545 // Add two Early Hints.
546 const size_t kNumEarlyHintsResponses = 2;
547 for (size_t i = 0; i < kNumEarlyHintsResponses; ++i) {
548 spdy::Http2HeaderBlock hints;
549 hints["link"] = "</image.png>; rel=preload; as=image";
550 early_hints.push_back(std::move(hints));
551 }
552
553 response_headers_[":status"] = "200";
554 response_headers_["content-length"] = "5";
555 memory_cache_backend_.AddResponseWithEarlyHints(
556 host, request_path, std::move(response_headers_), body, early_hints);
557 QuicStreamPeer::SetFinReceived(stream_);
558
559 InSequence s;
560 for (size_t i = 0; i < kNumEarlyHintsResponses; ++i) {
561 EXPECT_CALL(*stream_, WriteEarlyHintsHeadersMock(false));
562 }
563 EXPECT_CALL(*stream_, WriteHeadersMock(false));
564 if (UsesHttp3()) {
565 EXPECT_CALL(session_, WritevData(_, header_length, _, NO_FIN, _, _));
566 }
567 EXPECT_CALL(session_, WritevData(_, body.length(), _, FIN, _, _));
568
569 stream_->DoSendResponse();
570 EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
571 EXPECT_TRUE(stream_->write_side_closed());
572}
573
QUICHE teama6ef0a62019-03-07 20:34:33 -0500574TEST_P(QuicSimpleServerStreamTest, PushResponseOnClientInitiatedStream) {
575 // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
576 if (GetParam() != AllSupportedVersions()[0]) {
577 return;
578 }
579
580 // Calling PushResponse() on a client initialted stream is never supposed to
581 // happen.
QUICHE team82103522020-10-22 08:15:09 -0700582 EXPECT_QUIC_BUG(stream_->PushResponse(spdy::Http2HeaderBlock()),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500583 "Client initiated stream"
584 " shouldn't be used as promised stream.");
585}
586
587TEST_P(QuicSimpleServerStreamTest, PushResponseOnServerInitiatedStream) {
588 // Tests that PushResponse() should take the given headers as request headers
589 // and fetch response from cache, and send it out.
590
591 // Create a stream with even stream id and test against this stream.
592 const QuicStreamId kServerInitiatedStreamId =
593 GetNthServerInitiatedUnidirectionalStreamId(
renjietang87cd7de2019-08-16 08:35:10 -0700594 connection_->transport_version(), 3);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500595 // Create a server initiated stream and pass it to session_.
596 auto server_initiated_stream =
597 new StrictMock<TestStream>(kServerInitiatedStreamId, &session_,
598 WRITE_UNIDIRECTIONAL, &memory_cache_backend_);
bnc38b5aed2021-04-02 10:57:41 -0700599 session_.ActivateStream(absl::WrapUnique(server_initiated_stream));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500600
vasilvvc48c8712019-03-11 13:38:16 -0700601 const std::string kHost = "www.foo.com";
602 const std::string kPath = "/bar";
QUICHE team82103522020-10-22 08:15:09 -0700603 spdy::Http2HeaderBlock headers;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500604 headers[":path"] = kPath;
605 headers[":authority"] = kHost;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500606 headers[":method"] = "GET";
607
QUICHE teama6ef0a62019-03-07 20:34:33 -0500608 response_headers_[":status"] = "200";
609 response_headers_["content-length"] = "5";
vasilvvc48c8712019-03-11 13:38:16 -0700610 const std::string kBody = "Hello";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500611 std::unique_ptr<char[]> buffer;
612 QuicByteCount header_length =
bnc46942722019-10-29 11:56:21 -0700613 HttpEncoder::SerializeDataFrameHeader(kBody.length(), &buffer);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500614 memory_cache_backend_.AddResponse(kHost, kPath, std::move(response_headers_),
615 kBody);
616
617 // Call PushResponse() should trigger stream to fetch response from cache
618 // and send it back.
619 InSequence s;
620 EXPECT_CALL(*server_initiated_stream, WriteHeadersMock(false));
621
renjietanga29a96a2019-10-10 12:47:50 -0700622 if (UsesHttp3()) {
renjietang7c239172020-02-21 13:50:39 -0800623 EXPECT_CALL(session_, WritevData(kServerInitiatedStreamId, header_length, _,
renjietang41a1b412020-02-27 15:05:14 -0800624 NO_FIN, _, _));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500625 }
626 EXPECT_CALL(session_,
renjietang41a1b412020-02-27 15:05:14 -0800627 WritevData(kServerInitiatedStreamId, kBody.size(), _, FIN, _, _));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500628 server_initiated_stream->PushResponse(std::move(headers));
629 EXPECT_EQ(kPath, server_initiated_stream->GetHeader(":path"));
630 EXPECT_EQ("GET", server_initiated_stream->GetHeader(":method"));
631}
632
633TEST_P(QuicSimpleServerStreamTest, TestSendErrorResponse) {
fayang3a51d1a2020-04-16 13:42:08 -0700634 QuicStreamPeer::SetFinReceived(stream_);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500635
636 InSequence s;
637 EXPECT_CALL(*stream_, WriteHeadersMock(false));
renjietanga29a96a2019-10-10 12:47:50 -0700638 if (UsesHttp3()) {
renjietang41a1b412020-02-27 15:05:14 -0800639 EXPECT_CALL(session_,
640 WritevData(_, kDataFrameHeaderLength, _, NO_FIN, _, _));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500641 }
renjietang41a1b412020-02-27 15:05:14 -0800642 EXPECT_CALL(session_, WritevData(_, kErrorLength, _, FIN, _, _));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500643
644 stream_->DoSendErrorResponse();
645 EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
646 EXPECT_TRUE(stream_->write_side_closed());
647}
648
649TEST_P(QuicSimpleServerStreamTest, InvalidMultipleContentLength) {
QUICHE team82103522020-10-22 08:15:09 -0700650 spdy::Http2HeaderBlock request_headers;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500651 // \000 is a way to write the null byte when followed by a literal digit.
vasilvv6c9e9c32020-10-08 08:16:57 -0700652 header_list_.OnHeader("content-length", absl::string_view("11\00012", 5));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500653
654 EXPECT_CALL(*stream_, WriteHeadersMock(false));
renjietang41a1b412020-02-27 15:05:14 -0800655 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
renjietang7c239172020-02-21 13:50:39 -0800656 .WillRepeatedly(
657 Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500658 stream_->OnStreamHeaderList(true, kFakeFrameLen, header_list_);
659
660 EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream_));
661 EXPECT_TRUE(stream_->reading_stopped());
662 EXPECT_TRUE(stream_->write_side_closed());
663}
664
665TEST_P(QuicSimpleServerStreamTest, InvalidLeadingNullContentLength) {
QUICHE team82103522020-10-22 08:15:09 -0700666 spdy::Http2HeaderBlock request_headers;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500667 // \000 is a way to write the null byte when followed by a literal digit.
vasilvv6c9e9c32020-10-08 08:16:57 -0700668 header_list_.OnHeader("content-length", absl::string_view("\00012", 3));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500669
670 EXPECT_CALL(*stream_, WriteHeadersMock(false));
renjietang41a1b412020-02-27 15:05:14 -0800671 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
renjietang7c239172020-02-21 13:50:39 -0800672 .WillRepeatedly(
673 Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500674 stream_->OnStreamHeaderList(true, kFakeFrameLen, header_list_);
675
676 EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream_));
677 EXPECT_TRUE(stream_->reading_stopped());
678 EXPECT_TRUE(stream_->write_side_closed());
679}
680
681TEST_P(QuicSimpleServerStreamTest, ValidMultipleContentLength) {
QUICHE team82103522020-10-22 08:15:09 -0700682 spdy::Http2HeaderBlock request_headers;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500683 // \000 is a way to write the null byte when followed by a literal digit.
vasilvv6c9e9c32020-10-08 08:16:57 -0700684 header_list_.OnHeader("content-length", absl::string_view("11\00011", 5));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500685
686 stream_->OnStreamHeaderList(false, kFakeFrameLen, header_list_);
687
688 EXPECT_EQ(11, stream_->content_length());
689 EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
690 EXPECT_FALSE(stream_->reading_stopped());
691 EXPECT_FALSE(stream_->write_side_closed());
692}
693
694TEST_P(QuicSimpleServerStreamTest,
695 DoNotSendQuicRstStreamNoErrorWithRstReceived) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500696 EXPECT_FALSE(stream_->reading_stopped());
697
bnc6f18a822019-11-27 17:50:38 -0800698 if (VersionUsesHttp3(connection_->transport_version())) {
699 // Unidirectional stream type and then a Stream Cancellation instruction is
700 // sent on the QPACK decoder stream. Ignore these writes without any
701 // assumption on their number or size.
702 auto* qpack_decoder_stream =
703 QuicSpdySessionPeer::GetQpackDecoderSendStream(&session_);
renjietang41a1b412020-02-27 15:05:14 -0800704 EXPECT_CALL(session_, WritevData(qpack_decoder_stream->id(), _, _, _, _, _))
bnc6f18a822019-11-27 17:50:38 -0800705 .Times(AnyNumber());
706 }
renjietang052df7c2020-10-13 14:46:09 -0700707
renjietang861766b2021-02-02 09:59:04 -0800708 EXPECT_CALL(session_, MaybeSendRstStreamFrame(_,
709 session_.version().UsesHttp3()
710 ? QUIC_STREAM_CANCELLED
711 : QUIC_RST_ACKNOWLEDGEMENT,
712 _))
713 .Times(1);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500714 QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
715 QUIC_STREAM_CANCELLED, 1234);
716 stream_->OnStreamReset(rst_frame);
fkastenholz305e1732019-06-18 05:01:22 -0700717 if (VersionHasIetfQuicFrames(connection_->transport_version())) {
renjietang052df7c2020-10-13 14:46:09 -0700718 EXPECT_CALL(session_owner_, OnStopSendingReceived(_));
719 // Create and inject a STOP SENDING frame to complete the close
720 // of the stream. This is only needed for version 99/IETF QUIC.
721 QuicStopSendingFrame stop_sending(kInvalidControlFrameId, stream_->id(),
722 QUIC_STREAM_CANCELLED);
723 session_.OnStopSendingFrame(stop_sending);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500724 }
725 EXPECT_TRUE(stream_->reading_stopped());
726 EXPECT_TRUE(stream_->write_side_closed());
727}
728
729TEST_P(QuicSimpleServerStreamTest, InvalidHeadersWithFin) {
730 char arr[] = {
731 0x3a, 0x68, 0x6f, 0x73, // :hos
732 0x74, 0x00, 0x00, 0x00, // t...
733 0x00, 0x00, 0x00, 0x00, // ....
734 0x07, 0x3a, 0x6d, 0x65, // .:me
735 0x74, 0x68, 0x6f, 0x64, // thod
736 0x00, 0x00, 0x00, 0x03, // ....
737 0x47, 0x45, 0x54, 0x00, // GET.
738 0x00, 0x00, 0x05, 0x3a, // ...:
739 0x70, 0x61, 0x74, 0x68, // path
740 0x00, 0x00, 0x00, 0x04, // ....
741 0x2f, 0x66, 0x6f, 0x6f, // /foo
742 0x00, 0x00, 0x00, 0x07, // ....
743 0x3a, 0x73, 0x63, 0x68, // :sch
744 0x65, 0x6d, 0x65, 0x00, // eme.
745 0x00, 0x00, 0x00, 0x00, // ....
746 0x00, 0x00, 0x08, 0x3a, // ...:
747 0x76, 0x65, 0x72, 0x73, // vers
748 0x96, 0x6f, 0x6e, 0x00, // <i(69)>on.
749 0x00, 0x00, 0x08, 0x48, // ...H
750 0x54, 0x54, 0x50, 0x2f, // TTP/
751 0x31, 0x2e, 0x31, // 1.1
752 };
vasilvv035fe3d2020-10-20 08:38:37 -0700753 absl::string_view data(arr, ABSL_ARRAYSIZE(arr));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500754 QuicStreamFrame frame(stream_->id(), true, 0, data);
755 // Verify that we don't crash when we get a invalid headers in stream frame.
756 stream_->OnStreamFrame(frame);
757}
758
dschinazi9a630bf2020-11-25 11:34:29 -0800759TEST_P(QuicSimpleServerStreamTest, ConnectSendsResponseBeforeFinReceived) {
760 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
761 .WillRepeatedly(
762 Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
763 QuicHeaderList header_list;
764 header_list.OnHeaderBlockStart();
765 header_list.OnHeader(":authority", "www.google.com:4433");
766 header_list.OnHeader(":method", "CONNECT-SILLY");
767 header_list.OnHeaderBlockEnd(128, 128);
768 EXPECT_CALL(*stream_, WriteHeadersMock(/*fin=*/false));
769 stream_->OnStreamHeaderList(/*fin=*/false, kFakeFrameLen, header_list);
770 std::unique_ptr<char[]> buffer;
771 QuicByteCount header_length =
772 HttpEncoder::SerializeDataFrameHeader(body_.length(), &buffer);
773 std::string header = std::string(buffer.get(), header_length);
774 std::string data = UsesHttp3() ? header + body_ : body_;
775 stream_->OnStreamFrame(
776 QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
777 EXPECT_EQ("CONNECT-SILLY", StreamHeadersValue(":method"));
778 EXPECT_EQ(body_, StreamBody());
779 EXPECT_TRUE(stream_->send_response_was_called());
dschinazi8d63c922021-03-01 14:31:49 -0800780 EXPECT_FALSE(stream_->send_error_response_was_called());
dschinazi9a630bf2020-11-25 11:34:29 -0800781}
782
dschinazieb2046f2021-03-04 10:27:53 -0800783TEST_P(QuicSimpleServerStreamTest, ConnectWithInvalidHeader) {
784 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
785 .WillRepeatedly(
786 Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
787 QuicHeaderList header_list;
788 header_list.OnHeaderBlockStart();
789 header_list.OnHeader(":authority", "www.google.com:4433");
790 header_list.OnHeader(":method", "CONNECT-SILLY");
791 // QUIC requires lower-case header names.
792 header_list.OnHeader("InVaLiD-HeAdEr", "Well that's just wrong!");
793 header_list.OnHeaderBlockEnd(128, 128);
794 EXPECT_CALL(*stream_, WriteHeadersMock(/*fin=*/false));
795 stream_->OnStreamHeaderList(/*fin=*/false, kFakeFrameLen, header_list);
796 std::unique_ptr<char[]> buffer;
797 QuicByteCount header_length =
798 HttpEncoder::SerializeDataFrameHeader(body_.length(), &buffer);
799 std::string header = std::string(buffer.get(), header_length);
800 std::string data = UsesHttp3() ? header + body_ : body_;
801 stream_->OnStreamFrame(
802 QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
803 EXPECT_EQ("CONNECT-SILLY", StreamHeadersValue(":method"));
804 EXPECT_EQ(body_, StreamBody());
805 EXPECT_FALSE(stream_->send_response_was_called());
806 EXPECT_TRUE(stream_->send_error_response_was_called());
807}
808
QUICHE teama6ef0a62019-03-07 20:34:33 -0500809} // namespace
810} // namespace test
811} // namespace quic