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 <vector> 6 7 #include "base/basictypes.h" 8 #include "base/compiler_specific.h" 9 #include "base/memory/scoped_ptr.h" 10 #include "base/stl_util.h" 11 #include "net/base/capturing_net_log.h" 12 #include "net/base/net_log_unittest.h" 13 #include "net/base/test_completion_callback.h" 14 #include "net/cert/mock_cert_verifier.h" 15 #include "net/dns/mock_host_resolver.h" 16 #include "net/http/http_auth_handler_factory.h" 17 #include "net/http/http_network_session.h" 18 #include "net/http/http_network_transaction.h" 19 #include "net/http/http_server_properties_impl.h" 20 #include "net/http/http_stream.h" 21 #include "net/http/http_stream_factory.h" 22 #include "net/http/http_transaction_test_util.h" 23 #include "net/http/transport_security_state.h" 24 #include "net/proxy/proxy_config_service_fixed.h" 25 #include "net/proxy/proxy_resolver.h" 26 #include "net/proxy/proxy_service.h" 27 #include "net/quic/crypto/quic_decrypter.h" 28 #include "net/quic/crypto/quic_encrypter.h" 29 #include "net/quic/quic_framer.h" 30 #include "net/quic/quic_http_utils.h" 31 #include "net/quic/test_tools/crypto_test_utils.h" 32 #include "net/quic/test_tools/mock_clock.h" 33 #include "net/quic/test_tools/mock_crypto_client_stream_factory.h" 34 #include "net/quic/test_tools/mock_random.h" 35 #include "net/quic/test_tools/quic_test_packet_maker.h" 36 #include "net/quic/test_tools/quic_test_utils.h" 37 #include "net/socket/client_socket_factory.h" 38 #include "net/socket/mock_client_socket_pool_manager.h" 39 #include "net/socket/socket_test_util.h" 40 #include "net/socket/ssl_client_socket.h" 41 #include "net/spdy/spdy_frame_builder.h" 42 #include "net/spdy/spdy_framer.h" 43 #include "net/ssl/ssl_config_service_defaults.h" 44 #include "testing/gtest/include/gtest/gtest.h" 45 #include "testing/platform_test.h" 46 47 //----------------------------------------------------------------------------- 48 49 namespace { 50 51 // This is the expected return from a current server advertising QUIC. 52 static const char kQuicAlternateProtocolHttpHeader[] = 53 "Alternate-Protocol: 80:quic\r\n\r\n"; 54 static const char kQuicAlternateProtocol50pctHttpHeader[] = 55 "Alternate-Protocol: 80:quic,p=.5\r\n\r\n"; 56 static const char kQuicAlternateProtocolHttpsHeader[] = 57 "Alternate-Protocol: 443:quic\r\n\r\n"; 58 59 } // namespace 60 61 namespace net { 62 namespace test { 63 64 // Helper class to encapsulate MockReads and MockWrites for QUIC. 65 // Simplify ownership issues and the interaction with the MockSocketFactory. 66 class MockQuicData { 67 public: 68 ~MockQuicData() { 69 STLDeleteElements(&packets_); 70 } 71 72 void AddRead(scoped_ptr<QuicEncryptedPacket> packet) { 73 reads_.push_back(MockRead(SYNCHRONOUS, packet->data(), packet->length(), 74 sequence_number_++)); 75 packets_.push_back(packet.release()); 76 } 77 78 void AddRead(IoMode mode, int rv) { 79 reads_.push_back(MockRead(mode, rv)); 80 } 81 82 void AddWrite(scoped_ptr<QuicEncryptedPacket> packet) { 83 writes_.push_back(MockWrite(SYNCHRONOUS, packet->data(), packet->length(), 84 sequence_number_++)); 85 packets_.push_back(packet.release()); 86 } 87 88 void AddDelayedSocketDataToFactory(MockClientSocketFactory* factory, 89 size_t delay) { 90 MockRead* reads = reads_.empty() ? NULL : &reads_[0]; 91 MockWrite* writes = writes_.empty() ? NULL : &writes_[0]; 92 socket_data_.reset(new DelayedSocketData( 93 delay, reads, reads_.size(), writes, writes_.size())); 94 factory->AddSocketDataProvider(socket_data_.get()); 95 } 96 97 private: 98 std::vector<QuicEncryptedPacket*> packets_; 99 std::vector<MockWrite> writes_; 100 std::vector<MockRead> reads_; 101 size_t sequence_number_; 102 scoped_ptr<SocketDataProvider> socket_data_; 103 }; 104 105 class QuicNetworkTransactionTest 106 : public PlatformTest, 107 public ::testing::WithParamInterface<QuicVersion> { 108 protected: 109 QuicNetworkTransactionTest() 110 : clock_(new MockClock), 111 maker_(GetParam(), 0, clock_), 112 ssl_config_service_(new SSLConfigServiceDefaults), 113 proxy_service_(ProxyService::CreateDirect()), 114 auth_handler_factory_( 115 HttpAuthHandlerFactory::CreateDefault(&host_resolver_)), 116 random_generator_(0), 117 hanging_data_(NULL, 0, NULL, 0) { 118 request_.method = "GET"; 119 request_.url = GURL("http://www.google.com/"); 120 request_.load_flags = 0; 121 clock_->AdvanceTime(QuicTime::Delta::FromMilliseconds(20)); 122 } 123 124 virtual void SetUp() { 125 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 126 base::MessageLoop::current()->RunUntilIdle(); 127 } 128 129 virtual void TearDown() { 130 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 131 // Empty the current queue. 132 base::MessageLoop::current()->RunUntilIdle(); 133 PlatformTest::TearDown(); 134 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 135 base::MessageLoop::current()->RunUntilIdle(); 136 } 137 138 scoped_ptr<QuicEncryptedPacket> ConstructConnectionClosePacket( 139 QuicPacketSequenceNumber num) { 140 return maker_.MakeConnectionClosePacket(num); 141 } 142 143 scoped_ptr<QuicEncryptedPacket> ConstructAckPacket( 144 QuicPacketSequenceNumber largest_received, 145 QuicPacketSequenceNumber least_unacked) { 146 return maker_.MakeAckPacket(2, largest_received, least_unacked, true); 147 } 148 149 SpdyHeaderBlock GetRequestHeaders(const std::string& method, 150 const std::string& scheme, 151 const std::string& path) { 152 return maker_.GetRequestHeaders(method, scheme, path); 153 } 154 155 SpdyHeaderBlock GetResponseHeaders(const std::string& status) { 156 return maker_.GetResponseHeaders(status); 157 } 158 159 scoped_ptr<QuicEncryptedPacket> ConstructDataPacket( 160 QuicPacketSequenceNumber sequence_number, 161 QuicStreamId stream_id, 162 bool should_include_version, 163 bool fin, 164 QuicStreamOffset offset, 165 base::StringPiece data) { 166 return maker_.MakeDataPacket( 167 sequence_number, stream_id, should_include_version, fin, offset, data); 168 } 169 170 scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket( 171 QuicPacketSequenceNumber sequence_number, 172 QuicStreamId stream_id, 173 bool should_include_version, 174 bool fin, 175 const SpdyHeaderBlock& headers) { 176 return maker_.MakeRequestHeadersPacket( 177 sequence_number, stream_id, should_include_version, fin, headers); 178 } 179 180 scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket( 181 QuicPacketSequenceNumber sequence_number, 182 QuicStreamId stream_id, 183 bool should_include_version, 184 bool fin, 185 const SpdyHeaderBlock& headers) { 186 return maker_.MakeResponseHeadersPacket( 187 sequence_number, stream_id, should_include_version, fin, headers); 188 } 189 190 void CreateSession() { 191 CreateSessionWithFactory(&socket_factory_, false); 192 } 193 194 void CreateSessionWithNextProtos() { 195 CreateSessionWithFactory(&socket_factory_, true); 196 } 197 198 // If |use_next_protos| is true, enables SPDY and QUIC. 199 void CreateSessionWithFactory(ClientSocketFactory* socket_factory, 200 bool use_next_protos) { 201 params_.enable_quic = true; 202 params_.quic_clock = clock_; 203 params_.quic_random = &random_generator_; 204 params_.client_socket_factory = socket_factory; 205 params_.quic_crypto_client_stream_factory = &crypto_client_stream_factory_; 206 params_.host_resolver = &host_resolver_; 207 params_.cert_verifier = &cert_verifier_; 208 params_.transport_security_state = &transport_security_state_; 209 params_.proxy_service = proxy_service_.get(); 210 params_.ssl_config_service = ssl_config_service_.get(); 211 params_.http_auth_handler_factory = auth_handler_factory_.get(); 212 params_.http_server_properties = http_server_properties.GetWeakPtr(); 213 params_.quic_supported_versions = SupportedVersions(GetParam()); 214 215 if (use_next_protos) { 216 params_.use_alternate_protocols = true; 217 params_.next_protos = NextProtosSpdy3(); 218 } 219 220 session_ = new HttpNetworkSession(params_); 221 session_->quic_stream_factory()->set_require_confirmation(false); 222 } 223 224 void CheckWasQuicResponse(const scoped_ptr<HttpNetworkTransaction>& trans) { 225 const HttpResponseInfo* response = trans->GetResponseInfo(); 226 ASSERT_TRUE(response != NULL); 227 ASSERT_TRUE(response->headers.get() != NULL); 228 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 229 EXPECT_TRUE(response->was_fetched_via_spdy); 230 EXPECT_TRUE(response->was_npn_negotiated); 231 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_QUIC1_SPDY3, 232 response->connection_info); 233 } 234 235 void CheckWasHttpResponse(const scoped_ptr<HttpNetworkTransaction>& trans) { 236 const HttpResponseInfo* response = trans->GetResponseInfo(); 237 ASSERT_TRUE(response != NULL); 238 ASSERT_TRUE(response->headers.get() != NULL); 239 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 240 EXPECT_FALSE(response->was_fetched_via_spdy); 241 EXPECT_FALSE(response->was_npn_negotiated); 242 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1, 243 response->connection_info); 244 } 245 246 void CheckResponseData(HttpNetworkTransaction* trans, 247 const std::string& expected) { 248 std::string response_data; 249 ASSERT_EQ(OK, ReadTransaction(trans, &response_data)); 250 EXPECT_EQ(expected, response_data); 251 } 252 253 void RunTransaction(HttpNetworkTransaction* trans) { 254 TestCompletionCallback callback; 255 int rv = trans->Start(&request_, callback.callback(), net_log_.bound()); 256 EXPECT_EQ(ERR_IO_PENDING, rv); 257 EXPECT_EQ(OK, callback.WaitForResult()); 258 } 259 260 void SendRequestAndExpectHttpResponse(const std::string& expected) { 261 scoped_ptr<HttpNetworkTransaction> trans( 262 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get())); 263 RunTransaction(trans.get()); 264 CheckWasHttpResponse(trans); 265 CheckResponseData(trans.get(), expected); 266 } 267 268 void SendRequestAndExpectQuicResponse(const std::string& expected) { 269 scoped_ptr<HttpNetworkTransaction> trans( 270 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get())); 271 RunTransaction(trans.get()); 272 CheckWasQuicResponse(trans); 273 CheckResponseData(trans.get(), expected); 274 } 275 276 void AddQuicAlternateProtocolMapping( 277 MockCryptoClientStream::HandshakeMode handshake_mode) { 278 crypto_client_stream_factory_.set_handshake_mode(handshake_mode); 279 session_->http_server_properties()->SetAlternateProtocol( 280 HostPortPair::FromURL(request_.url), 80, QUIC, 1); 281 } 282 283 void ExpectBrokenAlternateProtocolMapping() { 284 ASSERT_TRUE(session_->http_server_properties()->HasAlternateProtocol( 285 HostPortPair::FromURL(request_.url))); 286 const AlternateProtocolInfo alternate = 287 session_->http_server_properties()->GetAlternateProtocol( 288 HostPortPair::FromURL(request_.url)); 289 EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol); 290 } 291 292 void ExpectQuicAlternateProtocolMapping() { 293 ASSERT_TRUE(session_->http_server_properties()->HasAlternateProtocol( 294 HostPortPair::FromURL(request_.url))); 295 const AlternateProtocolInfo alternate = 296 session_->http_server_properties()->GetAlternateProtocol( 297 HostPortPair::FromURL(request_.url)); 298 EXPECT_EQ(QUIC, alternate.protocol); 299 } 300 301 void AddHangingNonAlternateProtocolSocketData() { 302 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING); 303 hanging_data_.set_connect_data(hanging_connect); 304 socket_factory_.AddSocketDataProvider(&hanging_data_); 305 } 306 307 MockClock* clock_; // Owned by QuicStreamFactory after CreateSession. 308 QuicTestPacketMaker maker_; 309 scoped_refptr<HttpNetworkSession> session_; 310 MockClientSocketFactory socket_factory_; 311 MockCryptoClientStreamFactory crypto_client_stream_factory_; 312 MockHostResolver host_resolver_; 313 MockCertVerifier cert_verifier_; 314 TransportSecurityState transport_security_state_; 315 scoped_refptr<SSLConfigServiceDefaults> ssl_config_service_; 316 scoped_ptr<ProxyService> proxy_service_; 317 scoped_ptr<HttpAuthHandlerFactory> auth_handler_factory_; 318 MockRandom random_generator_; 319 HttpServerPropertiesImpl http_server_properties; 320 HttpNetworkSession::Params params_; 321 HttpRequestInfo request_; 322 CapturingBoundNetLog net_log_; 323 StaticSocketDataProvider hanging_data_; 324 }; 325 326 INSTANTIATE_TEST_CASE_P(Version, QuicNetworkTransactionTest, 327 ::testing::ValuesIn(QuicSupportedVersions())); 328 329 TEST_P(QuicNetworkTransactionTest, ForceQuic) { 330 params_.origin_to_force_quic_on = 331 HostPortPair::FromString("www.google.com:80"); 332 333 MockQuicData mock_quic_data; 334 mock_quic_data.AddWrite( 335 ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true, 336 GetRequestHeaders("GET", "http", "/"))); 337 mock_quic_data.AddRead( 338 ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false, 339 GetResponseHeaders("200 OK"))); 340 mock_quic_data.AddRead( 341 ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!")); 342 mock_quic_data.AddWrite(ConstructAckPacket(2, 1)); 343 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF 344 345 mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1); 346 347 // The non-alternate protocol job needs to hang in order to guarantee that 348 // the alternate-protocol job will "win". 349 AddHangingNonAlternateProtocolSocketData(); 350 351 CreateSession(); 352 353 SendRequestAndExpectQuicResponse("hello!"); 354 355 // Check that the NetLog was filled reasonably. 356 net::CapturingNetLog::CapturedEntryList entries; 357 net_log_.GetEntries(&entries); 358 EXPECT_LT(0u, entries.size()); 359 360 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED. 361 int pos = net::ExpectLogContainsSomewhere( 362 entries, 0, 363 net::NetLog::TYPE_QUIC_SESSION_PACKET_RECEIVED, 364 net::NetLog::PHASE_NONE); 365 EXPECT_LT(0, pos); 366 367 // ... and also a TYPE_QUIC_SESSION_PACKET_HEADER_RECEIVED. 368 pos = net::ExpectLogContainsSomewhere( 369 entries, 0, 370 net::NetLog::TYPE_QUIC_SESSION_PACKET_HEADER_RECEIVED, 371 net::NetLog::PHASE_NONE); 372 EXPECT_LT(0, pos); 373 374 std::string packet_sequence_number; 375 ASSERT_TRUE(entries[pos].GetStringValue( 376 "packet_sequence_number", &packet_sequence_number)); 377 EXPECT_EQ("1", packet_sequence_number); 378 379 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED. 380 pos = net::ExpectLogContainsSomewhere( 381 entries, 0, 382 net::NetLog::TYPE_QUIC_SESSION_STREAM_FRAME_RECEIVED, 383 net::NetLog::PHASE_NONE); 384 EXPECT_LT(0, pos); 385 386 int log_stream_id; 387 ASSERT_TRUE(entries[pos].GetIntegerValue("stream_id", &log_stream_id)); 388 EXPECT_EQ(3, log_stream_id); 389 } 390 391 TEST_P(QuicNetworkTransactionTest, QuicProxy) { 392 proxy_service_.reset( 393 ProxyService::CreateFixedFromPacResult("QUIC myproxy:70")); 394 395 MockQuicData mock_quic_data; 396 mock_quic_data.AddWrite( 397 ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true, 398 GetRequestHeaders("GET", "http", "/"))); 399 mock_quic_data.AddRead( 400 ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false, 401 GetResponseHeaders("200 OK"))); 402 mock_quic_data.AddRead( 403 ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!")); 404 mock_quic_data.AddWrite(ConstructAckPacket(2, 1)); 405 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF 406 407 mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1); 408 409 // There is no need to set up an alternate protocol job, because 410 // no attempt will be made to speak to the proxy over TCP. 411 412 CreateSession(); 413 414 SendRequestAndExpectQuicResponse("hello!"); 415 } 416 417 TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) { 418 params_.origin_to_force_quic_on = 419 HostPortPair::FromString("www.google.com:80"); 420 421 MockQuicData mock_quic_data; 422 mock_quic_data.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED); 423 424 mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 0); 425 426 CreateSession(); 427 428 scoped_ptr<HttpNetworkTransaction> trans( 429 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get())); 430 TestCompletionCallback callback; 431 int rv = trans->Start(&request_, callback.callback(), net_log_.bound()); 432 EXPECT_EQ(ERR_IO_PENDING, rv); 433 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult()); 434 } 435 436 TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) { 437 // Attempt to "force" quic on 443, which will not be honored. 438 params_.origin_to_force_quic_on = 439 HostPortPair::FromString("www.google.com:443"); 440 441 MockRead http_reads[] = { 442 MockRead("HTTP/1.1 200 OK\r\n\r\n"), 443 MockRead("hello world"), 444 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 445 MockRead(ASYNC, OK) 446 }; 447 448 StaticSocketDataProvider data(http_reads, arraysize(http_reads), NULL, 0); 449 socket_factory_.AddSocketDataProvider(&data); 450 SSLSocketDataProvider ssl(ASYNC, OK); 451 socket_factory_.AddSSLSocketDataProvider(&ssl); 452 453 CreateSession(); 454 455 SendRequestAndExpectHttpResponse("hello world"); 456 } 457 458 TEST_P(QuicNetworkTransactionTest, UseAlternateProtocolForQuic) { 459 MockRead http_reads[] = { 460 MockRead("HTTP/1.1 200 OK\r\n"), 461 MockRead(kQuicAlternateProtocolHttpHeader), 462 MockRead("hello world"), 463 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 464 MockRead(ASYNC, OK) 465 }; 466 467 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), 468 NULL, 0); 469 socket_factory_.AddSocketDataProvider(&http_data); 470 471 MockQuicData mock_quic_data; 472 mock_quic_data.AddWrite( 473 ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true, 474 GetRequestHeaders("GET", "http", "/"))); 475 mock_quic_data.AddRead( 476 ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false, 477 GetResponseHeaders("200 OK"))); 478 mock_quic_data.AddRead( 479 ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!")); 480 mock_quic_data.AddWrite(ConstructAckPacket(2, 1)); 481 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF 482 483 mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1); 484 485 // The non-alternate protocol job needs to hang in order to guarantee that 486 // the alternate-protocol job will "win". 487 AddHangingNonAlternateProtocolSocketData(); 488 489 CreateSessionWithNextProtos(); 490 491 SendRequestAndExpectHttpResponse("hello world"); 492 SendRequestAndExpectQuicResponse("hello!"); 493 } 494 495 TEST_P(QuicNetworkTransactionTest, UseAlternateProtocolProbabilityForQuic) { 496 MockRead http_reads[] = { 497 MockRead("HTTP/1.1 200 OK\r\n"), 498 MockRead(kQuicAlternateProtocol50pctHttpHeader), 499 MockRead("hello world"), 500 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 501 MockRead(ASYNC, OK) 502 }; 503 504 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), 505 NULL, 0); 506 socket_factory_.AddSocketDataProvider(&http_data); 507 508 MockQuicData mock_quic_data; 509 mock_quic_data.AddWrite( 510 ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true, 511 GetRequestHeaders("GET", "http", "/"))); 512 mock_quic_data.AddRead( 513 ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false, 514 GetResponseHeaders("200 OK"))); 515 mock_quic_data.AddRead( 516 ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!")); 517 mock_quic_data.AddWrite(ConstructAckPacket(2, 1)); 518 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF 519 520 mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1); 521 522 // The non-alternate protocol job needs to hang in order to guarantee that 523 // the alternate-protocol job will "win". 524 AddHangingNonAlternateProtocolSocketData(); 525 526 params_.alternate_protocol_probability_threshold = .25; 527 CreateSessionWithNextProtos(); 528 529 SendRequestAndExpectHttpResponse("hello world"); 530 SendRequestAndExpectQuicResponse("hello!"); 531 } 532 533 TEST_P(QuicNetworkTransactionTest, DontUseAlternateProtocolProbabilityForQuic) { 534 MockRead http_reads[] = { 535 MockRead("HTTP/1.1 200 OK\r\n"), 536 MockRead(kQuicAlternateProtocol50pctHttpHeader), 537 MockRead("hello world"), 538 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 539 MockRead(ASYNC, OK) 540 }; 541 542 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), 543 NULL, 0); 544 socket_factory_.AddSocketDataProvider(&http_data); 545 socket_factory_.AddSocketDataProvider(&http_data); 546 547 params_.alternate_protocol_probability_threshold = .75; 548 CreateSessionWithNextProtos(); 549 550 SendRequestAndExpectHttpResponse("hello world"); 551 SendRequestAndExpectHttpResponse("hello world"); 552 } 553 554 TEST_P(QuicNetworkTransactionTest, 555 DontUseAlternateProtocolWithBadProbabilityForQuic) { 556 MockRead http_reads[] = { 557 MockRead("HTTP/1.1 200 OK\r\n"), 558 MockRead("Alternate-Protocol: 443:quic,p=2\r\n\r\n"), 559 MockRead("hello world"), 560 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 561 MockRead(ASYNC, OK) 562 }; 563 564 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), 565 NULL, 0); 566 socket_factory_.AddSocketDataProvider(&http_data); 567 socket_factory_.AddSocketDataProvider(&http_data); 568 569 params_.alternate_protocol_probability_threshold = .75; 570 CreateSessionWithNextProtos(); 571 572 SendRequestAndExpectHttpResponse("hello world"); 573 SendRequestAndExpectHttpResponse("hello world"); 574 } 575 576 TEST_P(QuicNetworkTransactionTest, UseAlternateProtocolForQuicForHttps) { 577 params_.origin_to_force_quic_on = 578 HostPortPair::FromString("www.google.com:443"); 579 580 MockRead http_reads[] = { 581 MockRead("HTTP/1.1 200 OK\r\n"), 582 MockRead(kQuicAlternateProtocolHttpsHeader), 583 MockRead("hello world"), 584 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 585 MockRead(ASYNC, OK) 586 }; 587 588 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), 589 NULL, 0); 590 socket_factory_.AddSocketDataProvider(&http_data); 591 592 MockQuicData mock_quic_data; 593 mock_quic_data.AddWrite( 594 ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true, 595 GetRequestHeaders("GET", "http", "/"))); 596 mock_quic_data.AddRead( 597 ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false, 598 GetResponseHeaders("200 OK"))); 599 mock_quic_data.AddRead( 600 ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!")); 601 mock_quic_data.AddWrite(ConstructAckPacket(2, 1)); 602 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF 603 604 mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1); 605 606 // The non-alternate protocol job needs to hang in order to guarantee that 607 // the alternate-protocol job will "win". 608 AddHangingNonAlternateProtocolSocketData(); 609 610 CreateSessionWithNextProtos(); 611 612 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo(). 613 SendRequestAndExpectHttpResponse("hello world"); 614 } 615 616 TEST_P(QuicNetworkTransactionTest, HungAlternateProtocol) { 617 crypto_client_stream_factory_.set_handshake_mode( 618 MockCryptoClientStream::COLD_START); 619 620 MockWrite http_writes[] = { 621 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"), 622 MockWrite(SYNCHRONOUS, 1, "Host: www.google.com\r\n"), 623 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n") 624 }; 625 626 MockRead http_reads[] = { 627 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"), 628 MockRead(SYNCHRONOUS, 4, kQuicAlternateProtocolHttpHeader), 629 MockRead(SYNCHRONOUS, 5, "hello world"), 630 MockRead(SYNCHRONOUS, OK, 6) 631 }; 632 633 DeterministicMockClientSocketFactory socket_factory; 634 635 DeterministicSocketData http_data(http_reads, arraysize(http_reads), 636 http_writes, arraysize(http_writes)); 637 socket_factory.AddSocketDataProvider(&http_data); 638 639 // The QUIC transaction will not be allowed to complete. 640 MockWrite quic_writes[] = { 641 MockWrite(ASYNC, ERR_IO_PENDING, 0) 642 }; 643 MockRead quic_reads[] = { 644 MockRead(ASYNC, ERR_IO_PENDING, 1), 645 }; 646 DeterministicSocketData quic_data(quic_reads, arraysize(quic_reads), 647 quic_writes, arraysize(quic_writes)); 648 socket_factory.AddSocketDataProvider(&quic_data); 649 650 // The HTTP transaction will complete. 651 DeterministicSocketData http_data2(http_reads, arraysize(http_reads), 652 http_writes, arraysize(http_writes)); 653 socket_factory.AddSocketDataProvider(&http_data2); 654 655 CreateSessionWithFactory(&socket_factory, true); 656 657 // Run the first request. 658 http_data.StopAfter(arraysize(http_reads) + arraysize(http_writes)); 659 SendRequestAndExpectHttpResponse("hello world"); 660 ASSERT_TRUE(http_data.at_read_eof()); 661 ASSERT_TRUE(http_data.at_write_eof()); 662 663 // Now run the second request in which the QUIC socket hangs, 664 // and verify the the transaction continues over HTTP. 665 http_data2.StopAfter(arraysize(http_reads) + arraysize(http_writes)); 666 SendRequestAndExpectHttpResponse("hello world"); 667 668 ASSERT_TRUE(http_data2.at_read_eof()); 669 ASSERT_TRUE(http_data2.at_write_eof()); 670 ASSERT_TRUE(!quic_data.at_read_eof()); 671 ASSERT_TRUE(!quic_data.at_write_eof()); 672 } 673 674 TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) { 675 MockQuicData mock_quic_data; 676 mock_quic_data.AddWrite( 677 ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true, 678 GetRequestHeaders("GET", "http", "/"))); 679 mock_quic_data.AddRead( 680 ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false, 681 GetResponseHeaders("200 OK"))); 682 mock_quic_data.AddRead( 683 ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!")); 684 mock_quic_data.AddWrite(ConstructAckPacket(2, 1)); 685 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF 686 687 mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1); 688 689 // The non-alternate protocol job needs to hang in order to guarantee that 690 // the alternate-protocol job will "win". 691 AddHangingNonAlternateProtocolSocketData(); 692 693 CreateSessionWithNextProtos(); 694 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT); 695 SendRequestAndExpectQuicResponse("hello!"); 696 } 697 698 TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) { 699 MockQuicData mock_quic_data; 700 mock_quic_data.AddWrite( 701 ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true, 702 GetRequestHeaders("GET", "http", "/"))); 703 mock_quic_data.AddRead( 704 ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false, 705 GetResponseHeaders("200 OK"))); 706 mock_quic_data.AddRead( 707 ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!")); 708 mock_quic_data.AddWrite(ConstructAckPacket(2, 1)); 709 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF 710 mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1); 711 712 // In order for a new QUIC session to be established via alternate-protocol 713 // without racing an HTTP connection, we need the host resolution to happen 714 // synchronously. 715 host_resolver_.set_synchronous_mode(true); 716 host_resolver_.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", ""); 717 HostResolver::RequestInfo info(HostPortPair("www.google.com", 80)); 718 AddressList address; 719 host_resolver_.Resolve(info, 720 DEFAULT_PRIORITY, 721 &address, 722 CompletionCallback(), 723 NULL, 724 net_log_.bound()); 725 726 CreateSessionWithNextProtos(); 727 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT); 728 SendRequestAndExpectQuicResponse("hello!"); 729 } 730 731 TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) { 732 proxy_service_.reset( 733 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70")); 734 735 // Since we are using a proxy, the QUIC job will not succeed. 736 MockWrite http_writes[] = { 737 MockWrite(SYNCHRONOUS, 0, "GET http://www.google.com/ HTTP/1.1\r\n"), 738 MockWrite(SYNCHRONOUS, 1, "Host: www.google.com\r\n"), 739 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n") 740 }; 741 742 MockRead http_reads[] = { 743 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"), 744 MockRead(SYNCHRONOUS, 4, kQuicAlternateProtocolHttpHeader), 745 MockRead(SYNCHRONOUS, 5, "hello world"), 746 MockRead(SYNCHRONOUS, OK, 6) 747 }; 748 749 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), 750 http_writes, arraysize(http_writes)); 751 socket_factory_.AddSocketDataProvider(&http_data); 752 753 // In order for a new QUIC session to be established via alternate-protocol 754 // without racing an HTTP connection, we need the host resolution to happen 755 // synchronously. 756 host_resolver_.set_synchronous_mode(true); 757 host_resolver_.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", ""); 758 HostResolver::RequestInfo info(HostPortPair("www.google.com", 80)); 759 AddressList address; 760 host_resolver_.Resolve(info, 761 DEFAULT_PRIORITY, 762 &address, 763 CompletionCallback(), 764 NULL, 765 net_log_.bound()); 766 767 CreateSessionWithNextProtos(); 768 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT); 769 SendRequestAndExpectHttpResponse("hello world"); 770 } 771 772 TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) { 773 MockQuicData mock_quic_data; 774 mock_quic_data.AddWrite( 775 ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true, 776 GetRequestHeaders("GET", "http", "/"))); 777 mock_quic_data.AddRead( 778 ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false, 779 GetResponseHeaders("200 OK"))); 780 mock_quic_data.AddRead( 781 ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!")); 782 mock_quic_data.AddWrite(ConstructAckPacket(2, 1)); 783 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF 784 mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1); 785 786 // The non-alternate protocol job needs to hang in order to guarantee that 787 // the alternate-protocol job will "win". 788 AddHangingNonAlternateProtocolSocketData(); 789 790 // In order for a new QUIC session to be established via alternate-protocol 791 // without racing an HTTP connection, we need the host resolution to happen 792 // synchronously. Of course, even though QUIC *could* perform a 0-RTT 793 // connection to the the server, in this test we require confirmation 794 // before encrypting so the HTTP job will still start. 795 host_resolver_.set_synchronous_mode(true); 796 host_resolver_.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", ""); 797 HostResolver::RequestInfo info(HostPortPair("www.google.com", 80)); 798 AddressList address; 799 host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address, 800 CompletionCallback(), NULL, net_log_.bound()); 801 802 CreateSessionWithNextProtos(); 803 session_->quic_stream_factory()->set_require_confirmation(true); 804 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT); 805 806 scoped_ptr<HttpNetworkTransaction> trans( 807 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get())); 808 TestCompletionCallback callback; 809 int rv = trans->Start(&request_, callback.callback(), net_log_.bound()); 810 EXPECT_EQ(ERR_IO_PENDING, rv); 811 812 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent( 813 QuicSession::HANDSHAKE_CONFIRMED); 814 EXPECT_EQ(OK, callback.WaitForResult()); 815 } 816 817 TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) { 818 // Alternate-protocol job 819 scoped_ptr<QuicEncryptedPacket> close(ConstructConnectionClosePacket(1)); 820 MockRead quic_reads[] = { 821 MockRead(ASYNC, close->data(), close->length()), 822 MockRead(ASYNC, OK), // EOF 823 }; 824 StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads), 825 NULL, 0); 826 socket_factory_.AddSocketDataProvider(&quic_data); 827 828 // Main job which will succeed even though the alternate job fails. 829 MockRead http_reads[] = { 830 MockRead("HTTP/1.1 200 OK\r\n\r\n"), 831 MockRead("hello from http"), 832 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 833 MockRead(ASYNC, OK) 834 }; 835 836 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), 837 NULL, 0); 838 socket_factory_.AddSocketDataProvider(&http_data); 839 840 CreateSessionWithNextProtos(); 841 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START); 842 SendRequestAndExpectHttpResponse("hello from http"); 843 ExpectBrokenAlternateProtocolMapping(); 844 } 845 846 TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) { 847 // Alternate-protocol job 848 MockRead quic_reads[] = { 849 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED), 850 }; 851 StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads), 852 NULL, 0); 853 socket_factory_.AddSocketDataProvider(&quic_data); 854 855 // Main job which will succeed even though the alternate job fails. 856 MockRead http_reads[] = { 857 MockRead("HTTP/1.1 200 OK\r\n\r\n"), 858 MockRead("hello from http"), 859 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 860 MockRead(ASYNC, OK) 861 }; 862 863 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), 864 NULL, 0); 865 socket_factory_.AddSocketDataProvider(&http_data); 866 867 CreateSessionWithNextProtos(); 868 869 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START); 870 SendRequestAndExpectHttpResponse("hello from http"); 871 ExpectBrokenAlternateProtocolMapping(); 872 } 873 874 TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) { 875 // Alternate-protocol job will fail when the session attempts to read. 876 MockRead quic_reads[] = { 877 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED), 878 }; 879 StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads), 880 NULL, 0); 881 socket_factory_.AddSocketDataProvider(&quic_data); 882 883 // Main job will also fail. 884 MockRead http_reads[] = { 885 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED), 886 }; 887 888 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), 889 NULL, 0); 890 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED)); 891 socket_factory_.AddSocketDataProvider(&http_data); 892 893 CreateSessionWithNextProtos(); 894 895 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START); 896 scoped_ptr<HttpNetworkTransaction> trans( 897 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get())); 898 TestCompletionCallback callback; 899 int rv = trans->Start(&request_, callback.callback(), net_log_.bound()); 900 EXPECT_EQ(ERR_IO_PENDING, rv); 901 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, callback.WaitForResult()); 902 ExpectQuicAlternateProtocolMapping(); 903 } 904 905 TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) { 906 // Alternate-protocol job 907 MockRead quic_reads[] = { 908 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED), 909 }; 910 StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads), 911 NULL, 0); 912 socket_factory_.AddSocketDataProvider(&quic_data); 913 914 AddHangingNonAlternateProtocolSocketData(); 915 916 // Second Alternate-protocol job which will race with the TCP job. 917 StaticSocketDataProvider quic_data2(quic_reads, arraysize(quic_reads), 918 NULL, 0); 919 socket_factory_.AddSocketDataProvider(&quic_data2); 920 921 // Final job that will proceed when the QUIC job fails. 922 MockRead http_reads[] = { 923 MockRead("HTTP/1.1 200 OK\r\n\r\n"), 924 MockRead("hello from http"), 925 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 926 MockRead(ASYNC, OK) 927 }; 928 929 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), 930 NULL, 0); 931 socket_factory_.AddSocketDataProvider(&http_data); 932 933 CreateSessionWithNextProtos(); 934 935 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT); 936 937 SendRequestAndExpectHttpResponse("hello from http"); 938 939 ExpectBrokenAlternateProtocolMapping(); 940 941 EXPECT_TRUE(quic_data.at_read_eof()); 942 EXPECT_TRUE(quic_data.at_write_eof()); 943 } 944 945 TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) { 946 // Alternate-protocol job 947 MockRead quic_reads[] = { 948 MockRead(ASYNC, ERR_IO_PENDING), 949 }; 950 StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads), 951 NULL, 0); 952 socket_factory_.AddSocketDataProvider(&quic_data); 953 954 // Main job that will proceed when the QUIC job fails. 955 MockRead http_reads[] = { 956 MockRead("HTTP/1.1 200 OK\r\n\r\n"), 957 MockRead("hello from http"), 958 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 959 MockRead(ASYNC, OK) 960 }; 961 962 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), 963 NULL, 0); 964 socket_factory_.AddSocketDataProvider(&http_data); 965 966 CreateSessionWithNextProtos(); 967 968 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT); 969 970 SendRequestAndExpectHttpResponse("hello from http"); 971 } 972 973 TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) { 974 // Alternate-protocol job will fail before creating a QUIC session. 975 StaticSocketDataProvider quic_data(NULL, 0, NULL, 0); 976 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, 977 ERR_INTERNET_DISCONNECTED)); 978 socket_factory_.AddSocketDataProvider(&quic_data); 979 980 // Main job which will succeed even though the alternate job fails. 981 MockRead http_reads[] = { 982 MockRead("HTTP/1.1 200 OK\r\n\r\n"), 983 MockRead("hello from http"), 984 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 985 MockRead(ASYNC, OK) 986 }; 987 988 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), 989 NULL, 0); 990 socket_factory_.AddSocketDataProvider(&http_data); 991 992 CreateSessionWithNextProtos(); 993 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START); 994 SendRequestAndExpectHttpResponse("hello from http"); 995 996 ExpectBrokenAlternateProtocolMapping(); 997 } 998 999 TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) { 1000 MockQuicData mock_quic_data; 1001 mock_quic_data.AddRead(ConstructConnectionClosePacket(1)); 1002 mock_quic_data.AddWrite( 1003 ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true, 1004 GetRequestHeaders("GET", "http", "/"))); 1005 mock_quic_data.AddWrite(ConstructAckPacket(2, 1)); 1006 mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 0); 1007 1008 // When the QUIC connection fails, we will try the request again over HTTP. 1009 MockRead http_reads[] = { 1010 MockRead("HTTP/1.1 200 OK\r\n"), 1011 MockRead(kQuicAlternateProtocolHttpHeader), 1012 MockRead("hello world"), 1013 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 1014 MockRead(ASYNC, OK) 1015 }; 1016 1017 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), 1018 NULL, 0); 1019 socket_factory_.AddSocketDataProvider(&http_data); 1020 1021 // In order for a new QUIC session to be established via alternate-protocol 1022 // without racing an HTTP connection, we need the host resolution to happen 1023 // synchronously. 1024 host_resolver_.set_synchronous_mode(true); 1025 host_resolver_.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", ""); 1026 HostResolver::RequestInfo info(HostPortPair("www.google.com", 80)); 1027 AddressList address; 1028 host_resolver_.Resolve(info, 1029 DEFAULT_PRIORITY, 1030 &address, 1031 CompletionCallback(), 1032 NULL, 1033 net_log_.bound()); 1034 1035 CreateSessionWithNextProtos(); 1036 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT); 1037 SendRequestAndExpectHttpResponse("hello world"); 1038 } 1039 1040 } // namespace test 1041 } // namespace net 1042