blob: 2f46772d0fc24358219654fe9216e5b2082e4d69 [file] [log] [blame]
[email protected]e13201d82012-12-12 05:00:321// 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
3// found in the LICENSE file.
4
5#include "net/quic/quic_stream_factory.h"
6
[email protected]e13201d82012-12-12 05:00:327#include "base/run_loop.h"
[email protected]fc9be5802013-06-11 10:56:518#include "base/strings/string_util.h"
[email protected]6d1b4ed2013-07-10 03:57:549#include "net/cert/cert_verifier.h"
[email protected]f2cb3cf2013-03-21 01:40:5310#include "net/dns/mock_host_resolver.h"
[email protected]e13201d82012-12-12 05:00:3211#include "net/http/http_response_headers.h"
12#include "net/http/http_response_info.h"
13#include "net/http/http_util.h"
[email protected]4df69842013-02-27 06:32:1614#include "net/quic/crypto/quic_decrypter.h"
15#include "net/quic/crypto/quic_encrypter.h"
[email protected]e13201d82012-12-12 05:00:3216#include "net/quic/quic_http_stream.h"
17#include "net/quic/test_tools/mock_clock.h"
[email protected]e8ff26842013-03-22 21:02:0518#include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
[email protected]9558c5d32012-12-22 00:08:1419#include "net/quic/test_tools/mock_random.h"
[email protected]e13201d82012-12-12 05:00:3220#include "net/quic/test_tools/quic_test_utils.h"
21#include "net/socket/socket_test_util.h"
22#include "testing/gtest/include/gtest/gtest.h"
23
24namespace net {
[email protected]e13201d82012-12-12 05:00:3225namespace test {
26
27class QuicStreamFactoryTest : public ::testing::Test {
28 protected:
29 QuicStreamFactoryTest()
[email protected]872edd9e2013-01-16 08:51:1530 : clock_(new MockClock()),
31 factory_(&host_resolver_, &socket_factory_,
[email protected]e8ff26842013-03-22 21:02:0532 &crypto_client_stream_factory_,
[email protected]9d9e7932013-02-25 18:31:0533 &random_generator_, clock_),
[email protected]e13201d82012-12-12 05:00:3234 host_port_proxy_pair_(HostPortPair("www.google.com", 443),
[email protected]6d1b4ed2013-07-10 03:57:5435 ProxyServer::Direct()),
36 is_https_(false),
37 cert_verifier_(CertVerifier::CreateDefault()) {
[email protected]e13201d82012-12-12 05:00:3238 }
39
[email protected]e13201d82012-12-12 05:00:3240 scoped_ptr<QuicEncryptedPacket> ConstructRstPacket(
41 QuicPacketSequenceNumber num,
42 QuicStreamId stream_id) {
43 QuicPacketHeader header;
[email protected]c995c572013-01-18 05:43:2044 header.public_header.guid = 0xDEADBEEF;
[email protected]9db443912013-02-25 05:27:0345 header.public_header.reset_flag = false;
[email protected]e8ff26842013-03-22 21:02:0546 header.public_header.version_flag = true;
[email protected]e13201d82012-12-12 05:00:3247 header.packet_sequence_number = num;
[email protected]9db443912013-02-25 05:27:0348 header.entropy_flag = false;
[email protected]9db443912013-02-25 05:27:0349 header.fec_flag = false;
[email protected]e13201d82012-12-12 05:00:3250 header.fec_group = 0;
51
[email protected]74bda142013-03-31 02:49:1152 QuicRstStreamFrame rst(stream_id, QUIC_STREAM_NO_ERROR);
[email protected]e13201d82012-12-12 05:00:3253 return scoped_ptr<QuicEncryptedPacket>(
54 ConstructPacket(header, QuicFrame(&rst)));
55 }
56
57 scoped_ptr<QuicEncryptedPacket> ConstructAckPacket(
58 QuicPacketSequenceNumber largest_received,
59 QuicPacketSequenceNumber least_unacked) {
60 QuicPacketHeader header;
[email protected]c995c572013-01-18 05:43:2061 header.public_header.guid = 0xDEADBEEF;
[email protected]9db443912013-02-25 05:27:0362 header.public_header.reset_flag = false;
63 header.public_header.version_flag = false;
[email protected]e13201d82012-12-12 05:00:3264 header.packet_sequence_number = 2;
[email protected]9db443912013-02-25 05:27:0365 header.entropy_flag = false;
[email protected]9db443912013-02-25 05:27:0366 header.fec_flag = false;
[email protected]e13201d82012-12-12 05:00:3267 header.fec_group = 0;
68
[email protected]14e8106c2013-03-14 16:25:3369 QuicAckFrame ack(largest_received, QuicTime::Zero(), least_unacked);
[email protected]dda3e9b2012-12-22 21:49:2570 QuicCongestionFeedbackFrame feedback;
71 feedback.type = kTCP;
72 feedback.tcp.accumulated_number_of_lost_packets = 0;
73 feedback.tcp.receive_window = 16000;
74
[email protected]48878092013-07-26 14:51:5675 QuicFramer framer(QuicVersionMax(), QuicTime::Zero(), false);
[email protected]dda3e9b2012-12-22 21:49:2576 QuicFrames frames;
77 frames.push_back(QuicFrame(&ack));
78 frames.push_back(QuicFrame(&feedback));
79 scoped_ptr<QuicPacket> packet(
[email protected]3e60db82013-08-05 19:43:0680 framer.BuildUnsizedDataPacket(header, frames).packet);
[email protected]8ba81212013-05-03 13:11:4881 return scoped_ptr<QuicEncryptedPacket>(framer.EncryptPacket(
82 ENCRYPTION_NONE, header.packet_sequence_number, *packet));
[email protected]e13201d82012-12-12 05:00:3283 }
84
[email protected]26f3f8e2012-12-13 21:07:1985 // Returns a newly created packet to send congestion feedback data.
86 scoped_ptr<QuicEncryptedPacket> ConstructFeedbackPacket(
87 QuicPacketSequenceNumber sequence_number) {
88 QuicPacketHeader header;
[email protected]c995c572013-01-18 05:43:2089 header.public_header.guid = 0xDEADBEEF;
[email protected]9db443912013-02-25 05:27:0390 header.public_header.reset_flag = false;
91 header.public_header.version_flag = false;
[email protected]26f3f8e2012-12-13 21:07:1992 header.packet_sequence_number = sequence_number;
[email protected]9db443912013-02-25 05:27:0393 header.entropy_flag = false;
[email protected]9db443912013-02-25 05:27:0394 header.fec_flag = false;
[email protected]26f3f8e2012-12-13 21:07:1995 header.fec_group = 0;
96
97 QuicCongestionFeedbackFrame frame;
98 frame.type = kTCP;
99 frame.tcp.accumulated_number_of_lost_packets = 0;
100 frame.tcp.receive_window = 16000;
101
102 return scoped_ptr<QuicEncryptedPacket>(
103 ConstructPacket(header, QuicFrame(&frame)));
104 }
105
[email protected]e13201d82012-12-12 05:00:32106 scoped_ptr<QuicEncryptedPacket> ConstructPacket(
107 const QuicPacketHeader& header,
108 const QuicFrame& frame) {
[email protected]48878092013-07-26 14:51:56109 QuicFramer framer(QuicVersionMax(), QuicTime::Zero(), false);
[email protected]e13201d82012-12-12 05:00:32110 QuicFrames frames;
111 frames.push_back(frame);
[email protected]610a7e942012-12-18 00:21:39112 scoped_ptr<QuicPacket> packet(
[email protected]3e60db82013-08-05 19:43:06113 framer.BuildUnsizedDataPacket(header, frames).packet);
[email protected]8ba81212013-05-03 13:11:48114 return scoped_ptr<QuicEncryptedPacket>(framer.EncryptPacket(
115 ENCRYPTION_NONE, header.packet_sequence_number, *packet));
[email protected]e13201d82012-12-12 05:00:32116 }
117
118 MockHostResolver host_resolver_;
[email protected]0edce6a2013-05-08 18:02:40119 DeterministicMockClientSocketFactory socket_factory_;
[email protected]e8ff26842013-03-22 21:02:05120 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]9558c5d32012-12-22 00:08:14121 MockRandom random_generator_;
[email protected]872edd9e2013-01-16 08:51:15122 MockClock* clock_; // Owned by factory_.
[email protected]e13201d82012-12-12 05:00:32123 QuicStreamFactory factory_;
124 HostPortProxyPair host_port_proxy_pair_;
[email protected]6d1b4ed2013-07-10 03:57:54125 bool is_https_;
[email protected]ce542d52013-07-11 01:08:39126 scoped_ptr<CertVerifier> cert_verifier_;
[email protected]e13201d82012-12-12 05:00:32127 BoundNetLog net_log_;
128 TestCompletionCallback callback_;
[email protected]e13201d82012-12-12 05:00:32129};
130
131TEST_F(QuicStreamFactoryTest, CreateIfSessionExists) {
132 EXPECT_EQ(NULL, factory_.CreateIfSessionExists(host_port_proxy_pair_,
133 net_log_).get());
134}
135
136TEST_F(QuicStreamFactoryTest, Create) {
[email protected]69dfd1b2013-06-04 22:20:12137 MockRead reads[] = {
[email protected]25c31dc2013-06-05 17:56:04138 MockRead(ASYNC, OK, 0) // EOF
[email protected]69dfd1b2013-06-04 22:20:12139 };
[email protected]25c31dc2013-06-05 17:56:04140 DeterministicSocketData socket_data(reads, arraysize(reads), NULL, 0);
[email protected]e13201d82012-12-12 05:00:32141 socket_factory_.AddSocketDataProvider(&socket_data);
[email protected]25c31dc2013-06-05 17:56:04142 socket_data.StopAfter(1);
[email protected]e13201d82012-12-12 05:00:32143
144 QuicStreamRequest request(&factory_);
[email protected]6d1b4ed2013-07-10 03:57:54145 EXPECT_EQ(ERR_IO_PENDING, request.Request(host_port_proxy_pair_, is_https_,
[email protected]ce542d52013-07-11 01:08:39146 cert_verifier_.get(), net_log_,
[email protected]e13201d82012-12-12 05:00:32147 callback_.callback()));
148
149 EXPECT_EQ(OK, callback_.WaitForResult());
150 scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
[email protected]0edce6a2013-05-08 18:02:40151 EXPECT_TRUE(stream.get());
[email protected]e13201d82012-12-12 05:00:32152
153 // Will reset stream 3.
154 stream = factory_.CreateIfSessionExists(host_port_proxy_pair_, net_log_);
155 EXPECT_TRUE(stream.get());
156
[email protected]6d1b4ed2013-07-10 03:57:54157 // TODO(rtenneti): We should probably have a tests that HTTP and HTTPS result
158 // in streams on different sessions.
[email protected]e13201d82012-12-12 05:00:32159 QuicStreamRequest request2(&factory_);
[email protected]6d1b4ed2013-07-10 03:57:54160 EXPECT_EQ(OK, request2.Request(host_port_proxy_pair_, is_https_,
[email protected]ce542d52013-07-11 01:08:39161 cert_verifier_.get(), net_log_,
[email protected]e13201d82012-12-12 05:00:32162 callback_.callback()));
163 stream = request2.ReleaseStream(); // Will reset stream 5.
164 stream.reset(); // Will reset stream 7.
165
166 EXPECT_TRUE(socket_data.at_read_eof());
167 EXPECT_TRUE(socket_data.at_write_eof());
168}
169
[email protected]0b2294d32013-08-02 00:46:36170TEST_F(QuicStreamFactoryTest, MaxOpenStream) {
171 MockRead reads[] = {
172 MockRead(ASYNC, OK, 0) // EOF
173 };
174 DeterministicSocketData socket_data(reads, arraysize(reads), NULL, 0);
175 socket_factory_.AddSocketDataProvider(&socket_data);
176 socket_data.StopAfter(1);
177
178 HttpRequestInfo request_info;
179 std::vector<QuicHttpStream*> streams;
180 // The MockCryptoClientStream sets max_open_streams to be
181 // 2 * kDefaultMaxStreamsPerConnection.
182 for (size_t i = 0; i < 2 * kDefaultMaxStreamsPerConnection; i++) {
183 QuicStreamRequest request(&factory_);
184 int rv = request.Request(host_port_proxy_pair_, is_https_,
185 cert_verifier_.get(), net_log_,
186 callback_.callback());
187 if (i == 0) {
188 EXPECT_EQ(ERR_IO_PENDING, rv);
189 EXPECT_EQ(OK, callback_.WaitForResult());
190 } else {
191 EXPECT_EQ(OK, rv);
192 }
193 scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
194 EXPECT_TRUE(stream);
195 EXPECT_EQ(OK, stream->InitializeStream(
196 &request_info, DEFAULT_PRIORITY, net_log_, CompletionCallback()));
197 streams.push_back(stream.release());
198 }
199
200 QuicStreamRequest request(&factory_);
201 EXPECT_EQ(OK, request.Request(host_port_proxy_pair_, is_https_,
202 cert_verifier_.get(), net_log_,
203 CompletionCallback()));
204 scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
205 EXPECT_TRUE(stream);
206 EXPECT_EQ(ERR_IO_PENDING, stream->InitializeStream(
207 &request_info, DEFAULT_PRIORITY, net_log_, callback_.callback()));
208
209 // Close the first stream.
210 streams.front()->Close(false);
211
212 ASSERT_TRUE(callback_.have_result());
213
214 EXPECT_EQ(OK, callback_.WaitForResult());
215
216 EXPECT_TRUE(socket_data.at_read_eof());
217 EXPECT_TRUE(socket_data.at_write_eof());
218 STLDeleteElements(&streams);
219}
220
[email protected]e13201d82012-12-12 05:00:32221TEST_F(QuicStreamFactoryTest, CreateError) {
[email protected]0edce6a2013-05-08 18:02:40222 DeterministicSocketData socket_data(NULL, 0, NULL, 0);
[email protected]e13201d82012-12-12 05:00:32223 socket_factory_.AddSocketDataProvider(&socket_data);
224
225 host_resolver_.rules()->AddSimulatedFailure("www.google.com");
226
227 QuicStreamRequest request(&factory_);
[email protected]6d1b4ed2013-07-10 03:57:54228 EXPECT_EQ(ERR_IO_PENDING, request.Request(host_port_proxy_pair_, is_https_,
[email protected]ce542d52013-07-11 01:08:39229 cert_verifier_.get(), net_log_,
[email protected]e13201d82012-12-12 05:00:32230 callback_.callback()));
231
232 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, callback_.WaitForResult());
233
234 EXPECT_TRUE(socket_data.at_read_eof());
235 EXPECT_TRUE(socket_data.at_write_eof());
236}
237
238TEST_F(QuicStreamFactoryTest, CancelCreate) {
[email protected]69dfd1b2013-06-04 22:20:12239 MockRead reads[] = {
[email protected]25c31dc2013-06-05 17:56:04240 MockRead(ASYNC, OK, 0) // EOF
[email protected]69dfd1b2013-06-04 22:20:12241 };
[email protected]25c31dc2013-06-05 17:56:04242 DeterministicSocketData socket_data(reads, arraysize(reads), NULL, 0);
[email protected]e13201d82012-12-12 05:00:32243 socket_factory_.AddSocketDataProvider(&socket_data);
244 {
245 QuicStreamRequest request(&factory_);
[email protected]6d1b4ed2013-07-10 03:57:54246 EXPECT_EQ(ERR_IO_PENDING, request.Request(host_port_proxy_pair_, is_https_,
[email protected]ce542d52013-07-11 01:08:39247 cert_verifier_.get(), net_log_,
[email protected]e13201d82012-12-12 05:00:32248 callback_.callback()));
249 }
250
[email protected]25c31dc2013-06-05 17:56:04251 socket_data.StopAfter(1);
[email protected]e13201d82012-12-12 05:00:32252 base::RunLoop run_loop;
253 run_loop.RunUntilIdle();
254
255 scoped_ptr<QuicHttpStream> stream(
256 factory_.CreateIfSessionExists(host_port_proxy_pair_, net_log_));
257 EXPECT_TRUE(stream.get());
258 stream.reset();
259
260 EXPECT_TRUE(socket_data.at_read_eof());
261 EXPECT_TRUE(socket_data.at_write_eof());
262}
263
[email protected]56dfb902013-01-03 23:17:55264TEST_F(QuicStreamFactoryTest, CloseAllSessions) {
[email protected]56dfb902013-01-03 23:17:55265 MockRead reads[] = {
[email protected]0edce6a2013-05-08 18:02:40266 MockRead(ASYNC, 0, 0) // EOF
[email protected]56dfb902013-01-03 23:17:55267 };
[email protected]25c31dc2013-06-05 17:56:04268 DeterministicSocketData socket_data(reads, arraysize(reads), NULL, 0);
[email protected]56dfb902013-01-03 23:17:55269 socket_factory_.AddSocketDataProvider(&socket_data);
[email protected]0edce6a2013-05-08 18:02:40270 socket_data.StopAfter(1);
[email protected]56dfb902013-01-03 23:17:55271
[email protected]69dfd1b2013-06-04 22:20:12272 MockRead reads2[] = {
[email protected]25c31dc2013-06-05 17:56:04273 MockRead(ASYNC, 0, 0) // EOF
[email protected]69dfd1b2013-06-04 22:20:12274 };
[email protected]25c31dc2013-06-05 17:56:04275 DeterministicSocketData socket_data2(reads2, arraysize(reads2), NULL, 0);
[email protected]56dfb902013-01-03 23:17:55276 socket_factory_.AddSocketDataProvider(&socket_data2);
[email protected]0edce6a2013-05-08 18:02:40277 socket_data2.StopAfter(1);
[email protected]56dfb902013-01-03 23:17:55278
279 QuicStreamRequest request(&factory_);
[email protected]6d1b4ed2013-07-10 03:57:54280 EXPECT_EQ(ERR_IO_PENDING, request.Request(host_port_proxy_pair_, is_https_,
[email protected]ce542d52013-07-11 01:08:39281 cert_verifier_.get(), net_log_,
[email protected]56dfb902013-01-03 23:17:55282 callback_.callback()));
283
284 EXPECT_EQ(OK, callback_.WaitForResult());
285 scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
[email protected]0b2294d32013-08-02 00:46:36286 HttpRequestInfo request_info;
287 EXPECT_EQ(OK, stream->InitializeStream(&request_info,
288 DEFAULT_PRIORITY,
289 net_log_, CompletionCallback()));
[email protected]56dfb902013-01-03 23:17:55290
291 // Close the session and verify that stream saw the error.
292 factory_.CloseAllSessions(ERR_INTERNET_DISCONNECTED);
293 EXPECT_EQ(ERR_INTERNET_DISCONNECTED,
294 stream->ReadResponseHeaders(callback_.callback()));
295
296 // Now attempting to request a stream to the same origin should create
297 // a new session.
298
299 QuicStreamRequest request2(&factory_);
[email protected]6d1b4ed2013-07-10 03:57:54300 EXPECT_EQ(ERR_IO_PENDING, request2.Request(host_port_proxy_pair_, is_https_,
[email protected]ce542d52013-07-11 01:08:39301 cert_verifier_.get(), net_log_,
[email protected]56dfb902013-01-03 23:17:55302 callback_.callback()));
303
304 EXPECT_EQ(OK, callback_.WaitForResult());
305 stream = request2.ReleaseStream();
306 stream.reset(); // Will reset stream 3.
307
308 EXPECT_TRUE(socket_data.at_read_eof());
309 EXPECT_TRUE(socket_data.at_write_eof());
310 EXPECT_TRUE(socket_data2.at_read_eof());
311 EXPECT_TRUE(socket_data2.at_write_eof());
312}
313
[email protected]f698a012013-05-06 20:18:59314TEST_F(QuicStreamFactoryTest, OnIPAddressChanged) {
[email protected]f698a012013-05-06 20:18:59315 MockRead reads[] = {
[email protected]0edce6a2013-05-08 18:02:40316 MockRead(ASYNC, 0, 0) // EOF
[email protected]f698a012013-05-06 20:18:59317 };
[email protected]25c31dc2013-06-05 17:56:04318 DeterministicSocketData socket_data(reads, arraysize(reads), NULL, 0);
[email protected]f698a012013-05-06 20:18:59319 socket_factory_.AddSocketDataProvider(&socket_data);
[email protected]0edce6a2013-05-08 18:02:40320 socket_data.StopAfter(1);
[email protected]f698a012013-05-06 20:18:59321
[email protected]69dfd1b2013-06-04 22:20:12322 MockRead reads2[] = {
[email protected]25c31dc2013-06-05 17:56:04323 MockRead(ASYNC, 0, 0) // EOF
[email protected]69dfd1b2013-06-04 22:20:12324 };
[email protected]25c31dc2013-06-05 17:56:04325 DeterministicSocketData socket_data2(reads2, arraysize(reads2), NULL, 0);
[email protected]f698a012013-05-06 20:18:59326 socket_factory_.AddSocketDataProvider(&socket_data2);
[email protected]0edce6a2013-05-08 18:02:40327 socket_data2.StopAfter(1);
[email protected]f698a012013-05-06 20:18:59328
329 QuicStreamRequest request(&factory_);
[email protected]6d1b4ed2013-07-10 03:57:54330 EXPECT_EQ(ERR_IO_PENDING, request.Request(host_port_proxy_pair_, is_https_,
[email protected]ce542d52013-07-11 01:08:39331 cert_verifier_.get(), net_log_,
[email protected]f698a012013-05-06 20:18:59332 callback_.callback()));
333
334 EXPECT_EQ(OK, callback_.WaitForResult());
335 scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
[email protected]0b2294d32013-08-02 00:46:36336 HttpRequestInfo request_info;
337 EXPECT_EQ(OK, stream->InitializeStream(&request_info,
338 DEFAULT_PRIORITY,
339 net_log_, CompletionCallback()));
[email protected]f698a012013-05-06 20:18:59340
341 // Change the IP address and verify that stream saw the error.
342 factory_.OnIPAddressChanged();
343 EXPECT_EQ(ERR_NETWORK_CHANGED,
344 stream->ReadResponseHeaders(callback_.callback()));
345
346 // Now attempting to request a stream to the same origin should create
347 // a new session.
348
349 QuicStreamRequest request2(&factory_);
[email protected]6d1b4ed2013-07-10 03:57:54350 EXPECT_EQ(ERR_IO_PENDING, request2.Request(host_port_proxy_pair_, is_https_,
[email protected]ce542d52013-07-11 01:08:39351 cert_verifier_.get(), net_log_,
[email protected]f698a012013-05-06 20:18:59352 callback_.callback()));
353
354 EXPECT_EQ(OK, callback_.WaitForResult());
355 stream = request2.ReleaseStream();
356 stream.reset(); // Will reset stream 3.
357
358 EXPECT_TRUE(socket_data.at_read_eof());
359 EXPECT_TRUE(socket_data.at_write_eof());
360 EXPECT_TRUE(socket_data2.at_read_eof());
361 EXPECT_TRUE(socket_data2.at_write_eof());
362}
363
[email protected]e13201d82012-12-12 05:00:32364} // namespace test
[email protected]e13201d82012-12-12 05:00:32365} // namespace net