OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/quic_http_stream.h" | 5 #include "net/quic/quic_http_stream.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "net/base/net_errors.h" | 9 #include "net/base/net_errors.h" |
10 #include "net/base/test_completion_callback.h" | 10 #include "net/base/test_completion_callback.h" |
11 #include "net/base/upload_bytes_element_reader.h" | 11 #include "net/base/upload_bytes_element_reader.h" |
12 #include "net/base/upload_data_stream.h" | 12 #include "net/base/upload_data_stream.h" |
13 #include "net/http/http_response_headers.h" | 13 #include "net/http/http_response_headers.h" |
14 #include "net/quic/congestion_control/receive_algorithm_interface.h" | 14 #include "net/quic/congestion_control/receive_algorithm_interface.h" |
15 #include "net/quic/congestion_control/send_algorithm_interface.h" | 15 #include "net/quic/congestion_control/send_algorithm_interface.h" |
16 #include "net/quic/crypto/crypto_protocol.h" | 16 #include "net/quic/crypto/crypto_protocol.h" |
17 #include "net/quic/crypto/quic_decrypter.h" | 17 #include "net/quic/crypto/quic_decrypter.h" |
18 #include "net/quic/crypto/quic_encrypter.h" | 18 #include "net/quic/crypto/quic_encrypter.h" |
19 #include "net/quic/quic_client_session.h" | 19 #include "net/quic/quic_client_session.h" |
20 #include "net/quic/quic_connection.h" | 20 #include "net/quic/quic_connection.h" |
21 #include "net/quic/quic_connection_helper.h" | 21 #include "net/quic/quic_connection_helper.h" |
22 #include "net/quic/quic_default_packet_writer.h" | 22 #include "net/quic/quic_default_packet_writer.h" |
23 #include "net/quic/quic_http_utils.h" | 23 #include "net/quic/quic_http_utils.h" |
24 #include "net/quic/quic_reliable_client_stream.h" | 24 #include "net/quic/quic_reliable_client_stream.h" |
25 #include "net/quic/spdy_utils.h" | 25 #include "net/quic/spdy_utils.h" |
26 #include "net/quic/test_tools/mock_clock.h" | 26 #include "net/quic/test_tools/mock_clock.h" |
27 #include "net/quic/test_tools/mock_crypto_client_stream_factory.h" | 27 #include "net/quic/test_tools/mock_crypto_client_stream_factory.h" |
28 #include "net/quic/test_tools/mock_random.h" | 28 #include "net/quic/test_tools/mock_random.h" |
29 #include "net/quic/test_tools/quic_connection_peer.h" | 29 #include "net/quic/test_tools/quic_connection_peer.h" |
| 30 #include "net/quic/test_tools/quic_test_packet_maker.h" |
30 #include "net/quic/test_tools/quic_test_utils.h" | 31 #include "net/quic/test_tools/quic_test_utils.h" |
31 #include "net/quic/test_tools/test_task_runner.h" | 32 #include "net/quic/test_tools/test_task_runner.h" |
32 #include "net/socket/socket_test_util.h" | 33 #include "net/socket/socket_test_util.h" |
33 #include "net/spdy/spdy_frame_builder.h" | 34 #include "net/spdy/spdy_frame_builder.h" |
34 #include "net/spdy/spdy_framer.h" | 35 #include "net/spdy/spdy_framer.h" |
35 #include "net/spdy/spdy_http_utils.h" | 36 #include "net/spdy/spdy_http_utils.h" |
36 #include "net/spdy/spdy_protocol.h" | 37 #include "net/spdy/spdy_protocol.h" |
37 #include "net/spdy/write_blocked_list.h" | 38 #include "net/spdy/write_blocked_list.h" |
38 #include "testing/gmock/include/gmock/gmock.h" | 39 #include "testing/gmock/include/gmock/gmock.h" |
39 #include "testing/gtest/include/gtest/gtest.h" | 40 #include "testing/gtest/include/gtest/gtest.h" |
40 | 41 |
41 using testing::_; | 42 using testing::_; |
42 using testing::AnyNumber; | 43 using testing::AnyNumber; |
43 using testing::Return; | 44 using testing::Return; |
44 | 45 |
45 namespace net { | 46 namespace net { |
46 namespace test { | 47 namespace test { |
47 namespace { | 48 namespace { |
48 | 49 |
49 const char kUploadData[] = "hello world!"; | 50 const char kUploadData[] = "hello world!"; |
50 | 51 |
51 class TestQuicConnection : public QuicConnection { | 52 class TestQuicConnection : public QuicConnection { |
52 public: | 53 public: |
53 TestQuicConnection(QuicGuid guid, | 54 TestQuicConnection(const QuicVersionVector& versions, |
| 55 QuicGuid guid, |
54 IPEndPoint address, | 56 IPEndPoint address, |
55 QuicConnectionHelper* helper, | 57 QuicConnectionHelper* helper, |
56 QuicPacketWriter* writer) | 58 QuicPacketWriter* writer) |
57 : QuicConnection(guid, address, helper, writer, false, | 59 : QuicConnection(guid, address, helper, writer, false, versions) { |
58 QuicSupportedVersions()) { | |
59 } | 60 } |
60 | 61 |
61 void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) { | 62 void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) { |
62 QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm); | 63 QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm); |
63 } | 64 } |
64 | 65 |
65 void SetReceiveAlgorithm(ReceiveAlgorithmInterface* receive_algorithm) { | 66 void SetReceiveAlgorithm(ReceiveAlgorithmInterface* receive_algorithm) { |
66 QuicConnectionPeer::SetReceiveAlgorithm(this, receive_algorithm); | 67 QuicConnectionPeer::SetReceiveAlgorithm(this, receive_algorithm); |
67 } | 68 } |
68 }; | 69 }; |
69 | 70 |
70 class TestReceiveAlgorithm : public ReceiveAlgorithmInterface { | 71 class TestReceiveAlgorithm : public ReceiveAlgorithmInterface { |
71 public: | 72 public: |
72 explicit TestReceiveAlgorithm(QuicCongestionFeedbackFrame* feedback) | 73 virtual bool GenerateCongestionFeedback( |
73 : feedback_(feedback) { | 74 QuicCongestionFeedbackFrame* /*congestion_feedback*/) { |
74 } | 75 return false; |
75 | |
76 bool GenerateCongestionFeedback( | |
77 QuicCongestionFeedbackFrame* congestion_feedback) { | |
78 if (feedback_ == NULL) { | |
79 return false; | |
80 } | |
81 *congestion_feedback = *feedback_; | |
82 return true; | |
83 } | 76 } |
84 | 77 |
85 MOCK_METHOD4(RecordIncomingPacket, | 78 MOCK_METHOD4(RecordIncomingPacket, |
86 void(QuicByteCount, QuicPacketSequenceNumber, QuicTime, bool)); | 79 void(QuicByteCount, QuicPacketSequenceNumber, QuicTime, bool)); |
87 | |
88 private: | |
89 MockClock clock_; | |
90 QuicCongestionFeedbackFrame* feedback_; | |
91 | |
92 DISALLOW_COPY_AND_ASSIGN(TestReceiveAlgorithm); | |
93 }; | 80 }; |
94 | 81 |
95 // Subclass of QuicHttpStream that closes itself when the first piece of data | 82 // Subclass of QuicHttpStream that closes itself when the first piece of data |
96 // is received. | 83 // is received. |
97 class AutoClosingStream : public QuicHttpStream { | 84 class AutoClosingStream : public QuicHttpStream { |
98 public: | 85 public: |
99 explicit AutoClosingStream(const base::WeakPtr<QuicClientSession>& session) | 86 explicit AutoClosingStream(const base::WeakPtr<QuicClientSession>& session) |
100 : QuicHttpStream(session) { | 87 : QuicHttpStream(session) { |
101 } | 88 } |
102 | 89 |
103 virtual int OnDataReceived(const char* data, int length) OVERRIDE { | 90 virtual int OnDataReceived(const char* data, int length) OVERRIDE { |
104 Close(false); | 91 Close(false); |
105 return OK; | 92 return OK; |
106 } | 93 } |
107 }; | 94 }; |
108 | 95 |
109 } // namespace | 96 } // namespace |
110 | 97 |
111 class QuicHttpStreamPeer { | 98 class QuicHttpStreamPeer { |
112 public: | 99 public: |
113 static QuicReliableClientStream* GetQuicReliableClientStream( | 100 static QuicReliableClientStream* GetQuicReliableClientStream( |
114 QuicHttpStream* stream) { | 101 QuicHttpStream* stream) { |
115 return stream->stream_; | 102 return stream->stream_; |
116 } | 103 } |
117 }; | 104 }; |
118 | 105 |
119 class QuicHttpStreamTest : public ::testing::TestWithParam<bool> { | 106 class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> { |
120 protected: | 107 protected: |
121 const static bool kFin = true; | 108 static const bool kFin = true; |
| 109 static const bool kIncludeVersion = true; |
| 110 static const bool kIncludeCongestionFeedback = true; |
| 111 |
122 // Holds a packet to be written to the wire, and the IO mode that should | 112 // Holds a packet to be written to the wire, and the IO mode that should |
123 // be used by the mock socket when performing the write. | 113 // be used by the mock socket when performing the write. |
124 struct PacketToWrite { | 114 struct PacketToWrite { |
125 PacketToWrite(IoMode mode, QuicEncryptedPacket* packet) | 115 PacketToWrite(IoMode mode, QuicEncryptedPacket* packet) |
126 : mode(mode), | 116 : mode(mode), |
127 packet(packet) { | 117 packet(packet) { |
128 } | 118 } |
129 IoMode mode; | 119 IoMode mode; |
130 QuicEncryptedPacket* packet; | 120 QuicEncryptedPacket* packet; |
131 }; | 121 }; |
132 | 122 |
133 QuicHttpStreamTest() | 123 QuicHttpStreamTest() |
134 : net_log_(BoundNetLog()), | 124 : net_log_(BoundNetLog()), |
135 use_closing_stream_(false), | 125 use_closing_stream_(false), |
136 read_buffer_(new IOBufferWithSize(4096)), | 126 read_buffer_(new IOBufferWithSize(4096)), |
137 guid_(2), | 127 guid_(2), |
138 framer_(QuicSupportedVersions(), QuicTime::Zero(), false), | 128 stream_id_(GetParam() > QUIC_VERSION_12 ? 5 : 3), |
139 random_generator_(0), | 129 maker_(GetParam(), guid_), |
140 creator_(guid_, &framer_, &random_generator_, false) { | 130 random_generator_(0) { |
141 IPAddressNumber ip; | 131 IPAddressNumber ip; |
142 CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip)); | 132 CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip)); |
143 peer_addr_ = IPEndPoint(ip, 443); | 133 peer_addr_ = IPEndPoint(ip, 443); |
144 self_addr_ = IPEndPoint(ip, 8435); | 134 self_addr_ = IPEndPoint(ip, 8435); |
145 } | 135 } |
146 | 136 |
147 ~QuicHttpStreamTest() { | 137 ~QuicHttpStreamTest() { |
148 session_->CloseSessionOnError(ERR_ABORTED); | 138 session_->CloseSessionOnError(ERR_ABORTED); |
149 for (size_t i = 0; i < writes_.size(); i++) { | 139 for (size_t i = 0; i < writes_.size(); i++) { |
150 delete writes_[i].packet; | 140 delete writes_[i].packet; |
151 } | 141 } |
152 } | 142 } |
153 | 143 |
154 // Adds a packet to the list of expected writes. | 144 // Adds a packet to the list of expected writes. |
155 void AddWrite(IoMode mode, QuicEncryptedPacket* packet) { | 145 void AddWrite(scoped_ptr<QuicEncryptedPacket> packet) { |
156 writes_.push_back(PacketToWrite(mode, packet)); | 146 writes_.push_back(PacketToWrite(SYNCHRONOUS, packet.release())); |
157 } | 147 } |
158 | 148 |
159 // Returns the packet to be written at position |pos|. | 149 // Returns the packet to be written at position |pos|. |
160 QuicEncryptedPacket* GetWrite(size_t pos) { | 150 QuicEncryptedPacket* GetWrite(size_t pos) { |
161 return writes_[pos].packet; | 151 return writes_[pos].packet; |
162 } | 152 } |
163 | 153 |
164 bool AtEof() { | 154 bool AtEof() { |
165 return socket_data_->at_read_eof() && socket_data_->at_write_eof(); | 155 return socket_data_->at_read_eof() && socket_data_->at_write_eof(); |
166 } | 156 } |
167 | 157 |
168 void ProcessPacket(const QuicEncryptedPacket& packet) { | 158 void ProcessPacket(scoped_ptr<QuicEncryptedPacket> packet) { |
169 connection_->ProcessUdpPacket(self_addr_, peer_addr_, packet); | 159 connection_->ProcessUdpPacket(self_addr_, peer_addr_, *packet); |
170 } | 160 } |
171 | 161 |
172 // Configures the test fixture to use the list of expected writes. | 162 // Configures the test fixture to use the list of expected writes. |
173 void Initialize() { | 163 void Initialize() { |
174 mock_writes_.reset(new MockWrite[writes_.size()]); | 164 mock_writes_.reset(new MockWrite[writes_.size()]); |
175 for (size_t i = 0; i < writes_.size(); i++) { | 165 for (size_t i = 0; i < writes_.size(); i++) { |
176 mock_writes_[i] = MockWrite(writes_[i].mode, | 166 mock_writes_[i] = MockWrite(writes_[i].mode, |
177 writes_[i].packet->data(), | 167 writes_[i].packet->data(), |
178 writes_[i].packet->length()); | 168 writes_[i].packet->length()); |
179 }; | 169 }; |
180 | 170 |
181 socket_data_.reset(new StaticSocketDataProvider(NULL, 0, mock_writes_.get(), | 171 socket_data_.reset(new StaticSocketDataProvider(NULL, 0, mock_writes_.get(), |
182 writes_.size())); | 172 writes_.size())); |
183 | 173 |
184 MockUDPClientSocket* socket = new MockUDPClientSocket(socket_data_.get(), | 174 MockUDPClientSocket* socket = new MockUDPClientSocket(socket_data_.get(), |
185 net_log_.net_log()); | 175 net_log_.net_log()); |
186 socket->Connect(peer_addr_); | 176 socket->Connect(peer_addr_); |
187 runner_ = new TestTaskRunner(&clock_); | 177 runner_ = new TestTaskRunner(&clock_); |
188 send_algorithm_ = new MockSendAlgorithm(); | 178 send_algorithm_ = new MockSendAlgorithm(); |
189 receive_algorithm_ = new TestReceiveAlgorithm(NULL); | 179 receive_algorithm_ = new TestReceiveAlgorithm(); |
190 EXPECT_CALL(*receive_algorithm_, RecordIncomingPacket(_, _, _, _)). | 180 EXPECT_CALL(*receive_algorithm_, RecordIncomingPacket(_, _, _, _)). |
191 Times(AnyNumber()); | 181 Times(AnyNumber()); |
192 EXPECT_CALL(*send_algorithm_, | 182 EXPECT_CALL(*send_algorithm_, |
193 OnPacketSent(_, _, _, _, _)).WillRepeatedly(Return(true)); | 183 OnPacketSent(_, _, _, _, _)).WillRepeatedly(Return(true)); |
194 EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly( | 184 EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly( |
195 Return(QuicTime::Delta::Zero())); | 185 Return(QuicTime::Delta::Zero())); |
196 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _, _)). | 186 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _, _)). |
197 WillRepeatedly(Return(QuicTime::Delta::Zero())); | 187 WillRepeatedly(Return(QuicTime::Delta::Zero())); |
198 EXPECT_CALL(*send_algorithm_, SmoothedRtt()).WillRepeatedly( | 188 EXPECT_CALL(*send_algorithm_, SmoothedRtt()).WillRepeatedly( |
199 Return(QuicTime::Delta::Zero())); | 189 Return(QuicTime::Delta::Zero())); |
200 EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillRepeatedly( | 190 EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillRepeatedly( |
201 Return(QuicBandwidth::Zero())); | 191 Return(QuicBandwidth::Zero())); |
202 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber()); | 192 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber()); |
203 helper_.reset(new QuicConnectionHelper(runner_.get(), &clock_, | 193 helper_.reset(new QuicConnectionHelper(runner_.get(), &clock_, |
204 &random_generator_)); | 194 &random_generator_)); |
205 writer_.reset(new QuicDefaultPacketWriter(socket)); | 195 writer_.reset(new QuicDefaultPacketWriter(socket)); |
206 connection_ = new TestQuicConnection(guid_, peer_addr_, helper_.get(), | 196 connection_ = new TestQuicConnection(SupportedVersions(GetParam()), guid_, |
| 197 peer_addr_, helper_.get(), |
207 writer_.get()); | 198 writer_.get()); |
208 connection_->set_visitor(&visitor_); | 199 connection_->set_visitor(&visitor_); |
209 connection_->SetSendAlgorithm(send_algorithm_); | 200 connection_->SetSendAlgorithm(send_algorithm_); |
210 connection_->SetReceiveAlgorithm(receive_algorithm_); | 201 connection_->SetReceiveAlgorithm(receive_algorithm_); |
211 crypto_config_.SetDefaults(); | 202 crypto_config_.SetDefaults(); |
212 session_.reset( | 203 session_.reset( |
213 new QuicClientSession(connection_, | 204 new QuicClientSession(connection_, |
214 scoped_ptr<DatagramClientSocket>(socket), | 205 scoped_ptr<DatagramClientSocket>(socket), |
215 writer_.Pass(), NULL, | 206 writer_.Pass(), NULL, |
216 &crypto_client_stream_factory_, | 207 &crypto_client_stream_factory_, |
217 "www.google.com", DefaultQuicConfig(), | 208 "www.google.com", DefaultQuicConfig(), |
218 &crypto_config_, NULL)); | 209 &crypto_config_, NULL)); |
219 session_->GetCryptoStream()->CryptoConnect(); | 210 session_->GetCryptoStream()->CryptoConnect(); |
220 EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed()); | 211 EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed()); |
221 stream_.reset(use_closing_stream_ ? | 212 stream_.reset(use_closing_stream_ ? |
222 new AutoClosingStream(session_->GetWeakPtr()) : | 213 new AutoClosingStream(session_->GetWeakPtr()) : |
223 new QuicHttpStream(session_->GetWeakPtr())); | 214 new QuicHttpStream(session_->GetWeakPtr())); |
224 } | 215 } |
225 | 216 |
226 void SetRequestString(const std::string& method, | 217 void SetRequest(const std::string& method, |
227 const std::string& path, | 218 const std::string& path, |
228 RequestPriority priority) { | 219 RequestPriority priority) { |
229 SpdyHeaderBlock headers; | 220 request_headers_ = maker_.GetRequestHeaders(method, "http", path); |
230 headers[":method"] = method; | 221 request_data_ = GetParam() > QUIC_VERSION_12 ? "" : |
231 headers[":host"] = "www.google.com"; | 222 SerializeHeaderBlock(request_headers_, true, priority); |
232 headers[":path"] = path; | |
233 headers[":scheme"] = "http"; | |
234 headers[":version"] = "HTTP/1.1"; | |
235 request_data_ = SerializeHeaderBlock(headers, true, priority); | |
236 } | 223 } |
237 | 224 |
238 void SetResponseString(const std::string& status, const std::string& body) { | 225 void SetResponse(const std::string& status, const std::string& body) { |
239 SpdyHeaderBlock headers; | 226 response_headers_ = maker_.GetResponseHeaders(status); |
240 headers[":status"] = status; | 227 if (GetParam() > QUIC_VERSION_12) { |
241 headers[":version"] = "HTTP/1.1"; | 228 response_data_ = body; |
242 headers["content-type"] = "text/plain"; | 229 } else { |
243 response_data_ = SerializeHeaderBlock(headers, false, DEFAULT_PRIORITY) + | 230 response_data_ = |
244 body; | 231 SerializeHeaderBlock(response_headers_, false, DEFAULT_PRIORITY) + |
| 232 body; |
| 233 } |
245 } | 234 } |
246 | 235 |
247 std::string SerializeHeaderBlock(const SpdyHeaderBlock& headers, | 236 scoped_ptr<QuicEncryptedPacket> ConstructDataPacket( |
248 bool write_priority, | |
249 RequestPriority priority) { | |
250 QuicSpdyCompressor compressor; | |
251 if (write_priority) { | |
252 return compressor.CompressHeadersWithPriority( | |
253 ConvertRequestPriorityToQuicPriority(priority), headers); | |
254 } | |
255 return compressor.CompressHeaders(headers); | |
256 } | |
257 | |
258 // Returns a newly created packet to send kData on stream 3. | |
259 QuicEncryptedPacket* ConstructDataPacket( | |
260 QuicPacketSequenceNumber sequence_number, | 237 QuicPacketSequenceNumber sequence_number, |
261 bool should_include_version, | 238 bool should_include_version, |
262 bool fin, | 239 bool fin, |
263 QuicStreamOffset offset, | 240 QuicStreamOffset offset, |
264 base::StringPiece data) { | 241 base::StringPiece data) { |
265 InitializeHeader(sequence_number, should_include_version); | 242 return maker_.MakeDataPacket( |
266 QuicStreamFrame frame(3, fin, offset, MakeIOVector(data)); | 243 sequence_number, stream_id_, should_include_version, fin, offset, data); |
267 return ConstructPacket(header_, QuicFrame(&frame)); | |
268 } | 244 } |
269 | 245 |
270 // Returns a newly created packet to RST_STREAM stream 3. | 246 scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket( |
271 QuicEncryptedPacket* ConstructRstStreamPacket( | 247 QuicPacketSequenceNumber sequence_number, |
272 QuicPacketSequenceNumber sequence_number) { | 248 bool fin) { |
273 InitializeHeader(sequence_number, false); | 249 return maker_.MakeRequestHeadersPacket( |
274 QuicRstStreamFrame frame(3, QUIC_STREAM_CANCELLED); | 250 sequence_number, stream_id_, kIncludeVersion, fin, request_headers_); |
275 return ConstructPacket(header_, QuicFrame(&frame)); | |
276 } | 251 } |
277 | 252 |
278 // Returns a newly created packet to send ack data. | 253 scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket( |
279 QuicEncryptedPacket* ConstructAckPacket( | 254 QuicPacketSequenceNumber sequence_number, |
| 255 bool fin) { |
| 256 return maker_.MakeResponseHeadersPacket( |
| 257 sequence_number, stream_id_, !kIncludeVersion, fin, response_headers_); |
| 258 } |
| 259 |
| 260 scoped_ptr<QuicEncryptedPacket> ConstructRstStreamPacket( |
| 261 QuicPacketSequenceNumber sequence_number) { |
| 262 return maker_.MakeRstPacket( |
| 263 sequence_number, !kIncludeVersion, stream_id_, QUIC_STREAM_CANCELLED); |
| 264 } |
| 265 |
| 266 scoped_ptr<QuicEncryptedPacket> ConstructAckPacket( |
280 QuicPacketSequenceNumber sequence_number, | 267 QuicPacketSequenceNumber sequence_number, |
281 QuicPacketSequenceNumber largest_received, | 268 QuicPacketSequenceNumber largest_received, |
282 QuicPacketSequenceNumber least_unacked) { | 269 QuicPacketSequenceNumber least_unacked) { |
283 InitializeHeader(sequence_number, false); | 270 return maker_.MakeAckPacket(sequence_number, largest_received, |
284 | 271 least_unacked, !kIncludeCongestionFeedback); |
285 QuicAckFrame ack(largest_received, QuicTime::Zero(), least_unacked); | |
286 ack.sent_info.entropy_hash = 0; | |
287 ack.received_info.entropy_hash = 0; | |
288 | |
289 return ConstructPacket(header_, QuicFrame(&ack)); | |
290 } | |
291 | |
292 // Returns a newly created packet to send ack data. | |
293 QuicEncryptedPacket* ConstructRstPacket( | |
294 QuicPacketSequenceNumber sequence_number, | |
295 QuicStreamId stream_id) { | |
296 InitializeHeader(sequence_number, false); | |
297 | |
298 QuicRstStreamFrame rst(stream_id, QUIC_STREAM_NO_ERROR); | |
299 return ConstructPacket(header_, QuicFrame(&rst)); | |
300 } | 272 } |
301 | 273 |
302 BoundNetLog net_log_; | 274 BoundNetLog net_log_; |
303 bool use_closing_stream_; | 275 bool use_closing_stream_; |
304 MockSendAlgorithm* send_algorithm_; | 276 MockSendAlgorithm* send_algorithm_; |
305 TestReceiveAlgorithm* receive_algorithm_; | 277 TestReceiveAlgorithm* receive_algorithm_; |
306 scoped_refptr<TestTaskRunner> runner_; | 278 scoped_refptr<TestTaskRunner> runner_; |
307 scoped_ptr<MockWrite[]> mock_writes_; | 279 scoped_ptr<MockWrite[]> mock_writes_; |
308 MockClock clock_; | 280 MockClock clock_; |
309 TestQuicConnection* connection_; | 281 TestQuicConnection* connection_; |
310 scoped_ptr<QuicConnectionHelper> helper_; | 282 scoped_ptr<QuicConnectionHelper> helper_; |
311 testing::StrictMock<MockConnectionVisitor> visitor_; | 283 testing::StrictMock<MockConnectionVisitor> visitor_; |
312 scoped_ptr<QuicHttpStream> stream_; | 284 scoped_ptr<QuicHttpStream> stream_; |
313 scoped_ptr<QuicDefaultPacketWriter> writer_; | 285 scoped_ptr<QuicDefaultPacketWriter> writer_; |
314 scoped_ptr<QuicClientSession> session_; | 286 scoped_ptr<QuicClientSession> session_; |
315 QuicCryptoClientConfig crypto_config_; | 287 QuicCryptoClientConfig crypto_config_; |
316 TestCompletionCallback callback_; | 288 TestCompletionCallback callback_; |
317 HttpRequestInfo request_; | 289 HttpRequestInfo request_; |
318 HttpRequestHeaders headers_; | 290 HttpRequestHeaders headers_; |
319 HttpResponseInfo response_; | 291 HttpResponseInfo response_; |
320 scoped_refptr<IOBufferWithSize> read_buffer_; | 292 scoped_refptr<IOBufferWithSize> read_buffer_; |
| 293 SpdyHeaderBlock request_headers_; |
| 294 SpdyHeaderBlock response_headers_; |
321 std::string request_data_; | 295 std::string request_data_; |
322 std::string response_data_; | 296 std::string response_data_; |
323 | 297 |
324 private: | 298 private: |
325 void InitializeHeader(QuicPacketSequenceNumber sequence_number, | 299 std::string SerializeHeaderBlock(const SpdyHeaderBlock& headers, |
326 bool should_include_version) { | 300 bool write_priority, |
327 header_.public_header.guid = guid_; | 301 RequestPriority priority) { |
328 header_.public_header.reset_flag = false; | 302 QuicSpdyCompressor compressor; |
329 header_.public_header.version_flag = should_include_version; | 303 if (write_priority) { |
330 header_.public_header.sequence_number_length = PACKET_1BYTE_SEQUENCE_NUMBER; | 304 return compressor.CompressHeadersWithPriority( |
331 header_.packet_sequence_number = sequence_number; | 305 ConvertRequestPriorityToQuicPriority(priority), headers); |
332 header_.fec_group = 0; | 306 } |
333 header_.entropy_flag = false; | 307 return compressor.CompressHeaders(headers); |
334 header_.fec_flag = false; | |
335 } | |
336 | |
337 QuicEncryptedPacket* ConstructPacket(const QuicPacketHeader& header, | |
338 const QuicFrame& frame) { | |
339 QuicFrames frames; | |
340 frames.push_back(frame); | |
341 scoped_ptr<QuicPacket> packet( | |
342 framer_.BuildUnsizedDataPacket(header_, frames).packet); | |
343 return framer_.EncryptPacket( | |
344 ENCRYPTION_NONE, header.packet_sequence_number, *packet); | |
345 } | 308 } |
346 | 309 |
347 const QuicGuid guid_; | 310 const QuicGuid guid_; |
348 QuicFramer framer_; | 311 const QuicStreamId stream_id_; |
| 312 QuicTestPacketMaker maker_; |
349 IPEndPoint self_addr_; | 313 IPEndPoint self_addr_; |
350 IPEndPoint peer_addr_; | 314 IPEndPoint peer_addr_; |
351 MockRandom random_generator_; | 315 MockRandom random_generator_; |
352 MockCryptoClientStreamFactory crypto_client_stream_factory_; | 316 MockCryptoClientStreamFactory crypto_client_stream_factory_; |
353 QuicPacketCreator creator_; | |
354 QuicPacketHeader header_; | |
355 scoped_ptr<StaticSocketDataProvider> socket_data_; | 317 scoped_ptr<StaticSocketDataProvider> socket_data_; |
356 std::vector<PacketToWrite> writes_; | 318 std::vector<PacketToWrite> writes_; |
357 }; | 319 }; |
358 | 320 |
359 TEST_F(QuicHttpStreamTest, RenewStreamForAuth) { | 321 INSTANTIATE_TEST_CASE_P(Version, QuicHttpStreamTest, |
| 322 ::testing::ValuesIn(QuicSupportedVersions())); |
| 323 |
| 324 TEST_P(QuicHttpStreamTest, RenewStreamForAuth) { |
360 Initialize(); | 325 Initialize(); |
361 EXPECT_EQ(NULL, stream_->RenewStreamForAuth()); | 326 EXPECT_EQ(NULL, stream_->RenewStreamForAuth()); |
362 } | 327 } |
363 | 328 |
364 TEST_F(QuicHttpStreamTest, CanFindEndOfResponse) { | 329 TEST_P(QuicHttpStreamTest, CanFindEndOfResponse) { |
365 Initialize(); | 330 Initialize(); |
366 EXPECT_TRUE(stream_->CanFindEndOfResponse()); | 331 EXPECT_TRUE(stream_->CanFindEndOfResponse()); |
367 } | 332 } |
368 | 333 |
369 TEST_F(QuicHttpStreamTest, IsConnectionReusable) { | 334 TEST_P(QuicHttpStreamTest, IsConnectionReusable) { |
370 Initialize(); | 335 Initialize(); |
371 EXPECT_FALSE(stream_->IsConnectionReusable()); | 336 EXPECT_FALSE(stream_->IsConnectionReusable()); |
372 } | 337 } |
373 | 338 |
374 TEST_F(QuicHttpStreamTest, GetRequest) { | 339 TEST_P(QuicHttpStreamTest, GetRequest) { |
375 SetRequestString("GET", "/", DEFAULT_PRIORITY); | 340 SetRequest("GET", "/", DEFAULT_PRIORITY); |
376 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, kFin, 0, | 341 if (GetParam() > QUIC_VERSION_12) { |
377 request_data_)); | 342 AddWrite(ConstructRequestHeadersPacket(1, kFin)); |
| 343 } else { |
| 344 AddWrite(ConstructDataPacket(1, kIncludeVersion, kFin, 0, request_data_)); |
| 345 } |
378 Initialize(); | 346 Initialize(); |
379 | 347 |
380 request_.method = "GET"; | 348 request_.method = "GET"; |
381 request_.url = GURL("http://www.google.com/"); | 349 request_.url = GURL("http://www.google.com/"); |
382 | 350 |
383 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, | 351 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, |
384 net_log_, callback_.callback())); | 352 net_log_, callback_.callback())); |
385 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, | 353 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, |
386 callback_.callback())); | 354 callback_.callback())); |
387 EXPECT_EQ(&response_, stream_->GetResponseInfo()); | 355 EXPECT_EQ(&response_, stream_->GetResponseInfo()); |
388 | 356 |
389 // Ack the request. | 357 // Ack the request. |
390 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0, 0)); | 358 ProcessPacket(ConstructAckPacket(1, 0, 0)); |
391 ProcessPacket(*ack); | |
392 | 359 |
393 EXPECT_EQ(ERR_IO_PENDING, | 360 EXPECT_EQ(ERR_IO_PENDING, |
394 stream_->ReadResponseHeaders(callback_.callback())); | 361 stream_->ReadResponseHeaders(callback_.callback())); |
395 | 362 |
396 // Send the response without a body. | 363 SetResponse("404 Not Found", std::string()); |
397 SetResponseString("404 Not Found", std::string()); | 364 if (GetParam() > QUIC_VERSION_12) { |
398 scoped_ptr<QuicEncryptedPacket> resp( | 365 ProcessPacket(ConstructResponseHeadersPacket(2, kFin)); |
399 ConstructDataPacket(2, false, kFin, 0, response_data_)); | 366 } else { |
400 ProcessPacket(*resp); | 367 ProcessPacket(ConstructDataPacket(2, false, kFin, 0, response_data_)); |
| 368 } |
401 | 369 |
402 // Now that the headers have been processed, the callback will return. | 370 // Now that the headers have been processed, the callback will return. |
403 EXPECT_EQ(OK, callback_.WaitForResult()); | 371 EXPECT_EQ(OK, callback_.WaitForResult()); |
404 ASSERT_TRUE(response_.headers.get()); | 372 ASSERT_TRUE(response_.headers.get()); |
405 EXPECT_EQ(404, response_.headers->response_code()); | 373 EXPECT_EQ(404, response_.headers->response_code()); |
406 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); | 374 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); |
407 | 375 |
408 // There is no body, so this should return immediately. | 376 // There is no body, so this should return immediately. |
409 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(), | 377 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(), |
410 read_buffer_->size(), | 378 read_buffer_->size(), |
411 callback_.callback())); | 379 callback_.callback())); |
412 EXPECT_TRUE(stream_->IsResponseBodyComplete()); | 380 EXPECT_TRUE(stream_->IsResponseBodyComplete()); |
413 EXPECT_TRUE(AtEof()); | 381 EXPECT_TRUE(AtEof()); |
414 } | 382 } |
415 | 383 |
416 // Regression test for http://crbug.com/288128 | 384 // Regression test for http://crbug.com/288128 |
417 TEST_F(QuicHttpStreamTest, GetRequestLargeResponse) { | 385 TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) { |
418 SetRequestString("GET", "/", DEFAULT_PRIORITY); | 386 SetRequest("GET", "/", DEFAULT_PRIORITY); |
419 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, kFin, 0, | 387 if (GetParam() > QUIC_VERSION_12) { |
420 request_data_)); | 388 AddWrite(ConstructRequestHeadersPacket(1, kFin)); |
| 389 } else { |
| 390 AddWrite(ConstructDataPacket(1, kIncludeVersion, kFin, 0, request_data_)); |
| 391 } |
421 Initialize(); | 392 Initialize(); |
422 | 393 |
423 request_.method = "GET"; | 394 request_.method = "GET"; |
424 request_.url = GURL("http://www.google.com/"); | 395 request_.url = GURL("http://www.google.com/"); |
425 | 396 |
426 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, | 397 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, |
427 net_log_, callback_.callback())); | 398 net_log_, callback_.callback())); |
428 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, | 399 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, |
429 callback_.callback())); | 400 callback_.callback())); |
430 EXPECT_EQ(&response_, stream_->GetResponseInfo()); | 401 EXPECT_EQ(&response_, stream_->GetResponseInfo()); |
431 | 402 |
432 // Ack the request. | 403 // Ack the request. |
433 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0, 0)); | 404 ProcessPacket(ConstructAckPacket(1, 0, 0)); |
434 ProcessPacket(*ack); | |
435 | 405 |
436 EXPECT_EQ(ERR_IO_PENDING, | 406 EXPECT_EQ(ERR_IO_PENDING, |
437 stream_->ReadResponseHeaders(callback_.callback())); | 407 stream_->ReadResponseHeaders(callback_.callback())); |
438 | 408 |
439 SpdyHeaderBlock headers; | 409 SpdyHeaderBlock headers; |
440 headers[":status"] = "200 OK"; | 410 headers[":status"] = "200 OK"; |
441 headers[":version"] = "HTTP/1.1"; | 411 headers[":version"] = "HTTP/1.1"; |
442 headers["content-type"] = "text/plain"; | 412 headers["content-type"] = "text/plain"; |
443 headers["big6"] = std::string(10000, 'x'); // Lots of x's. | 413 headers["big6"] = std::string(10000, 'x'); // Lots of x's. |
444 | 414 |
445 std::string response = SpdyUtils::SerializeUncompressedHeaders(headers); | 415 std::string response = SpdyUtils::SerializeUncompressedHeaders(headers); |
446 EXPECT_LT(4096u, response.length()); | 416 EXPECT_LT(4096u, response.length()); |
447 stream_->OnDataReceived(response.data(), response.length()); | 417 stream_->OnDataReceived(response.data(), response.length()); |
448 stream_->OnClose(QUIC_NO_ERROR); | 418 stream_->OnClose(QUIC_NO_ERROR); |
449 | 419 |
450 // Now that the headers have been processed, the callback will return. | 420 // Now that the headers have been processed, the callback will return. |
451 EXPECT_EQ(OK, callback_.WaitForResult()); | 421 EXPECT_EQ(OK, callback_.WaitForResult()); |
452 ASSERT_TRUE(response_.headers.get()); | 422 ASSERT_TRUE(response_.headers.get()); |
453 EXPECT_EQ(200, response_.headers->response_code()); | 423 EXPECT_EQ(200, response_.headers->response_code()); |
454 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); | 424 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); |
455 | 425 |
456 // There is no body, so this should return immediately. | 426 // There is no body, so this should return immediately. |
457 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(), | 427 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(), |
458 read_buffer_->size(), | 428 read_buffer_->size(), |
459 callback_.callback())); | 429 callback_.callback())); |
460 EXPECT_TRUE(stream_->IsResponseBodyComplete()); | 430 EXPECT_TRUE(stream_->IsResponseBodyComplete()); |
461 EXPECT_TRUE(AtEof()); | 431 EXPECT_TRUE(AtEof()); |
462 } | 432 } |
463 | 433 |
464 TEST_F(QuicHttpStreamTest, GetRequestFullResponseInSinglePacket) { | 434 TEST_P(QuicHttpStreamTest, GetRequestFullResponseInSinglePacket) { |
465 SetRequestString("GET", "/", DEFAULT_PRIORITY); | 435 SetRequest("GET", "/", DEFAULT_PRIORITY); |
466 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, kFin, 0, request_data_)); | 436 AddWrite(ConstructDataPacket(1, kIncludeVersion, kFin, 0, request_data_)); |
467 Initialize(); | 437 Initialize(); |
468 | 438 |
| 439 if (GetParam() > QUIC_VERSION_12) { |
| 440 // we can't put the request and response into a single frame. |
| 441 return; |
| 442 } |
| 443 |
469 request_.method = "GET"; | 444 request_.method = "GET"; |
470 request_.url = GURL("http://www.google.com/"); | 445 request_.url = GURL("http://www.google.com/"); |
471 | 446 |
472 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, | 447 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, |
473 net_log_, callback_.callback())); | 448 net_log_, callback_.callback())); |
474 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, | 449 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, |
475 callback_.callback())); | 450 callback_.callback())); |
476 EXPECT_EQ(&response_, stream_->GetResponseInfo()); | 451 EXPECT_EQ(&response_, stream_->GetResponseInfo()); |
477 | 452 |
478 // Ack the request. | 453 // Ack the request. |
479 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0, 0)); | 454 ProcessPacket(ConstructAckPacket(1, 0, 0)); |
480 ProcessPacket(*ack); | |
481 | 455 |
482 EXPECT_EQ(ERR_IO_PENDING, | 456 EXPECT_EQ(ERR_IO_PENDING, |
483 stream_->ReadResponseHeaders(callback_.callback())); | 457 stream_->ReadResponseHeaders(callback_.callback())); |
484 | 458 |
485 // Send the response with a body. | 459 // Send the response with a body. |
486 SetResponseString("200 OK", "hello world!"); | 460 SetResponse("200 OK", "hello world!"); |
487 scoped_ptr<QuicEncryptedPacket> resp( | 461 ProcessPacket(ConstructDataPacket(2, false, kFin, 0, response_data_)); |
488 ConstructDataPacket(2, false, kFin, 0, response_data_)); | |
489 ProcessPacket(*resp); | |
490 | 462 |
491 // Now that the headers have been processed, the callback will return. | 463 // Now that the headers have been processed, the callback will return. |
492 EXPECT_EQ(OK, callback_.WaitForResult()); | 464 EXPECT_EQ(OK, callback_.WaitForResult()); |
493 ASSERT_TRUE(response_.headers.get()); | 465 ASSERT_TRUE(response_.headers.get()); |
494 EXPECT_EQ(200, response_.headers->response_code()); | 466 EXPECT_EQ(200, response_.headers->response_code()); |
495 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); | 467 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); |
496 | 468 |
497 // There is no body, so this should return immediately. | 469 // There is no body, so this should return immediately. |
498 // Since the body has already arrived, this should return immediately. | 470 // Since the body has already arrived, this should return immediately. |
499 EXPECT_EQ(12, stream_->ReadResponseBody(read_buffer_.get(), | 471 EXPECT_EQ(12, stream_->ReadResponseBody(read_buffer_.get(), |
500 read_buffer_->size(), | 472 read_buffer_->size(), |
501 callback_.callback())); | 473 callback_.callback())); |
502 EXPECT_TRUE(stream_->IsResponseBodyComplete()); | 474 EXPECT_TRUE(stream_->IsResponseBodyComplete()); |
503 EXPECT_TRUE(AtEof()); | 475 EXPECT_TRUE(AtEof()); |
504 } | 476 } |
505 | 477 |
506 TEST_F(QuicHttpStreamTest, SendPostRequest) { | 478 TEST_P(QuicHttpStreamTest, SendPostRequest) { |
507 SetRequestString("POST", "/", DEFAULT_PRIORITY); | 479 SetRequest("POST", "/", DEFAULT_PRIORITY); |
508 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, !kFin, 0, request_data_)); | 480 if (GetParam() > QUIC_VERSION_12) { |
509 AddWrite(SYNCHRONOUS, ConstructDataPacket(2, true, kFin, | 481 AddWrite(ConstructRequestHeadersPacket(1, !kFin)); |
510 request_data_.length(), | 482 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, kUploadData)); |
511 kUploadData)); | 483 } else { |
512 AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 3, 1)); | 484 AddWrite(ConstructDataPacket(1, kIncludeVersion, !kFin, 0, request_data_)); |
| 485 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, |
| 486 request_data_.length(), kUploadData)); |
| 487 } |
| 488 AddWrite(ConstructAckPacket(3, 3, 1)); |
513 | 489 |
514 Initialize(); | 490 Initialize(); |
515 | 491 |
516 ScopedVector<UploadElementReader> element_readers; | 492 ScopedVector<UploadElementReader> element_readers; |
517 element_readers.push_back( | 493 element_readers.push_back( |
518 new UploadBytesElementReader(kUploadData, strlen(kUploadData))); | 494 new UploadBytesElementReader(kUploadData, strlen(kUploadData))); |
519 UploadDataStream upload_data_stream(element_readers.Pass(), 0); | 495 UploadDataStream upload_data_stream(element_readers.Pass(), 0); |
520 request_.method = "POST"; | 496 request_.method = "POST"; |
521 request_.url = GURL("http://www.google.com/"); | 497 request_.url = GURL("http://www.google.com/"); |
522 request_.upload_data_stream = &upload_data_stream; | 498 request_.upload_data_stream = &upload_data_stream; |
523 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback())); | 499 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback())); |
524 | 500 |
525 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, | 501 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, |
526 net_log_, callback_.callback())); | 502 net_log_, callback_.callback())); |
527 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, | 503 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, |
528 callback_.callback())); | 504 callback_.callback())); |
529 EXPECT_EQ(&response_, stream_->GetResponseInfo()); | 505 EXPECT_EQ(&response_, stream_->GetResponseInfo()); |
530 | 506 |
531 // Ack both packets in the request. | 507 // Ack both packets in the request. |
532 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0, 0)); | 508 ProcessPacket(ConstructAckPacket(1, 0, 0)); |
533 ProcessPacket(*ack); | |
534 | 509 |
535 // Send the response headers (but not the body). | 510 // Send the response headers (but not the body). |
536 SetResponseString("200 OK", std::string()); | 511 SetResponse("200 OK", std::string()); |
537 scoped_ptr<QuicEncryptedPacket> resp( | 512 if (GetParam() > QUIC_VERSION_12) { |
538 ConstructDataPacket(2, false, !kFin, 0, response_data_)); | 513 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin)); |
539 ProcessPacket(*resp); | 514 } else { |
| 515 ProcessPacket(ConstructDataPacket(2, false, !kFin, 0, response_data_)); |
| 516 } |
540 | 517 |
541 // Since the headers have already arrived, this should return immediately. | 518 // Since the headers have already arrived, this should return immediately. |
542 EXPECT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback())); | 519 EXPECT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback())); |
543 ASSERT_TRUE(response_.headers.get()); | 520 ASSERT_TRUE(response_.headers.get()); |
544 EXPECT_EQ(200, response_.headers->response_code()); | 521 EXPECT_EQ(200, response_.headers->response_code()); |
545 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); | 522 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); |
546 | 523 |
547 // Send the response body. | 524 // Send the response body. |
548 const char kResponseBody[] = "Hello world!"; | 525 const char kResponseBody[] = "Hello world!"; |
549 scoped_ptr<QuicEncryptedPacket> resp_body( | 526 if (GetParam() > QUIC_VERSION_12) { |
550 ConstructDataPacket(3, false, kFin, response_data_.length(), | 527 ProcessPacket(ConstructDataPacket(3, false, kFin, 0, kResponseBody)); |
551 kResponseBody)); | 528 } else { |
552 ProcessPacket(*resp_body); | 529 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(), |
553 | 530 kResponseBody)); |
| 531 } |
554 // Since the body has already arrived, this should return immediately. | 532 // Since the body has already arrived, this should return immediately. |
555 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)), | 533 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)), |
556 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(), | 534 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(), |
557 callback_.callback())); | 535 callback_.callback())); |
558 | 536 |
559 EXPECT_TRUE(stream_->IsResponseBodyComplete()); | 537 EXPECT_TRUE(stream_->IsResponseBodyComplete()); |
560 EXPECT_TRUE(AtEof()); | 538 EXPECT_TRUE(AtEof()); |
561 } | 539 } |
562 | 540 |
563 TEST_F(QuicHttpStreamTest, SendChunkedPostRequest) { | 541 TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) { |
564 SetRequestString("POST", "/", DEFAULT_PRIORITY); | 542 SetRequest("POST", "/", DEFAULT_PRIORITY); |
565 size_t chunk_size = strlen(kUploadData); | 543 size_t chunk_size = strlen(kUploadData); |
566 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, !kFin, 0, request_data_)); | 544 if (GetParam() > QUIC_VERSION_12) { |
567 AddWrite(SYNCHRONOUS, ConstructDataPacket(2, true, !kFin, | 545 AddWrite(ConstructRequestHeadersPacket(1, !kFin)); |
568 request_data_.length(), | 546 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData)); |
569 kUploadData)); | 547 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size, |
570 AddWrite(SYNCHRONOUS, ConstructDataPacket(3, true, kFin, | 548 kUploadData)); |
571 request_data_.length() + chunk_size, | 549 } else { |
572 kUploadData)); | 550 AddWrite(ConstructDataPacket(1, kIncludeVersion, !kFin, 0, request_data_)); |
573 AddWrite(SYNCHRONOUS, ConstructAckPacket(4, 3, 1)); | 551 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, |
574 | 552 request_data_.length(), kUploadData)); |
| 553 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, |
| 554 request_data_.length() + chunk_size, |
| 555 kUploadData)); |
| 556 } |
| 557 AddWrite(ConstructAckPacket(4, 3, 1)); |
575 Initialize(); | 558 Initialize(); |
576 | 559 |
577 UploadDataStream upload_data_stream(UploadDataStream::CHUNKED, 0); | 560 UploadDataStream upload_data_stream(UploadDataStream::CHUNKED, 0); |
578 upload_data_stream.AppendChunk(kUploadData, chunk_size, false); | 561 upload_data_stream.AppendChunk(kUploadData, chunk_size, false); |
579 | 562 |
580 request_.method = "POST"; | 563 request_.method = "POST"; |
581 request_.url = GURL("http://www.google.com/"); | 564 request_.url = GURL("http://www.google.com/"); |
582 request_.upload_data_stream = &upload_data_stream; | 565 request_.upload_data_stream = &upload_data_stream; |
583 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback())); | 566 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback())); |
584 | 567 |
585 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, | 568 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, |
586 net_log_, callback_.callback())); | 569 net_log_, callback_.callback())); |
587 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_, | 570 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_, |
588 callback_.callback())); | 571 callback_.callback())); |
589 EXPECT_EQ(&response_, stream_->GetResponseInfo()); | 572 EXPECT_EQ(&response_, stream_->GetResponseInfo()); |
590 | 573 |
591 upload_data_stream.AppendChunk(kUploadData, chunk_size, true); | 574 upload_data_stream.AppendChunk(kUploadData, chunk_size, true); |
592 | 575 |
593 // Ack both packets in the request. | 576 // Ack both packets in the request. |
594 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0, 0)); | 577 ProcessPacket(ConstructAckPacket(1, 0, 0)); |
595 ProcessPacket(*ack); | |
596 | 578 |
597 // Send the response headers (but not the body). | 579 // Send the response headers (but not the body). |
598 SetResponseString("200 OK", std::string()); | 580 SetResponse("200 OK", std::string()); |
599 scoped_ptr<QuicEncryptedPacket> resp( | 581 if (GetParam() > QUIC_VERSION_12) { |
600 ConstructDataPacket(2, false, !kFin, 0, response_data_)); | 582 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin)); |
601 ProcessPacket(*resp); | 583 } else { |
| 584 ProcessPacket(ConstructDataPacket(2, false, !kFin, 0, response_data_)); |
| 585 } |
602 | 586 |
603 // Since the headers have already arrived, this should return immediately. | 587 // Since the headers have already arrived, this should return immediately. |
604 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback())); | 588 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback())); |
605 ASSERT_TRUE(response_.headers.get()); | 589 ASSERT_TRUE(response_.headers.get()); |
606 EXPECT_EQ(200, response_.headers->response_code()); | 590 EXPECT_EQ(200, response_.headers->response_code()); |
607 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); | 591 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); |
608 | 592 |
609 // Send the response body. | 593 // Send the response body. |
610 const char kResponseBody[] = "Hello world!"; | 594 const char kResponseBody[] = "Hello world!"; |
611 scoped_ptr<QuicEncryptedPacket> resp_body( | 595 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(), |
612 ConstructDataPacket(3, false, kFin, response_data_.length(), | 596 kResponseBody)); |
613 kResponseBody)); | |
614 ProcessPacket(*resp_body); | |
615 | 597 |
616 // Since the body has already arrived, this should return immediately. | 598 // Since the body has already arrived, this should return immediately. |
617 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)), | 599 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)), |
618 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(), | 600 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(), |
619 callback_.callback())); | 601 callback_.callback())); |
620 | 602 |
621 EXPECT_TRUE(stream_->IsResponseBodyComplete()); | 603 EXPECT_TRUE(stream_->IsResponseBodyComplete()); |
622 EXPECT_TRUE(AtEof()); | 604 EXPECT_TRUE(AtEof()); |
623 } | 605 } |
624 | 606 |
625 TEST_F(QuicHttpStreamTest, DestroyedEarly) { | 607 TEST_P(QuicHttpStreamTest, DestroyedEarly) { |
626 SetRequestString("GET", "/", DEFAULT_PRIORITY); | 608 SetRequest("GET", "/", DEFAULT_PRIORITY); |
627 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, kFin, 0, request_data_)); | 609 if (GetParam() > QUIC_VERSION_12) { |
628 AddWrite(SYNCHRONOUS, ConstructRstStreamPacket(2)); | 610 AddWrite(ConstructRequestHeadersPacket(1, kFin)); |
| 611 } else { |
| 612 AddWrite(ConstructDataPacket(1, kIncludeVersion, kFin, 0, request_data_)); |
| 613 } |
| 614 AddWrite(ConstructRstStreamPacket(2)); |
629 use_closing_stream_ = true; | 615 use_closing_stream_ = true; |
630 Initialize(); | 616 Initialize(); |
631 | 617 |
632 request_.method = "GET"; | 618 request_.method = "GET"; |
633 request_.url = GURL("http://www.google.com/"); | 619 request_.url = GURL("http://www.google.com/"); |
634 | 620 |
635 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, | 621 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, |
636 net_log_, callback_.callback())); | 622 net_log_, callback_.callback())); |
637 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, | 623 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, |
638 callback_.callback())); | 624 callback_.callback())); |
639 EXPECT_EQ(&response_, stream_->GetResponseInfo()); | 625 EXPECT_EQ(&response_, stream_->GetResponseInfo()); |
640 | 626 |
641 // Ack the request. | 627 // Ack the request. |
642 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0, 0)); | 628 ProcessPacket(ConstructAckPacket(1, 0, 0)); |
643 ProcessPacket(*ack); | |
644 EXPECT_EQ(ERR_IO_PENDING, | 629 EXPECT_EQ(ERR_IO_PENDING, |
645 stream_->ReadResponseHeaders(callback_.callback())); | 630 stream_->ReadResponseHeaders(callback_.callback())); |
646 | 631 |
647 // Send the response with a body. | 632 // Send the response with a body. |
648 SetResponseString("404 OK", "hello world!"); | 633 SetResponse("404 OK", "hello world!"); |
649 scoped_ptr<QuicEncryptedPacket> resp( | |
650 ConstructDataPacket(2, false, kFin, 0, response_data_)); | |
651 | |
652 // In the course of processing this packet, the QuicHttpStream close itself. | 634 // In the course of processing this packet, the QuicHttpStream close itself. |
653 ProcessPacket(*resp); | 635 if (GetParam() > QUIC_VERSION_12) { |
| 636 ProcessPacket(ConstructResponseHeadersPacket(2, kFin)); |
| 637 } else { |
| 638 ProcessPacket(ConstructDataPacket(2, false, kFin, 0, response_data_)); |
| 639 } |
654 | 640 |
655 EXPECT_TRUE(AtEof()); | 641 EXPECT_TRUE(AtEof()); |
656 } | 642 } |
657 | 643 |
658 TEST_F(QuicHttpStreamTest, Priority) { | 644 TEST_P(QuicHttpStreamTest, Priority) { |
659 SetRequestString("GET", "/", MEDIUM); | 645 SetRequest("GET", "/", MEDIUM); |
660 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, kFin, 0, request_data_)); | 646 if (GetParam() > QUIC_VERSION_12) { |
661 AddWrite(SYNCHRONOUS, ConstructRstStreamPacket(2)); | 647 AddWrite(ConstructRequestHeadersPacket(1, kFin)); |
| 648 } else { |
| 649 AddWrite(ConstructDataPacket(1, kIncludeVersion, kFin, 0, request_data_)); |
| 650 } |
| 651 AddWrite(ConstructRstStreamPacket(2)); |
662 use_closing_stream_ = true; | 652 use_closing_stream_ = true; |
663 Initialize(); | 653 Initialize(); |
664 | 654 |
665 request_.method = "GET"; | 655 request_.method = "GET"; |
666 request_.url = GURL("http://www.google.com/"); | 656 request_.url = GURL("http://www.google.com/"); |
667 | 657 |
668 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM, | 658 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM, |
669 net_log_, callback_.callback())); | 659 net_log_, callback_.callback())); |
670 | 660 |
671 // Check that priority is highest. | 661 // Check that priority is highest. |
672 QuicReliableClientStream* reliable_stream = | 662 QuicReliableClientStream* reliable_stream = |
673 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get()); | 663 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get()); |
674 DCHECK(reliable_stream); | 664 DCHECK(reliable_stream); |
675 DCHECK_EQ(static_cast<QuicPriority>(kHighestPriority), | 665 DCHECK_EQ(static_cast<QuicPriority>(kHighestPriority), |
676 reliable_stream->EffectivePriority()); | 666 reliable_stream->EffectivePriority()); |
677 | 667 |
678 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, | 668 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, |
679 callback_.callback())); | 669 callback_.callback())); |
680 EXPECT_EQ(&response_, stream_->GetResponseInfo()); | 670 EXPECT_EQ(&response_, stream_->GetResponseInfo()); |
681 | 671 |
682 // Check that priority has now dropped back to MEDIUM. | 672 // Check that priority has now dropped back to MEDIUM. |
683 DCHECK_EQ(MEDIUM, ConvertQuicPriorityToRequestPriority( | 673 DCHECK_EQ(MEDIUM, ConvertQuicPriorityToRequestPriority( |
684 reliable_stream->EffectivePriority())); | 674 reliable_stream->EffectivePriority())); |
685 | 675 |
686 // Ack the request. | 676 // Ack the request. |
687 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0, 0)); | 677 ProcessPacket(ConstructAckPacket(1, 0, 0)); |
688 ProcessPacket(*ack); | |
689 EXPECT_EQ(ERR_IO_PENDING, | 678 EXPECT_EQ(ERR_IO_PENDING, |
690 stream_->ReadResponseHeaders(callback_.callback())); | 679 stream_->ReadResponseHeaders(callback_.callback())); |
691 | 680 |
692 // Send the response with a body. | 681 // Send the response with a body. |
693 SetResponseString("404 OK", "hello world!"); | 682 SetResponse("404 OK", "hello world!"); |
694 scoped_ptr<QuicEncryptedPacket> resp( | |
695 ConstructDataPacket(2, false, kFin, 0, response_data_)); | |
696 | |
697 // In the course of processing this packet, the QuicHttpStream close itself. | 683 // In the course of processing this packet, the QuicHttpStream close itself. |
698 ProcessPacket(*resp); | 684 if (GetParam() > QUIC_VERSION_12) { |
| 685 ProcessPacket(ConstructResponseHeadersPacket(2, kFin)); |
| 686 } else { |
| 687 ProcessPacket(ConstructDataPacket(2, !kIncludeVersion, kFin, 0, |
| 688 response_data_)); |
| 689 } |
699 | 690 |
700 EXPECT_TRUE(AtEof()); | 691 EXPECT_TRUE(AtEof()); |
701 } | 692 } |
702 | 693 |
703 // Regression test for http://crbug.com/294870 | 694 // Regression test for http://crbug.com/294870 |
704 TEST_F(QuicHttpStreamTest, CheckPriorityWithNoDelegate) { | 695 TEST_P(QuicHttpStreamTest, CheckPriorityWithNoDelegate) { |
705 SetRequestString("GET", "/", MEDIUM); | 696 SetRequest("GET", "/", MEDIUM); |
706 use_closing_stream_ = true; | 697 use_closing_stream_ = true; |
707 Initialize(); | 698 Initialize(); |
708 | 699 |
709 request_.method = "GET"; | 700 request_.method = "GET"; |
710 request_.url = GURL("http://www.google.com/"); | 701 request_.url = GURL("http://www.google.com/"); |
711 | 702 |
712 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM, | 703 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM, |
713 net_log_, callback_.callback())); | 704 net_log_, callback_.callback())); |
714 | 705 |
715 // Check that priority is highest. | 706 // Check that priority is highest. |
716 QuicReliableClientStream* reliable_stream = | 707 QuicReliableClientStream* reliable_stream = |
717 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get()); | 708 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get()); |
718 DCHECK(reliable_stream); | 709 DCHECK(reliable_stream); |
719 QuicReliableClientStream::Delegate* delegate = reliable_stream->GetDelegate(); | 710 QuicReliableClientStream::Delegate* delegate = reliable_stream->GetDelegate(); |
720 DCHECK(delegate); | 711 DCHECK(delegate); |
721 DCHECK_EQ(static_cast<QuicPriority>(kHighestPriority), | 712 DCHECK_EQ(static_cast<QuicPriority>(kHighestPriority), |
722 reliable_stream->EffectivePriority()); | 713 reliable_stream->EffectivePriority()); |
723 | 714 |
724 // Set Delegate to NULL and make sure EffectivePriority returns highest | 715 // Set Delegate to NULL and make sure EffectivePriority returns highest |
725 // priority. | 716 // priority. |
726 reliable_stream->SetDelegate(NULL); | 717 reliable_stream->SetDelegate(NULL); |
727 DCHECK_EQ(static_cast<QuicPriority>(kHighestPriority), | 718 DCHECK_EQ(static_cast<QuicPriority>(kHighestPriority), |
728 reliable_stream->EffectivePriority()); | 719 reliable_stream->EffectivePriority()); |
729 reliable_stream->SetDelegate(delegate); | 720 reliable_stream->SetDelegate(delegate); |
730 } | 721 } |
731 | 722 |
732 TEST_F(QuicHttpStreamTest, DontCompressHeadersWhenNotWritable) { | 723 TEST_P(QuicHttpStreamTest, DontCompressHeadersWhenNotWritable) { |
733 SetRequestString("GET", "/", MEDIUM); | 724 SetRequest("GET", "/", MEDIUM); |
734 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, kFin, 0, request_data_)); | 725 AddWrite(ConstructDataPacket(1, kIncludeVersion, kFin, 0, request_data_)); |
| 726 Initialize(); |
735 | 727 |
736 Initialize(); | 728 if (GetParam() > QUIC_VERSION_12) { |
| 729 // The behavior tested here is obsolete. |
| 730 return; |
| 731 } |
737 request_.method = "GET"; | 732 request_.method = "GET"; |
738 request_.url = GURL("http://www.google.com/"); | 733 request_.url = GURL("http://www.google.com/"); |
739 | 734 |
740 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _, _)). | 735 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _, _)). |
741 WillRepeatedly(Return(QuicTime::Delta::Infinite())); | 736 WillRepeatedly(Return(QuicTime::Delta::Infinite())); |
742 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM, | 737 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM, |
743 net_log_, callback_.callback())); | 738 net_log_, callback_.callback())); |
744 EXPECT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_, | 739 EXPECT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_, |
745 callback_.callback())); | 740 callback_.callback())); |
746 | 741 |
747 // Verify that the headers have not been compressed and buffered in | 742 // Verify that the headers have not been compressed and buffered in |
748 // the stream. | 743 // the stream. |
749 QuicReliableClientStream* reliable_stream = | 744 QuicReliableClientStream* reliable_stream = |
750 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get()); | 745 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get()); |
751 EXPECT_FALSE(reliable_stream->HasBufferedData()); | 746 EXPECT_FALSE(reliable_stream->HasBufferedData()); |
752 EXPECT_FALSE(AtEof()); | 747 EXPECT_FALSE(AtEof()); |
753 | 748 |
754 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _, _)). | 749 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _, _)). |
755 WillRepeatedly(Return(QuicTime::Delta::Zero())); | 750 WillRepeatedly(Return(QuicTime::Delta::Zero())); |
756 | 751 |
757 // Data should flush out now. | 752 // Data should flush out now. |
758 connection_->OnCanWrite(); | 753 connection_->OnCanWrite(); |
759 EXPECT_FALSE(reliable_stream->HasBufferedData()); | 754 EXPECT_FALSE(reliable_stream->HasBufferedData()); |
760 EXPECT_TRUE(AtEof()); | 755 EXPECT_TRUE(AtEof()); |
761 } | 756 } |
762 | 757 |
763 } // namespace test | 758 } // namespace test |
764 | |
765 } // namespace net | 759 } // namespace net |
OLD | NEW |