quic_network_transaction_unittest.cc revision 7d4cd473f85ac64c3747c96c277f9e506a0d2246
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 45namespace { 46 47// This is the expected return from a current server advertising QUIC. 48static const char kQuicAlternateProtocolHttpHeader[] = 49 "Alternate-Protocol: 443:quic\r\n\r\n"; 50 51// Returns a vector of NPN protocol strings for negotiating QUIC. 52std::vector<std::string> QuicNextProtos() { 53 std::vector<std::string> protos; 54 protos.push_back("http/1.1"); 55 protos.push_back("quic"); 56 return protos; 57} 58 59} // namespace 60 61namespace net { 62namespace test { 63 64class QuicNetworkTransactionTest : public PlatformTest { 65 protected: 66 QuicNetworkTransactionTest() 67 : clock_(new MockClock), 68 ssl_config_service_(new SSLConfigServiceDefaults), 69 proxy_service_(ProxyService::CreateDirect()), 70 compressor_(new QuicSpdyCompressor()), 71 auth_handler_factory_( 72 HttpAuthHandlerFactory::CreateDefault(&host_resolver_)) { 73 request_.method = "GET"; 74 request_.url = GURL("http://www.google.com/"); 75 request_.load_flags = 0; 76 } 77 78 virtual void SetUp() { 79 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 80 base::MessageLoop::current()->RunUntilIdle(); 81 } 82 83 virtual void TearDown() { 84 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 85 // Empty the current queue. 86 base::MessageLoop::current()->RunUntilIdle(); 87 PlatformTest::TearDown(); 88 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 89 base::MessageLoop::current()->RunUntilIdle(); 90 HttpStreamFactory::set_use_alternate_protocols(false); 91 HttpStreamFactory::SetNextProtos(std::vector<std::string>()); 92 } 93 94 scoped_ptr<QuicEncryptedPacket> ConstructRstPacket( 95 QuicPacketSequenceNumber num, 96 QuicStreamId stream_id) { 97 QuicPacketHeader header; 98 header.public_header.guid = 0xDEADBEEF; 99 header.public_header.reset_flag = false; 100 header.public_header.version_flag = false; 101 header.packet_sequence_number = num; 102 header.entropy_flag = false; 103 header.fec_flag = false; 104 header.fec_group = 0; 105 106 QuicRstStreamFrame rst(stream_id, QUIC_STREAM_NO_ERROR); 107 return scoped_ptr<QuicEncryptedPacket>( 108 ConstructPacket(header, QuicFrame(&rst))); 109 } 110 111 scoped_ptr<QuicEncryptedPacket> ConstructConnectionClosePacket( 112 QuicPacketSequenceNumber num) { 113 QuicPacketHeader header; 114 header.public_header.guid = 0xDEADBEEF; 115 header.public_header.reset_flag = false; 116 header.public_header.version_flag = false; 117 header.packet_sequence_number = num; 118 header.entropy_flag = false; 119 header.fec_flag = false; 120 header.fec_group = 0; 121 122 QuicAckFrame ack_frame(0, QuicTime::Zero(), 0); 123 QuicConnectionCloseFrame close; 124 close.error_code = QUIC_CRYPTO_VERSION_NOT_SUPPORTED; 125 close.error_details = "Time to panic!"; 126 close.ack_frame = ack_frame; 127 return scoped_ptr<QuicEncryptedPacket>( 128 ConstructPacket(header, QuicFrame(&close))); 129 } 130 131 scoped_ptr<QuicEncryptedPacket> ConstructAckPacket( 132 QuicPacketSequenceNumber largest_received, 133 QuicPacketSequenceNumber least_unacked) { 134 QuicPacketHeader header; 135 header.public_header.guid = 0xDEADBEEF; 136 header.public_header.reset_flag = false; 137 header.public_header.version_flag = false; 138 header.packet_sequence_number = 2; 139 header.entropy_flag = false; 140 header.fec_flag = false; 141 header.fec_group = 0; 142 143 QuicAckFrame ack(largest_received, QuicTime::Zero(), least_unacked); 144 145 QuicCongestionFeedbackFrame feedback; 146 feedback.type = kTCP; 147 feedback.tcp.accumulated_number_of_lost_packets = 0; 148 feedback.tcp.receive_window = 256000; 149 150 QuicFramer framer(kQuicVersion1, QuicTime::Zero(), false); 151 QuicFrames frames; 152 frames.push_back(QuicFrame(&ack)); 153 frames.push_back(QuicFrame(&feedback)); 154 scoped_ptr<QuicPacket> packet( 155 framer.ConstructFrameDataPacket(header, frames).packet); 156 return scoped_ptr<QuicEncryptedPacket>(framer.EncryptPacket( 157 ENCRYPTION_NONE, header.packet_sequence_number, *packet)); 158 } 159 160 std::string GetRequestString(const std::string& method, 161 const std::string& path) { 162 SpdyHeaderBlock headers; 163 headers[":method"] = method; 164 headers[":host"] = "www.google.com"; 165 headers[":path"] = path; 166 headers[":scheme"] = "http"; 167 headers[":version"] = "HTTP/1.1"; 168 return SerializeHeaderBlock(headers); 169 } 170 171 std::string GetResponseString(const std::string& status, 172 const std::string& body) { 173 SpdyHeaderBlock headers; 174 headers[":status"] = status; 175 headers[":version"] = "HTTP/1.1"; 176 headers["content-type"] = "text/plain"; 177 return compressor_->CompressHeaders(headers) + body; 178 } 179 180 std::string SerializeHeaderBlock(const SpdyHeaderBlock& headers) { 181 QuicSpdyCompressor compressor; 182 return compressor.CompressHeaders(headers); 183 } 184 185 // Returns a newly created packet to send kData on stream 1. 186 QuicEncryptedPacket* ConstructDataPacket( 187 QuicPacketSequenceNumber sequence_number, 188 QuicStreamId stream_id, 189 bool should_include_version, 190 bool fin, 191 QuicStreamOffset offset, 192 base::StringPiece data) { 193 InitializeHeader(sequence_number, should_include_version); 194 QuicStreamFrame frame(stream_id, fin, offset, data); 195 return ConstructPacket(header_, QuicFrame(&frame)).release(); 196 } 197 198 scoped_ptr<QuicEncryptedPacket> ConstructPacket( 199 const QuicPacketHeader& header, 200 const QuicFrame& frame) { 201 QuicFramer framer(kQuicVersion1, QuicTime::Zero(), false); 202 QuicFrames frames; 203 frames.push_back(frame); 204 scoped_ptr<QuicPacket> packet( 205 framer.ConstructFrameDataPacket(header, frames).packet); 206 return scoped_ptr<QuicEncryptedPacket>(framer.EncryptPacket( 207 ENCRYPTION_NONE, header.packet_sequence_number, *packet)); 208 } 209 210 void InitializeHeader(QuicPacketSequenceNumber sequence_number, 211 bool should_include_version) { 212 header_.public_header.guid = random_generator_.RandUint64(); 213 header_.public_header.reset_flag = false; 214 header_.public_header.version_flag = should_include_version; 215 header_.packet_sequence_number = sequence_number; 216 header_.fec_group = 0; 217 header_.entropy_flag = false; 218 header_.fec_flag = false; 219 } 220 221 void CreateSession() { 222 params_.enable_quic = true; 223 params_.quic_clock = clock_; 224 params_.quic_random = &random_generator_; 225 params_.client_socket_factory = &socket_factory_; 226 params_.quic_crypto_client_stream_factory = &crypto_client_stream_factory_; 227 params_.host_resolver = &host_resolver_; 228 params_.cert_verifier = &cert_verifier_; 229 params_.transport_security_state = &transport_security_state_; 230 params_.proxy_service = proxy_service_.get(); 231 params_.ssl_config_service = ssl_config_service_.get(); 232 params_.http_auth_handler_factory = auth_handler_factory_.get(); 233 params_.http_server_properties = &http_server_properties; 234 235 session_ = new HttpNetworkSession(params_); 236 } 237 238 void CheckWasQuicResponse(const scoped_ptr<HttpNetworkTransaction>& trans) { 239 const HttpResponseInfo* response = trans->GetResponseInfo(); 240 ASSERT_TRUE(response != NULL); 241 ASSERT_TRUE(response->headers.get() != NULL); 242 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 243 EXPECT_TRUE(response->was_fetched_via_spdy); 244 EXPECT_TRUE(response->was_npn_negotiated); 245 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_QUIC1_SPDY3, 246 response->connection_info); 247 } 248 249 void CheckWasHttpResponse(const scoped_ptr<HttpNetworkTransaction>& trans) { 250 const HttpResponseInfo* response = trans->GetResponseInfo(); 251 ASSERT_TRUE(response != NULL); 252 ASSERT_TRUE(response->headers.get() != NULL); 253 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 254 EXPECT_FALSE(response->was_fetched_via_spdy); 255 EXPECT_FALSE(response->was_npn_negotiated); 256 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1, 257 response->connection_info); 258 } 259 260 void CheckResponseData(HttpNetworkTransaction* trans, 261 const std::string& expected) { 262 std::string response_data; 263 ASSERT_EQ(OK, ReadTransaction(trans, &response_data)); 264 EXPECT_EQ(expected, response_data); 265 } 266 267 void RunTransaction(HttpNetworkTransaction* trans) { 268 TestCompletionCallback callback; 269 int rv = trans->Start(&request_, callback.callback(), net_log_.bound()); 270 EXPECT_EQ(ERR_IO_PENDING, rv); 271 EXPECT_EQ(OK, callback.WaitForResult()); 272 } 273 274 void SendRequestAndExpectHttpResponse(const std::string& expected) { 275 scoped_ptr<HttpNetworkTransaction> trans( 276 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get())); 277 RunTransaction(trans.get()); 278 CheckWasHttpResponse(trans); 279 CheckResponseData(trans.get(), expected); 280 } 281 282 void SendRequestAndExpectQuicResponse(const std::string& expected) { 283 scoped_ptr<HttpNetworkTransaction> trans( 284 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get())); 285 RunTransaction(trans.get()); 286 CheckWasQuicResponse(trans); 287 CheckResponseData(trans.get(), expected); 288 } 289 290 void AddQuicAlternateProtocolMapping( 291 MockCryptoClientStream::HandshakeMode handshake_mode) { 292 crypto_client_stream_factory_.set_handshake_mode(handshake_mode); 293 session_->http_server_properties()->SetAlternateProtocol( 294 HostPortPair::FromURL(request_.url), 80, QUIC); 295 } 296 297 void ExpectBrokenAlternateProtocolMapping() { 298 ASSERT_TRUE(session_->http_server_properties()->HasAlternateProtocol( 299 HostPortPair::FromURL(request_.url))); 300 const PortAlternateProtocolPair alternate = 301 session_->http_server_properties()->GetAlternateProtocol( 302 HostPortPair::FromURL(request_.url)); 303 EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol); 304 } 305 306 void AddHangingNonAlternateProtocolSocketData() { 307 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING); 308 StaticSocketDataProvider data(NULL, 0, NULL, 0); 309 data.set_connect_data(never_finishing_connect); 310 socket_factory_.AddSocketDataProvider(&data); 311 } 312 313 QuicPacketHeader header_; 314 scoped_refptr<HttpNetworkSession> session_; 315 MockClientSocketFactory socket_factory_; 316 MockCryptoClientStreamFactory crypto_client_stream_factory_; 317 MockClock* clock_; // Owned by QuicStreamFactory after CreateSession. 318 MockHostResolver host_resolver_; 319 MockCertVerifier cert_verifier_; 320 TransportSecurityState transport_security_state_; 321 scoped_refptr<SSLConfigServiceDefaults> ssl_config_service_; 322 scoped_ptr<ProxyService> proxy_service_; 323 scoped_ptr<QuicSpdyCompressor> compressor_; 324 scoped_ptr<HttpAuthHandlerFactory> auth_handler_factory_; 325 MockRandom random_generator_; 326 HttpServerPropertiesImpl http_server_properties; 327 HttpNetworkSession::Params params_; 328 HttpRequestInfo request_; 329 CapturingBoundNetLog net_log_; 330}; 331 332TEST_F(QuicNetworkTransactionTest, ForceQuic) { 333 params_.origin_to_force_quic_on = 334 HostPortPair::FromString("www.google.com:80"); 335 336 QuicStreamId stream_id = 3; 337 scoped_ptr<QuicEncryptedPacket> req( 338 ConstructDataPacket(1, stream_id, true, true, 0, 339 GetRequestString("GET", "/"))); 340 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0)); 341 342 MockWrite quic_writes[] = { 343 MockWrite(SYNCHRONOUS, req->data(), req->length()), 344 MockWrite(SYNCHRONOUS, ack->data(), ack->length()), 345 }; 346 347 scoped_ptr<QuicEncryptedPacket> resp( 348 ConstructDataPacket( 349 1, stream_id, false, true, 0, GetResponseString("200 OK", "hello!"))); 350 MockRead quic_reads[] = { 351 MockRead(SYNCHRONOUS, resp->data(), resp->length()), 352 MockRead(ASYNC, OK), // EOF 353 }; 354 355 DelayedSocketData quic_data( 356 1, // wait for one write to finish before reading. 357 quic_reads, arraysize(quic_reads), 358 quic_writes, arraysize(quic_writes)); 359 360 socket_factory_.AddSocketDataProvider(&quic_data); 361 362 // The non-alternate protocol job needs to hang in order to guarantee that 363 // the alternate-protocol job will "win". 364 AddHangingNonAlternateProtocolSocketData(); 365 366 CreateSession(); 367 368 SendRequestAndExpectQuicResponse("hello!"); 369 370 // Check that the NetLog was filled reasonably. 371 net::CapturingNetLog::CapturedEntryList entries; 372 net_log_.GetEntries(&entries); 373 EXPECT_LT(0u, entries.size()); 374 375 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED. 376 int pos = net::ExpectLogContainsSomewhere( 377 entries, 0, 378 net::NetLog::TYPE_QUIC_SESSION_PACKET_RECEIVED, 379 net::NetLog::PHASE_NONE); 380 EXPECT_LT(0, pos); 381 382 // ... and also a TYPE_QUIC_SESSION_PACKET_HEADER_RECEIVED. 383 pos = net::ExpectLogContainsSomewhere( 384 entries, 0, 385 net::NetLog::TYPE_QUIC_SESSION_PACKET_HEADER_RECEIVED, 386 net::NetLog::PHASE_NONE); 387 EXPECT_LT(0, pos); 388 389 std::string packet_sequence_number; 390 ASSERT_TRUE(entries[pos].GetStringValue( 391 "packet_sequence_number", &packet_sequence_number)); 392 EXPECT_EQ("1", packet_sequence_number); 393 394 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED. 395 pos = net::ExpectLogContainsSomewhere( 396 entries, 0, 397 net::NetLog::TYPE_QUIC_SESSION_STREAM_FRAME_RECEIVED, 398 net::NetLog::PHASE_NONE); 399 EXPECT_LT(0, pos); 400 401 int log_stream_id; 402 ASSERT_TRUE(entries[pos].GetIntegerValue("stream_id", &log_stream_id)); 403 EXPECT_EQ(stream_id, static_cast<QuicStreamId>(log_stream_id)); 404} 405 406TEST_F(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) { 407 params_.origin_to_force_quic_on = 408 HostPortPair::FromString("www.google.com:80"); 409 410 MockRead quic_reads[] = { 411 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED), 412 }; 413 StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads), 414 NULL, 0); 415 socket_factory_.AddSocketDataProvider(&quic_data); 416 417 CreateSession(); 418 419 scoped_ptr<HttpNetworkTransaction> trans( 420 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get())); 421 TestCompletionCallback callback; 422 int rv = trans->Start(&request_, callback.callback(), net_log_.bound()); 423 EXPECT_EQ(ERR_IO_PENDING, rv); 424 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, callback.WaitForResult()); 425} 426 427TEST_F(QuicNetworkTransactionTest, DoNotForceQuicForHttps) { 428 // Attempt to "force" quic on 443, which will not be honored. 429 params_.origin_to_force_quic_on = 430 HostPortPair::FromString("www.google.com:443"); 431 432 MockRead http_reads[] = { 433 MockRead("HTTP/1.1 200 OK\r\n\r\n"), 434 MockRead("hello world"), 435 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 436 MockRead(ASYNC, OK) 437 }; 438 439 StaticSocketDataProvider data(http_reads, arraysize(http_reads), NULL, 0); 440 socket_factory_.AddSocketDataProvider(&data); 441 SSLSocketDataProvider ssl(ASYNC, OK); 442 socket_factory_.AddSSLSocketDataProvider(&ssl); 443 444 CreateSession(); 445 446 SendRequestAndExpectHttpResponse("hello world"); 447} 448 449TEST_F(QuicNetworkTransactionTest, UseAlternateProtocolForQuic) { 450 HttpStreamFactory::set_use_alternate_protocols(true); 451 HttpStreamFactory::SetNextProtos(QuicNextProtos()); 452 453 MockRead http_reads[] = { 454 MockRead("HTTP/1.1 200 OK\r\n"), 455 MockRead(kQuicAlternateProtocolHttpHeader), 456 MockRead("hello world"), 457 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 458 MockRead(ASYNC, OK) 459 }; 460 461 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), 462 NULL, 0); 463 socket_factory_.AddSocketDataProvider(&http_data); 464 465 scoped_ptr<QuicEncryptedPacket> req( 466 ConstructDataPacket(1, 3, true, true, 0, GetRequestString("GET", "/"))); 467 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0)); 468 469 MockWrite quic_writes[] = { 470 MockWrite(SYNCHRONOUS, req->data(), req->length()), 471 MockWrite(SYNCHRONOUS, ack->data(), ack->length()), 472 }; 473 474 scoped_ptr<QuicEncryptedPacket> resp( 475 ConstructDataPacket( 476 1, 3, false, true, 0, GetResponseString("200 OK", "hello!"))); 477 MockRead quic_reads[] = { 478 MockRead(SYNCHRONOUS, resp->data(), resp->length()), 479 MockRead(ASYNC, OK), // EOF 480 }; 481 482 DelayedSocketData quic_data( 483 1, // wait for one write to finish before reading. 484 quic_reads, arraysize(quic_reads), 485 quic_writes, arraysize(quic_writes)); 486 487 socket_factory_.AddSocketDataProvider(&quic_data); 488 489 // The non-alternate protocol job needs to hang in order to guarantee that 490 // the alternate-protocol job will "win". 491 AddHangingNonAlternateProtocolSocketData(); 492 493 CreateSession(); 494 495 SendRequestAndExpectHttpResponse("hello world"); 496 SendRequestAndExpectQuicResponse("hello!"); 497} 498 499TEST_F(QuicNetworkTransactionTest, DontUseAlternateProtocolForQuicHttps) { 500 HttpStreamFactory::set_use_alternate_protocols(true); 501 HttpStreamFactory::SetNextProtos(QuicNextProtos()); 502 503 MockRead http_reads[] = { 504 MockRead("HTTP/1.1 200 OK\r\n"), 505 MockRead("Content-length: 11\r\n"), 506 MockRead(kQuicAlternateProtocolHttpHeader), 507 MockRead("hello world"), 508 509 MockRead("HTTP/1.1 200 OK\r\n"), 510 MockRead("Content-length: 6\r\n"), 511 MockRead(kQuicAlternateProtocolHttpHeader), 512 MockRead("hello!"), 513 }; 514 515 StaticSocketDataProvider data(http_reads, arraysize(http_reads), NULL, 0); 516 socket_factory_.AddSocketDataProvider(&data); 517 SSLSocketDataProvider ssl(ASYNC, OK); 518 socket_factory_.AddSSLSocketDataProvider(&ssl); 519 520 request_.url = GURL("https://www.google.com/"); 521 522 CreateSession(); 523 524 SendRequestAndExpectHttpResponse("hello world"); 525 SendRequestAndExpectHttpResponse("hello!"); 526} 527 528TEST_F(QuicNetworkTransactionTest, ZeroRTT) { 529 HttpStreamFactory::set_use_alternate_protocols(true); 530 HttpStreamFactory::SetNextProtos(QuicNextProtos()); 531 532 scoped_ptr<QuicEncryptedPacket> req( 533 ConstructDataPacket(1, 3, true, true, 0, GetRequestString("GET", "/"))); 534 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0)); 535 536 MockWrite quic_writes[] = { 537 MockWrite(SYNCHRONOUS, req->data(), req->length()), 538 MockWrite(SYNCHRONOUS, ack->data(), ack->length()), 539 }; 540 541 scoped_ptr<QuicEncryptedPacket> resp( 542 ConstructDataPacket( 543 1, 3, false, true, 0, GetResponseString("200 OK", "hello!"))); 544 MockRead quic_reads[] = { 545 MockRead(SYNCHRONOUS, resp->data(), resp->length()), 546 MockRead(ASYNC, OK), // EOF 547 }; 548 549 DelayedSocketData quic_data( 550 1, // wait for one write to finish before reading. 551 quic_reads, arraysize(quic_reads), 552 quic_writes, arraysize(quic_writes)); 553 554 socket_factory_.AddSocketDataProvider(&quic_data); 555 556 CreateSession(); 557 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT); 558 SendRequestAndExpectQuicResponse("hello!"); 559} 560 561TEST_F(QuicNetworkTransactionTest, BrokenAlternateProtocol) { 562 HttpStreamFactory::set_use_alternate_protocols(true); 563 HttpStreamFactory::SetNextProtos(QuicNextProtos()); 564 565 // Alternate-protocol job 566 scoped_ptr<QuicEncryptedPacket> close(ConstructConnectionClosePacket(1)); 567 MockRead quic_reads[] = { 568 MockRead(ASYNC, close->data(), close->length()), 569 MockRead(ASYNC, OK), // EOF 570 }; 571 StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads), 572 NULL, 0); 573 socket_factory_.AddSocketDataProvider(&quic_data); 574 575 // Main job which will succeed even though the alternate job fails. 576 MockRead http_reads[] = { 577 MockRead("HTTP/1.1 200 OK\r\n\r\n"), 578 MockRead("hello from http"), 579 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 580 MockRead(ASYNC, OK) 581 }; 582 583 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), 584 NULL, 0); 585 socket_factory_.AddSocketDataProvider(&http_data); 586 587 CreateSession(); 588 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START); 589 SendRequestAndExpectHttpResponse("hello from http"); 590 ExpectBrokenAlternateProtocolMapping(); 591} 592 593TEST_F(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) { 594 HttpStreamFactory::set_use_alternate_protocols(true); 595 HttpStreamFactory::SetNextProtos(QuicNextProtos()); 596 597 // Alternate-protocol job 598 MockRead quic_reads[] = { 599 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED), 600 }; 601 StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads), 602 NULL, 0); 603 socket_factory_.AddSocketDataProvider(&quic_data); 604 605 // Main job which will succeed even though the alternate job fails. 606 MockRead http_reads[] = { 607 MockRead("HTTP/1.1 200 OK\r\n\r\n"), 608 MockRead("hello from http"), 609 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 610 MockRead(ASYNC, OK) 611 }; 612 613 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), 614 NULL, 0); 615 socket_factory_.AddSocketDataProvider(&http_data); 616 617 CreateSession(); 618 619 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START); 620 SendRequestAndExpectHttpResponse("hello from http"); 621 ExpectBrokenAlternateProtocolMapping(); 622} 623 624} // namespace test 625} // namespace net 626