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
3 // found in the LICENSE file.
5 #include "base/basictypes.h"
6 #include "base/compiler_specific.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "net/base/test_completion_callback.h"
9 #include "net/cert/mock_cert_verifier.h"
10 #include "net/dns/mock_host_resolver.h"
11 #include "net/http/http_auth_handler_factory.h"
12 #include "net/http/http_network_session.h"
13 #include "net/http/http_network_transaction.h"
14 #include "net/http/http_server_properties_impl.h"
15 #include "net/http/http_stream.h"
16 #include "net/http/http_stream_factory.h"
17 #include "net/http/http_transaction_unittest.h"
18 #include "net/proxy/proxy_config_service_fixed.h"
19 #include "net/proxy/proxy_resolver.h"
20 #include "net/proxy/proxy_service.h"
21 #include "net/quic/crypto/quic_decrypter.h"
22 #include "net/quic/crypto/quic_encrypter.h"
23 #include "net/quic/quic_framer.h"
24 #include "net/quic/test_tools/crypto_test_utils.h"
25 #include "net/quic/test_tools/mock_clock.h"
26 #include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
27 #include "net/quic/test_tools/mock_random.h"
28 #include "net/quic/test_tools/quic_test_utils.h"
29 #include "net/socket/client_socket_factory.h"
30 #include "net/socket/mock_client_socket_pool_manager.h"
31 #include "net/socket/socket_test_util.h"
32 #include "net/socket/ssl_client_socket.h"
33 #include "net/spdy/spdy_frame_builder.h"
34 #include "net/spdy/spdy_framer.h"
35 #include "net/ssl/ssl_config_service_defaults.h"
36 #include "testing/gtest/include/gtest/gtest.h"
37 #include "testing/platform_test.h"
39 //-----------------------------------------------------------------------------
43 // This is the expected return from a current server advertising QUIC.
44 static const char kQuicAlternateProtocolHttpHeader
[] =
45 "Alternate-Protocol: 443:quic\r\n\r\n";
47 // Returns a vector of NPN protocol strings for negotiating QUIC.
48 std::vector
<std::string
> QuicNextProtos() {
49 std::vector
<std::string
> protos
;
50 protos
.push_back("http/1.1");
51 protos
.push_back("quic");
60 class QuicNetworkTransactionTest
: public PlatformTest
{
62 QuicNetworkTransactionTest()
63 : clock_(new MockClock
),
64 ssl_config_service_(new SSLConfigServiceDefaults
),
65 proxy_service_(ProxyService::CreateDirect()),
66 auth_handler_factory_(
67 HttpAuthHandlerFactory::CreateDefault(&host_resolver_
)) {
70 virtual void SetUp() {
71 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
72 MessageLoop::current()->RunUntilIdle();
75 virtual void TearDown() {
76 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
77 // Empty the current queue.
78 MessageLoop::current()->RunUntilIdle();
79 PlatformTest::TearDown();
80 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
81 MessageLoop::current()->RunUntilIdle();
82 HttpStreamFactory::set_use_alternate_protocols(false);
83 HttpStreamFactory::SetNextProtos(std::vector
<std::string
>());
86 scoped_ptr
<QuicEncryptedPacket
> ConstructRstPacket(
87 QuicPacketSequenceNumber num
,
88 QuicStreamId stream_id
) {
89 QuicPacketHeader header
;
90 header
.public_header
.guid
= 0xDEADBEEF;
91 header
.public_header
.reset_flag
= false;
92 header
.public_header
.version_flag
= false;
93 header
.packet_sequence_number
= num
;
94 header
.entropy_flag
= false;
95 header
.fec_flag
= false;
96 header
.fec_entropy_flag
= false;
99 QuicRstStreamFrame
rst(stream_id
, QUIC_STREAM_NO_ERROR
);
100 return scoped_ptr
<QuicEncryptedPacket
>(
101 ConstructPacket(header
, QuicFrame(&rst
)));
104 scoped_ptr
<QuicEncryptedPacket
> ConstructAckPacket(
105 QuicPacketSequenceNumber largest_received
,
106 QuicPacketSequenceNumber least_unacked
) {
107 QuicPacketHeader header
;
108 header
.public_header
.guid
= 0xDEADBEEF;
109 header
.public_header
.reset_flag
= false;
110 header
.public_header
.version_flag
= false;
111 header
.packet_sequence_number
= 2;
112 header
.entropy_flag
= false;
113 header
.fec_flag
= false;
114 header
.fec_entropy_flag
= false;
115 header
.fec_group
= 0;
117 QuicAckFrame
ack(largest_received
, QuicTime::Zero(), least_unacked
);
119 QuicCongestionFeedbackFrame feedback
;
120 feedback
.type
= kTCP
;
121 feedback
.tcp
.accumulated_number_of_lost_packets
= 0;
122 feedback
.tcp
.receive_window
= 256000;
124 QuicFramer
framer(kQuicVersion1
,
125 QuicDecrypter::Create(kNULL
),
126 QuicEncrypter::Create(kNULL
),
130 frames
.push_back(QuicFrame(&ack
));
131 frames
.push_back(QuicFrame(&feedback
));
132 scoped_ptr
<QuicPacket
> packet(
133 framer
.ConstructFrameDataPacket(header
, frames
).packet
);
134 return scoped_ptr
<QuicEncryptedPacket
>(
135 framer
.EncryptPacket(header
.packet_sequence_number
, *packet
));
138 std::string
GetRequestString(const std::string
& method
,
139 const std::string
& path
) {
140 SpdyHeaderBlock headers
;
141 headers
[":method"] = method
;
142 headers
[":host"] = "www.google.com";
143 headers
[":path"] = path
;
144 headers
[":scheme"] = "http";
145 headers
[":version"] = "HTTP/1.1";
146 return SerializeHeaderBlock(headers
);
149 std::string
GetResponseString(const std::string
& status
,
150 const std::string
& body
) {
151 SpdyHeaderBlock headers
;
152 headers
[":status"] = status
;
153 headers
[":version"] = "HTTP/1.1";
154 headers
["content-type"] = "text/plain";
155 return SerializeHeaderBlock(headers
) + body
;
158 std::string
SerializeHeaderBlock(const SpdyHeaderBlock
& headers
) {
159 size_t len
= SpdyFramer::GetSerializedLength(3, &headers
);
160 SpdyFrameBuilder
builder(len
);
161 SpdyFramer::WriteHeaderBlock(&builder
, 3, &headers
);
162 scoped_ptr
<SpdyFrame
> frame(builder
.take());
163 return std::string(frame
->data(), len
);
166 // Returns a newly created packet to send kData on stream 1.
167 QuicEncryptedPacket
* ConstructDataPacket(
168 QuicPacketSequenceNumber sequence_number
,
169 bool should_include_version
,
171 QuicStreamOffset offset
,
172 base::StringPiece data
) {
173 InitializeHeader(sequence_number
, should_include_version
);
174 QuicStreamFrame
frame(3, fin
, offset
, data
);
175 return ConstructPacket(header_
, QuicFrame(&frame
)).release();
178 scoped_ptr
<QuicEncryptedPacket
> ConstructPacket(
179 const QuicPacketHeader
& header
,
180 const QuicFrame
& frame
) {
181 QuicFramer
framer(kQuicVersion1
,
182 QuicDecrypter::Create(kNULL
),
183 QuicEncrypter::Create(kNULL
),
187 frames
.push_back(frame
);
188 scoped_ptr
<QuicPacket
> packet(
189 framer
.ConstructFrameDataPacket(header
, frames
).packet
);
190 return scoped_ptr
<QuicEncryptedPacket
>(
191 framer
.EncryptPacket(header
.packet_sequence_number
, *packet
));
194 void InitializeHeader(QuicPacketSequenceNumber sequence_number
,
195 bool should_include_version
) {
196 header_
.public_header
.guid
= random_generator_
.RandUint64();
197 header_
.public_header
.reset_flag
= false;
198 header_
.public_header
.version_flag
= should_include_version
;
199 header_
.packet_sequence_number
= sequence_number
;
200 header_
.fec_group
= 0;
201 header_
.entropy_flag
= false;
202 header_
.fec_flag
= false;
203 header_
.fec_entropy_flag
= false;
206 void CreateSession() {
207 params_
.enable_quic
= true;
208 params_
.quic_clock
= clock_
;
209 params_
.quic_random
= &random_generator_
;
210 params_
.client_socket_factory
= &socket_factory_
;
211 params_
.quic_crypto_client_stream_factory
= &crypto_client_stream_factory_
;
212 params_
.host_resolver
= &host_resolver_
;
213 params_
.cert_verifier
= &cert_verifier_
;
214 params_
.proxy_service
= proxy_service_
.get();
215 params_
.ssl_config_service
= ssl_config_service_
.get();
216 params_
.http_auth_handler_factory
= auth_handler_factory_
.get();
217 params_
.http_server_properties
= &http_server_properties
;
219 session_
= new HttpNetworkSession(params_
);
222 QuicPacketHeader header_
;
223 scoped_refptr
<HttpNetworkSession
> session_
;
224 MockClientSocketFactory socket_factory_
;
225 MockCryptoClientStreamFactory crypto_client_stream_factory_
;
226 MockClock
* clock_
; // Owned by QuicStreamFactory after CreateSession.
227 MockHostResolver host_resolver_
;
228 MockCertVerifier cert_verifier_
;
229 scoped_refptr
<SSLConfigServiceDefaults
> ssl_config_service_
;
230 scoped_ptr
<ProxyService
> proxy_service_
;
231 scoped_ptr
<HttpAuthHandlerFactory
> auth_handler_factory_
;
232 MockRandom random_generator_
;
233 HttpServerPropertiesImpl http_server_properties
;
234 HttpNetworkSession::Params params_
;
237 TEST_F(QuicNetworkTransactionTest
, ForceQuic
) {
238 params_
.origin_port_to_force_quic_on
= 80;
240 HttpRequestInfo request
;
241 request
.method
= "GET";
242 request
.url
= GURL("http://www.google.com/");
243 request
.load_flags
= 0;
245 scoped_ptr
<QuicEncryptedPacket
> data(
246 ConstructDataPacket(1, true, true, 0, GetRequestString("GET", "/")));
247 scoped_ptr
<QuicEncryptedPacket
> ack(ConstructAckPacket(1, 0));
249 MockWrite quic_writes
[] = {
250 MockWrite(SYNCHRONOUS
, data
->data(), data
->length()),
251 MockWrite(SYNCHRONOUS
, ack
->data(), ack
->length()),
254 scoped_ptr
<QuicEncryptedPacket
> resp(
256 1, false, true, 0, GetResponseString("200 OK", "hello!")));
257 MockRead quic_reads
[] = {
258 MockRead(SYNCHRONOUS
, resp
->data(), resp
->length()),
259 MockRead(ASYNC
, OK
), // EOF
262 DelayedSocketData
quic_data(
263 1, // wait for one write to finish before reading.
264 quic_reads
, arraysize(quic_reads
),
265 quic_writes
, arraysize(quic_writes
));
267 socket_factory_
.AddSocketDataProvider(&quic_data
);
269 // The non-alternate protocol job needs to hang in order to guarantee that the
270 // alternate-protocol job will "win".
271 MockConnect
never_finishing_connect(SYNCHRONOUS
, ERR_IO_PENDING
);
272 StaticSocketDataProvider
hanging_non_alternate_protocol_socket(
274 hanging_non_alternate_protocol_socket
.set_connect_data(
275 never_finishing_connect
);
276 socket_factory_
.AddSocketDataProvider(
277 &hanging_non_alternate_protocol_socket
);
279 TestCompletionCallback callback
;
282 scoped_ptr
<HttpNetworkTransaction
> trans(
283 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
));
285 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
286 EXPECT_EQ(ERR_IO_PENDING
, rv
);
287 EXPECT_EQ(OK
, callback
.WaitForResult());
289 const HttpResponseInfo
* response
= trans
->GetResponseInfo();
290 ASSERT_TRUE(response
!= NULL
);
291 ASSERT_TRUE(response
->headers
!= NULL
);
292 EXPECT_EQ("HTTP/1.1 200 OK", response
->headers
->GetStatusLine());
293 EXPECT_TRUE(response
->was_fetched_via_spdy
);
294 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_QUIC1_SPDY3
,
295 response
->connection_info
);
297 std::string response_data
;
298 ASSERT_EQ(OK
, ReadTransaction(trans
.get(), &response_data
));
299 EXPECT_EQ("hello!", response_data
);
302 TEST_F(QuicNetworkTransactionTest
, DoNotForceQuicForHttps
) {
303 // Attempt to "force" quic on 443, which will not be honored.
304 params_
.origin_port_to_force_quic_on
= 443;
306 HttpRequestInfo request
;
307 request
.method
= "GET";
308 request
.url
= GURL("https://www.google.com/");
309 request
.load_flags
= 0;
311 MockRead data_reads
[] = {
312 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
313 MockRead("hello world"),
314 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
318 StaticSocketDataProvider
data(
319 data_reads
, arraysize(data_reads
), NULL
, 0);
320 socket_factory_
.AddSocketDataProvider(&data
);
321 SSLSocketDataProvider
ssl(ASYNC
, OK
);
322 socket_factory_
.AddSSLSocketDataProvider(&ssl
);
324 TestCompletionCallback callback
;
327 scoped_ptr
<HttpNetworkTransaction
> trans(
328 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
));
330 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
331 EXPECT_EQ(ERR_IO_PENDING
, rv
);
332 EXPECT_EQ(OK
, callback
.WaitForResult());
334 const HttpResponseInfo
* response
= trans
->GetResponseInfo();
335 ASSERT_TRUE(response
!= NULL
);
336 ASSERT_TRUE(response
->headers
!= NULL
);
337 EXPECT_EQ("HTTP/1.1 200 OK", response
->headers
->GetStatusLine());
339 std::string response_data
;
340 ASSERT_EQ(OK
, ReadTransaction(trans
.get(), &response_data
));
341 EXPECT_EQ("hello world", response_data
);
344 TEST_F(QuicNetworkTransactionTest
, UseAlternateProtocolForQuic
) {
345 HttpStreamFactory::set_use_alternate_protocols(true);
346 HttpStreamFactory::SetNextProtos(QuicNextProtos());
348 HttpRequestInfo request
;
349 request
.method
= "GET";
350 request
.url
= GURL("http://www.google.com/");
351 request
.load_flags
= 0;
353 MockRead data_reads
[] = {
354 MockRead("HTTP/1.1 200 OK\r\n"),
355 MockRead(kQuicAlternateProtocolHttpHeader
),
356 MockRead("hello world"),
357 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
361 StaticSocketDataProvider
first_transaction(
362 data_reads
, arraysize(data_reads
), NULL
, 0);
363 socket_factory_
.AddSocketDataProvider(&first_transaction
);
366 scoped_ptr
<QuicEncryptedPacket
> data(
367 ConstructDataPacket(1, true, true, 0, GetRequestString("GET", "/")));
368 scoped_ptr
<QuicEncryptedPacket
> ack(ConstructAckPacket(1, 0));
370 MockWrite quic_writes
[] = {
371 MockWrite(SYNCHRONOUS
, data
->data(), data
->length()),
372 MockWrite(SYNCHRONOUS
, ack
->data(), ack
->length()),
375 scoped_ptr
<QuicEncryptedPacket
> resp(
377 1, false, true, 0, GetResponseString("200 OK", "hello!")));
378 MockRead quic_reads
[] = {
379 MockRead(SYNCHRONOUS
, resp
->data(), resp
->length()),
380 MockRead(ASYNC
, OK
), // EOF
383 DelayedSocketData
quic_data(
384 1, // wait for one write to finish before reading.
385 quic_reads
, arraysize(quic_reads
),
386 quic_writes
, arraysize(quic_writes
));
388 socket_factory_
.AddSocketDataProvider(&quic_data
);
390 // The non-alternate protocol job needs to hang in order to guarantee that the
391 // alternate-protocol job will "win".
392 MockConnect
never_finishing_connect(SYNCHRONOUS
, ERR_IO_PENDING
);
393 StaticSocketDataProvider
hanging_non_alternate_protocol_socket(
395 hanging_non_alternate_protocol_socket
.set_connect_data(
396 never_finishing_connect
);
397 socket_factory_
.AddSocketDataProvider(
398 &hanging_non_alternate_protocol_socket
);
400 TestCompletionCallback callback
;
403 scoped_ptr
<HttpNetworkTransaction
> trans(
404 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
));
406 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
407 EXPECT_EQ(ERR_IO_PENDING
, rv
);
408 EXPECT_EQ(OK
, callback
.WaitForResult());
410 const HttpResponseInfo
* response
= trans
->GetResponseInfo();
411 ASSERT_TRUE(response
!= NULL
);
412 ASSERT_TRUE(response
->headers
!= NULL
);
413 EXPECT_EQ("HTTP/1.1 200 OK", response
->headers
->GetStatusLine());
415 std::string response_data
;
416 ASSERT_EQ(OK
, ReadTransaction(trans
.get(), &response_data
));
417 EXPECT_EQ("hello world", response_data
);
419 trans
.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
));
421 rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
422 EXPECT_EQ(ERR_IO_PENDING
, rv
);
423 EXPECT_EQ(OK
, callback
.WaitForResult());
425 response
= trans
->GetResponseInfo();
426 ASSERT_TRUE(response
!= NULL
);
427 ASSERT_TRUE(response
->headers
!= NULL
);
428 EXPECT_EQ("HTTP/1.1 200 OK", response
->headers
->GetStatusLine());
429 EXPECT_TRUE(response
->was_fetched_via_spdy
);
430 EXPECT_TRUE(response
->was_npn_negotiated
);
431 EXPECT_EQ("quic/1+spdy/3", response
->npn_negotiated_protocol
);
433 ASSERT_EQ(OK
, ReadTransaction(trans
.get(), &response_data
));
434 EXPECT_EQ("hello!", response_data
);
437 TEST_F(QuicNetworkTransactionTest
, DontUseAlternateProtocolForQuicHttps
) {
438 HttpStreamFactory::set_use_alternate_protocols(true);
439 HttpStreamFactory::SetNextProtos(QuicNextProtos());
441 HttpRequestInfo request
;
442 request
.method
= "GET";
443 request
.url
= GURL("https://www.google.com/");
444 request
.load_flags
= 0;
446 MockRead data_reads
[] = {
447 MockRead("HTTP/1.1 200 OK\r\n"),
448 MockRead("Content-length: 11\r\n"),
449 MockRead(kQuicAlternateProtocolHttpHeader
),
450 MockRead("hello world"),
452 MockRead("HTTP/1.1 200 OK\r\n"),
453 MockRead("Content-length: 6\r\n"),
454 MockRead(kQuicAlternateProtocolHttpHeader
),
458 StaticSocketDataProvider
first_transaction(
459 data_reads
, arraysize(data_reads
), NULL
, 0);
460 socket_factory_
.AddSocketDataProvider(&first_transaction
);
461 SSLSocketDataProvider
ssl(ASYNC
, OK
);
462 socket_factory_
.AddSSLSocketDataProvider(&ssl
);
464 TestCompletionCallback callback
;
467 scoped_ptr
<HttpNetworkTransaction
> trans(
468 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
));
470 int rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
471 EXPECT_EQ(ERR_IO_PENDING
, rv
);
472 EXPECT_EQ(OK
, callback
.WaitForResult());
474 const HttpResponseInfo
* response
= trans
->GetResponseInfo();
475 ASSERT_TRUE(response
!= NULL
);
476 ASSERT_TRUE(response
->headers
!= NULL
);
477 EXPECT_EQ("HTTP/1.1 200 OK", response
->headers
->GetStatusLine());
479 std::string response_data
;
480 ASSERT_EQ(OK
, ReadTransaction(trans
.get(), &response_data
));
481 EXPECT_EQ("hello world", response_data
);
483 trans
.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
));
485 rv
= trans
->Start(&request
, callback
.callback(), BoundNetLog());
486 EXPECT_EQ(ERR_IO_PENDING
, rv
);
487 EXPECT_EQ(OK
, callback
.WaitForResult());
489 response
= trans
->GetResponseInfo();
490 ASSERT_TRUE(response
!= NULL
);
491 ASSERT_TRUE(response
->headers
!= NULL
);
492 EXPECT_EQ("HTTP/1.1 200 OK", response
->headers
->GetStatusLine());
493 EXPECT_FALSE(response
->was_fetched_via_spdy
);
495 ASSERT_EQ(OK
, ReadTransaction(trans
.get(), &response_data
));
496 EXPECT_EQ("hello!", response_data
);