| 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_flags.h" | |
| 14 #include "net/quic/core/quic_utils.h" | 13 #include "net/quic/core/quic_utils.h" |
| 15 #include "net/quic/core/spdy_utils.h" | 14 #include "net/quic/core/spdy_utils.h" |
| 16 #include "net/quic/platform/api/quic_bug_tracker.h" | 15 #include "net/quic/platform/api/quic_bug_tracker.h" |
| 16 #include "net/quic/platform/api/quic_flags.h" |
| 17 #include "net/quic/platform/api/quic_logging.h" | 17 #include "net/quic/platform/api/quic_logging.h" |
| 18 #include "net/quic/platform/api/quic_ptr_util.h" | 18 #include "net/quic/platform/api/quic_ptr_util.h" |
| 19 #include "net/quic/platform/api/quic_str_cat.h" | 19 #include "net/quic/platform/api/quic_str_cat.h" |
| 20 #include "net/quic/platform/api/quic_string_piece.h" | 20 #include "net/quic/platform/api/quic_string_piece.h" |
| 21 #include "net/quic/test_tools/quic_connection_peer.h" | 21 #include "net/quic/test_tools/quic_connection_peer.h" |
| 22 #include "net/quic/test_tools/quic_spdy_session_peer.h" | 22 #include "net/quic/test_tools/quic_spdy_session_peer.h" |
| 23 #include "net/quic/test_tools/quic_stream_peer.h" | 23 #include "net/quic/test_tools/quic_stream_peer.h" |
| 24 #include "net/quic/test_tools/quic_test_utils.h" | 24 #include "net/quic/test_tools/quic_test_utils.h" |
| 25 #include "net/spdy/spdy_alt_svc_wire_format.h" | 25 #include "net/spdy/spdy_alt_svc_wire_format.h" |
| 26 #include "net/spdy/spdy_flags.h" | 26 #include "net/spdy/spdy_flags.h" |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 310 void WriteAndExpectResponseHeaders(QuicStreamId stream_id, bool fin) { | 310 void WriteAndExpectResponseHeaders(QuicStreamId stream_id, bool fin) { |
| 311 WriteHeadersAndCheckData(stream_id, fin, 0, false /*is_request*/); | 311 WriteHeadersAndCheckData(stream_id, fin, 0, false /*is_request*/); |
| 312 } | 312 } |
| 313 | 313 |
| 314 void WriteHeadersAndCheckData(QuicStreamId stream_id, | 314 void WriteHeadersAndCheckData(QuicStreamId stream_id, |
| 315 bool fin, | 315 bool fin, |
| 316 SpdyPriority priority, | 316 SpdyPriority priority, |
| 317 bool is_request) { | 317 bool is_request) { |
| 318 // Write the headers and capture the outgoing data | 318 // Write the headers and capture the outgoing data |
| 319 EXPECT_CALL(session_, | 319 EXPECT_CALL(session_, |
| 320 WritevData(headers_stream_, kHeadersStreamId, _, _, false, _)) | 320 WritevData(headers_stream_, kHeadersStreamId, _, _, NO_FIN, _)) |
| 321 .WillOnce(WithArgs<2>(Invoke(this, &QuicHeadersStreamTest::SaveIov))); | 321 .WillOnce(WithArgs<2>(Invoke(this, &QuicHeadersStreamTest::SaveIov))); |
| 322 QuicSpdySessionPeer::WriteHeadersImpl( | 322 QuicSpdySessionPeer::WriteHeadersImpl( |
| 323 &session_, stream_id, headers_.Clone(), fin, priority, nullptr); | 323 &session_, stream_id, headers_.Clone(), fin, priority, nullptr); |
| 324 | 324 |
| 325 // Parse the outgoing data and check that it matches was was written. | 325 // Parse the outgoing data and check that it matches was was written. |
| 326 if (is_request) { | 326 if (is_request) { |
| 327 EXPECT_CALL(visitor_, | 327 EXPECT_CALL(visitor_, |
| 328 OnHeaders(stream_id, kHasPriority, | 328 OnHeaders(stream_id, kHasPriority, |
| 329 Spdy3PriorityToHttp2Weight(priority), | 329 Spdy3PriorityToHttp2Weight(priority), |
| 330 /*parent_stream_id=*/0, | 330 /*parent_stream_id=*/0, |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 426 } | 426 } |
| 427 } | 427 } |
| 428 } | 428 } |
| 429 | 429 |
| 430 TEST_P(QuicHeadersStreamTest, WritePushPromises) { | 430 TEST_P(QuicHeadersStreamTest, WritePushPromises) { |
| 431 for (QuicStreamId stream_id = kClientDataStreamId1; | 431 for (QuicStreamId stream_id = kClientDataStreamId1; |
| 432 stream_id < kClientDataStreamId3; stream_id += 2) { | 432 stream_id < kClientDataStreamId3; stream_id += 2) { |
| 433 QuicStreamId promised_stream_id = NextPromisedStreamId(); | 433 QuicStreamId promised_stream_id = NextPromisedStreamId(); |
| 434 if (perspective() == Perspective::IS_SERVER) { | 434 if (perspective() == Perspective::IS_SERVER) { |
| 435 // Write the headers and capture the outgoing data | 435 // Write the headers and capture the outgoing data |
| 436 EXPECT_CALL(session_, | 436 EXPECT_CALL(session_, WritevData(headers_stream_, kHeadersStreamId, _, _, |
| 437 WritevData(headers_stream_, kHeadersStreamId, _, _, false, _)) | 437 NO_FIN, _)) |
| 438 .WillOnce(WithArgs<2>(Invoke(this, &QuicHeadersStreamTest::SaveIov))); | 438 .WillOnce(WithArgs<2>(Invoke(this, &QuicHeadersStreamTest::SaveIov))); |
| 439 session_.WritePushPromise(stream_id, promised_stream_id, | 439 session_.WritePushPromise(stream_id, promised_stream_id, |
| 440 headers_.Clone()); | 440 headers_.Clone()); |
| 441 | 441 |
| 442 // Parse the outgoing data and check that it matches was was written. | 442 // Parse the outgoing data and check that it matches was was written. |
| 443 EXPECT_CALL(visitor_, | 443 EXPECT_CALL(visitor_, |
| 444 OnPushPromise(stream_id, promised_stream_id, kFrameComplete)); | 444 OnPushPromise(stream_id, promised_stream_id, kFrameComplete)); |
| 445 headers_handler_.reset(new TestHeadersHandler); | 445 headers_handler_.reset(new TestHeadersHandler); |
| 446 EXPECT_CALL(visitor_, OnHeaderFrameStart(stream_id)) | 446 EXPECT_CALL(visitor_, OnHeaderFrameStart(stream_id)) |
| 447 .WillOnce(Return(headers_handler_.get())); | 447 .WillOnce(Return(headers_handler_.get())); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 532 SpdySerializedFrame frame(framer_->SerializeFrame(data)); | 532 SpdySerializedFrame frame(framer_->SerializeFrame(data)); |
| 533 stream_frame_.data_buffer = frame.data(); | 533 stream_frame_.data_buffer = frame.data(); |
| 534 stream_frame_.data_length = frame.size(); | 534 stream_frame_.data_length = frame.size(); |
| 535 if (perspective() == Perspective::IS_CLIENT) { | 535 if (perspective() == Perspective::IS_CLIENT) { |
| 536 EXPECT_CALL( | 536 EXPECT_CALL( |
| 537 *connection_, | 537 *connection_, |
| 538 CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, | 538 CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, |
| 539 "Unsupported field of HTTP/2 SETTINGS frame: 2", _)); | 539 "Unsupported field of HTTP/2 SETTINGS frame: 2", _)); |
| 540 } | 540 } |
| 541 headers_stream_->OnStreamFrame(stream_frame_); | 541 headers_stream_->OnStreamFrame(stream_frame_); |
| 542 EXPECT_EQ( | 542 EXPECT_EQ(session_.server_push_enabled(), |
| 543 session_.server_push_enabled(), | 543 perspective() == Perspective::IS_CLIENT); |
| 544 (perspective() == Perspective::IS_CLIENT && version() > QUIC_VERSION_34)); | |
| 545 } | 544 } |
| 546 | 545 |
| 547 TEST_P(QuicHeadersStreamTest, EmptyHeaderHOLBlockedTime) { | 546 TEST_P(QuicHeadersStreamTest, EmptyHeaderHOLBlockedTime) { |
| 548 EXPECT_CALL(session_, OnHeadersHeadOfLineBlocking(_)).Times(0); | 547 EXPECT_CALL(session_, OnHeadersHeadOfLineBlocking(_)).Times(0); |
| 549 InSequence seq; | 548 InSequence seq; |
| 550 bool fin = true; | 549 bool fin = true; |
| 551 for (int stream_num = 0; stream_num < 10; stream_num++) { | 550 for (int stream_num = 0; stream_num < 10; stream_num++) { |
| 552 QuicStreamId stream_id = QuicClientDataStreamId(stream_num); | 551 QuicStreamId stream_id = QuicClientDataStreamId(stream_num); |
| 553 // Replace with "WriteHeadersAndSaveData" | 552 // Replace with "WriteHeadersAndSaveData" |
| 554 SpdySerializedFrame frame; | 553 SpdySerializedFrame frame; |
| (...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 937 // Set headers stream send window large enough for data written below. | 936 // Set headers stream send window large enough for data written below. |
| 938 headers_stream_->flow_controller()->UpdateSendWindowOffset(data_len * 2 * 4); | 937 headers_stream_->flow_controller()->UpdateSendWindowOffset(data_len * 2 * 4); |
| 939 string data(data_len, 'a'); | 938 string data(data_len, 'a'); |
| 940 | 939 |
| 941 for (bool fin : {true, false}) { | 940 for (bool fin : {true, false}) { |
| 942 for (bool use_ack_listener : {true, false}) { | 941 for (bool use_ack_listener : {true, false}) { |
| 943 QuicReferenceCountedPointer<ForceHolAckListener> ack_listener; | 942 QuicReferenceCountedPointer<ForceHolAckListener> ack_listener; |
| 944 if (use_ack_listener) { | 943 if (use_ack_listener) { |
| 945 ack_listener = new ForceHolAckListener(); | 944 ack_listener = new ForceHolAckListener(); |
| 946 } | 945 } |
| 947 EXPECT_CALL(session_, | 946 EXPECT_CALL(session_, WritevData(headers_stream_, kHeadersStreamId, _, _, |
| 948 WritevData(headers_stream_, kHeadersStreamId, _, _, false, _)) | 947 NO_FIN, _)) |
| 949 .WillRepeatedly(WithArgs<2, 5>(Invoke( | 948 .WillRepeatedly(WithArgs<2, 5>(Invoke( |
| 950 this, &QuicHeadersStreamTest::SaveIovAndNotifyAckListener))); | 949 this, &QuicHeadersStreamTest::SaveIovAndNotifyAckListener))); |
| 951 | 950 |
| 952 QuicConsumedData consumed_data = session_.WritevStreamData( | 951 QuicConsumedData consumed_data = session_.WritevStreamData( |
| 953 id, MakeIOVector(data, &iov), offset, fin, ack_listener); | 952 id, MakeIOVector(data, &iov), offset, fin, ack_listener); |
| 954 | 953 |
| 955 EXPECT_EQ(consumed_data.bytes_consumed, data_len); | 954 EXPECT_EQ(consumed_data.bytes_consumed, data_len); |
| 956 EXPECT_EQ(consumed_data.fin_consumed, fin); | 955 EXPECT_EQ(consumed_data.fin_consumed, fin); |
| 957 // Now process the written data with the SPDY framer, and verify | 956 // Now process the written data with the SPDY framer, and verify |
| 958 // that the original data is unchanged. | 957 // that the original data is unchanged. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 976 saved_payloads_.clear(); | 975 saved_payloads_.clear(); |
| 977 } | 976 } |
| 978 } | 977 } |
| 979 } | 978 } |
| 980 | 979 |
| 981 TEST_P(QuicHeadersStreamTest, WritevStreamDataFinOnly) { | 980 TEST_P(QuicHeadersStreamTest, WritevStreamDataFinOnly) { |
| 982 struct iovec iov; | 981 struct iovec iov; |
| 983 string data; | 982 string data; |
| 984 | 983 |
| 985 EXPECT_CALL(session_, | 984 EXPECT_CALL(session_, |
| 986 WritevData(headers_stream_, kHeadersStreamId, _, _, false, _)) | 985 WritevData(headers_stream_, kHeadersStreamId, _, _, NO_FIN, _)) |
| 987 .WillOnce(WithArgs<2, 5>( | 986 .WillOnce(WithArgs<2, 5>( |
| 988 Invoke(this, &QuicHeadersStreamTest::SaveIovAndNotifyAckListener))); | 987 Invoke(this, &QuicHeadersStreamTest::SaveIovAndNotifyAckListener))); |
| 989 | 988 |
| 990 QuicConsumedData consumed_data = session_.WritevStreamData( | 989 QuicConsumedData consumed_data = session_.WritevStreamData( |
| 991 kClientDataStreamId1, MakeIOVector(data, &iov), 0, true, nullptr); | 990 kClientDataStreamId1, MakeIOVector(data, &iov), 0, true, nullptr); |
| 992 | 991 |
| 993 EXPECT_EQ(consumed_data.bytes_consumed, 0u); | 992 EXPECT_EQ(consumed_data.bytes_consumed, 0u); |
| 994 EXPECT_EQ(consumed_data.fin_consumed, true); | 993 EXPECT_EQ(consumed_data.fin_consumed, true); |
| 995 } | 994 } |
| 996 | 995 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1008 const size_t data_len = kSpdyInitialFrameSizeLimit * kMinDataFrames + 1024; | 1007 const size_t data_len = kSpdyInitialFrameSizeLimit * kMinDataFrames + 1024; |
| 1009 // Set headers stream send window large enough for data written below. | 1008 // Set headers stream send window large enough for data written below. |
| 1010 headers_stream_->flow_controller()->UpdateSendWindowOffset(data_len * 2 * 4); | 1009 headers_stream_->flow_controller()->UpdateSendWindowOffset(data_len * 2 * 4); |
| 1011 string data(data_len, 'a'); | 1010 string data(data_len, 'a'); |
| 1012 | 1011 |
| 1013 bool fin = true; | 1012 bool fin = true; |
| 1014 // So force the underlying |WritevData| to consume only 1 byte. | 1013 // So force the underlying |WritevData| to consume only 1 byte. |
| 1015 // In that case, |WritevStreamData| should consume just one | 1014 // In that case, |WritevStreamData| should consume just one |
| 1016 // HTTP/2 data frame's worth of data. | 1015 // HTTP/2 data frame's worth of data. |
| 1017 EXPECT_CALL(session_, | 1016 EXPECT_CALL(session_, |
| 1018 WritevData(headers_stream_, kHeadersStreamId, _, _, false, _)) | 1017 WritevData(headers_stream_, kHeadersStreamId, _, _, NO_FIN, _)) |
| 1019 .WillOnce( | 1018 .WillOnce( |
| 1020 WithArgs<2>(Invoke(this, &QuicHeadersStreamTest::SaveIovShort))); | 1019 WithArgs<2>(Invoke(this, &QuicHeadersStreamTest::SaveIovShort))); |
| 1021 | 1020 |
| 1022 QuicConsumedData consumed_data = session_.WritevStreamData( | 1021 QuicConsumedData consumed_data = session_.WritevStreamData( |
| 1023 id, MakeIOVector(data, &iov), offset, fin, nullptr); | 1022 id, MakeIOVector(data, &iov), offset, fin, nullptr); |
| 1024 | 1023 |
| 1025 // bytes_consumed is max HTTP/2 data frame size minus the HTTP/2 | 1024 // bytes_consumed is max HTTP/2 data frame size minus the HTTP/2 |
| 1026 // data header size. | 1025 // data header size. |
| 1027 EXPECT_EQ(consumed_data.bytes_consumed, | 1026 EXPECT_EQ(consumed_data.bytes_consumed, |
| 1028 kSpdyInitialFrameSizeLimit - kDataFrameMinimumSize); | 1027 kSpdyInitialFrameSizeLimit - kDataFrameMinimumSize); |
| 1029 EXPECT_EQ(consumed_data.fin_consumed, false); | 1028 EXPECT_EQ(consumed_data.fin_consumed, false); |
| 1030 | 1029 |
| 1031 // If session already blocked, then bytes_consumed should be zero. | 1030 // If session already blocked, then bytes_consumed should be zero. |
| 1032 consumed_data = session_.WritevStreamData(id, MakeIOVector(data, &iov), | 1031 consumed_data = session_.WritevStreamData(id, MakeIOVector(data, &iov), |
| 1033 offset, fin, nullptr); | 1032 offset, fin, nullptr); |
| 1034 | 1033 |
| 1035 EXPECT_EQ(consumed_data.bytes_consumed, 0u); | 1034 EXPECT_EQ(consumed_data.bytes_consumed, 0u); |
| 1036 EXPECT_EQ(consumed_data.fin_consumed, false); | 1035 EXPECT_EQ(consumed_data.fin_consumed, false); |
| 1037 } | 1036 } |
| 1038 | 1037 |
| 1039 } // namespace | 1038 } // namespace |
| 1040 } // namespace test | 1039 } // namespace test |
| 1041 } // namespace net | 1040 } // namespace net |
| OLD | NEW |