xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/http/quic_headers_stream_test.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 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/core/http/quic_headers_stream.h"
6 
7 #include <cstdint>
8 #include <ostream>
9 #include <string>
10 #include <tuple>
11 #include <utility>
12 #include <vector>
13 
14 #include "absl/strings/str_cat.h"
15 #include "absl/strings/string_view.h"
16 #include "quiche/quic/core/crypto/null_encrypter.h"
17 #include "quiche/quic/core/http/spdy_utils.h"
18 #include "quiche/quic/core/quic_data_writer.h"
19 #include "quiche/quic/core/quic_utils.h"
20 #include "quiche/quic/platform/api/quic_bug_tracker.h"
21 #include "quiche/quic/platform/api/quic_expect_bug.h"
22 #include "quiche/quic/platform/api/quic_flags.h"
23 #include "quiche/quic/platform/api/quic_logging.h"
24 #include "quiche/quic/platform/api/quic_test.h"
25 #include "quiche/quic/test_tools/quic_connection_peer.h"
26 #include "quiche/quic/test_tools/quic_spdy_session_peer.h"
27 #include "quiche/quic/test_tools/quic_stream_peer.h"
28 #include "quiche/quic/test_tools/quic_test_utils.h"
29 #include "quiche/common/quiche_endian.h"
30 #include "quiche/spdy/core/http2_frame_decoder_adapter.h"
31 #include "quiche/spdy/core/http2_header_block.h"
32 #include "quiche/spdy/core/recording_headers_handler.h"
33 #include "quiche/spdy/core/spdy_alt_svc_wire_format.h"
34 #include "quiche/spdy/core/spdy_protocol.h"
35 #include "quiche/spdy/test_tools/spdy_test_utils.h"
36 
37 using spdy::ERROR_CODE_PROTOCOL_ERROR;
38 using spdy::Http2HeaderBlock;
39 using spdy::RecordingHeadersHandler;
40 using spdy::SETTINGS_ENABLE_PUSH;
41 using spdy::SETTINGS_HEADER_TABLE_SIZE;
42 using spdy::SETTINGS_INITIAL_WINDOW_SIZE;
43 using spdy::SETTINGS_MAX_CONCURRENT_STREAMS;
44 using spdy::SETTINGS_MAX_FRAME_SIZE;
45 using spdy::Spdy3PriorityToHttp2Weight;
46 using spdy::SpdyAltSvcWireFormat;
47 using spdy::SpdyDataIR;
48 using spdy::SpdyErrorCode;
49 using spdy::SpdyFramer;
50 using spdy::SpdyFramerVisitorInterface;
51 using spdy::SpdyGoAwayIR;
52 using spdy::SpdyHeadersHandlerInterface;
53 using spdy::SpdyHeadersIR;
54 using spdy::SpdyPingId;
55 using spdy::SpdyPingIR;
56 using spdy::SpdyPriority;
57 using spdy::SpdyPriorityIR;
58 using spdy::SpdyPushPromiseIR;
59 using spdy::SpdyRstStreamIR;
60 using spdy::SpdySerializedFrame;
61 using spdy::SpdySettingsId;
62 using spdy::SpdySettingsIR;
63 using spdy::SpdyStreamId;
64 using spdy::SpdyWindowUpdateIR;
65 using testing::_;
66 using testing::AnyNumber;
67 using testing::AtLeast;
68 using testing::InSequence;
69 using testing::Invoke;
70 using testing::Return;
71 using testing::StrictMock;
72 using testing::WithArgs;
73 
74 namespace quic {
75 namespace test {
76 namespace {
77 
78 class MockVisitor : public SpdyFramerVisitorInterface {
79  public:
80   MOCK_METHOD(void, OnError,
81               (http2::Http2DecoderAdapter::SpdyFramerError error,
82                std::string detailed_error),
83               (override));
84   MOCK_METHOD(void, OnDataFrameHeader,
85               (SpdyStreamId stream_id, size_t length, bool fin), (override));
86   MOCK_METHOD(void, OnStreamFrameData,
87               (SpdyStreamId stream_id, const char*, size_t len), (override));
88   MOCK_METHOD(void, OnStreamEnd, (SpdyStreamId stream_id), (override));
89   MOCK_METHOD(void, OnStreamPadding, (SpdyStreamId stream_id, size_t len),
90               (override));
91   MOCK_METHOD(SpdyHeadersHandlerInterface*, OnHeaderFrameStart,
92               (SpdyStreamId stream_id), (override));
93   MOCK_METHOD(void, OnHeaderFrameEnd, (SpdyStreamId stream_id), (override));
94   MOCK_METHOD(void, OnRstStream,
95               (SpdyStreamId stream_id, SpdyErrorCode error_code), (override));
96   MOCK_METHOD(void, OnSettings, (), (override));
97   MOCK_METHOD(void, OnSetting, (SpdySettingsId id, uint32_t value), (override));
98   MOCK_METHOD(void, OnSettingsAck, (), (override));
99   MOCK_METHOD(void, OnSettingsEnd, (), (override));
100   MOCK_METHOD(void, OnPing, (SpdyPingId unique_id, bool is_ack), (override));
101   MOCK_METHOD(void, OnGoAway,
102               (SpdyStreamId last_accepted_stream_id, SpdyErrorCode error_code),
103               (override));
104   MOCK_METHOD(void, OnHeaders,
105               (SpdyStreamId stream_id, size_t payload_length, bool has_priority,
106                int weight, SpdyStreamId parent_stream_id, bool exclusive,
107                bool fin, bool end),
108               (override));
109   MOCK_METHOD(void, OnWindowUpdate,
110               (SpdyStreamId stream_id, int delta_window_size), (override));
111   MOCK_METHOD(void, OnPushPromise,
112               (SpdyStreamId stream_id, SpdyStreamId promised_stream_id,
113                bool end),
114               (override));
115   MOCK_METHOD(void, OnContinuation,
116               (SpdyStreamId stream_id, size_t payload_size, bool end),
117               (override));
118   MOCK_METHOD(
119       void, OnAltSvc,
120       (SpdyStreamId stream_id, absl::string_view origin,
121        const SpdyAltSvcWireFormat::AlternativeServiceVector& altsvc_vector),
122       (override));
123   MOCK_METHOD(void, OnPriority,
124               (SpdyStreamId stream_id, SpdyStreamId parent_stream_id,
125                int weight, bool exclusive),
126               (override));
127   MOCK_METHOD(void, OnPriorityUpdate,
128               (SpdyStreamId prioritized_stream_id,
129                absl::string_view priority_field_value),
130               (override));
131   MOCK_METHOD(bool, OnUnknownFrame,
132               (SpdyStreamId stream_id, uint8_t frame_type), (override));
133   MOCK_METHOD(void, OnUnknownFrameStart,
134               (SpdyStreamId stream_id, size_t length, uint8_t type,
135                uint8_t flags),
136               (override));
137   MOCK_METHOD(void, OnUnknownFramePayload,
138               (SpdyStreamId stream_id, absl::string_view payload), (override));
139 };
140 
141 struct TestParams {
TestParamsquic::test::__anon118f3eb60111::TestParams142   TestParams(const ParsedQuicVersion& version, Perspective perspective)
143       : version(version), perspective(perspective) {
144     QUIC_LOG(INFO) << "TestParams:  " << *this;
145   }
146 
TestParamsquic::test::__anon118f3eb60111::TestParams147   TestParams(const TestParams& other)
148       : version(other.version), perspective(other.perspective) {}
149 
operator <<(std::ostream & os,const TestParams & tp)150   friend std::ostream& operator<<(std::ostream& os, const TestParams& tp) {
151     os << "{ version: " << ParsedQuicVersionToString(tp.version)
152        << ", perspective: "
153        << (tp.perspective == Perspective::IS_CLIENT ? "client" : "server")
154        << "}";
155     return os;
156   }
157 
158   ParsedQuicVersion version;
159   Perspective perspective;
160 };
161 
162 // Used by ::testing::PrintToStringParamName().
PrintToString(const TestParams & tp)163 std::string PrintToString(const TestParams& tp) {
164   return absl::StrCat(
165       ParsedQuicVersionToString(tp.version), "_",
166       (tp.perspective == Perspective::IS_CLIENT ? "client" : "server"));
167 }
168 
GetTestParams()169 std::vector<TestParams> GetTestParams() {
170   std::vector<TestParams> params;
171   ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
172   for (size_t i = 0; i < all_supported_versions.size(); ++i) {
173     if (VersionUsesHttp3(all_supported_versions[i].transport_version)) {
174       continue;
175     }
176     for (Perspective p : {Perspective::IS_SERVER, Perspective::IS_CLIENT}) {
177       params.emplace_back(all_supported_versions[i], p);
178     }
179   }
180   return params;
181 }
182 
183 class QuicHeadersStreamTest : public QuicTestWithParam<TestParams> {
184  public:
QuicHeadersStreamTest()185   QuicHeadersStreamTest()
186       : connection_(new StrictMock<MockQuicConnection>(
187             &helper_, &alarm_factory_, perspective(), GetVersion())),
188         session_(connection_),
189         body_("hello world"),
190         stream_frame_(
191             QuicUtils::GetHeadersStreamId(connection_->transport_version()),
192             /*fin=*/false,
193             /*offset=*/0, ""),
194         next_promised_stream_id_(2) {
195     QuicSpdySessionPeer::SetMaxInboundHeaderListSize(&session_, 256 * 1024);
196     EXPECT_CALL(session_, OnCongestionWindowChange(_)).Times(AnyNumber());
197     session_.Initialize();
198     connection_->SetEncrypter(
199         quic::ENCRYPTION_FORWARD_SECURE,
200         std::make_unique<quic::NullEncrypter>(connection_->perspective()));
201     headers_stream_ = QuicSpdySessionPeer::GetHeadersStream(&session_);
202     headers_[":status"] = "200 Ok";
203     headers_["content-length"] = "11";
204     framer_ = std::unique_ptr<SpdyFramer>(
205         new SpdyFramer(SpdyFramer::ENABLE_COMPRESSION));
206     deframer_ = std::unique_ptr<http2::Http2DecoderAdapter>(
207         new http2::Http2DecoderAdapter());
208     deframer_->set_visitor(&visitor_);
209     EXPECT_EQ(transport_version(), session_.transport_version());
210     EXPECT_TRUE(headers_stream_ != nullptr);
211     connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
212     client_id_1_ = GetNthClientInitiatedBidirectionalStreamId(
213         connection_->transport_version(), 0);
214     client_id_2_ = GetNthClientInitiatedBidirectionalStreamId(
215         connection_->transport_version(), 1);
216     client_id_3_ = GetNthClientInitiatedBidirectionalStreamId(
217         connection_->transport_version(), 2);
218     next_stream_id_ =
219         QuicUtils::StreamIdDelta(connection_->transport_version());
220   }
221 
GetNthClientInitiatedId(int n)222   QuicStreamId GetNthClientInitiatedId(int n) {
223     return GetNthClientInitiatedBidirectionalStreamId(
224         connection_->transport_version(), n);
225   }
226 
SaveIov(size_t write_length)227   QuicConsumedData SaveIov(size_t write_length) {
228     char* buf = new char[write_length];
229     QuicDataWriter writer(write_length, buf, quiche::NETWORK_BYTE_ORDER);
230     headers_stream_->WriteStreamData(headers_stream_->stream_bytes_written(),
231                                      write_length, &writer);
232     saved_data_.append(buf, write_length);
233     delete[] buf;
234     return QuicConsumedData(write_length, false);
235   }
236 
SavePayload(const char * data,size_t len)237   void SavePayload(const char* data, size_t len) {
238     saved_payloads_.append(data, len);
239   }
240 
SaveHeaderData(const char * data,int len)241   bool SaveHeaderData(const char* data, int len) {
242     saved_header_data_.append(data, len);
243     return true;
244   }
245 
SaveHeaderDataStringPiece(absl::string_view data)246   void SaveHeaderDataStringPiece(absl::string_view data) {
247     saved_header_data_.append(data.data(), data.length());
248   }
249 
SavePromiseHeaderList(QuicStreamId,QuicStreamId,size_t size,const QuicHeaderList & header_list)250   void SavePromiseHeaderList(QuicStreamId /* stream_id */,
251                              QuicStreamId /* promised_stream_id */, size_t size,
252                              const QuicHeaderList& header_list) {
253     SaveToHandler(size, header_list);
254   }
255 
SaveHeaderList(QuicStreamId,bool,size_t size,const QuicHeaderList & header_list)256   void SaveHeaderList(QuicStreamId /* stream_id */, bool /* fin */, size_t size,
257                       const QuicHeaderList& header_list) {
258     SaveToHandler(size, header_list);
259   }
260 
SaveToHandler(size_t size,const QuicHeaderList & header_list)261   void SaveToHandler(size_t size, const QuicHeaderList& header_list) {
262     headers_handler_ = std::make_unique<RecordingHeadersHandler>();
263     headers_handler_->OnHeaderBlockStart();
264     for (const auto& p : header_list) {
265       headers_handler_->OnHeader(p.first, p.second);
266     }
267     headers_handler_->OnHeaderBlockEnd(size, size);
268   }
269 
WriteAndExpectRequestHeaders(QuicStreamId stream_id,bool fin,SpdyPriority priority)270   void WriteAndExpectRequestHeaders(QuicStreamId stream_id, bool fin,
271                                     SpdyPriority priority) {
272     WriteHeadersAndCheckData(stream_id, fin, priority, true /*is_request*/);
273   }
274 
WriteAndExpectResponseHeaders(QuicStreamId stream_id,bool fin)275   void WriteAndExpectResponseHeaders(QuicStreamId stream_id, bool fin) {
276     WriteHeadersAndCheckData(stream_id, fin, 0, false /*is_request*/);
277   }
278 
WriteHeadersAndCheckData(QuicStreamId stream_id,bool fin,SpdyPriority priority,bool is_request)279   void WriteHeadersAndCheckData(QuicStreamId stream_id, bool fin,
280                                 SpdyPriority priority, bool is_request) {
281     // Write the headers and capture the outgoing data
282     EXPECT_CALL(session_, WritevData(QuicUtils::GetHeadersStreamId(
283                                          connection_->transport_version()),
284                                      _, _, NO_FIN, _, _))
285         .WillOnce(WithArgs<1>(Invoke(this, &QuicHeadersStreamTest::SaveIov)));
286     QuicSpdySessionPeer::WriteHeadersOnHeadersStream(
287         &session_, stream_id, headers_.Clone(), fin,
288         spdy::SpdyStreamPrecedence(priority), nullptr);
289 
290     // Parse the outgoing data and check that it matches was was written.
291     if (is_request) {
292       EXPECT_CALL(
293           visitor_,
294           OnHeaders(stream_id, saved_data_.length() - spdy::kFrameHeaderSize,
295                     kHasPriority, Spdy3PriorityToHttp2Weight(priority),
296                     /*parent_stream_id=*/0,
297                     /*exclusive=*/false, fin, kFrameComplete));
298     } else {
299       EXPECT_CALL(
300           visitor_,
301           OnHeaders(stream_id, saved_data_.length() - spdy::kFrameHeaderSize,
302                     !kHasPriority,
303                     /*weight=*/0,
304                     /*parent_stream_id=*/0,
305                     /*exclusive=*/false, fin, kFrameComplete));
306     }
307     headers_handler_ = std::make_unique<RecordingHeadersHandler>();
308     EXPECT_CALL(visitor_, OnHeaderFrameStart(stream_id))
309         .WillOnce(Return(headers_handler_.get()));
310     EXPECT_CALL(visitor_, OnHeaderFrameEnd(stream_id)).Times(1);
311     if (fin) {
312       EXPECT_CALL(visitor_, OnStreamEnd(stream_id));
313     }
314     deframer_->ProcessInput(saved_data_.data(), saved_data_.length());
315     EXPECT_FALSE(deframer_->HasError())
316         << http2::Http2DecoderAdapter::SpdyFramerErrorToString(
317                deframer_->spdy_framer_error());
318 
319     CheckHeaders();
320     saved_data_.clear();
321   }
322 
CheckHeaders()323   void CheckHeaders() {
324     ASSERT_TRUE(headers_handler_);
325     EXPECT_EQ(headers_, headers_handler_->decoded_block());
326     headers_handler_.reset();
327   }
328 
perspective() const329   Perspective perspective() const { return GetParam().perspective; }
330 
transport_version() const331   QuicTransportVersion transport_version() const {
332     return GetParam().version.transport_version;
333   }
334 
GetVersion()335   ParsedQuicVersionVector GetVersion() {
336     ParsedQuicVersionVector versions;
337     versions.push_back(GetParam().version);
338     return versions;
339   }
340 
TearDownLocalConnectionState()341   void TearDownLocalConnectionState() {
342     QuicConnectionPeer::TearDownLocalConnectionState(connection_);
343   }
344 
NextPromisedStreamId()345   QuicStreamId NextPromisedStreamId() {
346     return next_promised_stream_id_ += next_stream_id_;
347   }
348 
349   static constexpr bool kFrameComplete = true;
350   static constexpr bool kHasPriority = true;
351 
352   MockQuicConnectionHelper helper_;
353   MockAlarmFactory alarm_factory_;
354   StrictMock<MockQuicConnection>* connection_;
355   StrictMock<MockQuicSpdySession> session_;
356   QuicHeadersStream* headers_stream_;
357   Http2HeaderBlock headers_;
358   std::unique_ptr<RecordingHeadersHandler> headers_handler_;
359   std::string body_;
360   std::string saved_data_;
361   std::string saved_header_data_;
362   std::string saved_payloads_;
363   std::unique_ptr<SpdyFramer> framer_;
364   std::unique_ptr<http2::Http2DecoderAdapter> deframer_;
365   StrictMock<MockVisitor> visitor_;
366   QuicStreamFrame stream_frame_;
367   QuicStreamId next_promised_stream_id_;
368   QuicStreamId client_id_1_;
369   QuicStreamId client_id_2_;
370   QuicStreamId client_id_3_;
371   QuicStreamId next_stream_id_;
372 };
373 
374 // Run all tests with each version and perspective (client or server).
375 INSTANTIATE_TEST_SUITE_P(Tests, QuicHeadersStreamTest,
376                          ::testing::ValuesIn(GetTestParams()),
377                          ::testing::PrintToStringParamName());
378 
TEST_P(QuicHeadersStreamTest,StreamId)379 TEST_P(QuicHeadersStreamTest, StreamId) {
380   EXPECT_EQ(QuicUtils::GetHeadersStreamId(connection_->transport_version()),
381             headers_stream_->id());
382 }
383 
TEST_P(QuicHeadersStreamTest,WriteHeaders)384 TEST_P(QuicHeadersStreamTest, WriteHeaders) {
385   for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
386        stream_id += next_stream_id_) {
387     for (bool fin : {false, true}) {
388       if (perspective() == Perspective::IS_SERVER) {
389         WriteAndExpectResponseHeaders(stream_id, fin);
390       } else {
391         for (SpdyPriority priority = 0; priority < 7; ++priority) {
392           // TODO(rch): implement priorities correctly.
393           WriteAndExpectRequestHeaders(stream_id, fin, 0);
394         }
395       }
396     }
397   }
398 }
399 
TEST_P(QuicHeadersStreamTest,ProcessRawData)400 TEST_P(QuicHeadersStreamTest, ProcessRawData) {
401   for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
402        stream_id += next_stream_id_) {
403     for (bool fin : {false, true}) {
404       for (SpdyPriority priority = 0; priority < 7; ++priority) {
405         // Replace with "WriteHeadersAndSaveData"
406         SpdySerializedFrame frame;
407         if (perspective() == Perspective::IS_SERVER) {
408           SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
409           headers_frame.set_fin(fin);
410           headers_frame.set_has_priority(true);
411           headers_frame.set_weight(Spdy3PriorityToHttp2Weight(0));
412           frame = framer_->SerializeFrame(headers_frame);
413           EXPECT_CALL(session_, OnStreamHeadersPriority(
414                                     stream_id, spdy::SpdyStreamPrecedence(0)));
415         } else {
416           SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
417           headers_frame.set_fin(fin);
418           frame = framer_->SerializeFrame(headers_frame);
419         }
420         EXPECT_CALL(session_,
421                     OnStreamHeaderList(stream_id, fin, frame.size(), _))
422             .WillOnce(Invoke(this, &QuicHeadersStreamTest::SaveHeaderList));
423         stream_frame_.data_buffer = frame.data();
424         stream_frame_.data_length = frame.size();
425         headers_stream_->OnStreamFrame(stream_frame_);
426         stream_frame_.offset += frame.size();
427         CheckHeaders();
428       }
429     }
430   }
431 }
432 
TEST_P(QuicHeadersStreamTest,ProcessPushPromise)433 TEST_P(QuicHeadersStreamTest, ProcessPushPromise) {
434   for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
435        stream_id += next_stream_id_) {
436     QuicStreamId promised_stream_id = NextPromisedStreamId();
437     SpdyPushPromiseIR push_promise(stream_id, promised_stream_id,
438                                    headers_.Clone());
439     SpdySerializedFrame frame(framer_->SerializeFrame(push_promise));
440     if (perspective() == Perspective::IS_SERVER) {
441       EXPECT_CALL(*connection_,
442                   CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
443                                   "PUSH_PROMISE not supported.", _))
444           .WillRepeatedly(InvokeWithoutArgs(
445               this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
446     } else {
447       EXPECT_CALL(session_, MaybeSendRstStreamFrame(promised_stream_id, _, _));
448     }
449     stream_frame_.data_buffer = frame.data();
450     stream_frame_.data_length = frame.size();
451     headers_stream_->OnStreamFrame(stream_frame_);
452     stream_frame_.offset += frame.size();
453   }
454 }
455 
TEST_P(QuicHeadersStreamTest,ProcessPriorityFrame)456 TEST_P(QuicHeadersStreamTest, ProcessPriorityFrame) {
457   QuicStreamId parent_stream_id = 0;
458   for (SpdyPriority priority = 0; priority < 7; ++priority) {
459     for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
460          stream_id += next_stream_id_) {
461       int weight = Spdy3PriorityToHttp2Weight(priority);
462       SpdyPriorityIR priority_frame(stream_id, parent_stream_id, weight, true);
463       SpdySerializedFrame frame(framer_->SerializeFrame(priority_frame));
464       parent_stream_id = stream_id;
465       if (perspective() == Perspective::IS_CLIENT) {
466         EXPECT_CALL(*connection_,
467                     CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
468                                     "Server must not send PRIORITY frames.", _))
469             .WillRepeatedly(InvokeWithoutArgs(
470                 this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
471       } else {
472         EXPECT_CALL(
473             session_,
474             OnPriorityFrame(stream_id, spdy::SpdyStreamPrecedence(priority)))
475             .Times(1);
476       }
477       stream_frame_.data_buffer = frame.data();
478       stream_frame_.data_length = frame.size();
479       headers_stream_->OnStreamFrame(stream_frame_);
480       stream_frame_.offset += frame.size();
481     }
482   }
483 }
484 
TEST_P(QuicHeadersStreamTest,ProcessPushPromiseDisabledSetting)485 TEST_P(QuicHeadersStreamTest, ProcessPushPromiseDisabledSetting) {
486   if (perspective() != Perspective::IS_CLIENT) {
487     return;
488   }
489 
490   session_.OnConfigNegotiated();
491   SpdySettingsIR data;
492   // Respect supported settings frames SETTINGS_ENABLE_PUSH.
493   data.AddSetting(SETTINGS_ENABLE_PUSH, 0);
494   SpdySerializedFrame frame(framer_->SerializeFrame(data));
495   stream_frame_.data_buffer = frame.data();
496   stream_frame_.data_length = frame.size();
497   EXPECT_CALL(
498       *connection_,
499       CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
500                       "Unsupported field of HTTP/2 SETTINGS frame: 2", _));
501   headers_stream_->OnStreamFrame(stream_frame_);
502 }
503 
TEST_P(QuicHeadersStreamTest,ProcessLargeRawData)504 TEST_P(QuicHeadersStreamTest, ProcessLargeRawData) {
505   // We want to create a frame that is more than the SPDY Framer's max control
506   // frame size, which is 16K, but less than the HPACK decoders max decode
507   // buffer size, which is 32K.
508   headers_["key0"] = std::string(1 << 13, '.');
509   headers_["key1"] = std::string(1 << 13, '.');
510   headers_["key2"] = std::string(1 << 13, '.');
511   for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
512        stream_id += next_stream_id_) {
513     for (bool fin : {false, true}) {
514       for (SpdyPriority priority = 0; priority < 7; ++priority) {
515         // Replace with "WriteHeadersAndSaveData"
516         SpdySerializedFrame frame;
517         if (perspective() == Perspective::IS_SERVER) {
518           SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
519           headers_frame.set_fin(fin);
520           headers_frame.set_has_priority(true);
521           headers_frame.set_weight(Spdy3PriorityToHttp2Weight(0));
522           frame = framer_->SerializeFrame(headers_frame);
523           EXPECT_CALL(session_, OnStreamHeadersPriority(
524                                     stream_id, spdy::SpdyStreamPrecedence(0)));
525         } else {
526           SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
527           headers_frame.set_fin(fin);
528           frame = framer_->SerializeFrame(headers_frame);
529         }
530         EXPECT_CALL(session_,
531                     OnStreamHeaderList(stream_id, fin, frame.size(), _))
532             .WillOnce(Invoke(this, &QuicHeadersStreamTest::SaveHeaderList));
533         stream_frame_.data_buffer = frame.data();
534         stream_frame_.data_length = frame.size();
535         headers_stream_->OnStreamFrame(stream_frame_);
536         stream_frame_.offset += frame.size();
537         CheckHeaders();
538       }
539     }
540   }
541 }
542 
TEST_P(QuicHeadersStreamTest,ProcessBadData)543 TEST_P(QuicHeadersStreamTest, ProcessBadData) {
544   const char kBadData[] = "blah blah blah";
545   EXPECT_CALL(*connection_,
546               CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
547       .Times(::testing::AnyNumber());
548   stream_frame_.data_buffer = kBadData;
549   stream_frame_.data_length = strlen(kBadData);
550   headers_stream_->OnStreamFrame(stream_frame_);
551 }
552 
TEST_P(QuicHeadersStreamTest,ProcessSpdyDataFrame)553 TEST_P(QuicHeadersStreamTest, ProcessSpdyDataFrame) {
554   SpdyDataIR data(/* stream_id = */ 2, "ping");
555   SpdySerializedFrame frame(framer_->SerializeFrame(data));
556 
557   EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
558                                             "SPDY DATA frame received.", _))
559       .WillOnce(InvokeWithoutArgs(
560           this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
561   stream_frame_.data_buffer = frame.data();
562   stream_frame_.data_length = frame.size();
563   headers_stream_->OnStreamFrame(stream_frame_);
564 }
565 
TEST_P(QuicHeadersStreamTest,ProcessSpdyRstStreamFrame)566 TEST_P(QuicHeadersStreamTest, ProcessSpdyRstStreamFrame) {
567   SpdyRstStreamIR data(/* stream_id = */ 2, ERROR_CODE_PROTOCOL_ERROR);
568   SpdySerializedFrame frame(framer_->SerializeFrame(data));
569   EXPECT_CALL(*connection_,
570               CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
571                               "SPDY RST_STREAM frame received.", _))
572       .WillOnce(InvokeWithoutArgs(
573           this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
574   stream_frame_.data_buffer = frame.data();
575   stream_frame_.data_length = frame.size();
576   headers_stream_->OnStreamFrame(stream_frame_);
577 }
578 
TEST_P(QuicHeadersStreamTest,RespectHttp2SettingsFrameSupportedFields)579 TEST_P(QuicHeadersStreamTest, RespectHttp2SettingsFrameSupportedFields) {
580   const uint32_t kTestHeaderTableSize = 1000;
581   SpdySettingsIR data;
582   // Respect supported settings frames SETTINGS_HEADER_TABLE_SIZE,
583   // SETTINGS_MAX_HEADER_LIST_SIZE.
584   data.AddSetting(SETTINGS_HEADER_TABLE_SIZE, kTestHeaderTableSize);
585   data.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE, 2000);
586   SpdySerializedFrame frame(framer_->SerializeFrame(data));
587   stream_frame_.data_buffer = frame.data();
588   stream_frame_.data_length = frame.size();
589   headers_stream_->OnStreamFrame(stream_frame_);
590   EXPECT_EQ(kTestHeaderTableSize, QuicSpdySessionPeer::GetSpdyFramer(&session_)
591                                       ->header_encoder_table_size());
592 }
593 
594 // Regression test for b/208997000.
TEST_P(QuicHeadersStreamTest,LimitEncoderDynamicTableSize)595 TEST_P(QuicHeadersStreamTest, LimitEncoderDynamicTableSize) {
596   const uint32_t kVeryLargeTableSizeLimit = 1024 * 1024 * 1024;
597   SpdySettingsIR data;
598   data.AddSetting(SETTINGS_HEADER_TABLE_SIZE, kVeryLargeTableSizeLimit);
599   SpdySerializedFrame frame(framer_->SerializeFrame(data));
600   stream_frame_.data_buffer = frame.data();
601   stream_frame_.data_length = frame.size();
602   headers_stream_->OnStreamFrame(stream_frame_);
603   EXPECT_EQ(16384u, QuicSpdySessionPeer::GetSpdyFramer(&session_)
604                         ->header_encoder_table_size());
605 }
606 
TEST_P(QuicHeadersStreamTest,RespectHttp2SettingsFrameUnsupportedFields)607 TEST_P(QuicHeadersStreamTest, RespectHttp2SettingsFrameUnsupportedFields) {
608   SpdySettingsIR data;
609   // Does not support SETTINGS_MAX_CONCURRENT_STREAMS,
610   // SETTINGS_INITIAL_WINDOW_SIZE, SETTINGS_ENABLE_PUSH and
611   // SETTINGS_MAX_FRAME_SIZE.
612   data.AddSetting(SETTINGS_MAX_CONCURRENT_STREAMS, 100);
613   data.AddSetting(SETTINGS_INITIAL_WINDOW_SIZE, 100);
614   data.AddSetting(SETTINGS_ENABLE_PUSH, 1);
615   data.AddSetting(SETTINGS_MAX_FRAME_SIZE, 1250);
616   SpdySerializedFrame frame(framer_->SerializeFrame(data));
617   EXPECT_CALL(*connection_,
618               CloseConnection(
619                   QUIC_INVALID_HEADERS_STREAM_DATA,
620                   absl::StrCat("Unsupported field of HTTP/2 SETTINGS frame: ",
621                                SETTINGS_MAX_CONCURRENT_STREAMS),
622                   _));
623   EXPECT_CALL(*connection_,
624               CloseConnection(
625                   QUIC_INVALID_HEADERS_STREAM_DATA,
626                   absl::StrCat("Unsupported field of HTTP/2 SETTINGS frame: ",
627                                SETTINGS_INITIAL_WINDOW_SIZE),
628                   _));
629   if (session_.perspective() == Perspective::IS_CLIENT) {
630     EXPECT_CALL(*connection_,
631                 CloseConnection(
632                     QUIC_INVALID_HEADERS_STREAM_DATA,
633                     absl::StrCat("Unsupported field of HTTP/2 SETTINGS frame: ",
634                                  SETTINGS_ENABLE_PUSH),
635                     _));
636   }
637   EXPECT_CALL(*connection_,
638               CloseConnection(
639                   QUIC_INVALID_HEADERS_STREAM_DATA,
640                   absl::StrCat("Unsupported field of HTTP/2 SETTINGS frame: ",
641                                SETTINGS_MAX_FRAME_SIZE),
642                   _));
643   stream_frame_.data_buffer = frame.data();
644   stream_frame_.data_length = frame.size();
645   headers_stream_->OnStreamFrame(stream_frame_);
646 }
647 
TEST_P(QuicHeadersStreamTest,ProcessSpdyPingFrame)648 TEST_P(QuicHeadersStreamTest, ProcessSpdyPingFrame) {
649   SpdyPingIR data(1);
650   SpdySerializedFrame frame(framer_->SerializeFrame(data));
651   EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
652                                             "SPDY PING frame received.", _))
653       .WillOnce(InvokeWithoutArgs(
654           this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
655   stream_frame_.data_buffer = frame.data();
656   stream_frame_.data_length = frame.size();
657   headers_stream_->OnStreamFrame(stream_frame_);
658 }
659 
TEST_P(QuicHeadersStreamTest,ProcessSpdyGoAwayFrame)660 TEST_P(QuicHeadersStreamTest, ProcessSpdyGoAwayFrame) {
661   SpdyGoAwayIR data(/* last_good_stream_id = */ 1, ERROR_CODE_PROTOCOL_ERROR,
662                     "go away");
663   SpdySerializedFrame frame(framer_->SerializeFrame(data));
664   EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
665                                             "SPDY GOAWAY frame received.", _))
666       .WillOnce(InvokeWithoutArgs(
667           this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
668   stream_frame_.data_buffer = frame.data();
669   stream_frame_.data_length = frame.size();
670   headers_stream_->OnStreamFrame(stream_frame_);
671 }
672 
TEST_P(QuicHeadersStreamTest,ProcessSpdyWindowUpdateFrame)673 TEST_P(QuicHeadersStreamTest, ProcessSpdyWindowUpdateFrame) {
674   SpdyWindowUpdateIR data(/* stream_id = */ 1, /* delta = */ 1);
675   SpdySerializedFrame frame(framer_->SerializeFrame(data));
676   EXPECT_CALL(*connection_,
677               CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
678                               "SPDY WINDOW_UPDATE frame received.", _))
679       .WillOnce(InvokeWithoutArgs(
680           this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
681   stream_frame_.data_buffer = frame.data();
682   stream_frame_.data_length = frame.size();
683   headers_stream_->OnStreamFrame(stream_frame_);
684 }
685 
TEST_P(QuicHeadersStreamTest,NoConnectionLevelFlowControl)686 TEST_P(QuicHeadersStreamTest, NoConnectionLevelFlowControl) {
687   EXPECT_FALSE(QuicStreamPeer::StreamContributesToConnectionFlowControl(
688       headers_stream_));
689 }
690 
TEST_P(QuicHeadersStreamTest,AckSentData)691 TEST_P(QuicHeadersStreamTest, AckSentData) {
692   EXPECT_CALL(session_, WritevData(QuicUtils::GetHeadersStreamId(
693                                        connection_->transport_version()),
694                                    _, _, NO_FIN, _, _))
695       .WillRepeatedly(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
696   InSequence s;
697   quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener1(
698       new MockAckListener());
699   quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener2(
700       new MockAckListener());
701   quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener3(
702       new MockAckListener());
703 
704   // Packet 1.
705   headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
706   headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
707   headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
708 
709   // Packet 2.
710   headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
711   headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
712 
713   // Packet 3.
714   headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
715 
716   // Packet 2 gets retransmitted.
717   EXPECT_CALL(*ack_listener3, OnPacketRetransmitted(7)).Times(1);
718   EXPECT_CALL(*ack_listener2, OnPacketRetransmitted(7)).Times(1);
719   headers_stream_->OnStreamFrameRetransmitted(21, 7, false);
720   headers_stream_->OnStreamFrameRetransmitted(28, 7, false);
721 
722   // Packets are acked in order: 2, 3, 1.
723   QuicByteCount newly_acked_length = 0;
724   EXPECT_CALL(*ack_listener3, OnPacketAcked(7, _));
725   EXPECT_CALL(*ack_listener2, OnPacketAcked(7, _));
726   EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
727       21, 7, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
728       &newly_acked_length));
729   EXPECT_EQ(7u, newly_acked_length);
730   EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
731       28, 7, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
732       &newly_acked_length));
733   EXPECT_EQ(7u, newly_acked_length);
734 
735   EXPECT_CALL(*ack_listener3, OnPacketAcked(7, _));
736   EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
737       35, 7, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
738       &newly_acked_length));
739   EXPECT_EQ(7u, newly_acked_length);
740 
741   EXPECT_CALL(*ack_listener1, OnPacketAcked(7, _));
742   EXPECT_CALL(*ack_listener1, OnPacketAcked(7, _));
743   EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
744       0, 7, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
745       &newly_acked_length));
746   EXPECT_EQ(7u, newly_acked_length);
747   EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
748       7, 7, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
749       &newly_acked_length));
750   EXPECT_EQ(7u, newly_acked_length);
751   // Unsent data is acked.
752   EXPECT_CALL(*ack_listener2, OnPacketAcked(7, _));
753   EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
754       14, 10, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
755       &newly_acked_length));
756   EXPECT_EQ(7u, newly_acked_length);
757 }
758 
TEST_P(QuicHeadersStreamTest,FrameContainsMultipleHeaders)759 TEST_P(QuicHeadersStreamTest, FrameContainsMultipleHeaders) {
760   // In this test, a stream frame can contain multiple headers.
761   EXPECT_CALL(session_, WritevData(QuicUtils::GetHeadersStreamId(
762                                        connection_->transport_version()),
763                                    _, _, NO_FIN, _, _))
764       .WillRepeatedly(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
765   InSequence s;
766   quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener1(
767       new MockAckListener());
768   quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener2(
769       new MockAckListener());
770   quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener3(
771       new MockAckListener());
772 
773   headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
774   headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
775   headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
776   headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
777   headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
778   headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
779 
780   // Frame 1 is retransmitted.
781   EXPECT_CALL(*ack_listener1, OnPacketRetransmitted(14));
782   EXPECT_CALL(*ack_listener2, OnPacketRetransmitted(3));
783   headers_stream_->OnStreamFrameRetransmitted(0, 17, false);
784 
785   // Frames are acked in order: 2, 3, 1.
786   QuicByteCount newly_acked_length = 0;
787   EXPECT_CALL(*ack_listener2, OnPacketAcked(4, _));
788   EXPECT_CALL(*ack_listener3, OnPacketAcked(7, _));
789   EXPECT_CALL(*ack_listener2, OnPacketAcked(2, _));
790   EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
791       17, 13, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
792       &newly_acked_length));
793   EXPECT_EQ(13u, newly_acked_length);
794 
795   EXPECT_CALL(*ack_listener2, OnPacketAcked(5, _));
796   EXPECT_CALL(*ack_listener3, OnPacketAcked(7, _));
797   EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
798       30, 12, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
799       &newly_acked_length));
800   EXPECT_EQ(12u, newly_acked_length);
801 
802   EXPECT_CALL(*ack_listener1, OnPacketAcked(14, _));
803   EXPECT_CALL(*ack_listener2, OnPacketAcked(3, _));
804   EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
805       0, 17, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
806       &newly_acked_length));
807   EXPECT_EQ(17u, newly_acked_length);
808 }
809 
TEST_P(QuicHeadersStreamTest,HeadersGetAckedMultipleTimes)810 TEST_P(QuicHeadersStreamTest, HeadersGetAckedMultipleTimes) {
811   EXPECT_CALL(session_, WritevData(QuicUtils::GetHeadersStreamId(
812                                        connection_->transport_version()),
813                                    _, _, NO_FIN, _, _))
814       .WillRepeatedly(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
815   InSequence s;
816   quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener1(
817       new MockAckListener());
818   quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener2(
819       new MockAckListener());
820   quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener3(
821       new MockAckListener());
822 
823   // Send [0, 42).
824   headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
825   headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
826   headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
827   headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
828   headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
829   headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
830 
831   // Ack [15, 20), [5, 25), [10, 17), [0, 12) and [22, 42).
832   QuicByteCount newly_acked_length = 0;
833   EXPECT_CALL(*ack_listener2, OnPacketAcked(5, _));
834   EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
835       15, 5, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
836       &newly_acked_length));
837   EXPECT_EQ(5u, newly_acked_length);
838 
839   EXPECT_CALL(*ack_listener1, OnPacketAcked(9, _));
840   EXPECT_CALL(*ack_listener2, OnPacketAcked(1, _));
841   EXPECT_CALL(*ack_listener2, OnPacketAcked(1, _));
842   EXPECT_CALL(*ack_listener3, OnPacketAcked(4, _));
843   EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
844       5, 20, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
845       &newly_acked_length));
846   EXPECT_EQ(15u, newly_acked_length);
847 
848   // Duplicate ack.
849   EXPECT_FALSE(headers_stream_->OnStreamFrameAcked(
850       10, 7, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
851       &newly_acked_length));
852   EXPECT_EQ(0u, newly_acked_length);
853 
854   EXPECT_CALL(*ack_listener1, OnPacketAcked(5, _));
855   EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
856       0, 12, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
857       &newly_acked_length));
858   EXPECT_EQ(5u, newly_acked_length);
859 
860   EXPECT_CALL(*ack_listener3, OnPacketAcked(3, _));
861   EXPECT_CALL(*ack_listener2, OnPacketAcked(7, _));
862   EXPECT_CALL(*ack_listener3, OnPacketAcked(7, _));
863   EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
864       22, 20, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
865       &newly_acked_length));
866   EXPECT_EQ(17u, newly_acked_length);
867 }
868 
TEST_P(QuicHeadersStreamTest,CloseOnPushPromiseToServer)869 TEST_P(QuicHeadersStreamTest, CloseOnPushPromiseToServer) {
870   if (perspective() == Perspective::IS_CLIENT) {
871     return;
872   }
873   QuicStreamId promised_id = 1;
874   SpdyPushPromiseIR push_promise(client_id_1_, promised_id, headers_.Clone());
875   SpdySerializedFrame frame = framer_->SerializeFrame(push_promise);
876   stream_frame_.data_buffer = frame.data();
877   stream_frame_.data_length = frame.size();
878   EXPECT_CALL(session_, OnStreamHeaderList(_, _, _, _));
879   // TODO(lassey): Check for HTTP_WRONG_STREAM error code.
880   EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
881                                             "PUSH_PROMISE not supported.", _));
882   headers_stream_->OnStreamFrame(stream_frame_);
883 }
884 
885 }  // namespace
886 }  // namespace test
887 }  // namespace quic
888