xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/tools/quic_simple_server_stream_test.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // 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 
5 #include "quiche/quic/tools/quic_simple_server_stream.h"
6 
7 #include <list>
8 #include <memory>
9 #include <optional>
10 #include <utility>
11 
12 #include "absl/base/macros.h"
13 #include "absl/memory/memory.h"
14 #include "absl/strings/string_view.h"
15 #include "quiche/quic/core/crypto/null_encrypter.h"
16 #include "quiche/quic/core/http/http_encoder.h"
17 #include "quiche/quic/core/http/spdy_utils.h"
18 #include "quiche/quic/core/quic_alarm_factory.h"
19 #include "quiche/quic/core/quic_default_clock.h"
20 #include "quiche/quic/core/quic_error_codes.h"
21 #include "quiche/quic/core/quic_types.h"
22 #include "quiche/quic/core/quic_utils.h"
23 #include "quiche/quic/platform/api/quic_expect_bug.h"
24 #include "quiche/quic/platform/api/quic_flags.h"
25 #include "quiche/quic/platform/api/quic_socket_address.h"
26 #include "quiche/quic/platform/api/quic_test.h"
27 #include "quiche/quic/test_tools/crypto_test_utils.h"
28 #include "quiche/quic/test_tools/quic_config_peer.h"
29 #include "quiche/quic/test_tools/quic_connection_peer.h"
30 #include "quiche/quic/test_tools/quic_session_peer.h"
31 #include "quiche/quic/test_tools/quic_spdy_session_peer.h"
32 #include "quiche/quic/test_tools/quic_stream_peer.h"
33 #include "quiche/quic/test_tools/quic_test_utils.h"
34 #include "quiche/quic/test_tools/simulator/simulator.h"
35 #include "quiche/quic/tools/quic_backend_response.h"
36 #include "quiche/quic/tools/quic_memory_cache_backend.h"
37 #include "quiche/quic/tools/quic_simple_server_backend.h"
38 #include "quiche/quic/tools/quic_simple_server_session.h"
39 #include "quiche/common/simple_buffer_allocator.h"
40 
41 using testing::_;
42 using testing::AnyNumber;
43 using testing::InSequence;
44 using testing::Invoke;
45 using testing::StrictMock;
46 
47 namespace quic {
48 namespace test {
49 
50 const size_t kFakeFrameLen = 60;
51 const size_t kErrorLength = strlen(QuicSimpleServerStream::kErrorResponseBody);
52 const size_t kDataFrameHeaderLength = 2;
53 
54 class TestStream : public QuicSimpleServerStream {
55  public:
TestStream(QuicStreamId stream_id,QuicSpdySession * session,StreamType type,QuicSimpleServerBackend * quic_simple_server_backend)56   TestStream(QuicStreamId stream_id, QuicSpdySession* session, StreamType type,
57              QuicSimpleServerBackend* quic_simple_server_backend)
58       : QuicSimpleServerStream(stream_id, session, type,
59                                quic_simple_server_backend) {
60     EXPECT_CALL(*this, WriteOrBufferBody(_, _))
61         .Times(AnyNumber())
62         .WillRepeatedly([this](absl::string_view data, bool fin) {
63           this->QuicSimpleServerStream::WriteOrBufferBody(data, fin);
64         });
65   }
66 
67   ~TestStream() override = default;
68 
69   MOCK_METHOD(void, FireAlarmMock, (), ());
70   MOCK_METHOD(void, WriteHeadersMock, (bool fin), ());
71   MOCK_METHOD(void, WriteEarlyHintsHeadersMock, (bool fin), ());
72   MOCK_METHOD(void, WriteOrBufferBody, (absl::string_view data, bool fin),
73               (override));
74 
WriteHeaders(spdy::Http2HeaderBlock header_block,bool fin,quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>)75   size_t WriteHeaders(
76       spdy::Http2HeaderBlock header_block, bool fin,
77       quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
78       /*ack_listener*/) override {
79     if (header_block[":status"] == "103") {
80       WriteEarlyHintsHeadersMock(fin);
81     } else {
82       WriteHeadersMock(fin);
83     }
84     return 0;
85   }
86 
87   // Expose protected QuicSimpleServerStream methods.
DoSendResponse()88   void DoSendResponse() { SendResponse(); }
DoSendErrorResponse()89   void DoSendErrorResponse() { QuicSimpleServerStream::SendErrorResponse(); }
90 
mutable_headers()91   spdy::Http2HeaderBlock* mutable_headers() { return &request_headers_; }
set_body(std::string body)92   void set_body(std::string body) { body_ = std::move(body); }
body() const93   const std::string& body() const { return body_; }
content_length() const94   int content_length() const { return content_length_; }
send_response_was_called() const95   bool send_response_was_called() const { return send_response_was_called_; }
send_error_response_was_called() const96   bool send_error_response_was_called() const {
97     return send_error_response_was_called_;
98   }
99 
GetHeader(absl::string_view key) const100   absl::string_view GetHeader(absl::string_view key) const {
101     auto it = request_headers_.find(key);
102     QUICHE_DCHECK(it != request_headers_.end());
103     return it->second;
104   }
105 
ReplaceBackend(QuicSimpleServerBackend * backend)106   void ReplaceBackend(QuicSimpleServerBackend* backend) {
107     set_quic_simple_server_backend_for_test(backend);
108   }
109 
110  protected:
SendResponse()111   void SendResponse() override {
112     send_response_was_called_ = true;
113     QuicSimpleServerStream::SendResponse();
114   }
115 
SendErrorResponse(int resp_code)116   void SendErrorResponse(int resp_code) override {
117     send_error_response_was_called_ = true;
118     QuicSimpleServerStream::SendErrorResponse(resp_code);
119   }
120 
121  private:
122   bool send_response_was_called_ = false;
123   bool send_error_response_was_called_ = false;
124 };
125 
126 namespace {
127 
128 class MockQuicSimpleServerSession : public QuicSimpleServerSession {
129  public:
130   const size_t kMaxStreamsForTest = 100;
131 
MockQuicSimpleServerSession(QuicConnection * connection,MockQuicSessionVisitor * owner,MockQuicCryptoServerStreamHelper * helper,QuicCryptoServerConfig * crypto_config,QuicCompressedCertsCache * compressed_certs_cache,QuicSimpleServerBackend * quic_simple_server_backend)132   MockQuicSimpleServerSession(
133       QuicConnection* connection, MockQuicSessionVisitor* owner,
134       MockQuicCryptoServerStreamHelper* helper,
135       QuicCryptoServerConfig* crypto_config,
136       QuicCompressedCertsCache* compressed_certs_cache,
137       QuicSimpleServerBackend* quic_simple_server_backend)
138       : QuicSimpleServerSession(DefaultQuicConfig(), CurrentSupportedVersions(),
139                                 connection, owner, helper, crypto_config,
140                                 compressed_certs_cache,
141                                 quic_simple_server_backend) {
142     if (VersionHasIetfQuicFrames(connection->transport_version())) {
143       QuicSessionPeer::SetMaxOpenIncomingUnidirectionalStreams(
144           this, kMaxStreamsForTest);
145       QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(
146           this, kMaxStreamsForTest);
147     } else {
148       QuicSessionPeer::SetMaxOpenIncomingStreams(this, kMaxStreamsForTest);
149       QuicSessionPeer::SetMaxOpenOutgoingStreams(this, kMaxStreamsForTest);
150     }
151     ON_CALL(*this, WritevData(_, _, _, _, _, _))
152         .WillByDefault(Invoke(this, &MockQuicSimpleServerSession::ConsumeData));
153   }
154 
155   MockQuicSimpleServerSession(const MockQuicSimpleServerSession&) = delete;
156   MockQuicSimpleServerSession& operator=(const MockQuicSimpleServerSession&) =
157       delete;
158   ~MockQuicSimpleServerSession() override = default;
159 
160   MOCK_METHOD(void, OnConnectionClosed,
161               (const QuicConnectionCloseFrame& frame,
162                ConnectionCloseSource source),
163               (override));
164   MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (QuicStreamId id),
165               (override));
166   MOCK_METHOD(QuicConsumedData, WritevData,
167               (QuicStreamId id, size_t write_length, QuicStreamOffset offset,
168                StreamSendingState state, TransmissionType type,
169                EncryptionLevel level),
170               (override));
171   MOCK_METHOD(void, OnStreamHeaderList,
172               (QuicStreamId stream_id, bool fin, size_t frame_len,
173                const QuicHeaderList& header_list),
174               (override));
175   MOCK_METHOD(void, OnStreamHeadersPriority,
176               (QuicStreamId stream_id,
177                const spdy::SpdyStreamPrecedence& precedence),
178               (override));
179   MOCK_METHOD(void, MaybeSendRstStreamFrame,
180               (QuicStreamId stream_id, QuicResetStreamError error,
181                QuicStreamOffset bytes_written),
182               (override));
183   MOCK_METHOD(void, MaybeSendStopSendingFrame,
184               (QuicStreamId stream_id, QuicResetStreamError error), (override));
185 
186   using QuicSession::ActivateStream;
187 
ConsumeData(QuicStreamId id,size_t write_length,QuicStreamOffset offset,StreamSendingState state,TransmissionType,std::optional<EncryptionLevel>)188   QuicConsumedData ConsumeData(QuicStreamId id, size_t write_length,
189                                QuicStreamOffset offset,
190                                StreamSendingState state,
191                                TransmissionType /*type*/,
192                                std::optional<EncryptionLevel> /*level*/) {
193     if (write_length > 0) {
194       auto buf = std::make_unique<char[]>(write_length);
195       QuicStream* stream = GetOrCreateStream(id);
196       QUICHE_DCHECK(stream);
197       QuicDataWriter writer(write_length, buf.get(), quiche::HOST_BYTE_ORDER);
198       stream->WriteStreamData(offset, write_length, &writer);
199     } else {
200       QUICHE_DCHECK(state != NO_FIN);
201     }
202     return QuicConsumedData(write_length, state != NO_FIN);
203   }
204 
205   spdy::Http2HeaderBlock original_request_headers_;
206 };
207 
208 class QuicSimpleServerStreamTest : public QuicTestWithParam<ParsedQuicVersion> {
209  public:
QuicSimpleServerStreamTest()210   QuicSimpleServerStreamTest()
211       : connection_(new StrictMock<MockQuicConnection>(
212             &simulator_, simulator_.GetAlarmFactory(), Perspective::IS_SERVER,
213             SupportedVersions(GetParam()))),
214         crypto_config_(new QuicCryptoServerConfig(
215             QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(),
216             crypto_test_utils::ProofSourceForTesting(),
217             KeyExchangeSource::Default())),
218         compressed_certs_cache_(
219             QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
220         session_(connection_, &session_owner_, &session_helper_,
221                  crypto_config_.get(), &compressed_certs_cache_,
222                  &memory_cache_backend_),
223         quic_response_(new QuicBackendResponse),
224         body_("hello world") {
225     connection_->set_visitor(&session_);
226     header_list_.OnHeaderBlockStart();
227     header_list_.OnHeader(":authority", "www.google.com");
228     header_list_.OnHeader(":path", "/");
229     header_list_.OnHeader(":method", "POST");
230     header_list_.OnHeader(":scheme", "https");
231     header_list_.OnHeader("content-length", "11");
232 
233     header_list_.OnHeaderBlockEnd(128, 128);
234 
235     // New streams rely on having the peer's flow control receive window
236     // negotiated in the config.
237     session_.config()->SetInitialStreamFlowControlWindowToSend(
238         kInitialStreamFlowControlWindowForTest);
239     session_.config()->SetInitialSessionFlowControlWindowToSend(
240         kInitialSessionFlowControlWindowForTest);
241     session_.Initialize();
242     connection_->SetEncrypter(
243         quic::ENCRYPTION_FORWARD_SECURE,
244         std::make_unique<quic::NullEncrypter>(connection_->perspective()));
245     if (connection_->version().SupportsAntiAmplificationLimit()) {
246       QuicConnectionPeer::SetAddressValidated(connection_);
247     }
248     stream_ = new StrictMock<TestStream>(
249         GetNthClientInitiatedBidirectionalStreamId(
250             connection_->transport_version(), 0),
251         &session_, BIDIRECTIONAL, &memory_cache_backend_);
252     // Register stream_ in dynamic_stream_map_ and pass ownership to session_.
253     session_.ActivateStream(absl::WrapUnique(stream_));
254     QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
255         session_.config(), kMinimumFlowControlSendWindow);
256     QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
257         session_.config(), kMinimumFlowControlSendWindow);
258     QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
259         session_.config(), kMinimumFlowControlSendWindow);
260     QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
261         session_.config(), kMinimumFlowControlSendWindow);
262     QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(session_.config(), 10);
263     session_.OnConfigNegotiated();
264     simulator_.RunFor(QuicTime::Delta::FromSeconds(1));
265   }
266 
StreamBody()267   const std::string& StreamBody() { return stream_->body(); }
268 
StreamHeadersValue(const std::string & key)269   std::string StreamHeadersValue(const std::string& key) {
270     return (*stream_->mutable_headers())[key].as_string();
271   }
272 
UsesHttp3() const273   bool UsesHttp3() const {
274     return VersionUsesHttp3(connection_->transport_version());
275   }
276 
ReplaceBackend(std::unique_ptr<QuicSimpleServerBackend> backend)277   void ReplaceBackend(std::unique_ptr<QuicSimpleServerBackend> backend) {
278     replacement_backend_ = std::move(backend);
279     stream_->ReplaceBackend(replacement_backend_.get());
280   }
281 
282   quic::simulator::Simulator simulator_;
283   spdy::Http2HeaderBlock response_headers_;
284   MockQuicConnectionHelper helper_;
285   StrictMock<MockQuicConnection>* connection_;
286   StrictMock<MockQuicSessionVisitor> session_owner_;
287   StrictMock<MockQuicCryptoServerStreamHelper> session_helper_;
288   std::unique_ptr<QuicCryptoServerConfig> crypto_config_;
289   QuicCompressedCertsCache compressed_certs_cache_;
290   QuicMemoryCacheBackend memory_cache_backend_;
291   std::unique_ptr<QuicSimpleServerBackend> replacement_backend_;
292   StrictMock<MockQuicSimpleServerSession> session_;
293   StrictMock<TestStream>* stream_;  // Owned by session_.
294   std::unique_ptr<QuicBackendResponse> quic_response_;
295   std::string body_;
296   QuicHeaderList header_list_;
297 };
298 
299 INSTANTIATE_TEST_SUITE_P(Tests, QuicSimpleServerStreamTest,
300                          ::testing::ValuesIn(AllSupportedVersions()),
301                          ::testing::PrintToStringParamName());
302 
TEST_P(QuicSimpleServerStreamTest,TestFraming)303 TEST_P(QuicSimpleServerStreamTest, TestFraming) {
304   EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
305       .WillRepeatedly(
306           Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
307   stream_->OnStreamHeaderList(false, kFakeFrameLen, header_list_);
308   quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
309       body_.length(), quiche::SimpleBufferAllocator::Get());
310   std::string data =
311       UsesHttp3() ? absl::StrCat(header.AsStringView(), body_) : body_;
312   stream_->OnStreamFrame(
313       QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
314   EXPECT_EQ("11", StreamHeadersValue("content-length"));
315   EXPECT_EQ("/", StreamHeadersValue(":path"));
316   EXPECT_EQ("POST", StreamHeadersValue(":method"));
317   EXPECT_EQ(body_, StreamBody());
318 }
319 
TEST_P(QuicSimpleServerStreamTest,TestFramingOnePacket)320 TEST_P(QuicSimpleServerStreamTest, TestFramingOnePacket) {
321   EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
322       .WillRepeatedly(
323           Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
324 
325   stream_->OnStreamHeaderList(false, kFakeFrameLen, header_list_);
326   quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
327       body_.length(), quiche::SimpleBufferAllocator::Get());
328   std::string data =
329       UsesHttp3() ? absl::StrCat(header.AsStringView(), body_) : body_;
330   stream_->OnStreamFrame(
331       QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
332   EXPECT_EQ("11", StreamHeadersValue("content-length"));
333   EXPECT_EQ("/", StreamHeadersValue(":path"));
334   EXPECT_EQ("POST", StreamHeadersValue(":method"));
335   EXPECT_EQ(body_, StreamBody());
336 }
337 
TEST_P(QuicSimpleServerStreamTest,SendQuicRstStreamNoErrorInStopReading)338 TEST_P(QuicSimpleServerStreamTest, SendQuicRstStreamNoErrorInStopReading) {
339   EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
340       .WillRepeatedly(
341           Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
342 
343   EXPECT_FALSE(stream_->fin_received());
344   EXPECT_FALSE(stream_->rst_received());
345 
346   QuicStreamPeer::SetFinSent(stream_);
347   stream_->CloseWriteSide();
348 
349   if (session_.version().UsesHttp3()) {
350     EXPECT_CALL(session_,
351                 MaybeSendStopSendingFrame(_, QuicResetStreamError::FromInternal(
352                                                  QUIC_STREAM_NO_ERROR)))
353         .Times(1);
354   } else {
355     EXPECT_CALL(
356         session_,
357         MaybeSendRstStreamFrame(
358             _, QuicResetStreamError::FromInternal(QUIC_STREAM_NO_ERROR), _))
359         .Times(1);
360   }
361   stream_->StopReading();
362 }
363 
TEST_P(QuicSimpleServerStreamTest,TestFramingExtraData)364 TEST_P(QuicSimpleServerStreamTest, TestFramingExtraData) {
365   InSequence seq;
366   std::string large_body = "hello world!!!!!!";
367 
368   // We'll automatically write out an error (headers + body)
369   EXPECT_CALL(*stream_, WriteHeadersMock(false));
370   if (UsesHttp3()) {
371     EXPECT_CALL(session_,
372                 WritevData(_, kDataFrameHeaderLength, _, NO_FIN, _, _));
373   }
374   EXPECT_CALL(session_, WritevData(_, kErrorLength, _, FIN, _, _));
375 
376   stream_->OnStreamHeaderList(false, kFakeFrameLen, header_list_);
377   quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
378       body_.length(), quiche::SimpleBufferAllocator::Get());
379   std::string data =
380       UsesHttp3() ? absl::StrCat(header.AsStringView(), body_) : body_;
381 
382   stream_->OnStreamFrame(
383       QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
384   // Content length is still 11.  This will register as an error and we won't
385   // accept the bytes.
386   header = HttpEncoder::SerializeDataFrameHeader(
387       large_body.length(), quiche::SimpleBufferAllocator::Get());
388   std::string data2 = UsesHttp3()
389                           ? absl::StrCat(header.AsStringView(), large_body)
390                           : large_body;
391   stream_->OnStreamFrame(
392       QuicStreamFrame(stream_->id(), /*fin=*/true, data.size(), data2));
393   EXPECT_EQ("11", StreamHeadersValue("content-length"));
394   EXPECT_EQ("/", StreamHeadersValue(":path"));
395   EXPECT_EQ("POST", StreamHeadersValue(":method"));
396 }
397 
TEST_P(QuicSimpleServerStreamTest,SendResponseWithIllegalResponseStatus)398 TEST_P(QuicSimpleServerStreamTest, SendResponseWithIllegalResponseStatus) {
399   // Send an illegal response with response status not supported by HTTP/2.
400   spdy::Http2HeaderBlock* request_headers = stream_->mutable_headers();
401   (*request_headers)[":path"] = "/bar";
402   (*request_headers)[":authority"] = "www.google.com";
403   (*request_headers)[":method"] = "GET";
404 
405   // HTTP/2 only supports integer responsecode, so "200 OK" is illegal.
406   response_headers_[":status"] = "200 OK";
407   response_headers_["content-length"] = "5";
408   std::string body = "Yummm";
409   quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
410       body.length(), quiche::SimpleBufferAllocator::Get());
411 
412   memory_cache_backend_.AddResponse("www.google.com", "/bar",
413                                     std::move(response_headers_), body);
414 
415   QuicStreamPeer::SetFinReceived(stream_);
416 
417   InSequence s;
418   EXPECT_CALL(*stream_, WriteHeadersMock(false));
419   if (UsesHttp3()) {
420     EXPECT_CALL(session_, WritevData(_, header.size(), _, NO_FIN, _, _));
421   }
422   EXPECT_CALL(session_, WritevData(_, kErrorLength, _, FIN, _, _));
423 
424   stream_->DoSendResponse();
425   EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
426   EXPECT_TRUE(stream_->write_side_closed());
427 }
428 
TEST_P(QuicSimpleServerStreamTest,SendResponseWithIllegalResponseStatus2)429 TEST_P(QuicSimpleServerStreamTest, SendResponseWithIllegalResponseStatus2) {
430   // Send an illegal response with response status not supported by HTTP/2.
431   spdy::Http2HeaderBlock* request_headers = stream_->mutable_headers();
432   (*request_headers)[":path"] = "/bar";
433   (*request_headers)[":authority"] = "www.google.com";
434   (*request_headers)[":method"] = "GET";
435 
436   // HTTP/2 only supports 3-digit-integer, so "+200" is illegal.
437   response_headers_[":status"] = "+200";
438   response_headers_["content-length"] = "5";
439   std::string body = "Yummm";
440 
441   quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
442       body.length(), quiche::SimpleBufferAllocator::Get());
443 
444   memory_cache_backend_.AddResponse("www.google.com", "/bar",
445                                     std::move(response_headers_), body);
446 
447   QuicStreamPeer::SetFinReceived(stream_);
448 
449   InSequence s;
450   EXPECT_CALL(*stream_, WriteHeadersMock(false));
451   if (UsesHttp3()) {
452     EXPECT_CALL(session_, WritevData(_, header.size(), _, NO_FIN, _, _));
453   }
454   EXPECT_CALL(session_, WritevData(_, kErrorLength, _, FIN, _, _));
455 
456   stream_->DoSendResponse();
457   EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
458   EXPECT_TRUE(stream_->write_side_closed());
459 }
460 
TEST_P(QuicSimpleServerStreamTest,SendResponseWithValidHeaders)461 TEST_P(QuicSimpleServerStreamTest, SendResponseWithValidHeaders) {
462   // Add a request and response with valid headers.
463   spdy::Http2HeaderBlock* request_headers = stream_->mutable_headers();
464   (*request_headers)[":path"] = "/bar";
465   (*request_headers)[":authority"] = "www.google.com";
466   (*request_headers)[":method"] = "GET";
467 
468   response_headers_[":status"] = "200";
469   response_headers_["content-length"] = "5";
470   std::string body = "Yummm";
471 
472   quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
473       body.length(), quiche::SimpleBufferAllocator::Get());
474 
475   memory_cache_backend_.AddResponse("www.google.com", "/bar",
476                                     std::move(response_headers_), body);
477   QuicStreamPeer::SetFinReceived(stream_);
478 
479   InSequence s;
480   EXPECT_CALL(*stream_, WriteHeadersMock(false));
481   if (UsesHttp3()) {
482     EXPECT_CALL(session_, WritevData(_, header.size(), _, NO_FIN, _, _));
483   }
484   EXPECT_CALL(session_, WritevData(_, body.length(), _, FIN, _, _));
485 
486   stream_->DoSendResponse();
487   EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
488   EXPECT_TRUE(stream_->write_side_closed());
489 }
490 
TEST_P(QuicSimpleServerStreamTest,SendResponseWithEarlyHints)491 TEST_P(QuicSimpleServerStreamTest, SendResponseWithEarlyHints) {
492   std::string host = "www.google.com";
493   std::string request_path = "/foo";
494   std::string body = "Yummm";
495 
496   // Add a request and response with early hints.
497   spdy::Http2HeaderBlock* request_headers = stream_->mutable_headers();
498   (*request_headers)[":path"] = request_path;
499   (*request_headers)[":authority"] = host;
500   (*request_headers)[":method"] = "GET";
501 
502   quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
503       body.length(), quiche::SimpleBufferAllocator::Get());
504   std::vector<spdy::Http2HeaderBlock> early_hints;
505   // Add two Early Hints.
506   const size_t kNumEarlyHintsResponses = 2;
507   for (size_t i = 0; i < kNumEarlyHintsResponses; ++i) {
508     spdy::Http2HeaderBlock hints;
509     hints["link"] = "</image.png>; rel=preload; as=image";
510     early_hints.push_back(std::move(hints));
511   }
512 
513   response_headers_[":status"] = "200";
514   response_headers_["content-length"] = "5";
515   memory_cache_backend_.AddResponseWithEarlyHints(
516       host, request_path, std::move(response_headers_), body, early_hints);
517   QuicStreamPeer::SetFinReceived(stream_);
518 
519   InSequence s;
520   for (size_t i = 0; i < kNumEarlyHintsResponses; ++i) {
521     EXPECT_CALL(*stream_, WriteEarlyHintsHeadersMock(false));
522   }
523   EXPECT_CALL(*stream_, WriteHeadersMock(false));
524   if (UsesHttp3()) {
525     EXPECT_CALL(session_, WritevData(_, header.size(), _, NO_FIN, _, _));
526   }
527   EXPECT_CALL(session_, WritevData(_, body.length(), _, FIN, _, _));
528 
529   stream_->DoSendResponse();
530   EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
531   EXPECT_TRUE(stream_->write_side_closed());
532 }
533 
534 class AlarmTestDelegate : public QuicAlarm::DelegateWithoutContext {
535  public:
AlarmTestDelegate(TestStream * stream)536   AlarmTestDelegate(TestStream* stream) : stream_(stream) {}
537 
OnAlarm()538   void OnAlarm() override { stream_->FireAlarmMock(); }
539 
540  private:
541   TestStream* stream_;
542 };
543 
TEST_P(QuicSimpleServerStreamTest,SendResponseWithDelay)544 TEST_P(QuicSimpleServerStreamTest, SendResponseWithDelay) {
545   // Add a request and response with valid headers.
546   spdy::Http2HeaderBlock* request_headers = stream_->mutable_headers();
547   std::string host = "www.google.com";
548   std::string path = "/bar";
549   (*request_headers)[":path"] = path;
550   (*request_headers)[":authority"] = host;
551   (*request_headers)[":method"] = "GET";
552 
553   response_headers_[":status"] = "200";
554   response_headers_["content-length"] = "5";
555   std::string body = "Yummm";
556   QuicTime::Delta delay = QuicTime::Delta::FromMilliseconds(3000);
557 
558   quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
559       body.length(), quiche::SimpleBufferAllocator::Get());
560 
561   memory_cache_backend_.AddResponse(host, path, std::move(response_headers_),
562                                     body);
563   auto did_delay_succeed =
564       memory_cache_backend_.SetResponseDelay(host, path, delay);
565   EXPECT_TRUE(did_delay_succeed);
566   auto did_invalid_delay_succeed =
567       memory_cache_backend_.SetResponseDelay(host, "nonsense", delay);
568   EXPECT_FALSE(did_invalid_delay_succeed);
569   std::unique_ptr<QuicAlarm> alarm(connection_->alarm_factory()->CreateAlarm(
570       new AlarmTestDelegate(stream_)));
571   alarm->Set(connection_->clock()->Now() + delay);
572   QuicStreamPeer::SetFinReceived(stream_);
573   InSequence s;
574   EXPECT_CALL(*stream_, FireAlarmMock());
575   EXPECT_CALL(*stream_, WriteHeadersMock(false));
576 
577   if (UsesHttp3()) {
578     EXPECT_CALL(session_, WritevData(_, header.size(), _, NO_FIN, _, _));
579   }
580   EXPECT_CALL(session_, WritevData(_, body.length(), _, FIN, _, _));
581 
582   stream_->DoSendResponse();
583   simulator_.RunFor(delay);
584 
585   EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
586   EXPECT_TRUE(stream_->write_side_closed());
587 }
588 
TEST_P(QuicSimpleServerStreamTest,TestSendErrorResponse)589 TEST_P(QuicSimpleServerStreamTest, TestSendErrorResponse) {
590   QuicStreamPeer::SetFinReceived(stream_);
591 
592   InSequence s;
593   EXPECT_CALL(*stream_, WriteHeadersMock(false));
594   if (UsesHttp3()) {
595     EXPECT_CALL(session_,
596                 WritevData(_, kDataFrameHeaderLength, _, NO_FIN, _, _));
597   }
598   EXPECT_CALL(session_, WritevData(_, kErrorLength, _, FIN, _, _));
599 
600   stream_->DoSendErrorResponse();
601   EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
602   EXPECT_TRUE(stream_->write_side_closed());
603 }
604 
TEST_P(QuicSimpleServerStreamTest,InvalidMultipleContentLength)605 TEST_P(QuicSimpleServerStreamTest, InvalidMultipleContentLength) {
606   spdy::Http2HeaderBlock request_headers;
607   // \000 is a way to write the null byte when followed by a literal digit.
608   header_list_.OnHeader("content-length", absl::string_view("11\00012", 5));
609 
610   if (session_.version().UsesHttp3()) {
611     EXPECT_CALL(session_,
612                 MaybeSendStopSendingFrame(_, QuicResetStreamError::FromInternal(
613                                                  QUIC_STREAM_NO_ERROR)));
614   }
615   EXPECT_CALL(*stream_, WriteHeadersMock(false));
616   EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
617       .WillRepeatedly(
618           Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
619   stream_->OnStreamHeaderList(true, kFakeFrameLen, header_list_);
620 
621   EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream_));
622   EXPECT_TRUE(stream_->reading_stopped());
623   EXPECT_TRUE(stream_->write_side_closed());
624 }
625 
TEST_P(QuicSimpleServerStreamTest,InvalidLeadingNullContentLength)626 TEST_P(QuicSimpleServerStreamTest, InvalidLeadingNullContentLength) {
627   spdy::Http2HeaderBlock request_headers;
628   // \000 is a way to write the null byte when followed by a literal digit.
629   header_list_.OnHeader("content-length", absl::string_view("\00012", 3));
630 
631   if (session_.version().UsesHttp3()) {
632     EXPECT_CALL(session_,
633                 MaybeSendStopSendingFrame(_, QuicResetStreamError::FromInternal(
634                                                  QUIC_STREAM_NO_ERROR)));
635   }
636   EXPECT_CALL(*stream_, WriteHeadersMock(false));
637   EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
638       .WillRepeatedly(
639           Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
640   stream_->OnStreamHeaderList(true, kFakeFrameLen, header_list_);
641 
642   EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream_));
643   EXPECT_TRUE(stream_->reading_stopped());
644   EXPECT_TRUE(stream_->write_side_closed());
645 }
646 
TEST_P(QuicSimpleServerStreamTest,InvalidMultipleContentLengthII)647 TEST_P(QuicSimpleServerStreamTest, InvalidMultipleContentLengthII) {
648   spdy::Http2HeaderBlock request_headers;
649   // \000 is a way to write the null byte when followed by a literal digit.
650   header_list_.OnHeader("content-length", absl::string_view("11\00011", 5));
651 
652   if (session_.version().UsesHttp3()) {
653     EXPECT_CALL(session_,
654                 MaybeSendStopSendingFrame(_, QuicResetStreamError::FromInternal(
655                                                  QUIC_STREAM_NO_ERROR)));
656     EXPECT_CALL(*stream_, WriteHeadersMock(false));
657     EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
658         .WillRepeatedly(
659             Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
660   }
661 
662   stream_->OnStreamHeaderList(false, kFakeFrameLen, header_list_);
663 
664   if (session_.version().UsesHttp3()) {
665     EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream_));
666     EXPECT_TRUE(stream_->reading_stopped());
667     EXPECT_TRUE(stream_->write_side_closed());
668   } else {
669     EXPECT_EQ(11, stream_->content_length());
670     EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
671     EXPECT_FALSE(stream_->reading_stopped());
672     EXPECT_FALSE(stream_->write_side_closed());
673   }
674 }
675 
TEST_P(QuicSimpleServerStreamTest,DoNotSendQuicRstStreamNoErrorWithRstReceived)676 TEST_P(QuicSimpleServerStreamTest,
677        DoNotSendQuicRstStreamNoErrorWithRstReceived) {
678   EXPECT_FALSE(stream_->reading_stopped());
679 
680   if (VersionUsesHttp3(connection_->transport_version())) {
681     // Unidirectional stream type and then a Stream Cancellation instruction is
682     // sent on the QPACK decoder stream.  Ignore these writes without any
683     // assumption on their number or size.
684     auto* qpack_decoder_stream =
685         QuicSpdySessionPeer::GetQpackDecoderSendStream(&session_);
686     EXPECT_CALL(session_, WritevData(qpack_decoder_stream->id(), _, _, _, _, _))
687         .Times(AnyNumber());
688   }
689 
690   EXPECT_CALL(
691       session_,
692       MaybeSendRstStreamFrame(
693           _,
694           session_.version().UsesHttp3()
695               ? QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED)
696               : QuicResetStreamError::FromInternal(QUIC_RST_ACKNOWLEDGEMENT),
697           _))
698       .Times(1);
699   QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
700                                QUIC_STREAM_CANCELLED, 1234);
701   stream_->OnStreamReset(rst_frame);
702   if (VersionHasIetfQuicFrames(connection_->transport_version())) {
703     EXPECT_CALL(session_owner_, OnStopSendingReceived(_));
704     // Create and inject a STOP SENDING frame to complete the close
705     // of the stream. This is only needed for version 99/IETF QUIC.
706     QuicStopSendingFrame stop_sending(kInvalidControlFrameId, stream_->id(),
707                                       QUIC_STREAM_CANCELLED);
708     session_.OnStopSendingFrame(stop_sending);
709   }
710   EXPECT_TRUE(stream_->reading_stopped());
711   EXPECT_TRUE(stream_->write_side_closed());
712 }
713 
TEST_P(QuicSimpleServerStreamTest,InvalidHeadersWithFin)714 TEST_P(QuicSimpleServerStreamTest, InvalidHeadersWithFin) {
715   char arr[] = {
716       0x3a,   0x68, 0x6f, 0x73,  // :hos
717       0x74,   0x00, 0x00, 0x00,  // t...
718       0x00,   0x00, 0x00, 0x00,  // ....
719       0x07,   0x3a, 0x6d, 0x65,  // .:me
720       0x74,   0x68, 0x6f, 0x64,  // thod
721       0x00,   0x00, 0x00, 0x03,  // ....
722       0x47,   0x45, 0x54, 0x00,  // GET.
723       0x00,   0x00, 0x05, 0x3a,  // ...:
724       0x70,   0x61, 0x74, 0x68,  // path
725       0x00,   0x00, 0x00, 0x04,  // ....
726       0x2f,   0x66, 0x6f, 0x6f,  // /foo
727       0x00,   0x00, 0x00, 0x07,  // ....
728       0x3a,   0x73, 0x63, 0x68,  // :sch
729       0x65,   0x6d, 0x65, 0x00,  // eme.
730       0x00,   0x00, 0x00, 0x00,  // ....
731       0x00,   0x00, 0x08, 0x3a,  // ...:
732       0x76,   0x65, 0x72, 0x73,  // vers
733       '\x96', 0x6f, 0x6e, 0x00,  // <i(69)>on.
734       0x00,   0x00, 0x08, 0x48,  // ...H
735       0x54,   0x54, 0x50, 0x2f,  // TTP/
736       0x31,   0x2e, 0x31,        // 1.1
737   };
738   absl::string_view data(arr, ABSL_ARRAYSIZE(arr));
739   QuicStreamFrame frame(stream_->id(), true, 0, data);
740   // Verify that we don't crash when we get a invalid headers in stream frame.
741   stream_->OnStreamFrame(frame);
742 }
743 
744 // Basic QuicSimpleServerBackend that implements its behavior through mocking.
745 class TestQuicSimpleServerBackend : public QuicSimpleServerBackend {
746  public:
747   TestQuicSimpleServerBackend() = default;
748   ~TestQuicSimpleServerBackend() override = default;
749 
750   // QuicSimpleServerBackend:
InitializeBackend(const std::string &)751   bool InitializeBackend(const std::string& /*backend_url*/) override {
752     return true;
753   }
IsBackendInitialized() const754   bool IsBackendInitialized() const override { return true; }
755   MOCK_METHOD(void, FetchResponseFromBackend,
756               (const spdy::Http2HeaderBlock&, const std::string&,
757                RequestHandler*),
758               (override));
759   MOCK_METHOD(void, HandleConnectHeaders,
760               (const spdy::Http2HeaderBlock&, RequestHandler*), (override));
761   MOCK_METHOD(void, HandleConnectData,
762               (absl::string_view, bool, RequestHandler*), (override));
CloseBackendResponseStream(RequestHandler *)763   void CloseBackendResponseStream(
764       RequestHandler* /*request_handler*/) override {}
765 };
766 
ACTION_P(SendHeadersResponse,response_ptr)767 ACTION_P(SendHeadersResponse, response_ptr) {
768   arg1->OnResponseBackendComplete(response_ptr);
769 }
770 
ACTION_P(SendStreamData,data,close_stream)771 ACTION_P(SendStreamData, data, close_stream) {
772   arg2->SendStreamData(data, close_stream);
773 }
774 
ACTION_P(TerminateStream,error)775 ACTION_P(TerminateStream, error) { arg1->TerminateStreamWithError(error); }
776 
TEST_P(QuicSimpleServerStreamTest,ConnectSendsIntermediateResponses)777 TEST_P(QuicSimpleServerStreamTest, ConnectSendsIntermediateResponses) {
778   auto test_backend = std::make_unique<TestQuicSimpleServerBackend>();
779   TestQuicSimpleServerBackend* test_backend_ptr = test_backend.get();
780   ReplaceBackend(std::move(test_backend));
781 
782   constexpr absl::string_view kRequestBody = "\x11\x11";
783   spdy::Http2HeaderBlock response_headers;
784   response_headers[":status"] = "200";
785   QuicBackendResponse headers_response;
786   headers_response.set_headers(response_headers.Clone());
787   headers_response.set_response_type(QuicBackendResponse::INCOMPLETE_RESPONSE);
788   constexpr absl::string_view kBody1 = "\x22\x22";
789   constexpr absl::string_view kBody2 = "\x33\x33";
790 
791   // Expect an initial headers-only request to result in a headers-only
792   // incomplete response. Then a data frame without fin, resulting in stream
793   // data. Then a data frame with fin, resulting in stream data with fin.
794   InSequence s;
795   EXPECT_CALL(*test_backend_ptr, HandleConnectHeaders(_, _))
796       .WillOnce(SendHeadersResponse(&headers_response));
797   EXPECT_CALL(*stream_, WriteHeadersMock(false));
798   EXPECT_CALL(*test_backend_ptr, HandleConnectData(kRequestBody, false, _))
799       .WillOnce(SendStreamData(kBody1,
800                                /*close_stream=*/false));
801   EXPECT_CALL(*stream_, WriteOrBufferBody(kBody1, false));
802   EXPECT_CALL(*test_backend_ptr, HandleConnectData(kRequestBody, true, _))
803       .WillOnce(SendStreamData(kBody2,
804                                /*close_stream=*/true));
805   EXPECT_CALL(*stream_, WriteOrBufferBody(kBody2, true));
806 
807   QuicHeaderList header_list;
808   header_list.OnHeaderBlockStart();
809   header_list.OnHeader(":authority", "www.google.com:4433");
810   header_list.OnHeader(":method", "CONNECT");
811   header_list.OnHeaderBlockEnd(128, 128);
812 
813   stream_->OnStreamHeaderList(/*fin=*/false, kFakeFrameLen, header_list);
814   quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
815       kRequestBody.length(), quiche::SimpleBufferAllocator::Get());
816   std::string data = UsesHttp3()
817                          ? absl::StrCat(header.AsStringView(), kRequestBody)
818                          : std::string(kRequestBody);
819   stream_->OnStreamFrame(
820       QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
821   stream_->OnStreamFrame(
822       QuicStreamFrame(stream_->id(), /*fin=*/true, data.length(), data));
823 
824   // Expect to not go through SendResponse().
825   EXPECT_FALSE(stream_->send_response_was_called());
826   EXPECT_FALSE(stream_->send_error_response_was_called());
827 }
828 
TEST_P(QuicSimpleServerStreamTest,ErrorOnUnhandledConnect)829 TEST_P(QuicSimpleServerStreamTest, ErrorOnUnhandledConnect) {
830   // Expect single set of failure response headers with FIN in response to the
831   // headers. Then, expect abrupt stream termination in response to the body.
832   EXPECT_CALL(*stream_, WriteHeadersMock(true));
833   EXPECT_CALL(session_, MaybeSendRstStreamFrame(stream_->id(), _, _));
834 
835   QuicHeaderList header_list;
836   header_list.OnHeaderBlockStart();
837   header_list.OnHeader(":authority", "www.google.com:4433");
838   header_list.OnHeader(":method", "CONNECT");
839   header_list.OnHeaderBlockEnd(128, 128);
840   constexpr absl::string_view kRequestBody = "\x11\x11";
841 
842   stream_->OnStreamHeaderList(/*fin=*/false, kFakeFrameLen, header_list);
843   quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
844       kRequestBody.length(), quiche::SimpleBufferAllocator::Get());
845   std::string data = UsesHttp3()
846                          ? absl::StrCat(header.AsStringView(), kRequestBody)
847                          : std::string(kRequestBody);
848   stream_->OnStreamFrame(
849       QuicStreamFrame(stream_->id(), /*fin=*/true, /*offset=*/0, data));
850 
851   // Expect failure to not go through SendResponse().
852   EXPECT_FALSE(stream_->send_response_was_called());
853   EXPECT_FALSE(stream_->send_error_response_was_called());
854 }
855 
TEST_P(QuicSimpleServerStreamTest,ConnectWithInvalidHeader)856 TEST_P(QuicSimpleServerStreamTest, ConnectWithInvalidHeader) {
857   EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
858       .WillRepeatedly(
859           Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
860   QuicHeaderList header_list;
861   header_list.OnHeaderBlockStart();
862   header_list.OnHeader(":authority", "www.google.com:4433");
863   header_list.OnHeader(":method", "CONNECT");
864   // QUIC requires lower-case header names.
865   header_list.OnHeader("InVaLiD-HeAdEr", "Well that's just wrong!");
866   header_list.OnHeaderBlockEnd(128, 128);
867 
868   if (UsesHttp3()) {
869     EXPECT_CALL(session_,
870                 MaybeSendStopSendingFrame(_, QuicResetStreamError::FromInternal(
871                                                  QUIC_STREAM_NO_ERROR)))
872         .Times(1);
873   } else {
874     EXPECT_CALL(
875         session_,
876         MaybeSendRstStreamFrame(
877             _, QuicResetStreamError::FromInternal(QUIC_STREAM_NO_ERROR), _))
878         .Times(1);
879   }
880   EXPECT_CALL(*stream_, WriteHeadersMock(/*fin=*/false));
881   stream_->OnStreamHeaderList(/*fin=*/false, kFakeFrameLen, header_list);
882   EXPECT_FALSE(stream_->send_response_was_called());
883   EXPECT_TRUE(stream_->send_error_response_was_called());
884 }
885 
TEST_P(QuicSimpleServerStreamTest,BackendCanTerminateStream)886 TEST_P(QuicSimpleServerStreamTest, BackendCanTerminateStream) {
887   auto test_backend = std::make_unique<TestQuicSimpleServerBackend>();
888   TestQuicSimpleServerBackend* test_backend_ptr = test_backend.get();
889   ReplaceBackend(std::move(test_backend));
890 
891   EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
892       .WillRepeatedly(
893           Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
894 
895   QuicResetStreamError expected_error =
896       QuicResetStreamError::FromInternal(QUIC_STREAM_CONNECT_ERROR);
897   EXPECT_CALL(*test_backend_ptr, HandleConnectHeaders(_, _))
898       .WillOnce(TerminateStream(expected_error));
899   EXPECT_CALL(session_,
900               MaybeSendRstStreamFrame(stream_->id(), expected_error, _));
901 
902   QuicHeaderList header_list;
903   header_list.OnHeaderBlockStart();
904   header_list.OnHeader(":authority", "www.google.com:4433");
905   header_list.OnHeader(":method", "CONNECT");
906   header_list.OnHeaderBlockEnd(128, 128);
907   stream_->OnStreamHeaderList(/*fin=*/false, kFakeFrameLen, header_list);
908 }
909 
910 }  // namespace
911 }  // namespace test
912 }  // namespace quic
913