| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/quic/core/quic_headers_stream.h" | 5 #include "net/quic/core/quic_headers_stream.h" |
| 6 | 6 |
| 7 #include <cstdint> | 7 #include <cstdint> |
| 8 #include <ostream> | 8 #include <ostream> |
| 9 #include <string> | 9 #include <string> |
| 10 #include <tuple> | 10 #include <tuple> |
| 11 #include <utility> | 11 #include <utility> |
| 12 | 12 |
| 13 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
| 14 #include "net/quic/core/quic_bug_tracker.h" | 14 #include "net/quic/core/quic_bug_tracker.h" |
| 15 #include "net/quic/core/quic_flags.h" | 15 #include "net/quic/core/quic_flags.h" |
| 16 #include "net/quic/core/quic_utils.h" | 16 #include "net/quic/core/quic_utils.h" |
| 17 #include "net/quic/core/spdy_utils.h" | 17 #include "net/quic/core/spdy_utils.h" |
| 18 #include "net/quic/platform/api/quic_str_cat.h" | 18 #include "net/quic/platform/api/quic_str_cat.h" |
| 19 #include "net/quic/test_tools/quic_connection_peer.h" | 19 #include "net/quic/test_tools/quic_connection_peer.h" |
| 20 #include "net/quic/test_tools/quic_headers_stream_peer.h" | |
| 21 #include "net/quic/test_tools/quic_spdy_session_peer.h" | 20 #include "net/quic/test_tools/quic_spdy_session_peer.h" |
| 22 #include "net/quic/test_tools/quic_stream_peer.h" | 21 #include "net/quic/test_tools/quic_stream_peer.h" |
| 23 #include "net/quic/test_tools/quic_test_utils.h" | 22 #include "net/quic/test_tools/quic_test_utils.h" |
| 24 #include "net/spdy/spdy_alt_svc_wire_format.h" | 23 #include "net/spdy/spdy_alt_svc_wire_format.h" |
| 25 #include "net/spdy/spdy_flags.h" | 24 #include "net/spdy/spdy_flags.h" |
| 26 #include "net/spdy/spdy_protocol.h" | 25 #include "net/spdy/spdy_protocol.h" |
| 27 #include "net/spdy/spdy_test_utils.h" | 26 #include "net/spdy/spdy_test_utils.h" |
| 28 #include "net/test/gtest_util.h" | 27 #include "net/test/gtest_util.h" |
| 29 #include "testing/gtest/include/gtest/gtest.h" | 28 #include "testing/gtest/include/gtest/gtest.h" |
| 30 | 29 |
| 31 using base::StringPiece; | 30 using base::StringPiece; |
| 32 using std::string; | 31 using std::string; |
| 33 using testing::_; | 32 using testing::_; |
| 34 using testing::AtLeast; | 33 using testing::AtLeast; |
| 35 using testing::HasSubstr; | 34 using testing::HasSubstr; |
| 36 using testing::InSequence; | 35 using testing::InSequence; |
| 37 using testing::Invoke; | 36 using testing::Invoke; |
| 38 using testing::Return; | 37 using testing::Return; |
| 39 using testing::StrictMock; | 38 using testing::StrictMock; |
| 40 using testing::WithArgs; | 39 using testing::WithArgs; |
| 41 | 40 |
| 42 // TODO(bnc): Merge these correctly. | 41 // TODO(bnc): Merge these correctly. |
| 43 bool FLAGS_use_http2_frame_decoder_adapter; | 42 bool FLAGS_use_http2_frame_decoder_adapter; |
| 44 bool FLAGS_spdy_use_hpack_decoder2; | 43 bool FLAGS_spdy_use_hpack_decoder2; |
| 45 bool FLAGS_spdy_framer_use_new_methods4; | 44 bool FLAGS_spdy_framer_use_new_methods4; |
| 46 | 45 |
| 47 namespace net { | 46 namespace net { |
| 48 namespace test { | 47 namespace test { |
| 49 | 48 |
| 50 class MockHpackDebugVisitor : public QuicHeadersStream::HpackDebugVisitor { | 49 class MockQuicHpackDebugVisitor : public QuicHpackDebugVisitor { |
| 51 public: | 50 public: |
| 52 MockHpackDebugVisitor() : HpackDebugVisitor() {} | 51 MockQuicHpackDebugVisitor() : QuicHpackDebugVisitor() {} |
| 53 | 52 |
| 54 MOCK_METHOD1(OnUseEntry, void(QuicTime::Delta elapsed)); | 53 MOCK_METHOD1(OnUseEntry, void(QuicTime::Delta elapsed)); |
| 55 | 54 |
| 56 private: | 55 private: |
| 57 DISALLOW_COPY_AND_ASSIGN(MockHpackDebugVisitor); | 56 DISALLOW_COPY_AND_ASSIGN(MockQuicHpackDebugVisitor); |
| 58 }; | 57 }; |
| 59 | 58 |
| 60 namespace { | 59 namespace { |
| 61 | 60 |
| 62 // TODO(ckrasic): this workaround is due to absence of std::initializer_list | 61 // TODO(ckrasic): this workaround is due to absence of std::initializer_list |
| 63 const bool kFins[] = {false, true}; | 62 const bool kFins[] = {false, true}; |
| 64 | 63 |
| 65 class MockVisitor : public SpdyFramerVisitorInterface { | 64 class MockVisitor : public SpdyFramerVisitorInterface { |
| 66 public: | 65 public: |
| 67 MOCK_METHOD1(OnError, void(SpdyFramer* framer)); | 66 MOCK_METHOD1(OnError, void(SpdyFramer* framer)); |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 // to construct a decoder adapter. | 221 // to construct a decoder adapter. |
| 223 QuicHeadersStreamTest() | 222 QuicHeadersStreamTest() |
| 224 : test_params_(GetParam()), | 223 : test_params_(GetParam()), |
| 225 connection_(new StrictMock<MockQuicConnection>(&helper_, | 224 connection_(new StrictMock<MockQuicConnection>(&helper_, |
| 226 &alarm_factory_, | 225 &alarm_factory_, |
| 227 perspective(), | 226 perspective(), |
| 228 GetVersion())), | 227 GetVersion())), |
| 229 session_(connection_), | 228 session_(connection_), |
| 230 headers_stream_(QuicSpdySessionPeer::GetHeadersStream(&session_)), | 229 headers_stream_(QuicSpdySessionPeer::GetHeadersStream(&session_)), |
| 231 body_("hello world"), | 230 body_("hello world"), |
| 232 hpack_encoder_visitor_(new StrictMock<MockHpackDebugVisitor>), | 231 hpack_encoder_visitor_(new StrictMock<MockQuicHpackDebugVisitor>), |
| 233 hpack_decoder_visitor_(new StrictMock<MockHpackDebugVisitor>), | 232 hpack_decoder_visitor_(new StrictMock<MockQuicHpackDebugVisitor>), |
| 234 stream_frame_(kHeadersStreamId, /*fin=*/false, /*offset=*/0, ""), | 233 stream_frame_(kHeadersStreamId, /*fin=*/false, /*offset=*/0, ""), |
| 235 next_promised_stream_id_(2) { | 234 next_promised_stream_id_(2) { |
| 236 headers_[":version"] = "HTTP/1.1"; | 235 headers_[":version"] = "HTTP/1.1"; |
| 237 headers_[":status"] = "200 Ok"; | 236 headers_[":status"] = "200 Ok"; |
| 238 headers_["content-length"] = "11"; | 237 headers_["content-length"] = "11"; |
| 239 framer_ = std::unique_ptr<SpdyFramer>( | 238 framer_ = std::unique_ptr<SpdyFramer>( |
| 240 new SpdyFramer(SpdyFramer::ENABLE_COMPRESSION)); | 239 new SpdyFramer(SpdyFramer::ENABLE_COMPRESSION)); |
| 241 framer_->set_visitor(&visitor_); | 240 framer_->set_visitor(&visitor_); |
| 242 EXPECT_EQ(version(), session_.connection()->version()); | 241 EXPECT_EQ(version(), session_.connection()->version()); |
| 243 EXPECT_TRUE(headers_stream_ != nullptr); | 242 EXPECT_TRUE(headers_stream_ != nullptr); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 } | 320 } |
| 322 | 321 |
| 323 void WriteHeadersAndCheckData(QuicStreamId stream_id, | 322 void WriteHeadersAndCheckData(QuicStreamId stream_id, |
| 324 bool fin, | 323 bool fin, |
| 325 SpdyPriority priority, | 324 SpdyPriority priority, |
| 326 bool is_request) { | 325 bool is_request) { |
| 327 // Write the headers and capture the outgoing data | 326 // Write the headers and capture the outgoing data |
| 328 EXPECT_CALL(session_, | 327 EXPECT_CALL(session_, |
| 329 WritevData(headers_stream_, kHeadersStreamId, _, _, false, _)) | 328 WritevData(headers_stream_, kHeadersStreamId, _, _, false, _)) |
| 330 .WillOnce(WithArgs<2>(Invoke(this, &QuicHeadersStreamTest::SaveIov))); | 329 .WillOnce(WithArgs<2>(Invoke(this, &QuicHeadersStreamTest::SaveIov))); |
| 331 headers_stream_->WriteHeaders(stream_id, headers_.Clone(), fin, priority, | 330 QuicSpdySessionPeer::WriteHeadersImpl( |
| 332 nullptr); | 331 &session_, stream_id, headers_.Clone(), fin, priority, nullptr); |
| 333 | 332 |
| 334 // Parse the outgoing data and check that it matches was was written. | 333 // Parse the outgoing data and check that it matches was was written. |
| 335 if (is_request) { | 334 if (is_request) { |
| 336 EXPECT_CALL(visitor_, | 335 EXPECT_CALL(visitor_, |
| 337 OnHeaders(stream_id, kHasPriority, | 336 OnHeaders(stream_id, kHasPriority, |
| 338 Spdy3PriorityToHttp2Weight(priority), | 337 Spdy3PriorityToHttp2Weight(priority), |
| 339 /*parent_stream_id=*/0, | 338 /*parent_stream_id=*/0, |
| 340 /*exclusive=*/false, fin, kFrameComplete)); | 339 /*exclusive=*/false, fin, kFrameComplete)); |
| 341 } else { | 340 } else { |
| 342 EXPECT_CALL(visitor_, | 341 EXPECT_CALL(visitor_, |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 392 StrictMock<MockQuicSpdySession> session_; | 391 StrictMock<MockQuicSpdySession> session_; |
| 393 QuicHeadersStream* headers_stream_; | 392 QuicHeadersStream* headers_stream_; |
| 394 SpdyHeaderBlock headers_; | 393 SpdyHeaderBlock headers_; |
| 395 std::unique_ptr<TestHeadersHandler> headers_handler_; | 394 std::unique_ptr<TestHeadersHandler> headers_handler_; |
| 396 string body_; | 395 string body_; |
| 397 string saved_data_; | 396 string saved_data_; |
| 398 string saved_header_data_; | 397 string saved_header_data_; |
| 399 string saved_payloads_; | 398 string saved_payloads_; |
| 400 std::unique_ptr<SpdyFramer> framer_; | 399 std::unique_ptr<SpdyFramer> framer_; |
| 401 StrictMock<MockVisitor> visitor_; | 400 StrictMock<MockVisitor> visitor_; |
| 402 std::unique_ptr<StrictMock<MockHpackDebugVisitor>> hpack_encoder_visitor_; | 401 std::unique_ptr<StrictMock<MockQuicHpackDebugVisitor>> hpack_encoder_visitor_; |
| 403 std::unique_ptr<StrictMock<MockHpackDebugVisitor>> hpack_decoder_visitor_; | 402 std::unique_ptr<StrictMock<MockQuicHpackDebugVisitor>> hpack_decoder_visitor_; |
| 404 QuicStreamFrame stream_frame_; | 403 QuicStreamFrame stream_frame_; |
| 405 QuicStreamId next_promised_stream_id_; | 404 QuicStreamId next_promised_stream_id_; |
| 406 }; | 405 }; |
| 407 | 406 |
| 408 // Run all tests with each version, perspective (client or server), | 407 // Run all tests with each version, perspective (client or server), |
| 409 // HTTP/2 and HPACK decoder. | 408 // HTTP/2 and HPACK decoder. |
| 410 INSTANTIATE_TEST_CASE_P( | 409 INSTANTIATE_TEST_CASE_P( |
| 411 Tests, | 410 Tests, |
| 412 QuicHeadersStreamTest, | 411 QuicHeadersStreamTest, |
| 413 ::testing::Combine( | 412 ::testing::Combine( |
| (...skipping 26 matching lines...) Expand all Loading... |
| 440 | 439 |
| 441 TEST_P(QuicHeadersStreamTest, WritePushPromises) { | 440 TEST_P(QuicHeadersStreamTest, WritePushPromises) { |
| 442 for (QuicStreamId stream_id = kClientDataStreamId1; | 441 for (QuicStreamId stream_id = kClientDataStreamId1; |
| 443 stream_id < kClientDataStreamId3; stream_id += 2) { | 442 stream_id < kClientDataStreamId3; stream_id += 2) { |
| 444 QuicStreamId promised_stream_id = NextPromisedStreamId(); | 443 QuicStreamId promised_stream_id = NextPromisedStreamId(); |
| 445 if (perspective() == Perspective::IS_SERVER) { | 444 if (perspective() == Perspective::IS_SERVER) { |
| 446 // Write the headers and capture the outgoing data | 445 // Write the headers and capture the outgoing data |
| 447 EXPECT_CALL(session_, | 446 EXPECT_CALL(session_, |
| 448 WritevData(headers_stream_, kHeadersStreamId, _, _, false, _)) | 447 WritevData(headers_stream_, kHeadersStreamId, _, _, false, _)) |
| 449 .WillOnce(WithArgs<2>(Invoke(this, &QuicHeadersStreamTest::SaveIov))); | 448 .WillOnce(WithArgs<2>(Invoke(this, &QuicHeadersStreamTest::SaveIov))); |
| 450 headers_stream_->WritePushPromise(stream_id, promised_stream_id, | 449 session_.WritePushPromise(stream_id, promised_stream_id, |
| 451 headers_.Clone()); | 450 headers_.Clone()); |
| 452 | 451 |
| 453 // Parse the outgoing data and check that it matches was was written. | 452 // Parse the outgoing data and check that it matches was was written. |
| 454 EXPECT_CALL(visitor_, | 453 EXPECT_CALL(visitor_, |
| 455 OnPushPromise(stream_id, promised_stream_id, kFrameComplete)); | 454 OnPushPromise(stream_id, promised_stream_id, kFrameComplete)); |
| 456 headers_handler_.reset(new TestHeadersHandler); | 455 headers_handler_.reset(new TestHeadersHandler); |
| 457 EXPECT_CALL(visitor_, OnHeaderFrameStart(stream_id)) | 456 EXPECT_CALL(visitor_, OnHeaderFrameStart(stream_id)) |
| 458 .WillOnce(Return(headers_handler_.get())); | 457 .WillOnce(Return(headers_handler_.get())); |
| 459 EXPECT_CALL(visitor_, OnHeaderFrameEnd(stream_id, true)).Times(1); | 458 EXPECT_CALL(visitor_, OnHeaderFrameEnd(stream_id, true)).Times(1); |
| 460 framer_->ProcessInput(saved_data_.data(), saved_data_.length()); | 459 framer_->ProcessInput(saved_data_.data(), saved_data_.length()); |
| 461 EXPECT_FALSE(framer_->HasError()) | 460 EXPECT_FALSE(framer_->HasError()) |
| 462 << SpdyFramer::ErrorCodeToString(framer_->error_code()); | 461 << SpdyFramer::ErrorCodeToString(framer_->error_code()); |
| 463 CheckHeaders(); | 462 CheckHeaders(); |
| 464 saved_data_.clear(); | 463 saved_data_.clear(); |
| 465 } else { | 464 } else { |
| 466 EXPECT_QUIC_BUG(headers_stream_->WritePushPromise( | 465 EXPECT_QUIC_BUG(session_.WritePushPromise(stream_id, promised_stream_id, |
| 467 stream_id, promised_stream_id, headers_.Clone()), | 466 headers_.Clone()), |
| 468 "Client shouldn't send PUSH_PROMISE"); | 467 "Client shouldn't send PUSH_PROMISE"); |
| 469 } | 468 } |
| 470 } | 469 } |
| 471 } | 470 } |
| 472 | 471 |
| 473 TEST_P(QuicHeadersStreamTest, ProcessRawData) { | 472 TEST_P(QuicHeadersStreamTest, ProcessRawData) { |
| 474 for (QuicStreamId stream_id = kClientDataStreamId1; | 473 for (QuicStreamId stream_id = kClientDataStreamId1; |
| 475 stream_id < kClientDataStreamId3; stream_id += 2) { | 474 stream_id < kClientDataStreamId3; stream_id += 2) { |
| 476 for (bool fin : {false, true}) { | 475 for (bool fin : {false, true}) { |
| 477 for (SpdyPriority priority = 0; priority < 7; ++priority) { | 476 for (SpdyPriority priority = 0; priority < 7; ++priority) { |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 623 | 622 |
| 624 for (int stream_num = 9; stream_num >= 0; --stream_num) { | 623 for (int stream_num = 9; stream_num >= 0; --stream_num) { |
| 625 DVLOG(1) << "OnStreamFrame for stream " << stream_num << " offset " | 624 DVLOG(1) << "OnStreamFrame for stream " << stream_num << " offset " |
| 626 << stream_frames[stream_num].offset; | 625 << stream_frames[stream_num].offset; |
| 627 headers_stream_->OnStreamFrame(stream_frames[stream_num]); | 626 headers_stream_->OnStreamFrame(stream_frames[stream_num]); |
| 628 connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1)); | 627 connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1)); |
| 629 } | 628 } |
| 630 } | 629 } |
| 631 | 630 |
| 632 TEST_P(QuicHeadersStreamTest, ProcessLargeRawData) { | 631 TEST_P(QuicHeadersStreamTest, ProcessLargeRawData) { |
| 633 headers_stream_->set_max_uncompressed_header_bytes(256 * 1024); | 632 QuicSpdySessionPeer::SetMaxUncompressedHeaderBytes(&session_, 256 * 1024); |
| 634 // We want to create a frame that is more than the SPDY Framer's max control | 633 // We want to create a frame that is more than the SPDY Framer's max control |
| 635 // frame size, which is 16K, but less than the HPACK decoders max decode | 634 // frame size, which is 16K, but less than the HPACK decoders max decode |
| 636 // buffer size, which is 32K. | 635 // buffer size, which is 32K. |
| 637 headers_["key0"] = string(1 << 13, '.'); | 636 headers_["key0"] = string(1 << 13, '.'); |
| 638 headers_["key1"] = string(1 << 13, '.'); | 637 headers_["key1"] = string(1 << 13, '.'); |
| 639 headers_["key2"] = string(1 << 13, '.'); | 638 headers_["key2"] = string(1 << 13, '.'); |
| 640 for (QuicStreamId stream_id = kClientDataStreamId1; | 639 for (QuicStreamId stream_id = kClientDataStreamId1; |
| 641 stream_id < kClientDataStreamId3; stream_id += 2) { | 640 stream_id < kClientDataStreamId3; stream_id += 2) { |
| 642 for (bool fin : {false, true}) { | 641 for (bool fin : {false, true}) { |
| 643 for (SpdyPriority priority = 0; priority < 7; ++priority) { | 642 for (SpdyPriority priority = 0; priority < 7; ++priority) { |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 752 SpdySettingsIR data; | 751 SpdySettingsIR data; |
| 753 // Respect supported settings frames SETTINGS_HEADER_TABLE_SIZE, | 752 // Respect supported settings frames SETTINGS_HEADER_TABLE_SIZE, |
| 754 // SETTINGS_MAX_HEADER_LIST_SIZE. | 753 // SETTINGS_MAX_HEADER_LIST_SIZE. |
| 755 data.AddSetting(SETTINGS_HEADER_TABLE_SIZE, kTestHeaderTableSize); | 754 data.AddSetting(SETTINGS_HEADER_TABLE_SIZE, kTestHeaderTableSize); |
| 756 data.AddSetting(SETTINGS_MAX_HEADER_LIST_SIZE, 2000); | 755 data.AddSetting(SETTINGS_MAX_HEADER_LIST_SIZE, 2000); |
| 757 SpdySerializedFrame frame(framer_->SerializeFrame(data)); | 756 SpdySerializedFrame frame(framer_->SerializeFrame(data)); |
| 758 stream_frame_.data_buffer = frame.data(); | 757 stream_frame_.data_buffer = frame.data(); |
| 759 stream_frame_.data_length = frame.size(); | 758 stream_frame_.data_length = frame.size(); |
| 760 headers_stream_->OnStreamFrame(stream_frame_); | 759 headers_stream_->OnStreamFrame(stream_frame_); |
| 761 EXPECT_EQ(kTestHeaderTableSize, | 760 EXPECT_EQ(kTestHeaderTableSize, |
| 762 QuicHeadersStreamPeer::GetSpdyFramer(headers_stream_) | 761 QuicSpdySessionPeer::GetSpdyFramer(&session_) |
| 763 .header_encoder_table_size()); | 762 .header_encoder_table_size()); |
| 764 } | 763 } |
| 765 | 764 |
| 766 TEST_P(QuicHeadersStreamTest, RespectHttp2SettingsFrameUnsupportedFields) { | 765 TEST_P(QuicHeadersStreamTest, RespectHttp2SettingsFrameUnsupportedFields) { |
| 767 FLAGS_quic_reloadable_flag_quic_respect_http2_settings_frame = true; | 766 FLAGS_quic_reloadable_flag_quic_respect_http2_settings_frame = true; |
| 768 FLAGS_quic_reloadable_flag_quic_send_max_header_list_size = true; | 767 FLAGS_quic_reloadable_flag_quic_send_max_header_list_size = true; |
| 769 SpdySettingsIR data; | 768 SpdySettingsIR data; |
| 770 // Does not support SETTINGS_MAX_CONCURRENT_STREAMS, | 769 // Does not support SETTINGS_MAX_CONCURRENT_STREAMS, |
| 771 // SETTINGS_INITIAL_WINDOW_SIZE, SETTINGS_ENABLE_PUSH and | 770 // SETTINGS_INITIAL_WINDOW_SIZE, SETTINGS_ENABLE_PUSH and |
| 772 // SETTINGS_MAX_FRAME_SIZE. | 771 // SETTINGS_MAX_FRAME_SIZE. |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 843 stream_frame_.data_length = frame.size(); | 842 stream_frame_.data_length = frame.size(); |
| 844 headers_stream_->OnStreamFrame(stream_frame_); | 843 headers_stream_->OnStreamFrame(stream_frame_); |
| 845 } | 844 } |
| 846 | 845 |
| 847 TEST_P(QuicHeadersStreamTest, NoConnectionLevelFlowControl) { | 846 TEST_P(QuicHeadersStreamTest, NoConnectionLevelFlowControl) { |
| 848 EXPECT_FALSE(QuicStreamPeer::StreamContributesToConnectionFlowControl( | 847 EXPECT_FALSE(QuicStreamPeer::StreamContributesToConnectionFlowControl( |
| 849 headers_stream_)); | 848 headers_stream_)); |
| 850 } | 849 } |
| 851 | 850 |
| 852 TEST_P(QuicHeadersStreamTest, HpackDecoderDebugVisitor) { | 851 TEST_P(QuicHeadersStreamTest, HpackDecoderDebugVisitor) { |
| 853 if (FLAGS_use_nested_spdy_framer_decoder) | 852 StrictMock<MockQuicHpackDebugVisitor>* hpack_decoder_visitor = |
| 854 return; | |
| 855 | |
| 856 StrictMock<MockHpackDebugVisitor>* hpack_decoder_visitor = | |
| 857 hpack_decoder_visitor_.get(); | 853 hpack_decoder_visitor_.get(); |
| 858 headers_stream_->SetHpackDecoderDebugVisitor( | 854 QuicSpdySessionPeer::SetHpackDecoderDebugVisitor( |
| 859 std::move(hpack_decoder_visitor_)); | 855 &session_, std::move(hpack_decoder_visitor_)); |
| 860 | 856 |
| 861 // Create some headers we expect to generate entries in HPACK's | 857 // Create some headers we expect to generate entries in HPACK's |
| 862 // dynamic table, in addition to content-length. | 858 // dynamic table, in addition to content-length. |
| 863 headers_["key0"] = string(1 << 1, '.'); | 859 headers_["key0"] = string(1 << 1, '.'); |
| 864 headers_["key1"] = string(1 << 2, '.'); | 860 headers_["key1"] = string(1 << 2, '.'); |
| 865 headers_["key2"] = string(1 << 3, '.'); | 861 headers_["key2"] = string(1 << 3, '.'); |
| 866 { | 862 { |
| 867 InSequence seq; | 863 InSequence seq; |
| 868 // Number of indexed representations generated in headers below. | 864 // Number of indexed representations generated in headers below. |
| 869 for (int i = 1; i < 28; i++) { | 865 for (int i = 1; i < 28; i++) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 898 connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1)); | 894 connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1)); |
| 899 headers_stream_->OnStreamFrame(stream_frame_); | 895 headers_stream_->OnStreamFrame(stream_frame_); |
| 900 stream_frame_.offset += frame.size(); | 896 stream_frame_.offset += frame.size(); |
| 901 CheckHeaders(); | 897 CheckHeaders(); |
| 902 } | 898 } |
| 903 } | 899 } |
| 904 } | 900 } |
| 905 } | 901 } |
| 906 | 902 |
| 907 TEST_P(QuicHeadersStreamTest, HpackEncoderDebugVisitor) { | 903 TEST_P(QuicHeadersStreamTest, HpackEncoderDebugVisitor) { |
| 908 StrictMock<MockHpackDebugVisitor>* hpack_encoder_visitor = | 904 StrictMock<MockQuicHpackDebugVisitor>* hpack_encoder_visitor = |
| 909 hpack_encoder_visitor_.get(); | 905 hpack_encoder_visitor_.get(); |
| 910 headers_stream_->SetHpackEncoderDebugVisitor( | 906 QuicSpdySessionPeer::SetHpackEncoderDebugVisitor( |
| 911 std::move(hpack_encoder_visitor_)); | 907 &session_, std::move(hpack_encoder_visitor_)); |
| 912 | 908 |
| 913 if (perspective() == Perspective::IS_SERVER) { | 909 if (perspective() == Perspective::IS_SERVER) { |
| 914 InSequence seq; | 910 InSequence seq; |
| 915 for (int i = 1; i < 4; i++) { | 911 for (int i = 1; i < 4; i++) { |
| 916 EXPECT_CALL(*hpack_encoder_visitor, | 912 EXPECT_CALL(*hpack_encoder_visitor, |
| 917 OnUseEntry(QuicTime::Delta::FromMilliseconds(i))); | 913 OnUseEntry(QuicTime::Delta::FromMilliseconds(i))); |
| 918 } | 914 } |
| 919 } else { | 915 } else { |
| 920 InSequence seq; | 916 InSequence seq; |
| 921 for (int i = 1; i < 28; i++) { | 917 for (int i = 1; i < 28; i++) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 958 for (bool use_ack_listener : {true, false}) { | 954 for (bool use_ack_listener : {true, false}) { |
| 959 QuicReferenceCountedPointer<ForceHolAckListener> ack_listener; | 955 QuicReferenceCountedPointer<ForceHolAckListener> ack_listener; |
| 960 if (use_ack_listener) { | 956 if (use_ack_listener) { |
| 961 ack_listener = new ForceHolAckListener(); | 957 ack_listener = new ForceHolAckListener(); |
| 962 } | 958 } |
| 963 EXPECT_CALL(session_, | 959 EXPECT_CALL(session_, |
| 964 WritevData(headers_stream_, kHeadersStreamId, _, _, false, _)) | 960 WritevData(headers_stream_, kHeadersStreamId, _, _, false, _)) |
| 965 .WillRepeatedly(WithArgs<2, 5>(Invoke( | 961 .WillRepeatedly(WithArgs<2, 5>(Invoke( |
| 966 this, &QuicHeadersStreamTest::SaveIovAndNotifyAckListener))); | 962 this, &QuicHeadersStreamTest::SaveIovAndNotifyAckListener))); |
| 967 | 963 |
| 968 QuicConsumedData consumed_data = headers_stream_->WritevStreamData( | 964 QuicConsumedData consumed_data = session_.WritevStreamData( |
| 969 id, MakeIOVector(data, &iov), offset, fin, ack_listener); | 965 id, MakeIOVector(data, &iov), offset, fin, ack_listener); |
| 970 | 966 |
| 971 EXPECT_EQ(consumed_data.bytes_consumed, data_len); | 967 EXPECT_EQ(consumed_data.bytes_consumed, data_len); |
| 972 EXPECT_EQ(consumed_data.fin_consumed, fin); | 968 EXPECT_EQ(consumed_data.fin_consumed, fin); |
| 973 // Now process the written data with the SPDY framer, and verify | 969 // Now process the written data with the SPDY framer, and verify |
| 974 // that the original data is unchanged. | 970 // that the original data is unchanged. |
| 975 EXPECT_CALL(visitor_, OnDataFrameHeader(id, _, _)) | 971 EXPECT_CALL(visitor_, OnDataFrameHeader(id, _, _)) |
| 976 .Times(AtLeast(kMinDataFrames)); | 972 .Times(AtLeast(kMinDataFrames)); |
| 977 EXPECT_CALL(visitor_, OnStreamFrameData(id, _, _)) | 973 EXPECT_CALL(visitor_, OnStreamFrameData(id, _, _)) |
| 978 .WillRepeatedly(WithArgs<1, 2>( | 974 .WillRepeatedly(WithArgs<1, 2>( |
| (...skipping 17 matching lines...) Expand all Loading... |
| 996 | 992 |
| 997 TEST_P(QuicHeadersStreamTest, WritevStreamDataFinOnly) { | 993 TEST_P(QuicHeadersStreamTest, WritevStreamDataFinOnly) { |
| 998 struct iovec iov; | 994 struct iovec iov; |
| 999 string data; | 995 string data; |
| 1000 | 996 |
| 1001 EXPECT_CALL(session_, | 997 EXPECT_CALL(session_, |
| 1002 WritevData(headers_stream_, kHeadersStreamId, _, _, false, _)) | 998 WritevData(headers_stream_, kHeadersStreamId, _, _, false, _)) |
| 1003 .WillOnce(WithArgs<2, 5>( | 999 .WillOnce(WithArgs<2, 5>( |
| 1004 Invoke(this, &QuicHeadersStreamTest::SaveIovAndNotifyAckListener))); | 1000 Invoke(this, &QuicHeadersStreamTest::SaveIovAndNotifyAckListener))); |
| 1005 | 1001 |
| 1006 QuicConsumedData consumed_data = headers_stream_->WritevStreamData( | 1002 QuicConsumedData consumed_data = session_.WritevStreamData( |
| 1007 kClientDataStreamId1, MakeIOVector(data, &iov), 0, true, nullptr); | 1003 kClientDataStreamId1, MakeIOVector(data, &iov), 0, true, nullptr); |
| 1008 | 1004 |
| 1009 EXPECT_EQ(consumed_data.bytes_consumed, 0u); | 1005 EXPECT_EQ(consumed_data.bytes_consumed, 0u); |
| 1010 EXPECT_EQ(consumed_data.fin_consumed, true); | 1006 EXPECT_EQ(consumed_data.fin_consumed, true); |
| 1011 } | 1007 } |
| 1012 | 1008 |
| 1013 TEST_P(QuicHeadersStreamTest, WritevStreamDataSendBlocked) { | 1009 TEST_P(QuicHeadersStreamTest, WritevStreamDataSendBlocked) { |
| 1014 QuicStreamId id = kClientDataStreamId1; | 1010 QuicStreamId id = kClientDataStreamId1; |
| 1015 QuicStreamOffset offset = 0; | 1011 QuicStreamOffset offset = 0; |
| 1016 struct iovec iov; | 1012 struct iovec iov; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1028 | 1024 |
| 1029 bool fin = true; | 1025 bool fin = true; |
| 1030 // So force the underlying |WritevData| to consume only 1 byte. | 1026 // So force the underlying |WritevData| to consume only 1 byte. |
| 1031 // In that case, |WritevStreamData| should consume just one | 1027 // In that case, |WritevStreamData| should consume just one |
| 1032 // HTTP/2 data frame's worth of data. | 1028 // HTTP/2 data frame's worth of data. |
| 1033 EXPECT_CALL(session_, | 1029 EXPECT_CALL(session_, |
| 1034 WritevData(headers_stream_, kHeadersStreamId, _, _, false, _)) | 1030 WritevData(headers_stream_, kHeadersStreamId, _, _, false, _)) |
| 1035 .WillOnce( | 1031 .WillOnce( |
| 1036 WithArgs<2>(Invoke(this, &QuicHeadersStreamTest::SaveIovShort))); | 1032 WithArgs<2>(Invoke(this, &QuicHeadersStreamTest::SaveIovShort))); |
| 1037 | 1033 |
| 1038 QuicConsumedData consumed_data = headers_stream_->WritevStreamData( | 1034 QuicConsumedData consumed_data = session_.WritevStreamData( |
| 1039 id, MakeIOVector(data, &iov), offset, fin, nullptr); | 1035 id, MakeIOVector(data, &iov), offset, fin, nullptr); |
| 1040 | 1036 |
| 1041 // bytes_consumed is max HTTP/2 data frame size minus the HTTP/2 | 1037 // bytes_consumed is max HTTP/2 data frame size minus the HTTP/2 |
| 1042 // data header size. | 1038 // data header size. |
| 1043 EXPECT_EQ(consumed_data.bytes_consumed, | 1039 EXPECT_EQ(consumed_data.bytes_consumed, |
| 1044 kSpdyInitialFrameSizeLimit - kDataFrameMinimumSize); | 1040 kSpdyInitialFrameSizeLimit - kDataFrameMinimumSize); |
| 1045 EXPECT_EQ(consumed_data.fin_consumed, false); | 1041 EXPECT_EQ(consumed_data.fin_consumed, false); |
| 1046 | 1042 |
| 1047 // If session already blocked, then bytes_consumed should be zero. | 1043 // If session already blocked, then bytes_consumed should be zero. |
| 1048 consumed_data = headers_stream_->WritevStreamData( | 1044 consumed_data = session_.WritevStreamData(id, MakeIOVector(data, &iov), |
| 1049 id, MakeIOVector(data, &iov), offset, fin, nullptr); | 1045 offset, fin, nullptr); |
| 1050 | 1046 |
| 1051 EXPECT_EQ(consumed_data.bytes_consumed, 0u); | 1047 EXPECT_EQ(consumed_data.bytes_consumed, 0u); |
| 1052 EXPECT_EQ(consumed_data.fin_consumed, false); | 1048 EXPECT_EQ(consumed_data.fin_consumed, false); |
| 1053 } | 1049 } |
| 1054 | 1050 |
| 1055 } // namespace | 1051 } // namespace |
| 1056 } // namespace test | 1052 } // namespace test |
| 1057 } // namespace net | 1053 } // namespace net |
| OLD | NEW |