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 712 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
992 // Notice, acked bytes doesn't include extra bytes used by | 985 // Notice, acked bytes doesn't include extra bytes used by |
993 // HTTP/2 DATA frame headers. | 986 // HTTP/2 DATA frame headers. |
994 EXPECT_EQ(ack_listener->total_acked_bytes(), data_len); | 987 EXPECT_EQ(ack_listener->total_acked_bytes(), data_len); |
995 } | 988 } |
996 saved_data_.clear(); | 989 saved_data_.clear(); |
997 saved_payloads_.clear(); | 990 saved_payloads_.clear(); |
998 } | 991 } |
999 } | 992 } |
1000 } | 993 } |
1001 | 994 |
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 | 995 } // namespace |
1065 } // namespace test | 996 } // namespace test |
1066 } // namespace net | 997 } // namespace net |
OLD | NEW |