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