| 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 <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
| 10 #include "net/quic/core/quic_bug_tracker.h" | 10 #include "net/quic/core/quic_bug_tracker.h" |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 const iovec* iov = data.iov; | 253 const iovec* iov = data.iov; |
| 254 int count = data.iov_count; | 254 int count = data.iov_count; |
| 255 int consumed = 0; | 255 int consumed = 0; |
| 256 for (int i = 0; i < count; ++i) { | 256 for (int i = 0; i < count; ++i) { |
| 257 saved_data_.append(static_cast<char*>(iov[i].iov_base), iov[i].iov_len); | 257 saved_data_.append(static_cast<char*>(iov[i].iov_base), iov[i].iov_len); |
| 258 consumed += iov[i].iov_len; | 258 consumed += iov[i].iov_len; |
| 259 } | 259 } |
| 260 return QuicConsumedData(consumed, false); | 260 return QuicConsumedData(consumed, false); |
| 261 } | 261 } |
| 262 | 262 |
| 263 QuicConsumedData SaveIovShort(const QuicIOVector& data) { | |
| 264 const iovec* iov = data.iov; | |
| 265 int consumed = 1; | |
| 266 saved_data_.append(static_cast<char*>(iov[0].iov_base), consumed); | |
| 267 return QuicConsumedData(consumed, false); | |
| 268 } | |
| 269 | |
| 270 QuicConsumedData SaveIovAndNotifyAckListener( | 263 QuicConsumedData SaveIovAndNotifyAckListener( |
| 271 const QuicIOVector& data, | 264 const QuicIOVector& data, |
| 272 QuicAckListenerInterface* ack_listener) { | 265 QuicAckListenerInterface* ack_listener) { |
| 273 QuicConsumedData result = SaveIov(data); | 266 QuicConsumedData result = SaveIov(data); |
| 274 if (ack_listener) { | 267 if (ack_listener) { |
| 275 ack_listener->OnPacketAcked(result.bytes_consumed, | 268 ack_listener->OnPacketAcked(result.bytes_consumed, |
| 276 QuicTime::Delta::Zero()); | 269 QuicTime::Delta::Zero()); |
| 277 } | 270 } |
| 278 return result; | 271 return result; |
| 279 } | 272 } |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 627 | 620 |
| 628 for (int stream_num = 9; stream_num >= 0; --stream_num) { | 621 for (int stream_num = 9; stream_num >= 0; --stream_num) { |
| 629 DVLOG(1) << "OnStreamFrame for stream " << stream_num << " offset " | 622 DVLOG(1) << "OnStreamFrame for stream " << stream_num << " offset " |
| 630 << stream_frames[stream_num].offset; | 623 << stream_frames[stream_num].offset; |
| 631 headers_stream_->OnStreamFrame(stream_frames[stream_num]); | 624 headers_stream_->OnStreamFrame(stream_frames[stream_num]); |
| 632 connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1)); | 625 connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1)); |
| 633 } | 626 } |
| 634 } | 627 } |
| 635 | 628 |
| 636 TEST_P(QuicHeadersStreamTest, ProcessLargeRawData) { | 629 TEST_P(QuicHeadersStreamTest, ProcessLargeRawData) { |
| 630 headers_stream_->set_max_uncompressed_header_bytes(256 * 1024); |
| 637 // We want to create a frame that is more than the SPDY Framer's max control | 631 // We want to create a frame that is more than the SPDY Framer's max control |
| 638 // frame size, which is 16K, but less than the HPACK decoders max decode | 632 // frame size, which is 16K, but less than the HPACK decoders max decode |
| 639 // buffer size, which is 32K. | 633 // buffer size, which is 32K. |
| 640 headers_["key0"] = string(1 << 13, '.'); | 634 headers_["key0"] = string(1 << 13, '.'); |
| 641 headers_["key1"] = string(1 << 13, '.'); | 635 headers_["key1"] = string(1 << 13, '.'); |
| 642 headers_["key2"] = string(1 << 13, '.'); | 636 headers_["key2"] = string(1 << 13, '.'); |
| 643 for (QuicStreamId stream_id = kClientDataStreamId1; | 637 for (QuicStreamId stream_id = kClientDataStreamId1; |
| 644 stream_id < kClientDataStreamId3; stream_id += 2) { | 638 stream_id < kClientDataStreamId3; stream_id += 2) { |
| 645 for (bool fin : {false, true}) { | 639 for (bool fin : {false, true}) { |
| 646 for (SpdyPriority priority = 0; priority < 7; ++priority) { | 640 for (SpdyPriority priority = 0; priority < 7; ++priority) { |
| (...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 992 // Notice, acked bytes doesn't include extra bytes used by | 986 // Notice, acked bytes doesn't include extra bytes used by |
| 993 // HTTP/2 DATA frame headers. | 987 // HTTP/2 DATA frame headers. |
| 994 EXPECT_EQ(ack_listener->total_acked_bytes(), data_len); | 988 EXPECT_EQ(ack_listener->total_acked_bytes(), data_len); |
| 995 } | 989 } |
| 996 saved_data_.clear(); | 990 saved_data_.clear(); |
| 997 saved_payloads_.clear(); | 991 saved_payloads_.clear(); |
| 998 } | 992 } |
| 999 } | 993 } |
| 1000 } | 994 } |
| 1001 | 995 |
| 1002 TEST_P(QuicHeadersStreamTest, WritevStreamDataFinOnly) { | |
| 1003 FLAGS_quic_bugfix_fhol_writev_fin_only_v2 = true; | |
| 1004 struct iovec iov; | |
| 1005 string data; | |
| 1006 | |
| 1007 EXPECT_CALL(session_, | |
| 1008 WritevData(headers_stream_, kHeadersStreamId, _, _, false, _)) | |
| 1009 .WillOnce(WithArgs<2, 5>( | |
| 1010 Invoke(this, &QuicHeadersStreamTest::SaveIovAndNotifyAckListener))); | |
| 1011 | |
| 1012 QuicConsumedData consumed_data = headers_stream_->WritevStreamData( | |
| 1013 kClientDataStreamId1, MakeIOVector(data, &iov), 0, true, nullptr); | |
| 1014 | |
| 1015 EXPECT_EQ(consumed_data.bytes_consumed, 0u); | |
| 1016 EXPECT_EQ(consumed_data.fin_consumed, true); | |
| 1017 } | |
| 1018 | |
| 1019 TEST_P(QuicHeadersStreamTest, WritevStreamDataSendBlocked) { | |
| 1020 FLAGS_quic_bugfix_fhol_writev_fin_only_v2 = true; | |
| 1021 QuicStreamId id = kClientDataStreamId1; | |
| 1022 QuicStreamOffset offset = 0; | |
| 1023 struct iovec iov; | |
| 1024 string data; | |
| 1025 | |
| 1026 // This test will issue a write that will require fragmenting into | |
| 1027 // multiple HTTP/2 DATA frames. It will ensure that only 1 frame | |
| 1028 // will go out in the case that the underlying session becomes write | |
| 1029 // blocked. Buffering is required to preserve framing, but the | |
| 1030 // amount of buffering is limited to one HTTP/2 data frame. | |
| 1031 const int kMinDataFrames = 4; | |
| 1032 const size_t data_len = kSpdyInitialFrameSizeLimit * kMinDataFrames + 1024; | |
| 1033 // Set headers stream send window large enough for data written below. | |
| 1034 headers_stream_->flow_controller()->UpdateSendWindowOffset(data_len * 2 * 4); | |
| 1035 test::GenerateBody(&data, data_len); | |
| 1036 | |
| 1037 bool fin = true; | |
| 1038 // So force the underlying |WritevData| to consume only 1 byte. | |
| 1039 // In that case, |WritevStreamData| should consume just one | |
| 1040 // HTTP/2 data frame's worth of data. | |
| 1041 EXPECT_CALL(session_, | |
| 1042 WritevData(headers_stream_, kHeadersStreamId, _, _, false, _)) | |
| 1043 .WillOnce( | |
| 1044 WithArgs<2>(Invoke(this, &QuicHeadersStreamTest::SaveIovShort))); | |
| 1045 | |
| 1046 QuicConsumedData consumed_data = headers_stream_->WritevStreamData( | |
| 1047 id, MakeIOVector(data, &iov), offset, fin, nullptr); | |
| 1048 | |
| 1049 // bytes_consumed is max HTTP/2 data frame size minus the HTTP/2 | |
| 1050 // data header size. | |
| 1051 EXPECT_EQ(consumed_data.bytes_consumed, | |
| 1052 kSpdyInitialFrameSizeLimit - | |
| 1053 SpdyConstants::GetDataFrameMinimumSize(HTTP2)); | |
| 1054 EXPECT_EQ(consumed_data.fin_consumed, false); | |
| 1055 | |
| 1056 // If session already blocked, then bytes_consumed should be zero. | |
| 1057 consumed_data = headers_stream_->WritevStreamData( | |
| 1058 id, MakeIOVector(data, &iov), offset, fin, nullptr); | |
| 1059 | |
| 1060 EXPECT_EQ(consumed_data.bytes_consumed, 0u); | |
| 1061 EXPECT_EQ(consumed_data.fin_consumed, false); | |
| 1062 } | |
| 1063 | |
| 1064 } // namespace | 996 } // namespace |
| 1065 } // namespace test | 997 } // namespace test |
| 1066 } // namespace net | 998 } // namespace net |
| OLD | NEW |