blob: 4df6ee015f7b6fdffdcb47e7eab29b5dd0797797 [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"
[email protected]61a527782013-02-21 03:58:0011#include "net/base/test_completion_callback.h"
[email protected]6e7845ae2013-03-29 21:48:1112#include "net/cert/mock_cert_verifier.h"
[email protected]f2cb3cf2013-03-21 01:40:5313#include "net/dns/mock_host_resolver.h"
[email protected]61a527782013-02-21 03:58:0014#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"
[email protected]c41737d2014-05-14 07:47:1920#include "net/http/http_transaction_test_util.h"
[email protected]b1c988b2013-06-13 06:48:1121#include "net/http/transport_security_state.h"
eroman87c53d62015-04-02 06:51:0722#include "net/log/capturing_net_log.h"
23#include "net/log/net_log_unittest.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]287d9412014-07-08 23:01:0054static const char kQuicAlternateProtocol50pctHttpHeader[] =
55 "Alternate-Protocol: 80:quic,p=.5\r\n\r\n";
[email protected]6d1b4ed2013-07-10 03:57:5456static const char kQuicAlternateProtocolHttpsHeader[] =
57 "Alternate-Protocol: 443:quic\r\n\r\n";
[email protected]1e960032013-12-20 19:00:2058
[email protected]61a527782013-02-21 03:58:0059} // namespace
60
61namespace net {
62namespace test {
63
[email protected]1e960032013-12-20 19:00:2064// Helper class to encapsulate MockReads and MockWrites for QUIC.
65// Simplify ownership issues and the interaction with the MockSocketFactory.
66class MockQuicData {
67 public:
68 ~MockQuicData() {
69 STLDeleteElements(&packets_);
70 }
71
72 void AddRead(scoped_ptr<QuicEncryptedPacket> packet) {
73 reads_.push_back(MockRead(SYNCHRONOUS, packet->data(), packet->length(),
74 sequence_number_++));
75 packets_.push_back(packet.release());
76 }
77
78 void AddRead(IoMode mode, int rv) {
79 reads_.push_back(MockRead(mode, rv));
80 }
81
82 void AddWrite(scoped_ptr<QuicEncryptedPacket> packet) {
83 writes_.push_back(MockWrite(SYNCHRONOUS, packet->data(), packet->length(),
84 sequence_number_++));
85 packets_.push_back(packet.release());
86 }
87
88 void AddDelayedSocketDataToFactory(MockClientSocketFactory* factory,
89 size_t delay) {
rtennetibe635732014-10-02 22:51:4290 MockRead* reads = reads_.empty() ? nullptr : &reads_[0];
91 MockWrite* writes = writes_.empty() ? nullptr : &writes_[0];
[email protected]1e960032013-12-20 19:00:2092 socket_data_.reset(new DelayedSocketData(
93 delay, reads, reads_.size(), writes, writes_.size()));
94 factory->AddSocketDataProvider(socket_data_.get());
95 }
96
97 private:
98 std::vector<QuicEncryptedPacket*> packets_;
99 std::vector<MockWrite> writes_;
100 std::vector<MockRead> reads_;
101 size_t sequence_number_;
102 scoped_ptr<SocketDataProvider> socket_data_;
103};
104
tbansal7cec3812015-02-05 21:25:12105class ProxyHeadersHandler {
106 public:
107 ProxyHeadersHandler() : was_called_(false) {}
108
109 bool was_called() { return was_called_; }
110
111 void OnBeforeProxyHeadersSent(const ProxyInfo& proxy_info,
112 HttpRequestHeaders* request_headers) {
113 was_called_ = true;
114 }
115
116 private:
117 bool was_called_;
118};
119
[email protected]1e960032013-12-20 19:00:20120class QuicNetworkTransactionTest
121 : public PlatformTest,
[email protected]5d03bbd2014-03-07 16:19:16122 public ::testing::WithParamInterface<QuicVersion> {
[email protected]61a527782013-02-21 03:58:00123 protected:
[email protected]1c04f9522013-02-21 20:32:43124 QuicNetworkTransactionTest()
rtenneti4b06ae72014-08-26 03:43:43125 : clock_(new MockClock),
126 maker_(GetParam(), 0, clock_),
[email protected]1c04f9522013-02-21 20:32:43127 ssl_config_service_(new SSLConfigServiceDefaults),
128 proxy_service_(ProxyService::CreateDirect()),
129 auth_handler_factory_(
[email protected]dda75ab2013-06-22 22:43:30130 HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
[email protected]457d6952013-12-13 09:24:58131 random_generator_(0),
rtennetibe635732014-10-02 22:51:42132 hanging_data_(nullptr, 0, nullptr, 0) {
[email protected]aa9b14d2013-05-10 23:45:19133 request_.method = "GET";
134 request_.url = GURL("http://www.google.com/");
135 request_.load_flags = 0;
[email protected]98a9d1252014-04-04 00:43:59136 clock_->AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
[email protected]1c04f9522013-02-21 20:32:43137 }
[email protected]61a527782013-02-21 03:58:00138
dcheng67be2b1f2014-10-27 21:47:29139 void SetUp() override {
[email protected]61a527782013-02-21 03:58:00140 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34141 base::MessageLoop::current()->RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00142 }
143
dcheng67be2b1f2014-10-27 21:47:29144 void TearDown() override {
[email protected]61a527782013-02-21 03:58:00145 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
146 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:34147 base::MessageLoop::current()->RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00148 PlatformTest::TearDown();
149 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34150 base::MessageLoop::current()->RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00151 }
152
[email protected]3316d422013-05-03 21:45:30153 scoped_ptr<QuicEncryptedPacket> ConstructConnectionClosePacket(
154 QuicPacketSequenceNumber num) {
[email protected]1e960032013-12-20 19:00:20155 return maker_.MakeConnectionClosePacket(num);
[email protected]3316d422013-05-03 21:45:30156 }
157
[email protected]61a527782013-02-21 03:58:00158 scoped_ptr<QuicEncryptedPacket> ConstructAckPacket(
159 QuicPacketSequenceNumber largest_received,
160 QuicPacketSequenceNumber least_unacked) {
[email protected]1e960032013-12-20 19:00:20161 return maker_.MakeAckPacket(2, largest_received, least_unacked, true);
162 }
[email protected]61a527782013-02-21 03:58:00163
[email protected]1e960032013-12-20 19:00:20164 SpdyHeaderBlock GetRequestHeaders(const std::string& method,
165 const std::string& scheme,
166 const std::string& path) {
167 return maker_.GetRequestHeaders(method, scheme, path);
[email protected]61a527782013-02-21 03:58:00168 }
169
[email protected]1e960032013-12-20 19:00:20170 SpdyHeaderBlock GetResponseHeaders(const std::string& status) {
171 return maker_.GetResponseHeaders(status);
[email protected]61a527782013-02-21 03:58:00172 }
173
[email protected]1e960032013-12-20 19:00:20174 scoped_ptr<QuicEncryptedPacket> ConstructDataPacket(
[email protected]61a527782013-02-21 03:58:00175 QuicPacketSequenceNumber sequence_number,
[email protected]98b20ce2013-05-10 05:55:26176 QuicStreamId stream_id,
[email protected]e8ff26842013-03-22 21:02:05177 bool should_include_version,
[email protected]61a527782013-02-21 03:58:00178 bool fin,
179 QuicStreamOffset offset,
180 base::StringPiece data) {
[email protected]1e960032013-12-20 19:00:20181 return maker_.MakeDataPacket(
182 sequence_number, stream_id, should_include_version, fin, offset, data);
[email protected]61a527782013-02-21 03:58:00183 }
184
[email protected]1e960032013-12-20 19:00:20185 scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket(
186 QuicPacketSequenceNumber sequence_number,
187 QuicStreamId stream_id,
188 bool should_include_version,
189 bool fin,
190 const SpdyHeaderBlock& headers) {
rtennetif4bdb542015-01-21 14:33:05191 QuicPriority priority =
192 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
193 return maker_.MakeRequestHeadersPacket(sequence_number, stream_id,
194 should_include_version, fin,
195 priority, headers);
[email protected]61a527782013-02-21 03:58:00196 }
197
[email protected]1e960032013-12-20 19:00:20198 scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket(
199 QuicPacketSequenceNumber sequence_number,
200 QuicStreamId stream_id,
201 bool should_include_version,
202 bool fin,
203 const SpdyHeaderBlock& headers) {
204 return maker_.MakeResponseHeadersPacket(
205 sequence_number, stream_id, should_include_version, fin, headers);
[email protected]61a527782013-02-21 03:58:00206 }
207
208 void CreateSession() {
[email protected]d7599122014-05-24 03:37:23209 CreateSessionWithFactory(&socket_factory_, false);
[email protected]dda75ab2013-06-22 22:43:30210 }
211
[email protected]d7599122014-05-24 03:37:23212 void CreateSessionWithNextProtos() {
213 CreateSessionWithFactory(&socket_factory_, true);
214 }
215
216 // If |use_next_protos| is true, enables SPDY and QUIC.
217 void CreateSessionWithFactory(ClientSocketFactory* socket_factory,
218 bool use_next_protos) {
[email protected]4dca587c2013-03-07 16:54:47219 params_.enable_quic = true;
220 params_.quic_clock = clock_;
221 params_.quic_random = &random_generator_;
[email protected]dda75ab2013-06-22 22:43:30222 params_.client_socket_factory = socket_factory;
[email protected]e8ff26842013-03-22 21:02:05223 params_.quic_crypto_client_stream_factory = &crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:43224 params_.host_resolver = &host_resolver_;
225 params_.cert_verifier = &cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:11226 params_.transport_security_state = &transport_security_state_;
[email protected]1c04f9522013-02-21 20:32:43227 params_.proxy_service = proxy_service_.get();
228 params_.ssl_config_service = ssl_config_service_.get();
229 params_.http_auth_handler_factory = auth_handler_factory_.get();
[email protected]30d4c022013-07-18 22:58:16230 params_.http_server_properties = http_server_properties.GetWeakPtr();
[email protected]1e960032013-12-20 19:00:20231 params_.quic_supported_versions = SupportedVersions(GetParam());
[email protected]61a527782013-02-21 03:58:00232
[email protected]d7599122014-05-24 03:37:23233 if (use_next_protos) {
234 params_.use_alternate_protocols = true;
bnc3bb2c232014-11-07 20:26:39235 params_.next_protos = NextProtosWithSpdyAndQuic(true, true);
[email protected]d7599122014-05-24 03:37:23236 }
237
[email protected]61a527782013-02-21 03:58:00238 session_ = new HttpNetworkSession(params_);
[email protected]11c05872013-08-20 02:04:12239 session_->quic_stream_factory()->set_require_confirmation(false);
[email protected]61a527782013-02-21 03:58:00240 }
241
[email protected]aa9b14d2013-05-10 23:45:19242 void CheckWasQuicResponse(const scoped_ptr<HttpNetworkTransaction>& trans) {
243 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42244 ASSERT_TRUE(response != nullptr);
245 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19246 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
247 EXPECT_TRUE(response->was_fetched_via_spdy);
248 EXPECT_TRUE(response->was_npn_negotiated);
249 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_QUIC1_SPDY3,
250 response->connection_info);
251 }
252
253 void CheckWasHttpResponse(const scoped_ptr<HttpNetworkTransaction>& trans) {
254 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42255 ASSERT_TRUE(response != nullptr);
256 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19257 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
258 EXPECT_FALSE(response->was_fetched_via_spdy);
259 EXPECT_FALSE(response->was_npn_negotiated);
260 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1,
261 response->connection_info);
262 }
263
264 void CheckResponseData(HttpNetworkTransaction* trans,
265 const std::string& expected) {
266 std::string response_data;
267 ASSERT_EQ(OK, ReadTransaction(trans, &response_data));
268 EXPECT_EQ(expected, response_data);
269 }
270
271 void RunTransaction(HttpNetworkTransaction* trans) {
272 TestCompletionCallback callback;
273 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
274 EXPECT_EQ(ERR_IO_PENDING, rv);
275 EXPECT_EQ(OK, callback.WaitForResult());
276 }
277
278 void SendRequestAndExpectHttpResponse(const std::string& expected) {
279 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:50280 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
[email protected]aa9b14d2013-05-10 23:45:19281 RunTransaction(trans.get());
282 CheckWasHttpResponse(trans);
283 CheckResponseData(trans.get(), expected);
284 }
285
286 void SendRequestAndExpectQuicResponse(const std::string& expected) {
tbansal7cec3812015-02-05 21:25:12287 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false);
288 }
289
290 void SendRequestAndExpectQuicResponseFromProxy(const std::string& expected) {
291 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, true);
[email protected]aa9b14d2013-05-10 23:45:19292 }
293
294 void AddQuicAlternateProtocolMapping(
295 MockCryptoClientStream::HandshakeMode handshake_mode) {
296 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
bnccacc0992015-03-20 20:22:22297 HostPortPair host_port_pair = HostPortPair::FromURL(request_.url);
298 AlternativeService alternative_service(QUIC, host_port_pair.host(), 80);
299 session_->http_server_properties()->SetAlternativeService(
300 host_port_pair, alternative_service, 1.0);
[email protected]aa9b14d2013-05-10 23:45:19301 }
302
303 void ExpectBrokenAlternateProtocolMapping() {
bnc8445b3002015-03-13 01:57:09304 const HostPortPair origin = HostPortPair::FromURL(request_.url);
bnc181b39a2015-03-17 21:36:47305 const AlternativeService alternative_service =
306 session_->http_server_properties()->GetAlternativeService(origin);
307 EXPECT_NE(UNINITIALIZED_ALTERNATE_PROTOCOL, alternative_service.protocol);
bnc8445b3002015-03-13 01:57:09308 EXPECT_TRUE(session_->http_server_properties()->IsAlternativeServiceBroken(
309 alternative_service));
[email protected]aa9b14d2013-05-10 23:45:19310 }
311
[email protected]4d590c9c2014-05-02 05:14:33312 void ExpectQuicAlternateProtocolMapping() {
bnc181b39a2015-03-17 21:36:47313 const AlternativeService alternative_service =
314 session_->http_server_properties()->GetAlternativeService(
[email protected]4d590c9c2014-05-02 05:14:33315 HostPortPair::FromURL(request_.url));
bnc181b39a2015-03-17 21:36:47316 EXPECT_EQ(QUIC, alternative_service.protocol);
[email protected]4d590c9c2014-05-02 05:14:33317 }
318
[email protected]aa9b14d2013-05-10 23:45:19319 void AddHangingNonAlternateProtocolSocketData() {
[email protected]dda75ab2013-06-22 22:43:30320 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
321 hanging_data_.set_connect_data(hanging_connect);
322 socket_factory_.AddSocketDataProvider(&hanging_data_);
[email protected]aa9b14d2013-05-10 23:45:19323 }
324
rtenneti4b06ae72014-08-26 03:43:43325 MockClock* clock_; // Owned by QuicStreamFactory after CreateSession.
[email protected]1e960032013-12-20 19:00:20326 QuicTestPacketMaker maker_;
[email protected]61a527782013-02-21 03:58:00327 scoped_refptr<HttpNetworkSession> session_;
328 MockClientSocketFactory socket_factory_;
[email protected]e8ff26842013-03-22 21:02:05329 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:43330 MockHostResolver host_resolver_;
331 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:11332 TransportSecurityState transport_security_state_;
[email protected]1c04f9522013-02-21 20:32:43333 scoped_refptr<SSLConfigServiceDefaults> ssl_config_service_;
334 scoped_ptr<ProxyService> proxy_service_;
335 scoped_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
[email protected]61a527782013-02-21 03:58:00336 MockRandom random_generator_;
337 HttpServerPropertiesImpl http_server_properties;
338 HttpNetworkSession::Params params_;
[email protected]aa9b14d2013-05-10 23:45:19339 HttpRequestInfo request_;
340 CapturingBoundNetLog net_log_;
[email protected]dda75ab2013-06-22 22:43:30341 StaticSocketDataProvider hanging_data_;
tbansal7cec3812015-02-05 21:25:12342
343 private:
344 void SendRequestAndExpectQuicResponseMaybeFromProxy(
345 const std::string& expected,
346 bool used_proxy) {
347 scoped_ptr<HttpNetworkTransaction> trans(
348 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
349 ProxyHeadersHandler proxy_headers_handler;
350 trans->SetBeforeProxyHeadersSentCallback(
351 base::Bind(&ProxyHeadersHandler::OnBeforeProxyHeadersSent,
352 base::Unretained(&proxy_headers_handler)));
353 RunTransaction(trans.get());
354 CheckWasQuicResponse(trans);
355 CheckResponseData(trans.get(), expected);
356 EXPECT_EQ(used_proxy, proxy_headers_handler.was_called());
357 }
[email protected]61a527782013-02-21 03:58:00358};
359
[email protected]1e960032013-12-20 19:00:20360INSTANTIATE_TEST_CASE_P(Version, QuicNetworkTransactionTest,
361 ::testing::ValuesIn(QuicSupportedVersions()));
362
363TEST_P(QuicNetworkTransactionTest, ForceQuic) {
[email protected]49e85332013-06-04 04:18:03364 params_.origin_to_force_quic_on =
365 HostPortPair::FromString("www.google.com:80");
[email protected]4dca587c2013-03-07 16:54:47366
[email protected]1e960032013-12-20 19:00:20367 MockQuicData mock_quic_data;
[email protected]92bf17c2014-03-03 21:14:03368 mock_quic_data.AddWrite(
[email protected]66ae5962014-05-22 11:13:05369 ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
[email protected]92bf17c2014-03-03 21:14:03370 GetRequestHeaders("GET", "http", "/")));
371 mock_quic_data.AddRead(
[email protected]66ae5962014-05-22 11:13:05372 ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false,
[email protected]92bf17c2014-03-03 21:14:03373 GetResponseHeaders("200 OK")));
374 mock_quic_data.AddRead(
[email protected]66ae5962014-05-22 11:13:05375 ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
[email protected]92bf17c2014-03-03 21:14:03376 mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
[email protected]1e960032013-12-20 19:00:20377 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
[email protected]4dca587c2013-03-07 16:54:47378
[email protected]1e960032013-12-20 19:00:20379 mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
[email protected]4dca587c2013-03-07 16:54:47380
[email protected]aa9b14d2013-05-10 23:45:19381 // The non-alternate protocol job needs to hang in order to guarantee that
382 // the alternate-protocol job will "win".
383 AddHangingNonAlternateProtocolSocketData();
[email protected]4dca587c2013-03-07 16:54:47384
385 CreateSession();
[email protected]4dca587c2013-03-07 16:54:47386
[email protected]aa9b14d2013-05-10 23:45:19387 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:47388
[email protected]98b20ce2013-05-10 05:55:26389 // Check that the NetLog was filled reasonably.
390 net::CapturingNetLog::CapturedEntryList entries;
[email protected]aa9b14d2013-05-10 23:45:19391 net_log_.GetEntries(&entries);
[email protected]98b20ce2013-05-10 05:55:26392 EXPECT_LT(0u, entries.size());
393
394 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
395 int pos = net::ExpectLogContainsSomewhere(
396 entries, 0,
397 net::NetLog::TYPE_QUIC_SESSION_PACKET_RECEIVED,
398 net::NetLog::PHASE_NONE);
399 EXPECT_LT(0, pos);
400
401 // ... and also a TYPE_QUIC_SESSION_PACKET_HEADER_RECEIVED.
402 pos = net::ExpectLogContainsSomewhere(
403 entries, 0,
404 net::NetLog::TYPE_QUIC_SESSION_PACKET_HEADER_RECEIVED,
405 net::NetLog::PHASE_NONE);
406 EXPECT_LT(0, pos);
407
408 std::string packet_sequence_number;
409 ASSERT_TRUE(entries[pos].GetStringValue(
410 "packet_sequence_number", &packet_sequence_number));
411 EXPECT_EQ("1", packet_sequence_number);
412
413 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
414 pos = net::ExpectLogContainsSomewhere(
415 entries, 0,
416 net::NetLog::TYPE_QUIC_SESSION_STREAM_FRAME_RECEIVED,
417 net::NetLog::PHASE_NONE);
418 EXPECT_LT(0, pos);
419
420 int log_stream_id;
421 ASSERT_TRUE(entries[pos].GetIntegerValue("stream_id", &log_stream_id));
[email protected]1e960032013-12-20 19:00:20422 EXPECT_EQ(3, log_stream_id);
[email protected]4dca587c2013-03-07 16:54:47423}
424
[email protected]cf3e3cd62014-02-05 16:16:16425TEST_P(QuicNetworkTransactionTest, QuicProxy) {
tbansaled0aecc2015-02-20 03:44:18426 params_.enable_quic_for_proxies = true;
[email protected]cf3e3cd62014-02-05 16:16:16427 proxy_service_.reset(
428 ProxyService::CreateFixedFromPacResult("QUIC myproxy:70"));
429
[email protected]cf3e3cd62014-02-05 16:16:16430 MockQuicData mock_quic_data;
[email protected]92bf17c2014-03-03 21:14:03431 mock_quic_data.AddWrite(
[email protected]66ae5962014-05-22 11:13:05432 ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
[email protected]92bf17c2014-03-03 21:14:03433 GetRequestHeaders("GET", "http", "/")));
434 mock_quic_data.AddRead(
[email protected]66ae5962014-05-22 11:13:05435 ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false,
[email protected]92bf17c2014-03-03 21:14:03436 GetResponseHeaders("200 OK")));
437 mock_quic_data.AddRead(
[email protected]66ae5962014-05-22 11:13:05438 ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
[email protected]92bf17c2014-03-03 21:14:03439 mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
[email protected]cf3e3cd62014-02-05 16:16:16440 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
441
442 mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
443
444 // There is no need to set up an alternate protocol job, because
445 // no attempt will be made to speak to the proxy over TCP.
446
447 CreateSession();
448
tbansal7cec3812015-02-05 21:25:12449 SendRequestAndExpectQuicResponseFromProxy("hello!");
[email protected]cf3e3cd62014-02-05 16:16:16450}
451
[email protected]1e960032013-12-20 19:00:20452TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
[email protected]49e85332013-06-04 04:18:03453 params_.origin_to_force_quic_on =
454 HostPortPair::FromString("www.google.com:80");
[email protected]cebe3282013-05-22 23:49:30455
[email protected]1e960032013-12-20 19:00:20456 MockQuicData mock_quic_data;
457 mock_quic_data.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
458
459 mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 0);
[email protected]cebe3282013-05-22 23:49:30460
461 CreateSession();
462
463 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:50464 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
[email protected]cebe3282013-05-22 23:49:30465 TestCompletionCallback callback;
466 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
467 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0b2294d32013-08-02 00:46:36468 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]cebe3282013-05-22 23:49:30469}
470
[email protected]1e960032013-12-20 19:00:20471TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
[email protected]4dca587c2013-03-07 16:54:47472 // Attempt to "force" quic on 443, which will not be honored.
[email protected]49e85332013-06-04 04:18:03473 params_.origin_to_force_quic_on =
474 HostPortPair::FromString("www.google.com:443");
[email protected]4dca587c2013-03-07 16:54:47475
[email protected]aa9b14d2013-05-10 23:45:19476 MockRead http_reads[] = {
[email protected]4dca587c2013-03-07 16:54:47477 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
478 MockRead("hello world"),
479 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
480 MockRead(ASYNC, OK)
481 };
482
rtennetibe635732014-10-02 22:51:42483 StaticSocketDataProvider data(http_reads, arraysize(http_reads), nullptr, 0);
[email protected]4dca587c2013-03-07 16:54:47484 socket_factory_.AddSocketDataProvider(&data);
485 SSLSocketDataProvider ssl(ASYNC, OK);
486 socket_factory_.AddSSLSocketDataProvider(&ssl);
487
[email protected]4dca587c2013-03-07 16:54:47488 CreateSession();
[email protected]4dca587c2013-03-07 16:54:47489
[email protected]aa9b14d2013-05-10 23:45:19490 SendRequestAndExpectHttpResponse("hello world");
[email protected]4dca587c2013-03-07 16:54:47491}
492
[email protected]1e960032013-12-20 19:00:20493TEST_P(QuicNetworkTransactionTest, UseAlternateProtocolForQuic) {
[email protected]aa9b14d2013-05-10 23:45:19494 MockRead http_reads[] = {
[email protected]61a527782013-02-21 03:58:00495 MockRead("HTTP/1.1 200 OK\r\n"),
496 MockRead(kQuicAlternateProtocolHttpHeader),
497 MockRead("hello world"),
498 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
499 MockRead(ASYNC, OK)
500 };
501
[email protected]aa9b14d2013-05-10 23:45:19502 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
rtennetibe635732014-10-02 22:51:42503 nullptr, 0);
[email protected]aa9b14d2013-05-10 23:45:19504 socket_factory_.AddSocketDataProvider(&http_data);
[email protected]61a527782013-02-21 03:58:00505
[email protected]1e960032013-12-20 19:00:20506 MockQuicData mock_quic_data;
[email protected]92bf17c2014-03-03 21:14:03507 mock_quic_data.AddWrite(
[email protected]66ae5962014-05-22 11:13:05508 ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
[email protected]92bf17c2014-03-03 21:14:03509 GetRequestHeaders("GET", "http", "/")));
510 mock_quic_data.AddRead(
[email protected]66ae5962014-05-22 11:13:05511 ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false,
[email protected]92bf17c2014-03-03 21:14:03512 GetResponseHeaders("200 OK")));
513 mock_quic_data.AddRead(
[email protected]66ae5962014-05-22 11:13:05514 ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
[email protected]92bf17c2014-03-03 21:14:03515 mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
[email protected]1e960032013-12-20 19:00:20516 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
[email protected]61a527782013-02-21 03:58:00517
[email protected]1e960032013-12-20 19:00:20518 mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
[email protected]61a527782013-02-21 03:58:00519
[email protected]aa9b14d2013-05-10 23:45:19520 // The non-alternate protocol job needs to hang in order to guarantee that
521 // the alternate-protocol job will "win".
522 AddHangingNonAlternateProtocolSocketData();
[email protected]61a527782013-02-21 03:58:00523
[email protected]d7599122014-05-24 03:37:23524 CreateSessionWithNextProtos();
[email protected]61a527782013-02-21 03:58:00525
[email protected]aa9b14d2013-05-10 23:45:19526 SendRequestAndExpectHttpResponse("hello world");
527 SendRequestAndExpectQuicResponse("hello!");
[email protected]61a527782013-02-21 03:58:00528}
529
bncae8db8402015-03-26 20:13:50530TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
531 MockRead http_reads[] = {
532 MockRead("HTTP/1.1 200 OK\r\n"),
533 MockRead(kQuicAlternateProtocolHttpHeader),
534 MockRead("hello world"),
535 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
536 MockRead(ASYNC, OK)};
537
538 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
539 0);
540 socket_factory_.AddSocketDataProvider(&http_data);
541
542 MockQuicData mock_quic_data;
543 mock_quic_data.AddWrite(
544 ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
545 GetRequestHeaders("GET", "http", "/")));
546 mock_quic_data.AddRead(ConstructResponseHeadersPacket(
547 1, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK")));
548 mock_quic_data.AddRead(
549 ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
550 mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
551 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
552
553 mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
554
555 // The non-alternate protocol job needs to hang in order to guarantee that
556 // the alternate-protocol job will "win".
557 AddHangingNonAlternateProtocolSocketData();
558
559 CreateSessionWithNextProtos();
560
561 AlternativeService alternative_service(QUIC,
562 HostPortPair::FromURL(request_.url));
563 session_->http_server_properties()->MarkAlternativeServiceRecentlyBroken(
564 alternative_service);
565 EXPECT_TRUE(
566 session_->http_server_properties()->WasAlternativeServiceRecentlyBroken(
567 alternative_service));
568
569 SendRequestAndExpectHttpResponse("hello world");
570 SendRequestAndExpectQuicResponse("hello!");
571
572 EXPECT_FALSE(
573 session_->http_server_properties()->WasAlternativeServiceRecentlyBroken(
574 alternative_service));
575}
576
[email protected]287d9412014-07-08 23:01:00577TEST_P(QuicNetworkTransactionTest, UseAlternateProtocolProbabilityForQuic) {
578 MockRead http_reads[] = {
579 MockRead("HTTP/1.1 200 OK\r\n"),
580 MockRead(kQuicAlternateProtocol50pctHttpHeader),
581 MockRead("hello world"),
582 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
583 MockRead(ASYNC, OK)
584 };
585
586 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
rtennetibe635732014-10-02 22:51:42587 nullptr, 0);
[email protected]287d9412014-07-08 23:01:00588 socket_factory_.AddSocketDataProvider(&http_data);
589
590 MockQuicData mock_quic_data;
591 mock_quic_data.AddWrite(
592 ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
593 GetRequestHeaders("GET", "http", "/")));
594 mock_quic_data.AddRead(
595 ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false,
596 GetResponseHeaders("200 OK")));
597 mock_quic_data.AddRead(
598 ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
599 mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
600 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
601
602 mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
603
604 // The non-alternate protocol job needs to hang in order to guarantee that
605 // the alternate-protocol job will "win".
606 AddHangingNonAlternateProtocolSocketData();
607
608 params_.alternate_protocol_probability_threshold = .25;
609 CreateSessionWithNextProtos();
610
611 SendRequestAndExpectHttpResponse("hello world");
612 SendRequestAndExpectQuicResponse("hello!");
613}
614
615TEST_P(QuicNetworkTransactionTest, DontUseAlternateProtocolProbabilityForQuic) {
616 MockRead http_reads[] = {
617 MockRead("HTTP/1.1 200 OK\r\n"),
618 MockRead(kQuicAlternateProtocol50pctHttpHeader),
619 MockRead("hello world"),
620 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
621 MockRead(ASYNC, OK)
622 };
623
624 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
rtennetibe635732014-10-02 22:51:42625 nullptr, 0);
[email protected]287d9412014-07-08 23:01:00626 socket_factory_.AddSocketDataProvider(&http_data);
627 socket_factory_.AddSocketDataProvider(&http_data);
628
629 params_.alternate_protocol_probability_threshold = .75;
630 CreateSessionWithNextProtos();
631
632 SendRequestAndExpectHttpResponse("hello world");
633 SendRequestAndExpectHttpResponse("hello world");
634}
635
636TEST_P(QuicNetworkTransactionTest,
637 DontUseAlternateProtocolWithBadProbabilityForQuic) {
638 MockRead http_reads[] = {
639 MockRead("HTTP/1.1 200 OK\r\n"),
640 MockRead("Alternate-Protocol: 443:quic,p=2\r\n\r\n"),
641 MockRead("hello world"),
642 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
643 MockRead(ASYNC, OK)
644 };
645
646 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
rtennetibe635732014-10-02 22:51:42647 nullptr, 0);
[email protected]287d9412014-07-08 23:01:00648 socket_factory_.AddSocketDataProvider(&http_data);
649 socket_factory_.AddSocketDataProvider(&http_data);
650
651 params_.alternate_protocol_probability_threshold = .75;
652 CreateSessionWithNextProtos();
653
654 SendRequestAndExpectHttpResponse("hello world");
655 SendRequestAndExpectHttpResponse("hello world");
656}
657
[email protected]1e960032013-12-20 19:00:20658TEST_P(QuicNetworkTransactionTest, UseAlternateProtocolForQuicForHttps) {
[email protected]6d1b4ed2013-07-10 03:57:54659 params_.origin_to_force_quic_on =
660 HostPortPair::FromString("www.google.com:443");
[email protected]6d1b4ed2013-07-10 03:57:54661
662 MockRead http_reads[] = {
663 MockRead("HTTP/1.1 200 OK\r\n"),
664 MockRead(kQuicAlternateProtocolHttpsHeader),
665 MockRead("hello world"),
666 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
667 MockRead(ASYNC, OK)
668 };
669
670 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
rtennetibe635732014-10-02 22:51:42671 nullptr, 0);
[email protected]6d1b4ed2013-07-10 03:57:54672 socket_factory_.AddSocketDataProvider(&http_data);
673
[email protected]1e960032013-12-20 19:00:20674 MockQuicData mock_quic_data;
[email protected]92bf17c2014-03-03 21:14:03675 mock_quic_data.AddWrite(
[email protected]66ae5962014-05-22 11:13:05676 ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
[email protected]92bf17c2014-03-03 21:14:03677 GetRequestHeaders("GET", "http", "/")));
678 mock_quic_data.AddRead(
[email protected]66ae5962014-05-22 11:13:05679 ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false,
[email protected]92bf17c2014-03-03 21:14:03680 GetResponseHeaders("200 OK")));
681 mock_quic_data.AddRead(
[email protected]66ae5962014-05-22 11:13:05682 ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
[email protected]92bf17c2014-03-03 21:14:03683 mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
[email protected]1e960032013-12-20 19:00:20684 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
[email protected]6d1b4ed2013-07-10 03:57:54685
[email protected]1e960032013-12-20 19:00:20686 mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
[email protected]6d1b4ed2013-07-10 03:57:54687
688 // The non-alternate protocol job needs to hang in order to guarantee that
689 // the alternate-protocol job will "win".
690 AddHangingNonAlternateProtocolSocketData();
691
[email protected]d7599122014-05-24 03:37:23692 CreateSessionWithNextProtos();
[email protected]6d1b4ed2013-07-10 03:57:54693
694 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
695 SendRequestAndExpectHttpResponse("hello world");
696}
697
[email protected]1e960032013-12-20 19:00:20698TEST_P(QuicNetworkTransactionTest, HungAlternateProtocol) {
[email protected]dda75ab2013-06-22 22:43:30699 crypto_client_stream_factory_.set_handshake_mode(
700 MockCryptoClientStream::COLD_START);
701
702 MockWrite http_writes[] = {
703 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
704 MockWrite(SYNCHRONOUS, 1, "Host: www.google.com\r\n"),
705 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")
706 };
707
708 MockRead http_reads[] = {
709 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
710 MockRead(SYNCHRONOUS, 4, kQuicAlternateProtocolHttpHeader),
711 MockRead(SYNCHRONOUS, 5, "hello world"),
712 MockRead(SYNCHRONOUS, OK, 6)
713 };
714
715 DeterministicMockClientSocketFactory socket_factory;
716
717 DeterministicSocketData http_data(http_reads, arraysize(http_reads),
718 http_writes, arraysize(http_writes));
719 socket_factory.AddSocketDataProvider(&http_data);
720
721 // The QUIC transaction will not be allowed to complete.
722 MockWrite quic_writes[] = {
723 MockWrite(ASYNC, ERR_IO_PENDING, 0)
724 };
725 MockRead quic_reads[] = {
726 MockRead(ASYNC, ERR_IO_PENDING, 1),
727 };
728 DeterministicSocketData quic_data(quic_reads, arraysize(quic_reads),
729 quic_writes, arraysize(quic_writes));
730 socket_factory.AddSocketDataProvider(&quic_data);
731
732 // The HTTP transaction will complete.
733 DeterministicSocketData http_data2(http_reads, arraysize(http_reads),
734 http_writes, arraysize(http_writes));
735 socket_factory.AddSocketDataProvider(&http_data2);
736
[email protected]d7599122014-05-24 03:37:23737 CreateSessionWithFactory(&socket_factory, true);
[email protected]dda75ab2013-06-22 22:43:30738
739 // Run the first request.
740 http_data.StopAfter(arraysize(http_reads) + arraysize(http_writes));
741 SendRequestAndExpectHttpResponse("hello world");
742 ASSERT_TRUE(http_data.at_read_eof());
743 ASSERT_TRUE(http_data.at_write_eof());
744
745 // Now run the second request in which the QUIC socket hangs,
746 // and verify the the transaction continues over HTTP.
747 http_data2.StopAfter(arraysize(http_reads) + arraysize(http_writes));
748 SendRequestAndExpectHttpResponse("hello world");
749
750 ASSERT_TRUE(http_data2.at_read_eof());
751 ASSERT_TRUE(http_data2.at_write_eof());
752 ASSERT_TRUE(!quic_data.at_read_eof());
753 ASSERT_TRUE(!quic_data.at_write_eof());
754}
755
[email protected]1e960032013-12-20 19:00:20756TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
[email protected]1e960032013-12-20 19:00:20757 MockQuicData mock_quic_data;
[email protected]92bf17c2014-03-03 21:14:03758 mock_quic_data.AddWrite(
[email protected]66ae5962014-05-22 11:13:05759 ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
[email protected]92bf17c2014-03-03 21:14:03760 GetRequestHeaders("GET", "http", "/")));
761 mock_quic_data.AddRead(
[email protected]66ae5962014-05-22 11:13:05762 ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false,
[email protected]92bf17c2014-03-03 21:14:03763 GetResponseHeaders("200 OK")));
764 mock_quic_data.AddRead(
[email protected]66ae5962014-05-22 11:13:05765 ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
[email protected]92bf17c2014-03-03 21:14:03766 mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
[email protected]1e960032013-12-20 19:00:20767 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
[email protected]8ba81212013-05-03 13:11:48768
[email protected]1e960032013-12-20 19:00:20769 mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
[email protected]8ba81212013-05-03 13:11:48770
[email protected]3a120a6b2013-06-25 01:08:27771 // The non-alternate protocol job needs to hang in order to guarantee that
772 // the alternate-protocol job will "win".
[email protected]dda75ab2013-06-22 22:43:30773 AddHangingNonAlternateProtocolSocketData();
774
[email protected]d7599122014-05-24 03:37:23775 CreateSessionWithNextProtos();
[email protected]aa9b14d2013-05-10 23:45:19776 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
777 SendRequestAndExpectQuicResponse("hello!");
[email protected]8ba81212013-05-03 13:11:48778}
779
[email protected]1e960032013-12-20 19:00:20780TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
[email protected]1e960032013-12-20 19:00:20781 MockQuicData mock_quic_data;
[email protected]92bf17c2014-03-03 21:14:03782 mock_quic_data.AddWrite(
[email protected]66ae5962014-05-22 11:13:05783 ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
[email protected]92bf17c2014-03-03 21:14:03784 GetRequestHeaders("GET", "http", "/")));
785 mock_quic_data.AddRead(
[email protected]66ae5962014-05-22 11:13:05786 ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false,
[email protected]92bf17c2014-03-03 21:14:03787 GetResponseHeaders("200 OK")));
788 mock_quic_data.AddRead(
[email protected]66ae5962014-05-22 11:13:05789 ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
[email protected]92bf17c2014-03-03 21:14:03790 mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
[email protected]1e960032013-12-20 19:00:20791 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
792 mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
[email protected]3a120a6b2013-06-25 01:08:27793
794 // In order for a new QUIC session to be established via alternate-protocol
795 // without racing an HTTP connection, we need the host resolution to happen
796 // synchronously.
797 host_resolver_.set_synchronous_mode(true);
798 host_resolver_.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
[email protected]5109c1952013-08-20 18:44:10799 HostResolver::RequestInfo info(HostPortPair("www.google.com", 80));
[email protected]3a120a6b2013-06-25 01:08:27800 AddressList address;
[email protected]5109c1952013-08-20 18:44:10801 host_resolver_.Resolve(info,
802 DEFAULT_PRIORITY,
803 &address,
804 CompletionCallback(),
rtennetibe635732014-10-02 22:51:42805 nullptr,
[email protected]3a120a6b2013-06-25 01:08:27806 net_log_.bound());
807
[email protected]d7599122014-05-24 03:37:23808 CreateSessionWithNextProtos();
[email protected]3a120a6b2013-06-25 01:08:27809 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
810 SendRequestAndExpectQuicResponse("hello!");
811}
812
[email protected]0fc924b2014-03-31 04:34:15813TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
814 proxy_service_.reset(
815 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]0fc924b2014-03-31 04:34:15816
817 // Since we are using a proxy, the QUIC job will not succeed.
818 MockWrite http_writes[] = {
819 MockWrite(SYNCHRONOUS, 0, "GET http://www.google.com/ HTTP/1.1\r\n"),
820 MockWrite(SYNCHRONOUS, 1, "Host: www.google.com\r\n"),
821 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")
822 };
823
824 MockRead http_reads[] = {
825 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
826 MockRead(SYNCHRONOUS, 4, kQuicAlternateProtocolHttpHeader),
827 MockRead(SYNCHRONOUS, 5, "hello world"),
828 MockRead(SYNCHRONOUS, OK, 6)
829 };
830
831 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
832 http_writes, arraysize(http_writes));
833 socket_factory_.AddSocketDataProvider(&http_data);
834
835 // In order for a new QUIC session to be established via alternate-protocol
836 // without racing an HTTP connection, we need the host resolution to happen
837 // synchronously.
838 host_resolver_.set_synchronous_mode(true);
839 host_resolver_.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
840 HostResolver::RequestInfo info(HostPortPair("www.google.com", 80));
841 AddressList address;
842 host_resolver_.Resolve(info,
843 DEFAULT_PRIORITY,
844 &address,
845 CompletionCallback(),
rtennetibe635732014-10-02 22:51:42846 nullptr,
[email protected]0fc924b2014-03-31 04:34:15847 net_log_.bound());
848
[email protected]d7599122014-05-24 03:37:23849 CreateSessionWithNextProtos();
[email protected]0fc924b2014-03-31 04:34:15850 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
851 SendRequestAndExpectHttpResponse("hello world");
852}
853
[email protected]1e960032013-12-20 19:00:20854TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
[email protected]1e960032013-12-20 19:00:20855 MockQuicData mock_quic_data;
[email protected]92bf17c2014-03-03 21:14:03856 mock_quic_data.AddWrite(
[email protected]66ae5962014-05-22 11:13:05857 ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
[email protected]92bf17c2014-03-03 21:14:03858 GetRequestHeaders("GET", "http", "/")));
859 mock_quic_data.AddRead(
[email protected]66ae5962014-05-22 11:13:05860 ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false,
[email protected]92bf17c2014-03-03 21:14:03861 GetResponseHeaders("200 OK")));
862 mock_quic_data.AddRead(
[email protected]66ae5962014-05-22 11:13:05863 ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
[email protected]92bf17c2014-03-03 21:14:03864 mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
[email protected]1e960032013-12-20 19:00:20865 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
866 mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
[email protected]11c05872013-08-20 02:04:12867
868 // The non-alternate protocol job needs to hang in order to guarantee that
869 // the alternate-protocol job will "win".
870 AddHangingNonAlternateProtocolSocketData();
871
872 // In order for a new QUIC session to be established via alternate-protocol
873 // without racing an HTTP connection, we need the host resolution to happen
874 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
875 // connection to the the server, in this test we require confirmation
876 // before encrypting so the HTTP job will still start.
877 host_resolver_.set_synchronous_mode(true);
878 host_resolver_.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
[email protected]5109c1952013-08-20 18:44:10879 HostResolver::RequestInfo info(HostPortPair("www.google.com", 80));
[email protected]11c05872013-08-20 02:04:12880 AddressList address;
[email protected]5109c1952013-08-20 18:44:10881 host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
rtennetibe635732014-10-02 22:51:42882 CompletionCallback(), nullptr, net_log_.bound());
[email protected]11c05872013-08-20 02:04:12883
[email protected]d7599122014-05-24 03:37:23884 CreateSessionWithNextProtos();
[email protected]11c05872013-08-20 02:04:12885 session_->quic_stream_factory()->set_require_confirmation(true);
886 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
887
888 scoped_ptr<HttpNetworkTransaction> trans(
889 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
890 TestCompletionCallback callback;
891 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
892 EXPECT_EQ(ERR_IO_PENDING, rv);
893
894 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
895 QuicSession::HANDSHAKE_CONFIRMED);
896 EXPECT_EQ(OK, callback.WaitForResult());
897}
898
[email protected]1e960032013-12-20 19:00:20899TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:30900 // Alternate-protocol job
901 scoped_ptr<QuicEncryptedPacket> close(ConstructConnectionClosePacket(1));
902 MockRead quic_reads[] = {
903 MockRead(ASYNC, close->data(), close->length()),
904 MockRead(ASYNC, OK), // EOF
905 };
906 StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
rtennetibe635732014-10-02 22:51:42907 nullptr, 0);
[email protected]3316d422013-05-03 21:45:30908 socket_factory_.AddSocketDataProvider(&quic_data);
909
910 // Main job which will succeed even though the alternate job fails.
911 MockRead http_reads[] = {
912 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
913 MockRead("hello from http"),
914 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
915 MockRead(ASYNC, OK)
916 };
917
918 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
rtennetibe635732014-10-02 22:51:42919 nullptr, 0);
[email protected]3316d422013-05-03 21:45:30920 socket_factory_.AddSocketDataProvider(&http_data);
921
[email protected]d7599122014-05-24 03:37:23922 CreateSessionWithNextProtos();
[email protected]aa9b14d2013-05-10 23:45:19923 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
924 SendRequestAndExpectHttpResponse("hello from http");
925 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:30926}
927
[email protected]1e960032013-12-20 19:00:20928TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:59929 // Alternate-protocol job
930 MockRead quic_reads[] = {
931 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
932 };
933 StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
rtennetibe635732014-10-02 22:51:42934 nullptr, 0);
[email protected]d03a66d2013-05-06 12:55:59935 socket_factory_.AddSocketDataProvider(&quic_data);
936
937 // Main job which will succeed even though the alternate job fails.
938 MockRead http_reads[] = {
939 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
940 MockRead("hello from http"),
941 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
942 MockRead(ASYNC, OK)
943 };
944
945 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
rtennetibe635732014-10-02 22:51:42946 nullptr, 0);
[email protected]d03a66d2013-05-06 12:55:59947 socket_factory_.AddSocketDataProvider(&http_data);
948
[email protected]d7599122014-05-24 03:37:23949 CreateSessionWithNextProtos();
[email protected]d03a66d2013-05-06 12:55:59950
[email protected]aa9b14d2013-05-10 23:45:19951 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
952 SendRequestAndExpectHttpResponse("hello from http");
953 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:59954}
955
[email protected]00c159f2014-05-21 22:38:16956TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:53957 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:16958 MockRead quic_reads[] = {
959 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
960 };
961 StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
rtennetibe635732014-10-02 22:51:42962 nullptr, 0);
[email protected]00c159f2014-05-21 22:38:16963 socket_factory_.AddSocketDataProvider(&quic_data);
964
[email protected]eb71ab62014-05-23 07:57:53965 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:16966 MockRead http_reads[] = {
967 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
968 };
969
970 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
rtennetibe635732014-10-02 22:51:42971 nullptr, 0);
[email protected]00c159f2014-05-21 22:38:16972 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
973 socket_factory_.AddSocketDataProvider(&http_data);
974
[email protected]d7599122014-05-24 03:37:23975 CreateSessionWithNextProtos();
[email protected]00c159f2014-05-21 22:38:16976
977 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
978 scoped_ptr<HttpNetworkTransaction> trans(
979 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
980 TestCompletionCallback callback;
981 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
982 EXPECT_EQ(ERR_IO_PENDING, rv);
983 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, callback.WaitForResult());
984 ExpectQuicAlternateProtocolMapping();
985}
986
[email protected]1e960032013-12-20 19:00:20987TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:45988 // Alternate-protocol job
989 MockRead quic_reads[] = {
990 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
991 };
992 StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
rtennetibe635732014-10-02 22:51:42993 nullptr, 0);
[email protected]77c6c162013-08-17 02:57:45994 socket_factory_.AddSocketDataProvider(&quic_data);
995
996 AddHangingNonAlternateProtocolSocketData();
997
[email protected]c92c1b52014-05-31 04:16:06998 // Second Alternate-protocol job which will race with the TCP job.
999 StaticSocketDataProvider quic_data2(quic_reads, arraysize(quic_reads),
rtennetibe635732014-10-02 22:51:421000 nullptr, 0);
[email protected]c92c1b52014-05-31 04:16:061001 socket_factory_.AddSocketDataProvider(&quic_data2);
1002
[email protected]4d283b32013-10-17 12:57:271003 // Final job that will proceed when the QUIC job fails.
1004 MockRead http_reads[] = {
1005 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
1006 MockRead("hello from http"),
1007 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1008 MockRead(ASYNC, OK)
1009 };
1010
1011 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
rtennetibe635732014-10-02 22:51:421012 nullptr, 0);
[email protected]4d283b32013-10-17 12:57:271013 socket_factory_.AddSocketDataProvider(&http_data);
1014
[email protected]d7599122014-05-24 03:37:231015 CreateSessionWithNextProtos();
[email protected]77c6c162013-08-17 02:57:451016
1017 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
1018
[email protected]4d283b32013-10-17 12:57:271019 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:451020
1021 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:271022
1023 EXPECT_TRUE(quic_data.at_read_eof());
1024 EXPECT_TRUE(quic_data.at_write_eof());
[email protected]77c6c162013-08-17 02:57:451025}
1026
[email protected]93b31772014-06-19 08:03:351027TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) {
[email protected]65768442014-06-06 23:37:031028 // Alternate-protocol job
1029 MockRead quic_reads[] = {
1030 MockRead(ASYNC, ERR_IO_PENDING),
1031 };
1032 StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
rtennetibe635732014-10-02 22:51:421033 nullptr, 0);
[email protected]65768442014-06-06 23:37:031034 socket_factory_.AddSocketDataProvider(&quic_data);
1035
1036 // Main job that will proceed when the QUIC job fails.
1037 MockRead http_reads[] = {
1038 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
1039 MockRead("hello from http"),
1040 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1041 MockRead(ASYNC, OK)
1042 };
1043
1044 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
rtennetibe635732014-10-02 22:51:421045 nullptr, 0);
[email protected]65768442014-06-06 23:37:031046 socket_factory_.AddSocketDataProvider(&http_data);
1047
1048 CreateSessionWithNextProtos();
1049
1050 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
1051
1052 SendRequestAndExpectHttpResponse("hello from http");
1053}
1054
[email protected]eb71ab62014-05-23 07:57:531055TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:331056 // Alternate-protocol job will fail before creating a QUIC session.
rtennetibe635732014-10-02 22:51:421057 StaticSocketDataProvider quic_data(nullptr, 0, nullptr, 0);
[email protected]4d590c9c2014-05-02 05:14:331058 quic_data.set_connect_data(MockConnect(SYNCHRONOUS,
1059 ERR_INTERNET_DISCONNECTED));
1060 socket_factory_.AddSocketDataProvider(&quic_data);
1061
1062 // Main job which will succeed even though the alternate job fails.
1063 MockRead http_reads[] = {
1064 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
1065 MockRead("hello from http"),
1066 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1067 MockRead(ASYNC, OK)
1068 };
1069
1070 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
rtennetibe635732014-10-02 22:51:421071 nullptr, 0);
[email protected]4d590c9c2014-05-02 05:14:331072 socket_factory_.AddSocketDataProvider(&http_data);
1073
[email protected]d7599122014-05-24 03:37:231074 CreateSessionWithNextProtos();
[email protected]4d590c9c2014-05-02 05:14:331075 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
1076 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:531077
1078 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:331079}
1080
[email protected]4fee9672014-01-08 14:47:151081TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
[email protected]4fee9672014-01-08 14:47:151082 MockQuicData mock_quic_data;
1083 mock_quic_data.AddRead(ConstructConnectionClosePacket(1));
[email protected]92bf17c2014-03-03 21:14:031084 mock_quic_data.AddWrite(
[email protected]66ae5962014-05-22 11:13:051085 ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
[email protected]92bf17c2014-03-03 21:14:031086 GetRequestHeaders("GET", "http", "/")));
1087 mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
[email protected]4fee9672014-01-08 14:47:151088 mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 0);
1089
1090 // When the QUIC connection fails, we will try the request again over HTTP.
1091 MockRead http_reads[] = {
1092 MockRead("HTTP/1.1 200 OK\r\n"),
1093 MockRead(kQuicAlternateProtocolHttpHeader),
1094 MockRead("hello world"),
1095 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1096 MockRead(ASYNC, OK)
1097 };
1098
1099 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
rtennetibe635732014-10-02 22:51:421100 nullptr, 0);
[email protected]4fee9672014-01-08 14:47:151101 socket_factory_.AddSocketDataProvider(&http_data);
1102
1103 // In order for a new QUIC session to be established via alternate-protocol
1104 // without racing an HTTP connection, we need the host resolution to happen
1105 // synchronously.
1106 host_resolver_.set_synchronous_mode(true);
1107 host_resolver_.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
1108 HostResolver::RequestInfo info(HostPortPair("www.google.com", 80));
1109 AddressList address;
1110 host_resolver_.Resolve(info,
1111 DEFAULT_PRIORITY,
1112 &address,
1113 CompletionCallback(),
rtennetibe635732014-10-02 22:51:421114 nullptr,
[email protected]4fee9672014-01-08 14:47:151115 net_log_.bound());
1116
[email protected]d7599122014-05-24 03:37:231117 CreateSessionWithNextProtos();
[email protected]4fee9672014-01-08 14:47:151118 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
1119 SendRequestAndExpectHttpResponse("hello world");
1120}
1121
[email protected]61a527782013-02-21 03:58:001122} // namespace test
1123} // namespace net