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