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. 4 5 #include "base/basictypes.h" 6 #include "base/compiler_specific.h" 7 #include "base/memory/scoped_ptr.h" 8 #include "base/stl_util.h" 9 #include "net/base/capturing_net_log.h" 10 #include "net/base/net_log_unittest.h" 11 #include "net/base/test_completion_callback.h" 12 #include "net/cert/mock_cert_verifier.h" 13 #include "net/dns/mock_host_resolver.h" 14 #include "net/http/http_auth_handler_factory.h" 15 #include "net/http/http_network_session.h" 16 #include "net/http/http_network_transaction.h" 17 #include "net/http/http_server_properties_impl.h" 18 #include "net/http/http_stream.h" 19 #include "net/http/http_stream_factory.h" 20 #include "net/http/http_transaction_unittest.h" 21 #include "net/http/transport_security_state.h" 22 #include "net/proxy/proxy_config_service_fixed.h" 23 #include "net/proxy/proxy_resolver.h" 24 #include "net/proxy/proxy_service.h" 25 #include "net/quic/crypto/quic_decrypter.h" 26 #include "net/quic/crypto/quic_encrypter.h" 27 #include "net/quic/quic_framer.h" 28 #include "net/quic/test_tools/crypto_test_utils.h" 29 #include "net/quic/test_tools/mock_clock.h" 30 #include "net/quic/test_tools/mock_crypto_client_stream_factory.h" 31 #include "net/quic/test_tools/mock_random.h" 32 #include "net/quic/test_tools/quic_test_utils.h" 33 #include "net/socket/client_socket_factory.h" 34 #include "net/socket/mock_client_socket_pool_manager.h" 35 #include "net/socket/socket_test_util.h" 36 #include "net/socket/ssl_client_socket.h" 37 #include "net/spdy/spdy_frame_builder.h" 38 #include "net/spdy/spdy_framer.h" 39 #include "net/ssl/ssl_config_service_defaults.h" 40 #include "testing/gtest/include/gtest/gtest.h" 41 #include "testing/platform_test.h" 42 43 //----------------------------------------------------------------------------- 44 45 namespace { 46 47 // This is the expected return from a current server advertising QUIC. 48 static const char kQuicAlternateProtocolHttpHeader[] = 49 "Alternate-Protocol: 80:quic\r\n\r\n"; 50 static const char kQuicAlternateProtocolHttpsHeader[] = 51 "Alternate-Protocol: 443:quic\r\n\r\n"; 52 } // namespace 53 54 namespace net { 55 namespace test { 56 57 class QuicNetworkTransactionTest : public PlatformTest { 58 protected: 59 QuicNetworkTransactionTest() 60 : clock_(new MockClock), 61 ssl_config_service_(new SSLConfigServiceDefaults), 62 proxy_service_(ProxyService::CreateDirect()), 63 compressor_(new QuicSpdyCompressor()), 64 auth_handler_factory_( 65 HttpAuthHandlerFactory::CreateDefault(&host_resolver_)), 66 hanging_data_(NULL, 0, NULL, 0) { 67 request_.method = "GET"; 68 request_.url = GURL("http://www.google.com/"); 69 request_.load_flags = 0; 70 } 71 72 virtual void SetUp() { 73 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 74 base::MessageLoop::current()->RunUntilIdle(); 75 } 76 77 virtual void TearDown() { 78 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 79 // Empty the current queue. 80 base::MessageLoop::current()->RunUntilIdle(); 81 PlatformTest::TearDown(); 82 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 83 base::MessageLoop::current()->RunUntilIdle(); 84 HttpStreamFactory::set_use_alternate_protocols(false); 85 HttpStreamFactory::SetNextProtos(std::vector<NextProto>()); 86 } 87 88 scoped_ptr<QuicEncryptedPacket> ConstructRstPacket( 89 QuicPacketSequenceNumber num, 90 QuicStreamId stream_id) { 91 QuicPacketHeader header; 92 header.public_header.guid = 0xDEADBEEF; 93 header.public_header.reset_flag = false; 94 header.public_header.version_flag = false; 95 header.packet_sequence_number = num; 96 header.entropy_flag = false; 97 header.fec_flag = false; 98 header.fec_group = 0; 99 100 QuicRstStreamFrame rst(stream_id, QUIC_STREAM_NO_ERROR); 101 return scoped_ptr<QuicEncryptedPacket>( 102 ConstructPacket(header, QuicFrame(&rst))); 103 } 104 105 scoped_ptr<QuicEncryptedPacket> ConstructConnectionClosePacket( 106 QuicPacketSequenceNumber num) { 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 = num; 112 header.entropy_flag = false; 113 header.fec_flag = false; 114 header.fec_group = 0; 115 116 QuicAckFrame ack_frame(0, QuicTime::Zero(), 0); 117 QuicConnectionCloseFrame close; 118 close.error_code = QUIC_CRYPTO_VERSION_NOT_SUPPORTED; 119 close.error_details = "Time to panic!"; 120 close.ack_frame = ack_frame; 121 return scoped_ptr<QuicEncryptedPacket>( 122 ConstructPacket(header, QuicFrame(&close))); 123 } 124 125 scoped_ptr<QuicEncryptedPacket> ConstructAckPacket( 126 QuicPacketSequenceNumber largest_received, 127 QuicPacketSequenceNumber least_unacked) { 128 QuicPacketHeader header; 129 header.public_header.guid = 0xDEADBEEF; 130 header.public_header.reset_flag = false; 131 header.public_header.version_flag = false; 132 header.packet_sequence_number = 2; 133 header.entropy_flag = false; 134 header.fec_flag = false; 135 header.fec_group = 0; 136 137 QuicAckFrame ack(largest_received, QuicTime::Zero(), least_unacked); 138 139 QuicCongestionFeedbackFrame feedback; 140 feedback.type = kTCP; 141 feedback.tcp.accumulated_number_of_lost_packets = 0; 142 feedback.tcp.receive_window = 256000; 143 144 QuicFramer framer(QuicVersionMax(), QuicTime::Zero(), false); 145 QuicFrames frames; 146 frames.push_back(QuicFrame(&ack)); 147 frames.push_back(QuicFrame(&feedback)); 148 scoped_ptr<QuicPacket> packet( 149 framer.BuildUnsizedDataPacket(header, frames).packet); 150 return scoped_ptr<QuicEncryptedPacket>(framer.EncryptPacket( 151 ENCRYPTION_NONE, header.packet_sequence_number, *packet)); 152 } 153 154 std::string GetRequestString(const std::string& method, 155 const std::string& scheme, 156 const std::string& path) { 157 SpdyHeaderBlock headers; 158 headers[":method"] = method; 159 headers[":host"] = "www.google.com"; 160 headers[":path"] = path; 161 headers[":scheme"] = scheme; 162 headers[":version"] = "HTTP/1.1"; 163 return SerializeHeaderBlock(headers); 164 } 165 166 std::string GetResponseString(const std::string& status, 167 const std::string& body) { 168 SpdyHeaderBlock headers; 169 headers[":status"] = status; 170 headers[":version"] = "HTTP/1.1"; 171 headers["content-type"] = "text/plain"; 172 return compressor_->CompressHeaders(headers) + body; 173 } 174 175 std::string SerializeHeaderBlock(const SpdyHeaderBlock& headers) { 176 QuicSpdyCompressor compressor; 177 return compressor.CompressHeaders(headers); 178 } 179 180 // Returns a newly created packet to send kData on stream 1. 181 QuicEncryptedPacket* ConstructDataPacket( 182 QuicPacketSequenceNumber sequence_number, 183 QuicStreamId stream_id, 184 bool should_include_version, 185 bool fin, 186 QuicStreamOffset offset, 187 base::StringPiece data) { 188 InitializeHeader(sequence_number, should_include_version); 189 QuicStreamFrame frame(stream_id, fin, offset, data); 190 return ConstructPacket(header_, QuicFrame(&frame)).release(); 191 } 192 193 scoped_ptr<QuicEncryptedPacket> ConstructPacket( 194 const QuicPacketHeader& header, 195 const QuicFrame& frame) { 196 QuicFramer framer(QuicVersionMax(), QuicTime::Zero(), false); 197 QuicFrames frames; 198 frames.push_back(frame); 199 scoped_ptr<QuicPacket> packet( 200 framer.BuildUnsizedDataPacket(header, frames).packet); 201 return scoped_ptr<QuicEncryptedPacket>(framer.EncryptPacket( 202 ENCRYPTION_NONE, header.packet_sequence_number, *packet)); 203 } 204 205 void InitializeHeader(QuicPacketSequenceNumber sequence_number, 206 bool should_include_version) { 207 header_.public_header.guid = random_generator_.RandUint64(); 208 header_.public_header.reset_flag = false; 209 header_.public_header.version_flag = should_include_version; 210 header_.packet_sequence_number = sequence_number; 211 header_.fec_group = 0; 212 header_.entropy_flag = false; 213 header_.fec_flag = false; 214 } 215 216 void CreateSession() { 217 CreateSessionWithFactory(&socket_factory_); 218 } 219 220 void CreateSessionWithFactory(ClientSocketFactory* socket_factory) { 221 params_.enable_quic = true; 222 params_.quic_clock = clock_; 223 params_.quic_random = &random_generator_; 224 params_.client_socket_factory = socket_factory; 225 params_.quic_crypto_client_stream_factory = &crypto_client_stream_factory_; 226 params_.host_resolver = &host_resolver_; 227 params_.cert_verifier = &cert_verifier_; 228 params_.transport_security_state = &transport_security_state_; 229 params_.proxy_service = proxy_service_.get(); 230 params_.ssl_config_service = ssl_config_service_.get(); 231 params_.http_auth_handler_factory = auth_handler_factory_.get(); 232 params_.http_server_properties = http_server_properties.GetWeakPtr(); 233 234 session_ = new HttpNetworkSession(params_); 235 } 236 237 void CheckWasQuicResponse(const scoped_ptr<HttpNetworkTransaction>& trans) { 238 const HttpResponseInfo* response = trans->GetResponseInfo(); 239 ASSERT_TRUE(response != NULL); 240 ASSERT_TRUE(response->headers.get() != NULL); 241 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 242 EXPECT_TRUE(response->was_fetched_via_spdy); 243 EXPECT_TRUE(response->was_npn_negotiated); 244 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_QUIC1_SPDY3, 245 response->connection_info); 246 } 247 248 void CheckWasHttpResponse(const scoped_ptr<HttpNetworkTransaction>& trans) { 249 const HttpResponseInfo* response = trans->GetResponseInfo(); 250 ASSERT_TRUE(response != NULL); 251 ASSERT_TRUE(response->headers.get() != NULL); 252 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 253 EXPECT_FALSE(response->was_fetched_via_spdy); 254 EXPECT_FALSE(response->was_npn_negotiated); 255 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1, 256 response->connection_info); 257 } 258 259 void CheckResponseData(HttpNetworkTransaction* trans, 260 const std::string& expected) { 261 std::string response_data; 262 ASSERT_EQ(OK, ReadTransaction(trans, &response_data)); 263 EXPECT_EQ(expected, response_data); 264 } 265 266 void RunTransaction(HttpNetworkTransaction* trans) { 267 TestCompletionCallback callback; 268 int rv = trans->Start(&request_, callback.callback(), net_log_.bound()); 269 EXPECT_EQ(ERR_IO_PENDING, rv); 270 EXPECT_EQ(OK, callback.WaitForResult()); 271 } 272 273 void SendRequestAndExpectHttpResponse(const std::string& expected) { 274 scoped_ptr<HttpNetworkTransaction> trans( 275 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get())); 276 RunTransaction(trans.get()); 277 CheckWasHttpResponse(trans); 278 CheckResponseData(trans.get(), expected); 279 } 280 281 void SendRequestAndExpectQuicResponse(const std::string& expected) { 282 scoped_ptr<HttpNetworkTransaction> trans( 283 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get())); 284 RunTransaction(trans.get()); 285 CheckWasQuicResponse(trans); 286 CheckResponseData(trans.get(), expected); 287 } 288 289 void AddQuicAlternateProtocolMapping( 290 MockCryptoClientStream::HandshakeMode handshake_mode) { 291 crypto_client_stream_factory_.set_handshake_mode(handshake_mode); 292 session_->http_server_properties()->SetAlternateProtocol( 293 HostPortPair::FromURL(request_.url), 80, QUIC); 294 } 295 296 void ExpectBrokenAlternateProtocolMapping() { 297 ASSERT_TRUE(session_->http_server_properties()->HasAlternateProtocol( 298 HostPortPair::FromURL(request_.url))); 299 const PortAlternateProtocolPair alternate = 300 session_->http_server_properties()->GetAlternateProtocol( 301 HostPortPair::FromURL(request_.url)); 302 EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol); 303 } 304 305 void AddHangingNonAlternateProtocolSocketData() { 306 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING); 307 hanging_data_.set_connect_data(hanging_connect); 308 socket_factory_.AddSocketDataProvider(&hanging_data_); 309 } 310 311 QuicPacketHeader header_; 312 scoped_refptr<HttpNetworkSession> session_; 313 MockClientSocketFactory socket_factory_; 314 MockCryptoClientStreamFactory crypto_client_stream_factory_; 315 MockClock* clock_; // Owned by QuicStreamFactory after CreateSession. 316 MockHostResolver host_resolver_; 317 MockCertVerifier cert_verifier_; 318 TransportSecurityState transport_security_state_; 319 scoped_refptr<SSLConfigServiceDefaults> ssl_config_service_; 320 scoped_ptr<ProxyService> proxy_service_; 321 scoped_ptr<QuicSpdyCompressor> compressor_; 322 scoped_ptr<HttpAuthHandlerFactory> auth_handler_factory_; 323 MockRandom random_generator_; 324 HttpServerPropertiesImpl http_server_properties; 325 HttpNetworkSession::Params params_; 326 HttpRequestInfo request_; 327 CapturingBoundNetLog net_log_; 328 StaticSocketDataProvider hanging_data_; 329 }; 330 331 TEST_F(QuicNetworkTransactionTest, ForceQuic) { 332 params_.origin_to_force_quic_on = 333 HostPortPair::FromString("www.google.com:80"); 334 335 QuicStreamId stream_id = 3; 336 scoped_ptr<QuicEncryptedPacket> req( 337 ConstructDataPacket(1, stream_id, true, true, 0, 338 GetRequestString("GET", "http", "/"))); 339 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0)); 340 341 MockWrite quic_writes[] = { 342 MockWrite(SYNCHRONOUS, req->data(), req->length()), 343 MockWrite(SYNCHRONOUS, ack->data(), ack->length()), 344 }; 345 346 scoped_ptr<QuicEncryptedPacket> resp( 347 ConstructDataPacket( 348 1, stream_id, false, true, 0, GetResponseString("200 OK", "hello!"))); 349 MockRead quic_reads[] = { 350 MockRead(SYNCHRONOUS, resp->data(), resp->length()), 351 MockRead(ASYNC, OK), // EOF 352 }; 353 354 DelayedSocketData quic_data( 355 1, // wait for one write to finish before reading. 356 quic_reads, arraysize(quic_reads), 357 quic_writes, arraysize(quic_writes)); 358 359 socket_factory_.AddSocketDataProvider(&quic_data); 360 361 // The non-alternate protocol job needs to hang in order to guarantee that 362 // the alternate-protocol job will "win". 363 AddHangingNonAlternateProtocolSocketData(); 364 365 CreateSession(); 366 367 SendRequestAndExpectQuicResponse("hello!"); 368 369 // Check that the NetLog was filled reasonably. 370 net::CapturingNetLog::CapturedEntryList entries; 371 net_log_.GetEntries(&entries); 372 EXPECT_LT(0u, entries.size()); 373 374 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED. 375 int pos = net::ExpectLogContainsSomewhere( 376 entries, 0, 377 net::NetLog::TYPE_QUIC_SESSION_PACKET_RECEIVED, 378 net::NetLog::PHASE_NONE); 379 EXPECT_LT(0, pos); 380 381 // ... and also a TYPE_QUIC_SESSION_PACKET_HEADER_RECEIVED. 382 pos = net::ExpectLogContainsSomewhere( 383 entries, 0, 384 net::NetLog::TYPE_QUIC_SESSION_PACKET_HEADER_RECEIVED, 385 net::NetLog::PHASE_NONE); 386 EXPECT_LT(0, pos); 387 388 std::string packet_sequence_number; 389 ASSERT_TRUE(entries[pos].GetStringValue( 390 "packet_sequence_number", &packet_sequence_number)); 391 EXPECT_EQ("1", packet_sequence_number); 392 393 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED. 394 pos = net::ExpectLogContainsSomewhere( 395 entries, 0, 396 net::NetLog::TYPE_QUIC_SESSION_STREAM_FRAME_RECEIVED, 397 net::NetLog::PHASE_NONE); 398 EXPECT_LT(0, pos); 399 400 int log_stream_id; 401 ASSERT_TRUE(entries[pos].GetIntegerValue("stream_id", &log_stream_id)); 402 EXPECT_EQ(stream_id, static_cast<QuicStreamId>(log_stream_id)); 403 } 404 405 TEST_F(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) { 406 params_.origin_to_force_quic_on = 407 HostPortPair::FromString("www.google.com:80"); 408 409 MockRead quic_reads[] = { 410 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED), 411 }; 412 StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads), 413 NULL, 0); 414 socket_factory_.AddSocketDataProvider(&quic_data); 415 416 CreateSession(); 417 418 scoped_ptr<HttpNetworkTransaction> trans( 419 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get())); 420 TestCompletionCallback callback; 421 int rv = trans->Start(&request_, callback.callback(), net_log_.bound()); 422 EXPECT_EQ(ERR_IO_PENDING, rv); 423 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult()); 424 } 425 426 TEST_F(QuicNetworkTransactionTest, DoNotForceQuicForHttps) { 427 // Attempt to "force" quic on 443, which will not be honored. 428 params_.origin_to_force_quic_on = 429 HostPortPair::FromString("www.google.com:443"); 430 431 MockRead http_reads[] = { 432 MockRead("HTTP/1.1 200 OK\r\n\r\n"), 433 MockRead("hello world"), 434 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 435 MockRead(ASYNC, OK) 436 }; 437 438 StaticSocketDataProvider data(http_reads, arraysize(http_reads), NULL, 0); 439 socket_factory_.AddSocketDataProvider(&data); 440 SSLSocketDataProvider ssl(ASYNC, OK); 441 socket_factory_.AddSSLSocketDataProvider(&ssl); 442 443 CreateSession(); 444 445 SendRequestAndExpectHttpResponse("hello world"); 446 } 447 448 TEST_F(QuicNetworkTransactionTest, UseAlternateProtocolForQuic) { 449 HttpStreamFactory::EnableNpnSpdy(); // Enables QUIC too. 450 451 MockRead http_reads[] = { 452 MockRead("HTTP/1.1 200 OK\r\n"), 453 MockRead(kQuicAlternateProtocolHttpHeader), 454 MockRead("hello world"), 455 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 456 MockRead(ASYNC, OK) 457 }; 458 459 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), 460 NULL, 0); 461 socket_factory_.AddSocketDataProvider(&http_data); 462 463 scoped_ptr<QuicEncryptedPacket> req( 464 ConstructDataPacket(1, 3, true, true, 0, 465 GetRequestString("GET", "http", "/"))); 466 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0)); 467 468 MockWrite quic_writes[] = { 469 MockWrite(SYNCHRONOUS, req->data(), req->length()), 470 MockWrite(SYNCHRONOUS, ack->data(), ack->length()), 471 }; 472 473 scoped_ptr<QuicEncryptedPacket> resp( 474 ConstructDataPacket( 475 1, 3, false, true, 0, GetResponseString("200 OK", "hello!"))); 476 MockRead quic_reads[] = { 477 MockRead(SYNCHRONOUS, resp->data(), resp->length()), 478 MockRead(ASYNC, OK), // EOF 479 }; 480 481 DelayedSocketData quic_data( 482 1, // wait for one write to finish before reading. 483 quic_reads, arraysize(quic_reads), 484 quic_writes, arraysize(quic_writes)); 485 486 socket_factory_.AddSocketDataProvider(&quic_data); 487 488 // The non-alternate protocol job needs to hang in order to guarantee that 489 // the alternate-protocol job will "win". 490 AddHangingNonAlternateProtocolSocketData(); 491 492 CreateSession(); 493 494 SendRequestAndExpectHttpResponse("hello world"); 495 SendRequestAndExpectQuicResponse("hello!"); 496 } 497 498 TEST_F(QuicNetworkTransactionTest, UseAlternateProtocolForQuicForHttps) { 499 params_.origin_to_force_quic_on = 500 HostPortPair::FromString("www.google.com:443"); 501 params_.enable_quic_https = true; 502 HttpStreamFactory::EnableNpnSpdy(); // Enables QUIC too. 503 504 MockRead http_reads[] = { 505 MockRead("HTTP/1.1 200 OK\r\n"), 506 MockRead(kQuicAlternateProtocolHttpsHeader), 507 MockRead("hello world"), 508 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 509 MockRead(ASYNC, OK) 510 }; 511 512 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), 513 NULL, 0); 514 socket_factory_.AddSocketDataProvider(&http_data); 515 516 scoped_ptr<QuicEncryptedPacket> req( 517 ConstructDataPacket(1, 3, true, true, 0, 518 GetRequestString("GET", "https", "/"))); 519 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0)); 520 521 MockWrite quic_writes[] = { 522 MockWrite(SYNCHRONOUS, req->data(), req->length()), 523 MockWrite(SYNCHRONOUS, ack->data(), ack->length()), 524 }; 525 526 scoped_ptr<QuicEncryptedPacket> resp( 527 ConstructDataPacket( 528 1, 3, false, true, 0, GetResponseString("200 OK", "hello!"))); 529 MockRead quic_reads[] = { 530 MockRead(SYNCHRONOUS, resp->data(), resp->length()), 531 MockRead(ASYNC, OK), // EOF 532 }; 533 534 DelayedSocketData quic_data( 535 1, // wait for one write to finish before reading. 536 quic_reads, arraysize(quic_reads), 537 quic_writes, arraysize(quic_writes)); 538 539 socket_factory_.AddSocketDataProvider(&quic_data); 540 541 // The non-alternate protocol job needs to hang in order to guarantee that 542 // the alternate-protocol job will "win". 543 AddHangingNonAlternateProtocolSocketData(); 544 545 CreateSession(); 546 547 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo(). 548 SendRequestAndExpectHttpResponse("hello world"); 549 } 550 551 TEST_F(QuicNetworkTransactionTest, HungAlternateProtocol) { 552 HttpStreamFactory::EnableNpnSpdy(); // Enables QUIC too. 553 crypto_client_stream_factory_.set_handshake_mode( 554 MockCryptoClientStream::COLD_START); 555 556 MockWrite http_writes[] = { 557 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"), 558 MockWrite(SYNCHRONOUS, 1, "Host: www.google.com\r\n"), 559 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n") 560 }; 561 562 MockRead http_reads[] = { 563 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"), 564 MockRead(SYNCHRONOUS, 4, kQuicAlternateProtocolHttpHeader), 565 MockRead(SYNCHRONOUS, 5, "hello world"), 566 MockRead(SYNCHRONOUS, OK, 6) 567 }; 568 569 DeterministicMockClientSocketFactory socket_factory; 570 571 DeterministicSocketData http_data(http_reads, arraysize(http_reads), 572 http_writes, arraysize(http_writes)); 573 socket_factory.AddSocketDataProvider(&http_data); 574 575 // The QUIC transaction will not be allowed to complete. 576 MockWrite quic_writes[] = { 577 MockWrite(ASYNC, ERR_IO_PENDING, 0) 578 }; 579 MockRead quic_reads[] = { 580 MockRead(ASYNC, ERR_IO_PENDING, 1), 581 }; 582 DeterministicSocketData quic_data(quic_reads, arraysize(quic_reads), 583 quic_writes, arraysize(quic_writes)); 584 socket_factory.AddSocketDataProvider(&quic_data); 585 586 // The HTTP transaction will complete. 587 DeterministicSocketData http_data2(http_reads, arraysize(http_reads), 588 http_writes, arraysize(http_writes)); 589 socket_factory.AddSocketDataProvider(&http_data2); 590 591 CreateSessionWithFactory(&socket_factory); 592 593 // Run the first request. 594 http_data.StopAfter(arraysize(http_reads) + arraysize(http_writes)); 595 SendRequestAndExpectHttpResponse("hello world"); 596 ASSERT_TRUE(http_data.at_read_eof()); 597 ASSERT_TRUE(http_data.at_write_eof()); 598 599 // Now run the second request in which the QUIC socket hangs, 600 // and verify the the transaction continues over HTTP. 601 http_data2.StopAfter(arraysize(http_reads) + arraysize(http_writes)); 602 SendRequestAndExpectHttpResponse("hello world"); 603 604 ASSERT_TRUE(http_data2.at_read_eof()); 605 ASSERT_TRUE(http_data2.at_write_eof()); 606 ASSERT_TRUE(!quic_data.at_read_eof()); 607 ASSERT_TRUE(!quic_data.at_write_eof()); 608 } 609 610 TEST_F(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) { 611 HttpStreamFactory::EnableNpnSpdy(); // Enables QUIC too. 612 613 scoped_ptr<QuicEncryptedPacket> req( 614 ConstructDataPacket(1, 3, true, true, 0, 615 GetRequestString("GET", "http", "/"))); 616 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0)); 617 618 MockWrite quic_writes[] = { 619 MockWrite(SYNCHRONOUS, req->data(), req->length()), 620 MockWrite(SYNCHRONOUS, ack->data(), ack->length()), 621 }; 622 623 scoped_ptr<QuicEncryptedPacket> resp( 624 ConstructDataPacket( 625 1, 3, false, true, 0, GetResponseString("200 OK", "hello!"))); 626 MockRead quic_reads[] = { 627 MockRead(SYNCHRONOUS, resp->data(), resp->length()), 628 MockRead(ASYNC, OK), // EOF 629 }; 630 631 DelayedSocketData quic_data( 632 1, // wait for one write to finish before reading. 633 quic_reads, arraysize(quic_reads), 634 quic_writes, arraysize(quic_writes)); 635 636 socket_factory_.AddSocketDataProvider(&quic_data); 637 638 // The non-alternate protocol job needs to hang in order to guarantee that 639 // the alternate-protocol job will "win". 640 AddHangingNonAlternateProtocolSocketData(); 641 642 CreateSession(); 643 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT); 644 SendRequestAndExpectQuicResponse("hello!"); 645 } 646 647 TEST_F(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) { 648 HttpStreamFactory::EnableNpnSpdy(); // Enables QUIC too. 649 650 scoped_ptr<QuicEncryptedPacket> req( 651 ConstructDataPacket(1, 3, true, true, 0, 652 GetRequestString("GET", "http", "/"))); 653 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0)); 654 655 MockWrite quic_writes[] = { 656 MockWrite(SYNCHRONOUS, req->data(), req->length()), 657 MockWrite(SYNCHRONOUS, ack->data(), ack->length()), 658 }; 659 660 scoped_ptr<QuicEncryptedPacket> resp( 661 ConstructDataPacket( 662 1, 3, false, true, 0, GetResponseString("200 OK", "hello!"))); 663 MockRead quic_reads[] = { 664 MockRead(SYNCHRONOUS, resp->data(), resp->length()), 665 MockRead(ASYNC, OK), // EOF 666 }; 667 668 DelayedSocketData quic_data( 669 1, // wait for one write to finish before reading. 670 quic_reads, arraysize(quic_reads), 671 quic_writes, arraysize(quic_writes)); 672 673 socket_factory_.AddSocketDataProvider(&quic_data); 674 675 // In order for a new QUIC session to be established via alternate-protocol 676 // without racing an HTTP connection, we need the host resolution to happen 677 // synchronously. 678 host_resolver_.set_synchronous_mode(true); 679 host_resolver_.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", ""); 680 HostResolver::RequestInfo info(HostPortPair("www.google.com", 80)); 681 AddressList address; 682 host_resolver_.Resolve(info, &address, CompletionCallback(), NULL, 683 net_log_.bound()); 684 685 CreateSession(); 686 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT); 687 SendRequestAndExpectQuicResponse("hello!"); 688 } 689 690 TEST_F(QuicNetworkTransactionTest, BrokenAlternateProtocol) { 691 HttpStreamFactory::EnableNpnSpdy(); // Enables QUIC too. 692 693 // Alternate-protocol job 694 scoped_ptr<QuicEncryptedPacket> close(ConstructConnectionClosePacket(1)); 695 MockRead quic_reads[] = { 696 MockRead(ASYNC, close->data(), close->length()), 697 MockRead(ASYNC, OK), // EOF 698 }; 699 StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads), 700 NULL, 0); 701 socket_factory_.AddSocketDataProvider(&quic_data); 702 703 // Main job which will succeed even though the alternate job fails. 704 MockRead http_reads[] = { 705 MockRead("HTTP/1.1 200 OK\r\n\r\n"), 706 MockRead("hello from http"), 707 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 708 MockRead(ASYNC, OK) 709 }; 710 711 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), 712 NULL, 0); 713 socket_factory_.AddSocketDataProvider(&http_data); 714 715 CreateSession(); 716 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START); 717 SendRequestAndExpectHttpResponse("hello from http"); 718 ExpectBrokenAlternateProtocolMapping(); 719 } 720 721 TEST_F(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) { 722 HttpStreamFactory::EnableNpnSpdy(); // Enables QUIC too. 723 724 // Alternate-protocol job 725 MockRead quic_reads[] = { 726 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED), 727 }; 728 StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads), 729 NULL, 0); 730 socket_factory_.AddSocketDataProvider(&quic_data); 731 732 // Main job which will succeed even though the alternate job fails. 733 MockRead http_reads[] = { 734 MockRead("HTTP/1.1 200 OK\r\n\r\n"), 735 MockRead("hello from http"), 736 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 737 MockRead(ASYNC, OK) 738 }; 739 740 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), 741 NULL, 0); 742 socket_factory_.AddSocketDataProvider(&http_data); 743 744 CreateSession(); 745 746 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START); 747 SendRequestAndExpectHttpResponse("hello from http"); 748 ExpectBrokenAlternateProtocolMapping(); 749 } 750 751 } // namespace test 752 } // namespace net 753