blob: dd0bdb7b28a289caea4416d195bd2260be7397f1 [file] [log] [blame]
[email protected]61a527782013-02-21 03:58:001// 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
[email protected]1e960032013-12-20 19:00:205#include <vector>
6
[email protected]61a527782013-02-21 03:58:007#include "base/basictypes.h"
8#include "base/compiler_specific.h"
9#include "base/memory/scoped_ptr.h"
[email protected]98b20ce2013-05-10 05:55:2610#include "base/stl_util.h"
11#include "net/base/capturing_net_log.h"
12#include "net/base/net_log_unittest.h"
[email protected]61a527782013-02-21 03:58:0013#include "net/base/test_completion_callback.h"
[email protected]6e7845ae2013-03-29 21:48:1114#include "net/cert/mock_cert_verifier.h"
[email protected]f2cb3cf2013-03-21 01:40:5315#include "net/dns/mock_host_resolver.h"
[email protected]61a527782013-02-21 03:58:0016#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_unittest.h"
[email protected]b1c988b2013-06-13 06:48:1123#include "net/http/transport_security_state.h"
[email protected]61a527782013-02-21 03:58:0024#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"
[email protected]24e5bc52013-09-18 15:36:5830#include "net/quic/quic_http_utils.h"
[email protected]ed3fc15d2013-03-08 18:37:4431#include "net/quic/test_tools/crypto_test_utils.h"
[email protected]61a527782013-02-21 03:58:0032#include "net/quic/test_tools/mock_clock.h"
[email protected]e8ff26842013-03-22 21:02:0533#include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
[email protected]61a527782013-02-21 03:58:0034#include "net/quic/test_tools/mock_random.h"
[email protected]1e960032013-12-20 19:00:2035#include "net/quic/test_tools/quic_test_packet_maker.h"
[email protected]61a527782013-02-21 03:58:0036#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"
[email protected]536fd0b2013-03-14 17:41:5743#include "net/ssl/ssl_config_service_defaults.h"
[email protected]61a527782013-02-21 03:58:0044#include "testing/gtest/include/gtest/gtest.h"
45#include "testing/platform_test.h"
46
47//-----------------------------------------------------------------------------
48
49namespace {
50
51// This is the expected return from a current server advertising QUIC.
52static const char kQuicAlternateProtocolHttpHeader[] =
[email protected]4ff65372013-06-21 05:45:4653 "Alternate-Protocol: 80:quic\r\n\r\n";
[email protected]6d1b4ed2013-07-10 03:57:5454static const char kQuicAlternateProtocolHttpsHeader[] =
55 "Alternate-Protocol: 443:quic\r\n\r\n";
[email protected]1e960032013-12-20 19:00:2056
[email protected]61a527782013-02-21 03:58:0057} // namespace
58
59namespace net {
60namespace test {
61
[email protected]1e960032013-12-20 19:00:2062// Helper class to encapsulate MockReads and MockWrites for QUIC.
63// Simplify ownership issues and the interaction with the MockSocketFactory.
64class MockQuicData {
65 public:
66 ~MockQuicData() {
67 STLDeleteElements(&packets_);
68 }
69
70 void AddRead(scoped_ptr<QuicEncryptedPacket> packet) {
71 reads_.push_back(MockRead(SYNCHRONOUS, packet->data(), packet->length(),
72 sequence_number_++));
73 packets_.push_back(packet.release());
74 }
75
76 void AddRead(IoMode mode, int rv) {
77 reads_.push_back(MockRead(mode, rv));
78 }
79
80 void AddWrite(scoped_ptr<QuicEncryptedPacket> packet) {
81 writes_.push_back(MockWrite(SYNCHRONOUS, packet->data(), packet->length(),
82 sequence_number_++));
83 packets_.push_back(packet.release());
84 }
85
86 void AddDelayedSocketDataToFactory(MockClientSocketFactory* factory,
87 size_t delay) {
88 MockRead* reads = reads_.empty() ? NULL : &reads_[0];
89 MockWrite* writes = writes_.empty() ? NULL : &writes_[0];
90 socket_data_.reset(new DelayedSocketData(
91 delay, reads, reads_.size(), writes, writes_.size()));
92 factory->AddSocketDataProvider(socket_data_.get());
93 }
94
95 private:
96 std::vector<QuicEncryptedPacket*> packets_;
97 std::vector<MockWrite> writes_;
98 std::vector<MockRead> reads_;
99 size_t sequence_number_;
100 scoped_ptr<SocketDataProvider> socket_data_;
101};
102
103class QuicNetworkTransactionTest
104 : public PlatformTest,
105 public testing::WithParamInterface<QuicVersion> {
[email protected]61a527782013-02-21 03:58:00106 protected:
[email protected]1c04f9522013-02-21 20:32:43107 QuicNetworkTransactionTest()
[email protected]1e960032013-12-20 19:00:20108 : maker_(GetParam(), 0),
109 clock_(new MockClock),
[email protected]1c04f9522013-02-21 20:32:43110 ssl_config_service_(new SSLConfigServiceDefaults),
111 proxy_service_(ProxyService::CreateDirect()),
112 auth_handler_factory_(
[email protected]dda75ab2013-06-22 22:43:30113 HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
[email protected]457d6952013-12-13 09:24:58114 random_generator_(0),
[email protected]dda75ab2013-06-22 22:43:30115 hanging_data_(NULL, 0, NULL, 0) {
[email protected]aa9b14d2013-05-10 23:45:19116 request_.method = "GET";
117 request_.url = GURL("http://www.google.com/");
118 request_.load_flags = 0;
[email protected]1c04f9522013-02-21 20:32:43119 }
[email protected]61a527782013-02-21 03:58:00120
121 virtual void SetUp() {
122 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34123 base::MessageLoop::current()->RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00124 }
125
126 virtual void TearDown() {
127 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
128 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:34129 base::MessageLoop::current()->RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00130 PlatformTest::TearDown();
131 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34132 base::MessageLoop::current()->RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00133 HttpStreamFactory::set_use_alternate_protocols(false);
[email protected]0ce3af82013-07-22 16:17:16134 HttpStreamFactory::SetNextProtos(std::vector<NextProto>());
[email protected]61a527782013-02-21 03:58:00135 }
136
[email protected]61a527782013-02-21 03:58:00137 scoped_ptr<QuicEncryptedPacket> ConstructRstPacket(
138 QuicPacketSequenceNumber num,
139 QuicStreamId stream_id) {
[email protected]1e960032013-12-20 19:00:20140 return maker_.MakeRstPacket(
141 num, false, stream_id, QUIC_STREAM_NO_ERROR);
[email protected]61a527782013-02-21 03:58:00142 }
143
[email protected]3316d422013-05-03 21:45:30144 scoped_ptr<QuicEncryptedPacket> ConstructConnectionClosePacket(
145 QuicPacketSequenceNumber num) {
[email protected]1e960032013-12-20 19:00:20146 return maker_.MakeConnectionClosePacket(num);
[email protected]3316d422013-05-03 21:45:30147 }
148
[email protected]61a527782013-02-21 03:58:00149 scoped_ptr<QuicEncryptedPacket> ConstructAckPacket(
150 QuicPacketSequenceNumber largest_received,
151 QuicPacketSequenceNumber least_unacked) {
[email protected]1e960032013-12-20 19:00:20152 return maker_.MakeAckPacket(2, largest_received, least_unacked, true);
153 }
[email protected]61a527782013-02-21 03:58:00154
[email protected]1e960032013-12-20 19:00:20155 SpdyHeaderBlock GetRequestHeaders(const std::string& method,
156 const std::string& scheme,
157 const std::string& path) {
158 return maker_.GetRequestHeaders(method, scheme, path);
[email protected]61a527782013-02-21 03:58:00159 }
160
161 std::string GetRequestString(const std::string& method,
[email protected]6d1b4ed2013-07-10 03:57:54162 const std::string& scheme,
[email protected]61a527782013-02-21 03:58:00163 const std::string& path) {
[email protected]1e960032013-12-20 19:00:20164 return maker_.GetRequestString(method, scheme, path);
165 }
166
167 SpdyHeaderBlock GetResponseHeaders(const std::string& status) {
168 return maker_.GetResponseHeaders(status);
[email protected]61a527782013-02-21 03:58:00169 }
170
171 std::string GetResponseString(const std::string& status,
172 const std::string& body) {
[email protected]1e960032013-12-20 19:00:20173 return maker_.GetResponseString(status, body);
[email protected]61a527782013-02-21 03:58:00174 }
175
[email protected]1e960032013-12-20 19:00:20176 scoped_ptr<QuicEncryptedPacket> ConstructDataPacket(
[email protected]61a527782013-02-21 03:58:00177 QuicPacketSequenceNumber sequence_number,
[email protected]98b20ce2013-05-10 05:55:26178 QuicStreamId stream_id,
[email protected]e8ff26842013-03-22 21:02:05179 bool should_include_version,
[email protected]61a527782013-02-21 03:58:00180 bool fin,
181 QuicStreamOffset offset,
182 base::StringPiece data) {
[email protected]1e960032013-12-20 19:00:20183 return maker_.MakeDataPacket(
184 sequence_number, stream_id, should_include_version, fin, offset, data);
[email protected]61a527782013-02-21 03:58:00185 }
186
[email protected]1e960032013-12-20 19:00:20187 scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket(
188 QuicPacketSequenceNumber sequence_number,
189 QuicStreamId stream_id,
190 bool should_include_version,
191 bool fin,
192 const SpdyHeaderBlock& headers) {
193 return maker_.MakeRequestHeadersPacket(
194 sequence_number, stream_id, should_include_version, fin, headers);
[email protected]61a527782013-02-21 03:58:00195 }
196
[email protected]1e960032013-12-20 19:00:20197 scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket(
198 QuicPacketSequenceNumber sequence_number,
199 QuicStreamId stream_id,
200 bool should_include_version,
201 bool fin,
202 const SpdyHeaderBlock& headers) {
203 return maker_.MakeResponseHeadersPacket(
204 sequence_number, stream_id, should_include_version, fin, headers);
[email protected]61a527782013-02-21 03:58:00205 }
206
207 void CreateSession() {
[email protected]dda75ab2013-06-22 22:43:30208 CreateSessionWithFactory(&socket_factory_);
209 }
210
211 void CreateSessionWithFactory(ClientSocketFactory* socket_factory) {
[email protected]4dca587c2013-03-07 16:54:47212 params_.enable_quic = true;
213 params_.quic_clock = clock_;
214 params_.quic_random = &random_generator_;
[email protected]dda75ab2013-06-22 22:43:30215 params_.client_socket_factory = socket_factory;
[email protected]e8ff26842013-03-22 21:02:05216 params_.quic_crypto_client_stream_factory = &crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:43217 params_.host_resolver = &host_resolver_;
218 params_.cert_verifier = &cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:11219 params_.transport_security_state = &transport_security_state_;
[email protected]1c04f9522013-02-21 20:32:43220 params_.proxy_service = proxy_service_.get();
221 params_.ssl_config_service = ssl_config_service_.get();
222 params_.http_auth_handler_factory = auth_handler_factory_.get();
[email protected]30d4c022013-07-18 22:58:16223 params_.http_server_properties = http_server_properties.GetWeakPtr();
[email protected]1e960032013-12-20 19:00:20224 params_.quic_supported_versions = SupportedVersions(GetParam());
[email protected]61a527782013-02-21 03:58:00225
226 session_ = new HttpNetworkSession(params_);
[email protected]11c05872013-08-20 02:04:12227 session_->quic_stream_factory()->set_require_confirmation(false);
[email protected]61a527782013-02-21 03:58:00228 }
229
[email protected]aa9b14d2013-05-10 23:45:19230 void CheckWasQuicResponse(const scoped_ptr<HttpNetworkTransaction>& trans) {
231 const HttpResponseInfo* response = trans->GetResponseInfo();
232 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:50233 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]aa9b14d2013-05-10 23:45:19234 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
235 EXPECT_TRUE(response->was_fetched_via_spdy);
236 EXPECT_TRUE(response->was_npn_negotiated);
237 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_QUIC1_SPDY3,
238 response->connection_info);
239 }
240
241 void CheckWasHttpResponse(const scoped_ptr<HttpNetworkTransaction>& trans) {
242 const HttpResponseInfo* response = trans->GetResponseInfo();
243 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:50244 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]aa9b14d2013-05-10 23:45:19245 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
246 EXPECT_FALSE(response->was_fetched_via_spdy);
247 EXPECT_FALSE(response->was_npn_negotiated);
248 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1,
249 response->connection_info);
250 }
251
252 void CheckResponseData(HttpNetworkTransaction* trans,
253 const std::string& expected) {
254 std::string response_data;
255 ASSERT_EQ(OK, ReadTransaction(trans, &response_data));
256 EXPECT_EQ(expected, response_data);
257 }
258
259 void RunTransaction(HttpNetworkTransaction* trans) {
260 TestCompletionCallback callback;
261 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
262 EXPECT_EQ(ERR_IO_PENDING, rv);
263 EXPECT_EQ(OK, callback.WaitForResult());
264 }
265
266 void SendRequestAndExpectHttpResponse(const std::string& expected) {
267 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:50268 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
[email protected]aa9b14d2013-05-10 23:45:19269 RunTransaction(trans.get());
270 CheckWasHttpResponse(trans);
271 CheckResponseData(trans.get(), expected);
272 }
273
274 void SendRequestAndExpectQuicResponse(const std::string& expected) {
275 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:50276 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
[email protected]aa9b14d2013-05-10 23:45:19277 RunTransaction(trans.get());
278 CheckWasQuicResponse(trans);
279 CheckResponseData(trans.get(), expected);
280 }
281
282 void AddQuicAlternateProtocolMapping(
283 MockCryptoClientStream::HandshakeMode handshake_mode) {
284 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
285 session_->http_server_properties()->SetAlternateProtocol(
286 HostPortPair::FromURL(request_.url), 80, QUIC);
287 }
288
289 void ExpectBrokenAlternateProtocolMapping() {
290 ASSERT_TRUE(session_->http_server_properties()->HasAlternateProtocol(
291 HostPortPair::FromURL(request_.url)));
292 const PortAlternateProtocolPair alternate =
293 session_->http_server_properties()->GetAlternateProtocol(
294 HostPortPair::FromURL(request_.url));
295 EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol);
296 }
297
298 void AddHangingNonAlternateProtocolSocketData() {
[email protected]dda75ab2013-06-22 22:43:30299 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
300 hanging_data_.set_connect_data(hanging_connect);
301 socket_factory_.AddSocketDataProvider(&hanging_data_);
[email protected]aa9b14d2013-05-10 23:45:19302 }
303
[email protected]1e960032013-12-20 19:00:20304 QuicTestPacketMaker maker_;
[email protected]61a527782013-02-21 03:58:00305 scoped_refptr<HttpNetworkSession> session_;
306 MockClientSocketFactory socket_factory_;
[email protected]e8ff26842013-03-22 21:02:05307 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:43308 MockClock* clock_; // Owned by QuicStreamFactory after CreateSession.
309 MockHostResolver host_resolver_;
310 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:11311 TransportSecurityState transport_security_state_;
[email protected]1c04f9522013-02-21 20:32:43312 scoped_refptr<SSLConfigServiceDefaults> ssl_config_service_;
313 scoped_ptr<ProxyService> proxy_service_;
314 scoped_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
[email protected]61a527782013-02-21 03:58:00315 MockRandom random_generator_;
316 HttpServerPropertiesImpl http_server_properties;
317 HttpNetworkSession::Params params_;
[email protected]aa9b14d2013-05-10 23:45:19318 HttpRequestInfo request_;
319 CapturingBoundNetLog net_log_;
[email protected]dda75ab2013-06-22 22:43:30320 StaticSocketDataProvider hanging_data_;
[email protected]61a527782013-02-21 03:58:00321};
322
[email protected]1e960032013-12-20 19:00:20323INSTANTIATE_TEST_CASE_P(Version, QuicNetworkTransactionTest,
324 ::testing::ValuesIn(QuicSupportedVersions()));
325
326TEST_P(QuicNetworkTransactionTest, ForceQuic) {
[email protected]49e85332013-06-04 04:18:03327 params_.origin_to_force_quic_on =
328 HostPortPair::FromString("www.google.com:80");
[email protected]4dca587c2013-03-07 16:54:47329
[email protected]1e960032013-12-20 19:00:20330 QuicStreamId stream_id = GetParam() > QUIC_VERSION_12 ? 5 : 3;
331 MockQuicData mock_quic_data;
332 if (GetParam() > QUIC_VERSION_12) {
333 mock_quic_data.AddWrite(
334 ConstructRequestHeadersPacket(1, stream_id, true, true,
335 GetRequestHeaders("GET", "http", "/")));
336 mock_quic_data.AddRead(
337 ConstructResponseHeadersPacket(1, stream_id, false, false,
338 GetResponseHeaders("200 OK")));
339 mock_quic_data.AddRead(
340 ConstructDataPacket(2, stream_id, false, true, 0, "hello!"));
341 mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
342 } else {
343 mock_quic_data.AddWrite(
344 ConstructDataPacket(1, stream_id, true, true, 0,
345 GetRequestString("GET", "http", "/")));
346 mock_quic_data.AddRead(
347 ConstructDataPacket(1, stream_id, false, true, 0,
348 GetResponseString("200 OK", "hello!")));
349 mock_quic_data.AddWrite(ConstructAckPacket(1, 0));
350 }
351 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
[email protected]4dca587c2013-03-07 16:54:47352
[email protected]1e960032013-12-20 19:00:20353 mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
[email protected]4dca587c2013-03-07 16:54:47354
[email protected]aa9b14d2013-05-10 23:45:19355 // The non-alternate protocol job needs to hang in order to guarantee that
356 // the alternate-protocol job will "win".
357 AddHangingNonAlternateProtocolSocketData();
[email protected]4dca587c2013-03-07 16:54:47358
359 CreateSession();
[email protected]4dca587c2013-03-07 16:54:47360
[email protected]aa9b14d2013-05-10 23:45:19361 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:47362
[email protected]98b20ce2013-05-10 05:55:26363 // Check that the NetLog was filled reasonably.
364 net::CapturingNetLog::CapturedEntryList entries;
[email protected]aa9b14d2013-05-10 23:45:19365 net_log_.GetEntries(&entries);
[email protected]98b20ce2013-05-10 05:55:26366 EXPECT_LT(0u, entries.size());
367
368 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
369 int pos = net::ExpectLogContainsSomewhere(
370 entries, 0,
371 net::NetLog::TYPE_QUIC_SESSION_PACKET_RECEIVED,
372 net::NetLog::PHASE_NONE);
373 EXPECT_LT(0, pos);
374
375 // ... and also a TYPE_QUIC_SESSION_PACKET_HEADER_RECEIVED.
376 pos = net::ExpectLogContainsSomewhere(
377 entries, 0,
378 net::NetLog::TYPE_QUIC_SESSION_PACKET_HEADER_RECEIVED,
379 net::NetLog::PHASE_NONE);
380 EXPECT_LT(0, pos);
381
382 std::string packet_sequence_number;
383 ASSERT_TRUE(entries[pos].GetStringValue(
384 "packet_sequence_number", &packet_sequence_number));
385 EXPECT_EQ("1", packet_sequence_number);
386
387 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
388 pos = net::ExpectLogContainsSomewhere(
389 entries, 0,
390 net::NetLog::TYPE_QUIC_SESSION_STREAM_FRAME_RECEIVED,
391 net::NetLog::PHASE_NONE);
392 EXPECT_LT(0, pos);
393
394 int log_stream_id;
395 ASSERT_TRUE(entries[pos].GetIntegerValue("stream_id", &log_stream_id));
[email protected]1e960032013-12-20 19:00:20396 EXPECT_EQ(3, log_stream_id);
[email protected]4dca587c2013-03-07 16:54:47397}
398
[email protected]1e960032013-12-20 19:00:20399TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
[email protected]49e85332013-06-04 04:18:03400 params_.origin_to_force_quic_on =
401 HostPortPair::FromString("www.google.com:80");
[email protected]cebe3282013-05-22 23:49:30402
[email protected]1e960032013-12-20 19:00:20403 MockQuicData mock_quic_data;
404 mock_quic_data.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
405
406 mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 0);
[email protected]cebe3282013-05-22 23:49:30407
408 CreateSession();
409
410 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:50411 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
[email protected]cebe3282013-05-22 23:49:30412 TestCompletionCallback callback;
413 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
414 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0b2294d32013-08-02 00:46:36415 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]cebe3282013-05-22 23:49:30416}
417
[email protected]1e960032013-12-20 19:00:20418TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
[email protected]4dca587c2013-03-07 16:54:47419 // Attempt to "force" quic on 443, which will not be honored.
[email protected]49e85332013-06-04 04:18:03420 params_.origin_to_force_quic_on =
421 HostPortPair::FromString("www.google.com:443");
[email protected]4dca587c2013-03-07 16:54:47422
[email protected]aa9b14d2013-05-10 23:45:19423 MockRead http_reads[] = {
[email protected]4dca587c2013-03-07 16:54:47424 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
425 MockRead("hello world"),
426 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
427 MockRead(ASYNC, OK)
428 };
429
[email protected]aa9b14d2013-05-10 23:45:19430 StaticSocketDataProvider data(http_reads, arraysize(http_reads), NULL, 0);
[email protected]4dca587c2013-03-07 16:54:47431 socket_factory_.AddSocketDataProvider(&data);
432 SSLSocketDataProvider ssl(ASYNC, OK);
433 socket_factory_.AddSSLSocketDataProvider(&ssl);
434
[email protected]4dca587c2013-03-07 16:54:47435 CreateSession();
[email protected]4dca587c2013-03-07 16:54:47436
[email protected]aa9b14d2013-05-10 23:45:19437 SendRequestAndExpectHttpResponse("hello world");
[email protected]4dca587c2013-03-07 16:54:47438}
439
[email protected]1e960032013-12-20 19:00:20440TEST_P(QuicNetworkTransactionTest, UseAlternateProtocolForQuic) {
[email protected]b05bcaa32013-10-06 05:26:02441 HttpStreamFactory::EnableNpnSpdy3(); // Enables QUIC too.
[email protected]61a527782013-02-21 03:58:00442
[email protected]aa9b14d2013-05-10 23:45:19443 MockRead http_reads[] = {
[email protected]61a527782013-02-21 03:58:00444 MockRead("HTTP/1.1 200 OK\r\n"),
445 MockRead(kQuicAlternateProtocolHttpHeader),
446 MockRead("hello world"),
447 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
448 MockRead(ASYNC, OK)
449 };
450
[email protected]aa9b14d2013-05-10 23:45:19451 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
452 NULL, 0);
453 socket_factory_.AddSocketDataProvider(&http_data);
[email protected]61a527782013-02-21 03:58:00454
[email protected]1e960032013-12-20 19:00:20455 QuicStreamId stream_id = GetParam() > QUIC_VERSION_12 ? 5 : 3;
456 MockQuicData mock_quic_data;
457 if (GetParam() > QUIC_VERSION_12) {
458 mock_quic_data.AddWrite(
459 ConstructRequestHeadersPacket(1, stream_id, true, true,
460 GetRequestHeaders("GET", "http", "/")));
461 mock_quic_data.AddRead(
462 ConstructResponseHeadersPacket(1, stream_id, false, false,
463 GetResponseHeaders("200 OK")));
464 mock_quic_data.AddRead(
465 ConstructDataPacket(2, stream_id, false, true, 0, "hello!"));
466 mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
467 } else {
468 mock_quic_data.AddWrite(
469 ConstructDataPacket(1, stream_id, true, true, 0,
470 GetRequestString("GET", "http", "/")));
471 mock_quic_data.AddRead(
472 ConstructDataPacket(1, stream_id, false, true, 0,
473 GetResponseString("200 OK", "hello!")));
474 mock_quic_data.AddWrite(ConstructAckPacket(1, 0));
475 }
476 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
[email protected]61a527782013-02-21 03:58:00477
[email protected]1e960032013-12-20 19:00:20478 mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
[email protected]61a527782013-02-21 03:58:00479
[email protected]aa9b14d2013-05-10 23:45:19480 // The non-alternate protocol job needs to hang in order to guarantee that
481 // the alternate-protocol job will "win".
482 AddHangingNonAlternateProtocolSocketData();
[email protected]61a527782013-02-21 03:58:00483
484 CreateSession();
[email protected]61a527782013-02-21 03:58:00485
[email protected]aa9b14d2013-05-10 23:45:19486 SendRequestAndExpectHttpResponse("hello world");
487 SendRequestAndExpectQuicResponse("hello!");
[email protected]61a527782013-02-21 03:58:00488}
489
[email protected]1e960032013-12-20 19:00:20490TEST_P(QuicNetworkTransactionTest, UseAlternateProtocolForQuicForHttps) {
[email protected]6d1b4ed2013-07-10 03:57:54491 params_.origin_to_force_quic_on =
492 HostPortPair::FromString("www.google.com:443");
493 params_.enable_quic_https = true;
[email protected]b05bcaa32013-10-06 05:26:02494 HttpStreamFactory::EnableNpnSpdy3(); // Enables QUIC too.
[email protected]6d1b4ed2013-07-10 03:57:54495
496 MockRead http_reads[] = {
497 MockRead("HTTP/1.1 200 OK\r\n"),
498 MockRead(kQuicAlternateProtocolHttpsHeader),
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
[email protected]1e960032013-12-20 19:00:20508 QuicStreamId stream_id = GetParam() > QUIC_VERSION_12 ? 5 : 3;
509 MockQuicData mock_quic_data;
510 if (GetParam() > QUIC_VERSION_12) {
511 mock_quic_data.AddWrite(
512 ConstructRequestHeadersPacket(1, stream_id, true, true,
513 GetRequestHeaders("GET", "http", "/")));
514 mock_quic_data.AddRead(
515 ConstructResponseHeadersPacket(1, stream_id, false, false,
516 GetResponseHeaders("200 OK")));
517 mock_quic_data.AddRead(
518 ConstructDataPacket(2, stream_id, false, true, 0, "hello!"));
519 mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
520 } else {
521 mock_quic_data.AddWrite(
522 ConstructDataPacket(1, stream_id, true, true, 0,
523 GetRequestString("GET", "http", "/")));
524 mock_quic_data.AddRead(
525 ConstructDataPacket(1, stream_id, false, true, 0,
526 GetResponseString("200 OK", "hello!")));
527 mock_quic_data.AddWrite(ConstructAckPacket(1, 0));
528 }
529 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
[email protected]6d1b4ed2013-07-10 03:57:54530
[email protected]1e960032013-12-20 19:00:20531 mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
[email protected]6d1b4ed2013-07-10 03:57:54532
533 // The non-alternate protocol job needs to hang in order to guarantee that
534 // the alternate-protocol job will "win".
535 AddHangingNonAlternateProtocolSocketData();
536
537 CreateSession();
538
539 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
540 SendRequestAndExpectHttpResponse("hello world");
541}
542
[email protected]1e960032013-12-20 19:00:20543TEST_P(QuicNetworkTransactionTest, HungAlternateProtocol) {
[email protected]b05bcaa32013-10-06 05:26:02544 HttpStreamFactory::EnableNpnSpdy3(); // Enables QUIC too.
[email protected]dda75ab2013-06-22 22:43:30545 crypto_client_stream_factory_.set_handshake_mode(
546 MockCryptoClientStream::COLD_START);
547
548 MockWrite http_writes[] = {
549 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
550 MockWrite(SYNCHRONOUS, 1, "Host: www.google.com\r\n"),
551 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")
552 };
553
554 MockRead http_reads[] = {
555 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
556 MockRead(SYNCHRONOUS, 4, kQuicAlternateProtocolHttpHeader),
557 MockRead(SYNCHRONOUS, 5, "hello world"),
558 MockRead(SYNCHRONOUS, OK, 6)
559 };
560
561 DeterministicMockClientSocketFactory socket_factory;
562
563 DeterministicSocketData http_data(http_reads, arraysize(http_reads),
564 http_writes, arraysize(http_writes));
565 socket_factory.AddSocketDataProvider(&http_data);
566
567 // The QUIC transaction will not be allowed to complete.
568 MockWrite quic_writes[] = {
569 MockWrite(ASYNC, ERR_IO_PENDING, 0)
570 };
571 MockRead quic_reads[] = {
572 MockRead(ASYNC, ERR_IO_PENDING, 1),
573 };
574 DeterministicSocketData quic_data(quic_reads, arraysize(quic_reads),
575 quic_writes, arraysize(quic_writes));
576 socket_factory.AddSocketDataProvider(&quic_data);
577
578 // The HTTP transaction will complete.
579 DeterministicSocketData http_data2(http_reads, arraysize(http_reads),
580 http_writes, arraysize(http_writes));
581 socket_factory.AddSocketDataProvider(&http_data2);
582
583 CreateSessionWithFactory(&socket_factory);
584
585 // Run the first request.
586 http_data.StopAfter(arraysize(http_reads) + arraysize(http_writes));
587 SendRequestAndExpectHttpResponse("hello world");
588 ASSERT_TRUE(http_data.at_read_eof());
589 ASSERT_TRUE(http_data.at_write_eof());
590
591 // Now run the second request in which the QUIC socket hangs,
592 // and verify the the transaction continues over HTTP.
593 http_data2.StopAfter(arraysize(http_reads) + arraysize(http_writes));
594 SendRequestAndExpectHttpResponse("hello world");
595
596 ASSERT_TRUE(http_data2.at_read_eof());
597 ASSERT_TRUE(http_data2.at_write_eof());
598 ASSERT_TRUE(!quic_data.at_read_eof());
599 ASSERT_TRUE(!quic_data.at_write_eof());
600}
601
[email protected]1e960032013-12-20 19:00:20602TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
[email protected]b05bcaa32013-10-06 05:26:02603 HttpStreamFactory::EnableNpnSpdy3(); // Enables QUIC too.
[email protected]8ba81212013-05-03 13:11:48604
[email protected]1e960032013-12-20 19:00:20605 QuicStreamId stream_id = GetParam() > QUIC_VERSION_12 ? 5 : 3;
606 MockQuicData mock_quic_data;
607 if (GetParam() > QUIC_VERSION_12) {
608 mock_quic_data.AddWrite(
609 ConstructRequestHeadersPacket(1, stream_id, true, true,
610 GetRequestHeaders("GET", "http", "/")));
611 mock_quic_data.AddRead(
612 ConstructResponseHeadersPacket(1, stream_id, false, false,
613 GetResponseHeaders("200 OK")));
614 mock_quic_data.AddRead(
615 ConstructDataPacket(2, stream_id, false, true, 0, "hello!"));
616 mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
617 } else {
618 mock_quic_data.AddWrite(
619 ConstructDataPacket(1, stream_id, true, true, 0,
620 GetRequestString("GET", "http", "/")));
621 mock_quic_data.AddRead(
622 ConstructDataPacket(1, stream_id, false, true, 0,
623 GetResponseString("200 OK", "hello!")));
624 mock_quic_data.AddWrite(ConstructAckPacket(1, 0));
625 }
626 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
[email protected]8ba81212013-05-03 13:11:48627
[email protected]1e960032013-12-20 19:00:20628 mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
[email protected]8ba81212013-05-03 13:11:48629
[email protected]3a120a6b2013-06-25 01:08:27630 // The non-alternate protocol job needs to hang in order to guarantee that
631 // the alternate-protocol job will "win".
[email protected]dda75ab2013-06-22 22:43:30632 AddHangingNonAlternateProtocolSocketData();
633
[email protected]8ba81212013-05-03 13:11:48634 CreateSession();
[email protected]aa9b14d2013-05-10 23:45:19635 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
636 SendRequestAndExpectQuicResponse("hello!");
[email protected]8ba81212013-05-03 13:11:48637}
638
[email protected]1e960032013-12-20 19:00:20639TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
[email protected]b05bcaa32013-10-06 05:26:02640 HttpStreamFactory::EnableNpnSpdy3(); // Enables QUIC too.
[email protected]3a120a6b2013-06-25 01:08:27641
[email protected]1e960032013-12-20 19:00:20642 QuicStreamId stream_id = GetParam() > QUIC_VERSION_12 ? 5 : 3;
643 MockQuicData mock_quic_data;
644 if (GetParam() > QUIC_VERSION_12) {
645 mock_quic_data.AddWrite(
646 ConstructRequestHeadersPacket(1, stream_id, true, true,
647 GetRequestHeaders("GET", "http", "/")));
648 mock_quic_data.AddRead(
649 ConstructResponseHeadersPacket(1, stream_id, false, false,
650 GetResponseHeaders("200 OK")));
651 mock_quic_data.AddRead(
652 ConstructDataPacket(2, stream_id, false, true, 0, "hello!"));
653 mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
654 } else {
655 mock_quic_data.AddWrite(
656 ConstructDataPacket(1, stream_id, true, true, 0,
657 GetRequestString("GET", "http", "/")));
658 mock_quic_data.AddRead(
659 ConstructDataPacket(1, stream_id, false, true, 0,
660 GetResponseString("200 OK", "hello!")));
661 mock_quic_data.AddWrite(ConstructAckPacket(1, 0));
662 }
663 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
664 mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
[email protected]3a120a6b2013-06-25 01:08:27665
666 // In order for a new QUIC session to be established via alternate-protocol
667 // without racing an HTTP connection, we need the host resolution to happen
668 // synchronously.
669 host_resolver_.set_synchronous_mode(true);
670 host_resolver_.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
[email protected]5109c1952013-08-20 18:44:10671 HostResolver::RequestInfo info(HostPortPair("www.google.com", 80));
[email protected]3a120a6b2013-06-25 01:08:27672 AddressList address;
[email protected]5109c1952013-08-20 18:44:10673 host_resolver_.Resolve(info,
674 DEFAULT_PRIORITY,
675 &address,
676 CompletionCallback(),
677 NULL,
[email protected]3a120a6b2013-06-25 01:08:27678 net_log_.bound());
679
680 CreateSession();
681 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
682 SendRequestAndExpectQuicResponse("hello!");
683}
684
[email protected]1e960032013-12-20 19:00:20685TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
[email protected]b05bcaa32013-10-06 05:26:02686 HttpStreamFactory::EnableNpnSpdy3(); // Enables QUIC too.
[email protected]11c05872013-08-20 02:04:12687
[email protected]1e960032013-12-20 19:00:20688 QuicStreamId stream_id = GetParam() > QUIC_VERSION_12 ? 5 : 3;
689 MockQuicData mock_quic_data;
690 if (GetParam() > QUIC_VERSION_12) {
691 mock_quic_data.AddWrite(
692 ConstructRequestHeadersPacket(1, stream_id, true, true,
693 GetRequestHeaders("GET", "http", "/")));
694 mock_quic_data.AddRead(
695 ConstructResponseHeadersPacket(1, stream_id, false, false,
696 GetResponseHeaders("200 OK")));
697 mock_quic_data.AddRead(
698 ConstructDataPacket(2, stream_id, false, true, 0, "hello!"));
699 mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
700 } else {
701 mock_quic_data.AddWrite(
702 ConstructDataPacket(1, stream_id, true, true, 0,
703 GetRequestString("GET", "http", "/")));
704 mock_quic_data.AddRead(
705 ConstructDataPacket(1, stream_id, false, true, 0,
706 GetResponseString("200 OK", "hello!")));
707 mock_quic_data.AddWrite(ConstructAckPacket(1, 0));
708 }
709 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
710 mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
[email protected]11c05872013-08-20 02:04:12711
712 // The non-alternate protocol job needs to hang in order to guarantee that
713 // the alternate-protocol job will "win".
714 AddHangingNonAlternateProtocolSocketData();
715
716 // In order for a new QUIC session to be established via alternate-protocol
717 // without racing an HTTP connection, we need the host resolution to happen
718 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
719 // connection to the the server, in this test we require confirmation
720 // before encrypting so the HTTP job will still start.
721 host_resolver_.set_synchronous_mode(true);
722 host_resolver_.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
[email protected]5109c1952013-08-20 18:44:10723 HostResolver::RequestInfo info(HostPortPair("www.google.com", 80));
[email protected]11c05872013-08-20 02:04:12724 AddressList address;
[email protected]5109c1952013-08-20 18:44:10725 host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
726 CompletionCallback(), NULL, net_log_.bound());
[email protected]11c05872013-08-20 02:04:12727
728 CreateSession();
729 session_->quic_stream_factory()->set_require_confirmation(true);
730 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
731
732 scoped_ptr<HttpNetworkTransaction> trans(
733 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
734 TestCompletionCallback callback;
735 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
736 EXPECT_EQ(ERR_IO_PENDING, rv);
737
738 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
739 QuicSession::HANDSHAKE_CONFIRMED);
740 EXPECT_EQ(OK, callback.WaitForResult());
741}
742
[email protected]1e960032013-12-20 19:00:20743TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]b05bcaa32013-10-06 05:26:02744 HttpStreamFactory::EnableNpnSpdy3(); // Enables QUIC too.
[email protected]3316d422013-05-03 21:45:30745
[email protected]3316d422013-05-03 21:45:30746 // Alternate-protocol job
747 scoped_ptr<QuicEncryptedPacket> close(ConstructConnectionClosePacket(1));
748 MockRead quic_reads[] = {
749 MockRead(ASYNC, close->data(), close->length()),
750 MockRead(ASYNC, OK), // EOF
751 };
752 StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
753 NULL, 0);
754 socket_factory_.AddSocketDataProvider(&quic_data);
755
756 // Main job which will succeed even though the alternate job fails.
757 MockRead http_reads[] = {
758 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
759 MockRead("hello from http"),
760 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
761 MockRead(ASYNC, OK)
762 };
763
764 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
765 NULL, 0);
766 socket_factory_.AddSocketDataProvider(&http_data);
767
[email protected]3316d422013-05-03 21:45:30768 CreateSession();
[email protected]aa9b14d2013-05-10 23:45:19769 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
770 SendRequestAndExpectHttpResponse("hello from http");
771 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:30772}
773
[email protected]1e960032013-12-20 19:00:20774TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]b05bcaa32013-10-06 05:26:02775 HttpStreamFactory::EnableNpnSpdy3(); // Enables QUIC too.
[email protected]d03a66d2013-05-06 12:55:59776
[email protected]d03a66d2013-05-06 12:55:59777 // Alternate-protocol job
778 MockRead quic_reads[] = {
779 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
780 };
781 StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
782 NULL, 0);
783 socket_factory_.AddSocketDataProvider(&quic_data);
784
785 // Main job which will succeed even though the alternate job fails.
786 MockRead http_reads[] = {
787 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
788 MockRead("hello from http"),
789 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
790 MockRead(ASYNC, OK)
791 };
792
793 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
794 NULL, 0);
795 socket_factory_.AddSocketDataProvider(&http_data);
796
[email protected]d03a66d2013-05-06 12:55:59797 CreateSession();
[email protected]d03a66d2013-05-06 12:55:59798
[email protected]aa9b14d2013-05-10 23:45:19799 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
800 SendRequestAndExpectHttpResponse("hello from http");
801 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:59802}
803
[email protected]1e960032013-12-20 19:00:20804TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]b05bcaa32013-10-06 05:26:02805 HttpStreamFactory::EnableNpnSpdy3(); // Enables QUIC too.
[email protected]77c6c162013-08-17 02:57:45806
807 // Alternate-protocol job
808 MockRead quic_reads[] = {
809 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
810 };
811 StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
812 NULL, 0);
813 socket_factory_.AddSocketDataProvider(&quic_data);
814
815 AddHangingNonAlternateProtocolSocketData();
816
[email protected]4d283b32013-10-17 12:57:27817 // Final job that will proceed when the QUIC job fails.
818 MockRead http_reads[] = {
819 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
820 MockRead("hello from http"),
821 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
822 MockRead(ASYNC, OK)
823 };
824
825 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
826 NULL, 0);
827 socket_factory_.AddSocketDataProvider(&http_data);
828
[email protected]77c6c162013-08-17 02:57:45829 CreateSession();
830
831 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
832
[email protected]4d283b32013-10-17 12:57:27833 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:45834
835 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:27836
837 EXPECT_TRUE(quic_data.at_read_eof());
838 EXPECT_TRUE(quic_data.at_write_eof());
[email protected]77c6c162013-08-17 02:57:45839}
840
[email protected]4fee9672014-01-08 14:47:15841TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
842 HttpStreamFactory::EnableNpnSpdy3(); // Enables QUIC too.
843
844 QuicStreamId stream_id = GetParam() > QUIC_VERSION_12 ? 5 : 3;
845 MockQuicData mock_quic_data;
846 mock_quic_data.AddRead(ConstructConnectionClosePacket(1));
847 if (GetParam() > QUIC_VERSION_12) {
848 mock_quic_data.AddWrite(
849 ConstructRequestHeadersPacket(1, stream_id, true, true,
850 GetRequestHeaders("GET", "http", "/")));
851 mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
852 } else {
853 mock_quic_data.AddWrite(
854 ConstructDataPacket(1, stream_id, true, true, 0,
855 GetRequestString("GET", "http", "/")));
856 mock_quic_data.AddWrite(ConstructAckPacket(1, 0));
857 }
858 mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 0);
859
860 // When the QUIC connection fails, we will try the request again over HTTP.
861 MockRead http_reads[] = {
862 MockRead("HTTP/1.1 200 OK\r\n"),
863 MockRead(kQuicAlternateProtocolHttpHeader),
864 MockRead("hello world"),
865 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
866 MockRead(ASYNC, OK)
867 };
868
869 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
870 NULL, 0);
871 socket_factory_.AddSocketDataProvider(&http_data);
872
873 // In order for a new QUIC session to be established via alternate-protocol
874 // without racing an HTTP connection, we need the host resolution to happen
875 // synchronously.
876 host_resolver_.set_synchronous_mode(true);
877 host_resolver_.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
878 HostResolver::RequestInfo info(HostPortPair("www.google.com", 80));
879 AddressList address;
880 host_resolver_.Resolve(info,
881 DEFAULT_PRIORITY,
882 &address,
883 CompletionCallback(),
884 NULL,
885 net_log_.bound());
886
887 CreateSession();
888 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
889 SendRequestAndExpectHttpResponse("hello world");
890}
891
[email protected]61a527782013-02-21 03:58:00892} // namespace test
893} // namespace net