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 |
263 QuicConsumedData SaveIovAndNotifyAckListener( | 270 QuicConsumedData SaveIovAndNotifyAckListener( |
264 const QuicIOVector& data, | 271 const QuicIOVector& data, |
265 QuicAckListenerInterface* ack_listener) { | 272 QuicAckListenerInterface* ack_listener) { |
266 QuicConsumedData result = SaveIov(data); | 273 QuicConsumedData result = SaveIov(data); |
267 if (ack_listener) { | 274 if (ack_listener) { |
268 ack_listener->OnPacketAcked(result.bytes_consumed, | 275 ack_listener->OnPacketAcked(result.bytes_consumed, |
269 QuicTime::Delta::Zero()); | 276 QuicTime::Delta::Zero()); |
270 } | 277 } |
271 return result; | 278 return result; |
272 } | 279 } |
(...skipping 712 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
985 // Notice, acked bytes doesn't include extra bytes used by | 992 // Notice, acked bytes doesn't include extra bytes used by |
986 // HTTP/2 DATA frame headers. | 993 // HTTP/2 DATA frame headers. |
987 EXPECT_EQ(ack_listener->total_acked_bytes(), data_len); | 994 EXPECT_EQ(ack_listener->total_acked_bytes(), data_len); |
988 } | 995 } |
989 saved_data_.clear(); | 996 saved_data_.clear(); |
990 saved_payloads_.clear(); | 997 saved_payloads_.clear(); |
991 } | 998 } |
992 } | 999 } |
993 } | 1000 } |
994 | 1001 |
| 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 |
995 } // namespace | 1064 } // namespace |
996 } // namespace test | 1065 } // namespace test |
997 } // namespace net | 1066 } // namespace net |
OLD | NEW |