blob: c8532a3af2932d6a8a785f3c85006434145640fd [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"
bnc508835902015-05-12 20:10:2912#include "net/base/test_data_directory.h"
[email protected]6e7845ae2013-03-29 21:48:1113#include "net/cert/mock_cert_verifier.h"
[email protected]f2cb3cf2013-03-21 01:40:5314#include "net/dns/mock_host_resolver.h"
[email protected]61a527782013-02-21 03:58:0015#include "net/http/http_auth_handler_factory.h"
16#include "net/http/http_network_session.h"
17#include "net/http/http_network_transaction.h"
18#include "net/http/http_server_properties_impl.h"
19#include "net/http/http_stream.h"
20#include "net/http/http_stream_factory.h"
[email protected]c41737d2014-05-14 07:47:1921#include "net/http/http_transaction_test_util.h"
[email protected]b1c988b2013-06-13 06:48:1122#include "net/http/transport_security_state.h"
vishal.b62985ca92015-04-17 08:45:5123#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4624#include "net/log/test_net_log_entry.h"
25#include "net/log/test_net_log_util.h"
[email protected]61a527782013-02-21 03:58:0026#include "net/proxy/proxy_config_service_fixed.h"
27#include "net/proxy/proxy_resolver.h"
28#include "net/proxy/proxy_service.h"
bnc508835902015-05-12 20:10:2929#include "net/quic/crypto/proof_verifier_chromium.h"
[email protected]61a527782013-02-21 03:58:0030#include "net/quic/crypto/quic_decrypter.h"
31#include "net/quic/crypto/quic_encrypter.h"
32#include "net/quic/quic_framer.h"
[email protected]24e5bc52013-09-18 15:36:5833#include "net/quic/quic_http_utils.h"
[email protected]ed3fc15d2013-03-08 18:37:4434#include "net/quic/test_tools/crypto_test_utils.h"
[email protected]61a527782013-02-21 03:58:0035#include "net/quic/test_tools/mock_clock.h"
[email protected]e8ff26842013-03-22 21:02:0536#include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
[email protected]61a527782013-02-21 03:58:0037#include "net/quic/test_tools/mock_random.h"
[email protected]1e960032013-12-20 19:00:2038#include "net/quic/test_tools/quic_test_packet_maker.h"
[email protected]61a527782013-02-21 03:58:0039#include "net/quic/test_tools/quic_test_utils.h"
40#include "net/socket/client_socket_factory.h"
41#include "net/socket/mock_client_socket_pool_manager.h"
42#include "net/socket/socket_test_util.h"
43#include "net/socket/ssl_client_socket.h"
44#include "net/spdy/spdy_frame_builder.h"
45#include "net/spdy/spdy_framer.h"
[email protected]536fd0b2013-03-14 17:41:5746#include "net/ssl/ssl_config_service_defaults.h"
bnc508835902015-05-12 20:10:2947#include "net/test/cert_test_util.h"
[email protected]61a527782013-02-21 03:58:0048#include "testing/gtest/include/gtest/gtest.h"
49#include "testing/platform_test.h"
50
bnc508835902015-05-12 20:10:2951namespace net {
52namespace test {
[email protected]61a527782013-02-21 03:58:0053
54namespace {
55
56// This is the expected return from a current server advertising QUIC.
57static const char kQuicAlternateProtocolHttpHeader[] =
[email protected]4ff65372013-06-21 05:45:4658 "Alternate-Protocol: 80:quic\r\n\r\n";
[email protected]287d9412014-07-08 23:01:0059static const char kQuicAlternateProtocol50pctHttpHeader[] =
60 "Alternate-Protocol: 80:quic,p=.5\r\n\r\n";
bnc62a44f022015-04-02 15:59:4161static const char kQuicAlternateProtocolDifferentPortHttpHeader[] =
62 "Alternate-Protocol: 137:quic\r\n\r\n";
[email protected]6d1b4ed2013-07-10 03:57:5463static const char kQuicAlternateProtocolHttpsHeader[] =
64 "Alternate-Protocol: 443:quic\r\n\r\n";
[email protected]1e960032013-12-20 19:00:2065
bncb07c05532015-05-14 19:07:2066const char kDefaultServerHostName[] = "www.google.com";
67
[email protected]61a527782013-02-21 03:58:0068} // namespace
69
[email protected]1e960032013-12-20 19:00:2070// Helper class to encapsulate MockReads and MockWrites for QUIC.
71// Simplify ownership issues and the interaction with the MockSocketFactory.
72class MockQuicData {
73 public:
rcha5399e02015-04-21 19:32:0474 MockQuicData() : sequence_number_(0) {}
75
[email protected]1e960032013-12-20 19:00:2076 ~MockQuicData() {
77 STLDeleteElements(&packets_);
78 }
79
rcha5399e02015-04-21 19:32:0480 void AddSynchronousRead(scoped_ptr<QuicEncryptedPacket> packet) {
[email protected]1e960032013-12-20 19:00:2081 reads_.push_back(MockRead(SYNCHRONOUS, packet->data(), packet->length(),
82 sequence_number_++));
83 packets_.push_back(packet.release());
84 }
85
rcha5399e02015-04-21 19:32:0486 void AddRead(scoped_ptr<QuicEncryptedPacket> packet) {
87 reads_.push_back(
88 MockRead(ASYNC, packet->data(), packet->length(), sequence_number_++));
89 packets_.push_back(packet.release());
90 }
91
[email protected]1e960032013-12-20 19:00:2092 void AddRead(IoMode mode, int rv) {
rcha5399e02015-04-21 19:32:0493 reads_.push_back(MockRead(mode, rv, sequence_number_++));
[email protected]1e960032013-12-20 19:00:2094 }
95
96 void AddWrite(scoped_ptr<QuicEncryptedPacket> packet) {
97 writes_.push_back(MockWrite(SYNCHRONOUS, packet->data(), packet->length(),
98 sequence_number_++));
99 packets_.push_back(packet.release());
100 }
101
rcha5399e02015-04-21 19:32:04102 void AddSocketDataToFactory(MockClientSocketFactory* factory) {
rtennetibe635732014-10-02 22:51:42103 MockRead* reads = reads_.empty() ? nullptr : &reads_[0];
104 MockWrite* writes = writes_.empty() ? nullptr : &writes_[0];
rcha5399e02015-04-21 19:32:04105 socket_data_.reset(
106 new SequencedSocketData(reads, reads_.size(), writes, writes_.size()));
[email protected]1e960032013-12-20 19:00:20107 factory->AddSocketDataProvider(socket_data_.get());
108 }
109
110 private:
111 std::vector<QuicEncryptedPacket*> packets_;
112 std::vector<MockWrite> writes_;
113 std::vector<MockRead> reads_;
114 size_t sequence_number_;
115 scoped_ptr<SocketDataProvider> socket_data_;
116};
117
tbansal7cec3812015-02-05 21:25:12118class ProxyHeadersHandler {
119 public:
120 ProxyHeadersHandler() : was_called_(false) {}
121
122 bool was_called() { return was_called_; }
123
124 void OnBeforeProxyHeadersSent(const ProxyInfo& proxy_info,
125 HttpRequestHeaders* request_headers) {
126 was_called_ = true;
127 }
128
129 private:
130 bool was_called_;
131};
132
[email protected]1e960032013-12-20 19:00:20133class QuicNetworkTransactionTest
134 : public PlatformTest,
[email protected]5d03bbd2014-03-07 16:19:16135 public ::testing::WithParamInterface<QuicVersion> {
[email protected]61a527782013-02-21 03:58:00136 protected:
[email protected]1c04f9522013-02-21 20:32:43137 QuicNetworkTransactionTest()
rtenneti4b06ae72014-08-26 03:43:43138 : clock_(new MockClock),
bncb07c05532015-05-14 19:07:20139 maker_(GetParam(), 0, clock_, kDefaultServerHostName),
[email protected]1c04f9522013-02-21 20:32:43140 ssl_config_service_(new SSLConfigServiceDefaults),
141 proxy_service_(ProxyService::CreateDirect()),
142 auth_handler_factory_(
[email protected]dda75ab2013-06-22 22:43:30143 HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
[email protected]457d6952013-12-13 09:24:58144 random_generator_(0),
rtennetibe635732014-10-02 22:51:42145 hanging_data_(nullptr, 0, nullptr, 0) {
[email protected]aa9b14d2013-05-10 23:45:19146 request_.method = "GET";
bncb07c05532015-05-14 19:07:20147 std::string url("http://");
148 url.append(kDefaultServerHostName);
149 request_.url = GURL(url);
[email protected]aa9b14d2013-05-10 23:45:19150 request_.load_flags = 0;
[email protected]98a9d1252014-04-04 00:43:59151 clock_->AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
[email protected]1c04f9522013-02-21 20:32:43152 }
[email protected]61a527782013-02-21 03:58:00153
dcheng67be2b1f2014-10-27 21:47:29154 void SetUp() override {
[email protected]61a527782013-02-21 03:58:00155 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34156 base::MessageLoop::current()->RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00157 }
158
dcheng67be2b1f2014-10-27 21:47:29159 void TearDown() override {
[email protected]61a527782013-02-21 03:58:00160 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
161 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:34162 base::MessageLoop::current()->RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00163 PlatformTest::TearDown();
164 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34165 base::MessageLoop::current()->RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00166 }
167
[email protected]3316d422013-05-03 21:45:30168 scoped_ptr<QuicEncryptedPacket> ConstructConnectionClosePacket(
169 QuicPacketSequenceNumber num) {
[email protected]1e960032013-12-20 19:00:20170 return maker_.MakeConnectionClosePacket(num);
[email protected]3316d422013-05-03 21:45:30171 }
172
[email protected]61a527782013-02-21 03:58:00173 scoped_ptr<QuicEncryptedPacket> ConstructAckPacket(
174 QuicPacketSequenceNumber largest_received,
175 QuicPacketSequenceNumber least_unacked) {
[email protected]1e960032013-12-20 19:00:20176 return maker_.MakeAckPacket(2, largest_received, least_unacked, true);
177 }
[email protected]61a527782013-02-21 03:58:00178
[email protected]1e960032013-12-20 19:00:20179 SpdyHeaderBlock GetRequestHeaders(const std::string& method,
180 const std::string& scheme,
181 const std::string& path) {
182 return maker_.GetRequestHeaders(method, scheme, path);
[email protected]61a527782013-02-21 03:58:00183 }
184
[email protected]1e960032013-12-20 19:00:20185 SpdyHeaderBlock GetResponseHeaders(const std::string& status) {
186 return maker_.GetResponseHeaders(status);
[email protected]61a527782013-02-21 03:58:00187 }
188
[email protected]1e960032013-12-20 19:00:20189 scoped_ptr<QuicEncryptedPacket> ConstructDataPacket(
[email protected]61a527782013-02-21 03:58:00190 QuicPacketSequenceNumber sequence_number,
[email protected]98b20ce2013-05-10 05:55:26191 QuicStreamId stream_id,
[email protected]e8ff26842013-03-22 21:02:05192 bool should_include_version,
[email protected]61a527782013-02-21 03:58:00193 bool fin,
194 QuicStreamOffset offset,
195 base::StringPiece data) {
[email protected]1e960032013-12-20 19:00:20196 return maker_.MakeDataPacket(
197 sequence_number, stream_id, should_include_version, fin, offset, data);
[email protected]61a527782013-02-21 03:58:00198 }
199
[email protected]1e960032013-12-20 19:00:20200 scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket(
201 QuicPacketSequenceNumber sequence_number,
202 QuicStreamId stream_id,
203 bool should_include_version,
204 bool fin,
205 const SpdyHeaderBlock& headers) {
rtennetif4bdb542015-01-21 14:33:05206 QuicPriority priority =
207 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
208 return maker_.MakeRequestHeadersPacket(sequence_number, stream_id,
209 should_include_version, fin,
210 priority, headers);
[email protected]61a527782013-02-21 03:58:00211 }
212
[email protected]1e960032013-12-20 19:00:20213 scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket(
214 QuicPacketSequenceNumber sequence_number,
215 QuicStreamId stream_id,
216 bool should_include_version,
217 bool fin,
218 const SpdyHeaderBlock& headers) {
219 return maker_.MakeResponseHeadersPacket(
220 sequence_number, stream_id, should_include_version, fin, headers);
[email protected]61a527782013-02-21 03:58:00221 }
222
223 void CreateSession() {
[email protected]d7599122014-05-24 03:37:23224 CreateSessionWithFactory(&socket_factory_, false);
[email protected]dda75ab2013-06-22 22:43:30225 }
226
[email protected]d7599122014-05-24 03:37:23227 void CreateSessionWithNextProtos() {
228 CreateSessionWithFactory(&socket_factory_, true);
229 }
230
231 // If |use_next_protos| is true, enables SPDY and QUIC.
232 void CreateSessionWithFactory(ClientSocketFactory* socket_factory,
233 bool use_next_protos) {
[email protected]4dca587c2013-03-07 16:54:47234 params_.enable_quic = true;
235 params_.quic_clock = clock_;
236 params_.quic_random = &random_generator_;
[email protected]dda75ab2013-06-22 22:43:30237 params_.client_socket_factory = socket_factory;
[email protected]e8ff26842013-03-22 21:02:05238 params_.quic_crypto_client_stream_factory = &crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:43239 params_.host_resolver = &host_resolver_;
240 params_.cert_verifier = &cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:11241 params_.transport_security_state = &transport_security_state_;
[email protected]1c04f9522013-02-21 20:32:43242 params_.proxy_service = proxy_service_.get();
243 params_.ssl_config_service = ssl_config_service_.get();
244 params_.http_auth_handler_factory = auth_handler_factory_.get();
bnc6be245c12015-05-15 11:24:07245 params_.http_server_properties = http_server_properties_.GetWeakPtr();
[email protected]1e960032013-12-20 19:00:20246 params_.quic_supported_versions = SupportedVersions(GetParam());
[email protected]61a527782013-02-21 03:58:00247
[email protected]d7599122014-05-24 03:37:23248 if (use_next_protos) {
249 params_.use_alternate_protocols = true;
bnc3bb2c232014-11-07 20:26:39250 params_.next_protos = NextProtosWithSpdyAndQuic(true, true);
[email protected]d7599122014-05-24 03:37:23251 }
252
[email protected]61a527782013-02-21 03:58:00253 session_ = new HttpNetworkSession(params_);
[email protected]11c05872013-08-20 02:04:12254 session_->quic_stream_factory()->set_require_confirmation(false);
rch185ebee2015-07-14 23:56:22255 ASSERT_EQ(params_.quic_socket_receive_buffer_size,
256 session_->quic_stream_factory()->socket_receive_buffer_size());
[email protected]61a527782013-02-21 03:58:00257 }
258
[email protected]aa9b14d2013-05-10 23:45:19259 void CheckWasQuicResponse(const scoped_ptr<HttpNetworkTransaction>& trans) {
260 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42261 ASSERT_TRUE(response != nullptr);
262 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19263 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
264 EXPECT_TRUE(response->was_fetched_via_spdy);
265 EXPECT_TRUE(response->was_npn_negotiated);
266 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_QUIC1_SPDY3,
267 response->connection_info);
268 }
269
bnc62a44f022015-04-02 15:59:41270 void CheckResponsePort(const scoped_ptr<HttpNetworkTransaction>& trans,
271 uint16 port) {
272 const HttpResponseInfo* response = trans->GetResponseInfo();
273 ASSERT_TRUE(response != nullptr);
274 EXPECT_EQ(port, response->socket_address.port());
275 }
276
[email protected]aa9b14d2013-05-10 23:45:19277 void CheckWasHttpResponse(const scoped_ptr<HttpNetworkTransaction>& trans) {
278 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42279 ASSERT_TRUE(response != nullptr);
280 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19281 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
282 EXPECT_FALSE(response->was_fetched_via_spdy);
283 EXPECT_FALSE(response->was_npn_negotiated);
284 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1,
285 response->connection_info);
286 }
287
bncffc2fdf2015-05-14 18:29:49288 void CheckResponseData(const scoped_ptr<HttpNetworkTransaction>& trans,
[email protected]aa9b14d2013-05-10 23:45:19289 const std::string& expected) {
290 std::string response_data;
bncffc2fdf2015-05-14 18:29:49291 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]aa9b14d2013-05-10 23:45:19292 EXPECT_EQ(expected, response_data);
293 }
294
bncffc2fdf2015-05-14 18:29:49295 void RunTransaction(const scoped_ptr<HttpNetworkTransaction>& trans) {
[email protected]aa9b14d2013-05-10 23:45:19296 TestCompletionCallback callback;
297 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
298 EXPECT_EQ(ERR_IO_PENDING, rv);
299 EXPECT_EQ(OK, callback.WaitForResult());
300 }
301
302 void SendRequestAndExpectHttpResponse(const std::string& expected) {
303 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:50304 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
bncffc2fdf2015-05-14 18:29:49305 RunTransaction(trans);
[email protected]aa9b14d2013-05-10 23:45:19306 CheckWasHttpResponse(trans);
bncffc2fdf2015-05-14 18:29:49307 CheckResponseData(trans, expected);
[email protected]aa9b14d2013-05-10 23:45:19308 }
309
310 void SendRequestAndExpectQuicResponse(const std::string& expected) {
bnc62a44f022015-04-02 15:59:41311 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 80);
tbansal7cec3812015-02-05 21:25:12312 }
313
bnc62a44f022015-04-02 15:59:41314 void SendRequestAndExpectQuicResponseOnPort(const std::string& expected,
315 uint16 port) {
316 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, port);
317 }
318
319 void SendRequestAndExpectQuicResponseFromProxyOnPort(
320 const std::string& expected,
321 uint16 port) {
322 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, true, port);
[email protected]aa9b14d2013-05-10 23:45:19323 }
324
325 void AddQuicAlternateProtocolMapping(
326 MockCryptoClientStream::HandshakeMode handshake_mode) {
327 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
bnccacc0992015-03-20 20:22:22328 HostPortPair host_port_pair = HostPortPair::FromURL(request_.url);
329 AlternativeService alternative_service(QUIC, host_port_pair.host(), 80);
bnc6be245c12015-05-15 11:24:07330 http_server_properties_.SetAlternativeService(host_port_pair,
331 alternative_service, 1.0);
[email protected]aa9b14d2013-05-10 23:45:19332 }
333
334 void ExpectBrokenAlternateProtocolMapping() {
bnc8445b3002015-03-13 01:57:09335 const HostPortPair origin = HostPortPair::FromURL(request_.url);
bncd9b132e2015-07-08 05:16:10336 const AlternativeServiceVector alternative_service_vector =
337 http_server_properties_.GetAlternativeServices(origin);
338 EXPECT_EQ(1u, alternative_service_vector.size());
bnc6be245c12015-05-15 11:24:07339 EXPECT_TRUE(http_server_properties_.IsAlternativeServiceBroken(
bncd9b132e2015-07-08 05:16:10340 alternative_service_vector[0]));
[email protected]aa9b14d2013-05-10 23:45:19341 }
342
[email protected]4d590c9c2014-05-02 05:14:33343 void ExpectQuicAlternateProtocolMapping() {
bncd9b132e2015-07-08 05:16:10344 const HostPortPair origin = HostPortPair::FromURL(request_.url);
345 const AlternativeServiceVector alternative_service_vector =
346 http_server_properties_.GetAlternativeServices(origin);
347 EXPECT_EQ(1u, alternative_service_vector.size());
348 EXPECT_EQ(QUIC, alternative_service_vector[0].protocol);
[email protected]4d590c9c2014-05-02 05:14:33349 }
350
[email protected]aa9b14d2013-05-10 23:45:19351 void AddHangingNonAlternateProtocolSocketData() {
[email protected]dda75ab2013-06-22 22:43:30352 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
353 hanging_data_.set_connect_data(hanging_connect);
354 socket_factory_.AddSocketDataProvider(&hanging_data_);
[email protected]aa9b14d2013-05-10 23:45:19355 }
356
rtenneti4b06ae72014-08-26 03:43:43357 MockClock* clock_; // Owned by QuicStreamFactory after CreateSession.
[email protected]1e960032013-12-20 19:00:20358 QuicTestPacketMaker maker_;
[email protected]61a527782013-02-21 03:58:00359 scoped_refptr<HttpNetworkSession> session_;
360 MockClientSocketFactory socket_factory_;
[email protected]e8ff26842013-03-22 21:02:05361 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:43362 MockHostResolver host_resolver_;
363 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:11364 TransportSecurityState transport_security_state_;
[email protected]1c04f9522013-02-21 20:32:43365 scoped_refptr<SSLConfigServiceDefaults> ssl_config_service_;
366 scoped_ptr<ProxyService> proxy_service_;
367 scoped_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
[email protected]61a527782013-02-21 03:58:00368 MockRandom random_generator_;
bnc6be245c12015-05-15 11:24:07369 HttpServerPropertiesImpl http_server_properties_;
[email protected]61a527782013-02-21 03:58:00370 HttpNetworkSession::Params params_;
[email protected]aa9b14d2013-05-10 23:45:19371 HttpRequestInfo request_;
vishal.b62985ca92015-04-17 08:45:51372 BoundTestNetLog net_log_;
[email protected]dda75ab2013-06-22 22:43:30373 StaticSocketDataProvider hanging_data_;
tbansal7cec3812015-02-05 21:25:12374
375 private:
376 void SendRequestAndExpectQuicResponseMaybeFromProxy(
377 const std::string& expected,
bnc62a44f022015-04-02 15:59:41378 bool used_proxy,
379 uint16 port) {
tbansal7cec3812015-02-05 21:25:12380 scoped_ptr<HttpNetworkTransaction> trans(
381 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
382 ProxyHeadersHandler proxy_headers_handler;
383 trans->SetBeforeProxyHeadersSentCallback(
384 base::Bind(&ProxyHeadersHandler::OnBeforeProxyHeadersSent,
385 base::Unretained(&proxy_headers_handler)));
bncffc2fdf2015-05-14 18:29:49386 RunTransaction(trans);
tbansal7cec3812015-02-05 21:25:12387 CheckWasQuicResponse(trans);
bnc62a44f022015-04-02 15:59:41388 CheckResponsePort(trans, port);
bncffc2fdf2015-05-14 18:29:49389 CheckResponseData(trans, expected);
tbansal7cec3812015-02-05 21:25:12390 EXPECT_EQ(used_proxy, proxy_headers_handler.was_called());
391 }
[email protected]61a527782013-02-21 03:58:00392};
393
[email protected]1e960032013-12-20 19:00:20394INSTANTIATE_TEST_CASE_P(Version, QuicNetworkTransactionTest,
395 ::testing::ValuesIn(QuicSupportedVersions()));
396
397TEST_P(QuicNetworkTransactionTest, ForceQuic) {
rchff012122015-07-27 20:01:40398 // TODO(rch): switch these tests to use secure QUIC.
399 params_.enable_insecure_quic = true;
[email protected]49e85332013-06-04 04:18:03400 params_.origin_to_force_quic_on =
401 HostPortPair::FromString("www.google.com:80");
[email protected]4dca587c2013-03-07 16:54:47402
[email protected]1e960032013-12-20 19:00:20403 MockQuicData mock_quic_data;
[email protected]92bf17c2014-03-03 21:14:03404 mock_quic_data.AddWrite(
[email protected]66ae5962014-05-22 11:13:05405 ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
[email protected]92bf17c2014-03-03 21:14:03406 GetRequestHeaders("GET", "http", "/")));
407 mock_quic_data.AddRead(
[email protected]66ae5962014-05-22 11:13:05408 ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false,
[email protected]92bf17c2014-03-03 21:14:03409 GetResponseHeaders("200 OK")));
410 mock_quic_data.AddRead(
[email protected]66ae5962014-05-22 11:13:05411 ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
[email protected]92bf17c2014-03-03 21:14:03412 mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
[email protected]1e960032013-12-20 19:00:20413 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
[email protected]4dca587c2013-03-07 16:54:47414
rcha5399e02015-04-21 19:32:04415 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4dca587c2013-03-07 16:54:47416
[email protected]aa9b14d2013-05-10 23:45:19417 // The non-alternate protocol job needs to hang in order to guarantee that
418 // the alternate-protocol job will "win".
419 AddHangingNonAlternateProtocolSocketData();
[email protected]4dca587c2013-03-07 16:54:47420
421 CreateSession();
[email protected]4dca587c2013-03-07 16:54:47422
[email protected]aa9b14d2013-05-10 23:45:19423 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:47424
[email protected]98b20ce2013-05-10 05:55:26425 // Check that the NetLog was filled reasonably.
mmenke43758e62015-05-04 21:09:46426 TestNetLogEntry::List entries;
[email protected]aa9b14d2013-05-10 23:45:19427 net_log_.GetEntries(&entries);
[email protected]98b20ce2013-05-10 05:55:26428 EXPECT_LT(0u, entries.size());
429
430 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:29431 int pos = ExpectLogContainsSomewhere(
432 entries, 0, NetLog::TYPE_QUIC_SESSION_PACKET_RECEIVED,
433 NetLog::PHASE_NONE);
[email protected]98b20ce2013-05-10 05:55:26434 EXPECT_LT(0, pos);
435
436 // ... and also a TYPE_QUIC_SESSION_PACKET_HEADER_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:29437 pos = ExpectLogContainsSomewhere(
438 entries, 0, NetLog::TYPE_QUIC_SESSION_PACKET_HEADER_RECEIVED,
439 NetLog::PHASE_NONE);
[email protected]98b20ce2013-05-10 05:55:26440 EXPECT_LT(0, pos);
441
442 std::string packet_sequence_number;
443 ASSERT_TRUE(entries[pos].GetStringValue(
444 "packet_sequence_number", &packet_sequence_number));
445 EXPECT_EQ("1", packet_sequence_number);
446
447 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:29448 pos = ExpectLogContainsSomewhere(
449 entries, 0, NetLog::TYPE_QUIC_SESSION_STREAM_FRAME_RECEIVED,
450 NetLog::PHASE_NONE);
[email protected]98b20ce2013-05-10 05:55:26451 EXPECT_LT(0, pos);
452
453 int log_stream_id;
454 ASSERT_TRUE(entries[pos].GetIntegerValue("stream_id", &log_stream_id));
[email protected]1e960032013-12-20 19:00:20455 EXPECT_EQ(3, log_stream_id);
[email protected]4dca587c2013-03-07 16:54:47456}
457
[email protected]cf3e3cd62014-02-05 16:16:16458TEST_P(QuicNetworkTransactionTest, QuicProxy) {
rchff012122015-07-27 20:01:40459 params_.enable_insecure_quic = true;
tbansaled0aecc2015-02-20 03:44:18460 params_.enable_quic_for_proxies = true;
[email protected]cf3e3cd62014-02-05 16:16:16461 proxy_service_.reset(
462 ProxyService::CreateFixedFromPacResult("QUIC myproxy:70"));
463
[email protected]cf3e3cd62014-02-05 16:16:16464 MockQuicData mock_quic_data;
[email protected]92bf17c2014-03-03 21:14:03465 mock_quic_data.AddWrite(
[email protected]66ae5962014-05-22 11:13:05466 ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
[email protected]92bf17c2014-03-03 21:14:03467 GetRequestHeaders("GET", "http", "/")));
468 mock_quic_data.AddRead(
[email protected]66ae5962014-05-22 11:13:05469 ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false,
[email protected]92bf17c2014-03-03 21:14:03470 GetResponseHeaders("200 OK")));
471 mock_quic_data.AddRead(
[email protected]66ae5962014-05-22 11:13:05472 ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
[email protected]92bf17c2014-03-03 21:14:03473 mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
[email protected]cf3e3cd62014-02-05 16:16:16474 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
475
rcha5399e02015-04-21 19:32:04476 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cf3e3cd62014-02-05 16:16:16477
478 // There is no need to set up an alternate protocol job, because
479 // no attempt will be made to speak to the proxy over TCP.
480
481 CreateSession();
482
bnc62a44f022015-04-02 15:59:41483 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
[email protected]cf3e3cd62014-02-05 16:16:16484}
485
bnc313ba9c2015-06-11 15:42:31486// Regression test for https://crbug.com/492458. Test that for an HTTP
487// connection through a QUIC proxy, the certificate exhibited by the proxy is
488// checked against the proxy hostname, not the origin hostname.
489TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
490 const std::string origin_host = "news.example.com";
491 const std::string proxy_host = "www.example.org";
492
rchff012122015-07-27 20:01:40493 params_.enable_insecure_quic = true;
bnc313ba9c2015-06-11 15:42:31494 params_.enable_quic_for_proxies = true;
495 proxy_service_.reset(
496 ProxyService::CreateFixedFromPacResult("QUIC " + proxy_host + ":70"));
497
498 maker_.set_hostname(origin_host);
499 MockQuicData mock_quic_data;
500 mock_quic_data.AddWrite(
501 ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
502 GetRequestHeaders("GET", "http", "/")));
503 mock_quic_data.AddRead(ConstructResponseHeadersPacket(
504 1, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK")));
505 mock_quic_data.AddRead(
506 ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
507 mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
508 mock_quic_data.AddRead(SYNCHRONOUS, 0);
509 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
510
511 scoped_refptr<X509Certificate> cert(
512 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
513 ASSERT_TRUE(cert.get());
514 // This certificate is valid for the proxy, but not for the origin.
515 bool common_name_fallback_used;
516 EXPECT_TRUE(cert->VerifyNameMatch(proxy_host, &common_name_fallback_used));
517 EXPECT_FALSE(cert->VerifyNameMatch(origin_host, &common_name_fallback_used));
518 ProofVerifyDetailsChromium verify_details;
519 verify_details.cert_verify_result.verified_cert = cert;
520 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
521
522 request_.url = GURL("http://" + origin_host);
523 AddHangingNonAlternateProtocolSocketData();
524 CreateSessionWithNextProtos();
525 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
526 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
527}
528
[email protected]1e960032013-12-20 19:00:20529TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
rchff012122015-07-27 20:01:40530 params_.enable_insecure_quic = true;
[email protected]49e85332013-06-04 04:18:03531 params_.origin_to_force_quic_on =
532 HostPortPair::FromString("www.google.com:80");
[email protected]cebe3282013-05-22 23:49:30533
[email protected]1e960032013-12-20 19:00:20534 MockQuicData mock_quic_data;
535 mock_quic_data.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
536
rcha5399e02015-04-21 19:32:04537 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:30538
539 CreateSession();
540
541 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:50542 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
[email protected]cebe3282013-05-22 23:49:30543 TestCompletionCallback callback;
544 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
545 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0b2294d32013-08-02 00:46:36546 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]cebe3282013-05-22 23:49:30547}
548
[email protected]1e960032013-12-20 19:00:20549TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
[email protected]4dca587c2013-03-07 16:54:47550 // Attempt to "force" quic on 443, which will not be honored.
[email protected]49e85332013-06-04 04:18:03551 params_.origin_to_force_quic_on =
552 HostPortPair::FromString("www.google.com:443");
[email protected]4dca587c2013-03-07 16:54:47553
[email protected]aa9b14d2013-05-10 23:45:19554 MockRead http_reads[] = {
[email protected]4dca587c2013-03-07 16:54:47555 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
556 MockRead("hello world"),
557 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
558 MockRead(ASYNC, OK)
559 };
560
rtennetibe635732014-10-02 22:51:42561 StaticSocketDataProvider data(http_reads, arraysize(http_reads), nullptr, 0);
[email protected]4dca587c2013-03-07 16:54:47562 socket_factory_.AddSocketDataProvider(&data);
563 SSLSocketDataProvider ssl(ASYNC, OK);
564 socket_factory_.AddSSLSocketDataProvider(&ssl);
565
[email protected]4dca587c2013-03-07 16:54:47566 CreateSession();
[email protected]4dca587c2013-03-07 16:54:47567
[email protected]aa9b14d2013-05-10 23:45:19568 SendRequestAndExpectHttpResponse("hello world");
[email protected]4dca587c2013-03-07 16:54:47569}
570
[email protected]1e960032013-12-20 19:00:20571TEST_P(QuicNetworkTransactionTest, UseAlternateProtocolForQuic) {
rchff012122015-07-27 20:01:40572 params_.enable_insecure_quic = true;
573
[email protected]aa9b14d2013-05-10 23:45:19574 MockRead http_reads[] = {
[email protected]61a527782013-02-21 03:58:00575 MockRead("HTTP/1.1 200 OK\r\n"),
576 MockRead(kQuicAlternateProtocolHttpHeader),
577 MockRead("hello world"),
578 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
579 MockRead(ASYNC, OK)
580 };
581
[email protected]aa9b14d2013-05-10 23:45:19582 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
rtennetibe635732014-10-02 22:51:42583 nullptr, 0);
[email protected]aa9b14d2013-05-10 23:45:19584 socket_factory_.AddSocketDataProvider(&http_data);
[email protected]61a527782013-02-21 03:58:00585
[email protected]1e960032013-12-20 19:00:20586 MockQuicData mock_quic_data;
[email protected]92bf17c2014-03-03 21:14:03587 mock_quic_data.AddWrite(
[email protected]66ae5962014-05-22 11:13:05588 ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
[email protected]92bf17c2014-03-03 21:14:03589 GetRequestHeaders("GET", "http", "/")));
590 mock_quic_data.AddRead(
[email protected]66ae5962014-05-22 11:13:05591 ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false,
[email protected]92bf17c2014-03-03 21:14:03592 GetResponseHeaders("200 OK")));
593 mock_quic_data.AddRead(
[email protected]66ae5962014-05-22 11:13:05594 ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
[email protected]92bf17c2014-03-03 21:14:03595 mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
[email protected]1e960032013-12-20 19:00:20596 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
[email protected]61a527782013-02-21 03:58:00597
rcha5399e02015-04-21 19:32:04598 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]61a527782013-02-21 03:58:00599
[email protected]aa9b14d2013-05-10 23:45:19600 // The non-alternate protocol job needs to hang in order to guarantee that
601 // the alternate-protocol job will "win".
602 AddHangingNonAlternateProtocolSocketData();
[email protected]61a527782013-02-21 03:58:00603
[email protected]d7599122014-05-24 03:37:23604 CreateSessionWithNextProtos();
[email protected]61a527782013-02-21 03:58:00605
[email protected]aa9b14d2013-05-10 23:45:19606 SendRequestAndExpectHttpResponse("hello world");
607 SendRequestAndExpectQuicResponse("hello!");
[email protected]61a527782013-02-21 03:58:00608}
609
bnc62a44f022015-04-02 15:59:41610TEST_P(QuicNetworkTransactionTest, AlternateProtocolDifferentPort) {
rchff012122015-07-27 20:01:40611 params_.enable_insecure_quic = true;
612
bnc62a44f022015-04-02 15:59:41613 MockRead http_reads[] = {
614 MockRead("HTTP/1.1 200 OK\r\n"),
615 MockRead(kQuicAlternateProtocolDifferentPortHttpHeader),
616 MockRead("hello world"),
617 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
618 MockRead(ASYNC, OK)};
619
620 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
621 0);
622 socket_factory_.AddSocketDataProvider(&http_data);
623
624 MockQuicData mock_quic_data;
625 mock_quic_data.AddWrite(
626 ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
627 GetRequestHeaders("GET", "http", "/")));
628 mock_quic_data.AddRead(ConstructResponseHeadersPacket(
629 1, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK")));
630 mock_quic_data.AddRead(
631 ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
632 mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
633 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
634
rcha5399e02015-04-21 19:32:04635 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc62a44f022015-04-02 15:59:41636
637 // The non-alternate protocol job needs to hang in order to guarantee that
638 // the alternate-protocol job will "win".
639 AddHangingNonAlternateProtocolSocketData();
640
641 CreateSessionWithNextProtos();
642
643 SendRequestAndExpectHttpResponse("hello world");
644 SendRequestAndExpectQuicResponseOnPort("hello!", 137);
645}
646
bncae8db8402015-03-26 20:13:50647TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
rchff012122015-07-27 20:01:40648 params_.enable_insecure_quic = true;
649
bncae8db8402015-03-26 20:13:50650 MockRead http_reads[] = {
651 MockRead("HTTP/1.1 200 OK\r\n"),
652 MockRead(kQuicAlternateProtocolHttpHeader),
653 MockRead("hello world"),
654 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
655 MockRead(ASYNC, OK)};
656
657 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
658 0);
659 socket_factory_.AddSocketDataProvider(&http_data);
660
661 MockQuicData mock_quic_data;
662 mock_quic_data.AddWrite(
663 ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
664 GetRequestHeaders("GET", "http", "/")));
665 mock_quic_data.AddRead(ConstructResponseHeadersPacket(
666 1, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK")));
667 mock_quic_data.AddRead(
668 ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
669 mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
670 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
671
rcha5399e02015-04-21 19:32:04672 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bncae8db8402015-03-26 20:13:50673
674 // The non-alternate protocol job needs to hang in order to guarantee that
675 // the alternate-protocol job will "win".
676 AddHangingNonAlternateProtocolSocketData();
677
678 CreateSessionWithNextProtos();
679
680 AlternativeService alternative_service(QUIC,
681 HostPortPair::FromURL(request_.url));
bnc6be245c12015-05-15 11:24:07682 http_server_properties_.MarkAlternativeServiceRecentlyBroken(
bncae8db8402015-03-26 20:13:50683 alternative_service);
bnc6be245c12015-05-15 11:24:07684 EXPECT_TRUE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
685 alternative_service));
bncae8db8402015-03-26 20:13:50686
687 SendRequestAndExpectHttpResponse("hello world");
688 SendRequestAndExpectQuicResponse("hello!");
689
bnc6be245c12015-05-15 11:24:07690 EXPECT_FALSE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
691 alternative_service));
bncae8db8402015-03-26 20:13:50692}
693
[email protected]287d9412014-07-08 23:01:00694TEST_P(QuicNetworkTransactionTest, UseAlternateProtocolProbabilityForQuic) {
rchff012122015-07-27 20:01:40695 params_.enable_insecure_quic = true;
696
[email protected]287d9412014-07-08 23:01:00697 MockRead http_reads[] = {
698 MockRead("HTTP/1.1 200 OK\r\n"),
699 MockRead(kQuicAlternateProtocol50pctHttpHeader),
700 MockRead("hello world"),
701 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
702 MockRead(ASYNC, OK)
703 };
704
705 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
rtennetibe635732014-10-02 22:51:42706 nullptr, 0);
[email protected]287d9412014-07-08 23:01:00707 socket_factory_.AddSocketDataProvider(&http_data);
708
709 MockQuicData mock_quic_data;
710 mock_quic_data.AddWrite(
711 ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
712 GetRequestHeaders("GET", "http", "/")));
713 mock_quic_data.AddRead(
714 ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false,
715 GetResponseHeaders("200 OK")));
716 mock_quic_data.AddRead(
717 ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
718 mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
719 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
720
rcha5399e02015-04-21 19:32:04721 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]287d9412014-07-08 23:01:00722
723 // The non-alternate protocol job needs to hang in order to guarantee that
724 // the alternate-protocol job will "win".
725 AddHangingNonAlternateProtocolSocketData();
726
bnc62891a52015-04-27 14:14:12727 params_.alternative_service_probability_threshold = .25;
[email protected]287d9412014-07-08 23:01:00728 CreateSessionWithNextProtos();
729
730 SendRequestAndExpectHttpResponse("hello world");
731 SendRequestAndExpectQuicResponse("hello!");
732}
733
734TEST_P(QuicNetworkTransactionTest, DontUseAlternateProtocolProbabilityForQuic) {
rchff012122015-07-27 20:01:40735 params_.enable_insecure_quic = true;
736
[email protected]287d9412014-07-08 23:01:00737 MockRead http_reads[] = {
738 MockRead("HTTP/1.1 200 OK\r\n"),
739 MockRead(kQuicAlternateProtocol50pctHttpHeader),
740 MockRead("hello world"),
741 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
742 MockRead(ASYNC, OK)
743 };
744
745 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
rtennetibe635732014-10-02 22:51:42746 nullptr, 0);
[email protected]287d9412014-07-08 23:01:00747 socket_factory_.AddSocketDataProvider(&http_data);
748 socket_factory_.AddSocketDataProvider(&http_data);
749
bnc62891a52015-04-27 14:14:12750 params_.alternative_service_probability_threshold = .75;
[email protected]287d9412014-07-08 23:01:00751 CreateSessionWithNextProtos();
752
753 SendRequestAndExpectHttpResponse("hello world");
754 SendRequestAndExpectHttpResponse("hello world");
755}
756
rch405ed7a2015-05-12 01:10:16757TEST_P(QuicNetworkTransactionTest, DontUseAlternateProtocolForInsecureQuic) {
rchff012122015-07-27 20:01:40758 params_.enable_insecure_quic = true;
759
rch405ed7a2015-05-12 01:10:16760 MockRead http_reads[] = {MockRead("HTTP/1.1 200 OK\r\n"),
761 MockRead("Content-length: 11\r\n"),
762 MockRead("Alternate-Protocol: 443:quic\r\n\r\n"),
763 MockRead("hello world"),
764 MockRead("HTTP/1.1 200 OK\r\n"),
765 MockRead("Content-length: 11\r\n"),
766 MockRead("Alternate-Protocol: 443:quic\r\n\r\n"),
767 MockRead("hello world"),
768 MockRead(ASYNC, OK)};
769
770 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
771 0);
772 socket_factory_.AddSocketDataProvider(&http_data);
773 socket_factory_.AddSocketDataProvider(&http_data);
774
rchff012122015-07-27 20:01:40775 params_.enable_insecure_quic = false;
rch405ed7a2015-05-12 01:10:16776 CreateSessionWithNextProtos();
777
778 SendRequestAndExpectHttpResponse("hello world");
779 SendRequestAndExpectHttpResponse("hello world");
780}
781
[email protected]287d9412014-07-08 23:01:00782TEST_P(QuicNetworkTransactionTest,
783 DontUseAlternateProtocolWithBadProbabilityForQuic) {
rchff012122015-07-27 20:01:40784 params_.enable_insecure_quic = true;
785
[email protected]287d9412014-07-08 23:01:00786 MockRead http_reads[] = {
787 MockRead("HTTP/1.1 200 OK\r\n"),
788 MockRead("Alternate-Protocol: 443:quic,p=2\r\n\r\n"),
789 MockRead("hello world"),
790 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
791 MockRead(ASYNC, OK)
792 };
793
794 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
rtennetibe635732014-10-02 22:51:42795 nullptr, 0);
[email protected]287d9412014-07-08 23:01:00796 socket_factory_.AddSocketDataProvider(&http_data);
797 socket_factory_.AddSocketDataProvider(&http_data);
798
bnc62891a52015-04-27 14:14:12799 params_.alternative_service_probability_threshold = .75;
[email protected]287d9412014-07-08 23:01:00800 CreateSessionWithNextProtos();
801
802 SendRequestAndExpectHttpResponse("hello world");
803 SendRequestAndExpectHttpResponse("hello world");
804}
805
[email protected]1e960032013-12-20 19:00:20806TEST_P(QuicNetworkTransactionTest, UseAlternateProtocolForQuicForHttps) {
rchff012122015-07-27 20:01:40807 params_.enable_insecure_quic = true;
[email protected]6d1b4ed2013-07-10 03:57:54808 params_.origin_to_force_quic_on =
809 HostPortPair::FromString("www.google.com:443");
[email protected]6d1b4ed2013-07-10 03:57:54810
811 MockRead http_reads[] = {
812 MockRead("HTTP/1.1 200 OK\r\n"),
813 MockRead(kQuicAlternateProtocolHttpsHeader),
814 MockRead("hello world"),
815 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
816 MockRead(ASYNC, OK)
817 };
818
819 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
rtennetibe635732014-10-02 22:51:42820 nullptr, 0);
[email protected]6d1b4ed2013-07-10 03:57:54821 socket_factory_.AddSocketDataProvider(&http_data);
822
[email protected]1e960032013-12-20 19:00:20823 MockQuicData mock_quic_data;
[email protected]92bf17c2014-03-03 21:14:03824 mock_quic_data.AddWrite(
[email protected]66ae5962014-05-22 11:13:05825 ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
[email protected]92bf17c2014-03-03 21:14:03826 GetRequestHeaders("GET", "http", "/")));
827 mock_quic_data.AddRead(
[email protected]66ae5962014-05-22 11:13:05828 ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false,
[email protected]92bf17c2014-03-03 21:14:03829 GetResponseHeaders("200 OK")));
830 mock_quic_data.AddRead(
[email protected]66ae5962014-05-22 11:13:05831 ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
[email protected]92bf17c2014-03-03 21:14:03832 mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
[email protected]1e960032013-12-20 19:00:20833 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
[email protected]6d1b4ed2013-07-10 03:57:54834
rcha5399e02015-04-21 19:32:04835 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]6d1b4ed2013-07-10 03:57:54836
837 // The non-alternate protocol job needs to hang in order to guarantee that
838 // the alternate-protocol job will "win".
839 AddHangingNonAlternateProtocolSocketData();
840
[email protected]d7599122014-05-24 03:37:23841 CreateSessionWithNextProtos();
[email protected]6d1b4ed2013-07-10 03:57:54842
843 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
844 SendRequestAndExpectHttpResponse("hello world");
845}
846
bnccb7ff3c2015-05-21 20:51:55847class QuicAltSvcCertificateVerificationTest
848 : public QuicNetworkTransactionTest {
849 public:
850 void Run(bool valid) {
851 HostPortPair origin(valid ? "mail.example.org" : "invalid.example.org",
852 443);
853 HostPortPair alternative("www.example.org", 443);
854 std::string url("https://");
855 url.append(origin.host());
856 url.append(":443");
857 request_.url = GURL(url);
858
859 maker_.set_hostname(origin.host());
860 MockQuicData mock_quic_data;
861 mock_quic_data.AddWrite(
862 ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
863 GetRequestHeaders("GET", "https", "/")));
864 mock_quic_data.AddRead(ConstructResponseHeadersPacket(
865 1, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK")));
866 mock_quic_data.AddRead(
867 ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
868 mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
869 mock_quic_data.AddRead(SYNCHRONOUS, 0);
870 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
871
872 scoped_refptr<X509Certificate> cert(
873 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
874 ASSERT_TRUE(cert.get());
875 bool common_name_fallback_used;
876 EXPECT_EQ(valid,
877 cert->VerifyNameMatch(origin.host(), &common_name_fallback_used));
878 EXPECT_TRUE(
879 cert->VerifyNameMatch(alternative.host(), &common_name_fallback_used));
880 ProofVerifyDetailsChromium verify_details;
881 verify_details.cert_verify_result.verified_cert = cert;
882 verify_details.cert_verify_result.is_issued_by_known_root = true;
883 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
884 crypto_client_stream_factory_.set_handshake_mode(
885 MockCryptoClientStream::CONFIRM_HANDSHAKE);
886
887 // Connection to |origin| fails, so that success of |request| depends on
888 // connection to |alternate| only.
889 MockConnect refused_connect(ASYNC, ERR_CONNECTION_REFUSED);
890 StaticSocketDataProvider refused_data;
891 refused_data.set_connect_data(refused_connect);
892 socket_factory_.AddSocketDataProvider(&refused_data);
893
894 CreateSessionWithNextProtos();
895 AlternativeService alternative_service(QUIC, alternative);
896 session_->http_server_properties()->SetAlternativeService(
897 origin, alternative_service, 1.0);
898 scoped_ptr<HttpNetworkTransaction> trans(
899 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
900 TestCompletionCallback callback;
901 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
902 EXPECT_EQ(ERR_IO_PENDING, rv);
903 rv = callback.WaitForResult();
904 if (valid) {
905 EXPECT_EQ(OK, rv);
906 CheckWasQuicResponse(trans);
907 CheckResponsePort(trans, 443);
908 CheckResponseData(trans, "hello!");
909 } else {
910 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
911 }
912 }
913};
914
915INSTANTIATE_TEST_CASE_P(Version,
916 QuicAltSvcCertificateVerificationTest,
917 ::testing::ValuesIn(QuicSupportedVersions()));
918
919TEST_P(QuicAltSvcCertificateVerificationTest,
920 RequestSucceedsWithValidCertificate) {
921 Run(true);
922}
923
924TEST_P(QuicAltSvcCertificateVerificationTest,
925 RequestFailsWithInvalidCertificate) {
926 Run(false);
927}
928
[email protected]1e960032013-12-20 19:00:20929TEST_P(QuicNetworkTransactionTest, HungAlternateProtocol) {
rchff012122015-07-27 20:01:40930 params_.enable_insecure_quic = true;
[email protected]dda75ab2013-06-22 22:43:30931 crypto_client_stream_factory_.set_handshake_mode(
932 MockCryptoClientStream::COLD_START);
933
934 MockWrite http_writes[] = {
935 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
936 MockWrite(SYNCHRONOUS, 1, "Host: www.google.com\r\n"),
937 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")
938 };
939
940 MockRead http_reads[] = {
941 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
942 MockRead(SYNCHRONOUS, 4, kQuicAlternateProtocolHttpHeader),
943 MockRead(SYNCHRONOUS, 5, "hello world"),
944 MockRead(SYNCHRONOUS, OK, 6)
945 };
946
947 DeterministicMockClientSocketFactory socket_factory;
948
949 DeterministicSocketData http_data(http_reads, arraysize(http_reads),
950 http_writes, arraysize(http_writes));
951 socket_factory.AddSocketDataProvider(&http_data);
952
953 // The QUIC transaction will not be allowed to complete.
954 MockWrite quic_writes[] = {
955 MockWrite(ASYNC, ERR_IO_PENDING, 0)
956 };
957 MockRead quic_reads[] = {
958 MockRead(ASYNC, ERR_IO_PENDING, 1),
959 };
960 DeterministicSocketData quic_data(quic_reads, arraysize(quic_reads),
961 quic_writes, arraysize(quic_writes));
962 socket_factory.AddSocketDataProvider(&quic_data);
963
964 // The HTTP transaction will complete.
965 DeterministicSocketData http_data2(http_reads, arraysize(http_reads),
966 http_writes, arraysize(http_writes));
967 socket_factory.AddSocketDataProvider(&http_data2);
968
[email protected]d7599122014-05-24 03:37:23969 CreateSessionWithFactory(&socket_factory, true);
[email protected]dda75ab2013-06-22 22:43:30970
971 // Run the first request.
972 http_data.StopAfter(arraysize(http_reads) + arraysize(http_writes));
973 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:17974 ASSERT_TRUE(http_data.AllReadDataConsumed());
975 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:30976
977 // Now run the second request in which the QUIC socket hangs,
978 // and verify the the transaction continues over HTTP.
979 http_data2.StopAfter(arraysize(http_reads) + arraysize(http_writes));
980 SendRequestAndExpectHttpResponse("hello world");
981
rch37de576c2015-05-17 20:28:17982 ASSERT_TRUE(http_data2.AllReadDataConsumed());
983 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
984 ASSERT_TRUE(!quic_data.AllReadDataConsumed());
985 ASSERT_TRUE(!quic_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:30986}
987
[email protected]1e960032013-12-20 19:00:20988TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
rchff012122015-07-27 20:01:40989 params_.enable_insecure_quic = true;
[email protected]1e960032013-12-20 19:00:20990 MockQuicData mock_quic_data;
[email protected]92bf17c2014-03-03 21:14:03991 mock_quic_data.AddWrite(
[email protected]66ae5962014-05-22 11:13:05992 ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
[email protected]92bf17c2014-03-03 21:14:03993 GetRequestHeaders("GET", "http", "/")));
994 mock_quic_data.AddRead(
[email protected]66ae5962014-05-22 11:13:05995 ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false,
[email protected]92bf17c2014-03-03 21:14:03996 GetResponseHeaders("200 OK")));
997 mock_quic_data.AddRead(
[email protected]66ae5962014-05-22 11:13:05998 ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
[email protected]92bf17c2014-03-03 21:14:03999 mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
[email protected]1e960032013-12-20 19:00:201000 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
[email protected]8ba81212013-05-03 13:11:481001
rcha5399e02015-04-21 19:32:041002 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:481003
[email protected]3a120a6b2013-06-25 01:08:271004 // The non-alternate protocol job needs to hang in order to guarantee that
1005 // the alternate-protocol job will "win".
[email protected]dda75ab2013-06-22 22:43:301006 AddHangingNonAlternateProtocolSocketData();
1007
[email protected]d7599122014-05-24 03:37:231008 CreateSessionWithNextProtos();
[email protected]aa9b14d2013-05-10 23:45:191009 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
1010 SendRequestAndExpectQuicResponse("hello!");
[email protected]8ba81212013-05-03 13:11:481011}
1012
[email protected]1e960032013-12-20 19:00:201013TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
rchff012122015-07-27 20:01:401014 params_.enable_insecure_quic = true;
[email protected]1e960032013-12-20 19:00:201015 MockQuicData mock_quic_data;
[email protected]92bf17c2014-03-03 21:14:031016 mock_quic_data.AddWrite(
[email protected]66ae5962014-05-22 11:13:051017 ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
[email protected]92bf17c2014-03-03 21:14:031018 GetRequestHeaders("GET", "http", "/")));
1019 mock_quic_data.AddRead(
[email protected]66ae5962014-05-22 11:13:051020 ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false,
[email protected]92bf17c2014-03-03 21:14:031021 GetResponseHeaders("200 OK")));
1022 mock_quic_data.AddRead(
[email protected]66ae5962014-05-22 11:13:051023 ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
[email protected]92bf17c2014-03-03 21:14:031024 mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
[email protected]1e960032013-12-20 19:00:201025 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
rcha5399e02015-04-21 19:32:041026 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:271027
1028 // In order for a new QUIC session to be established via alternate-protocol
1029 // without racing an HTTP connection, we need the host resolution to happen
1030 // synchronously.
1031 host_resolver_.set_synchronous_mode(true);
1032 host_resolver_.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
[email protected]5109c1952013-08-20 18:44:101033 HostResolver::RequestInfo info(HostPortPair("www.google.com", 80));
[email protected]3a120a6b2013-06-25 01:08:271034 AddressList address;
[email protected]5109c1952013-08-20 18:44:101035 host_resolver_.Resolve(info,
1036 DEFAULT_PRIORITY,
1037 &address,
1038 CompletionCallback(),
rtennetibe635732014-10-02 22:51:421039 nullptr,
[email protected]3a120a6b2013-06-25 01:08:271040 net_log_.bound());
1041
[email protected]d7599122014-05-24 03:37:231042 CreateSessionWithNextProtos();
[email protected]3a120a6b2013-06-25 01:08:271043 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
1044 SendRequestAndExpectQuicResponse("hello!");
1045}
1046
[email protected]0fc924b2014-03-31 04:34:151047TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
rchff012122015-07-27 20:01:401048 params_.enable_insecure_quic = true;
[email protected]0fc924b2014-03-31 04:34:151049 proxy_service_.reset(
1050 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]0fc924b2014-03-31 04:34:151051
1052 // Since we are using a proxy, the QUIC job will not succeed.
1053 MockWrite http_writes[] = {
1054 MockWrite(SYNCHRONOUS, 0, "GET http://www.google.com/ HTTP/1.1\r\n"),
1055 MockWrite(SYNCHRONOUS, 1, "Host: www.google.com\r\n"),
1056 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")
1057 };
1058
1059 MockRead http_reads[] = {
1060 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
1061 MockRead(SYNCHRONOUS, 4, kQuicAlternateProtocolHttpHeader),
1062 MockRead(SYNCHRONOUS, 5, "hello world"),
1063 MockRead(SYNCHRONOUS, OK, 6)
1064 };
1065
1066 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
1067 http_writes, arraysize(http_writes));
1068 socket_factory_.AddSocketDataProvider(&http_data);
1069
1070 // In order for a new QUIC session to be established via alternate-protocol
1071 // without racing an HTTP connection, we need the host resolution to happen
1072 // synchronously.
1073 host_resolver_.set_synchronous_mode(true);
1074 host_resolver_.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
1075 HostResolver::RequestInfo info(HostPortPair("www.google.com", 80));
1076 AddressList address;
1077 host_resolver_.Resolve(info,
1078 DEFAULT_PRIORITY,
1079 &address,
1080 CompletionCallback(),
rtennetibe635732014-10-02 22:51:421081 nullptr,
[email protected]0fc924b2014-03-31 04:34:151082 net_log_.bound());
1083
[email protected]d7599122014-05-24 03:37:231084 CreateSessionWithNextProtos();
[email protected]0fc924b2014-03-31 04:34:151085 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
1086 SendRequestAndExpectHttpResponse("hello world");
1087}
1088
[email protected]1e960032013-12-20 19:00:201089TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
rchff012122015-07-27 20:01:401090 params_.enable_insecure_quic = true;
[email protected]1e960032013-12-20 19:00:201091 MockQuicData mock_quic_data;
[email protected]92bf17c2014-03-03 21:14:031092 mock_quic_data.AddWrite(
[email protected]66ae5962014-05-22 11:13:051093 ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
[email protected]92bf17c2014-03-03 21:14:031094 GetRequestHeaders("GET", "http", "/")));
1095 mock_quic_data.AddRead(
[email protected]66ae5962014-05-22 11:13:051096 ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false,
[email protected]92bf17c2014-03-03 21:14:031097 GetResponseHeaders("200 OK")));
1098 mock_quic_data.AddRead(
[email protected]66ae5962014-05-22 11:13:051099 ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
[email protected]92bf17c2014-03-03 21:14:031100 mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
[email protected]1e960032013-12-20 19:00:201101 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
rcha5399e02015-04-21 19:32:041102 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:121103
1104 // The non-alternate protocol job needs to hang in order to guarantee that
1105 // the alternate-protocol job will "win".
1106 AddHangingNonAlternateProtocolSocketData();
1107
1108 // In order for a new QUIC session to be established via alternate-protocol
1109 // without racing an HTTP connection, we need the host resolution to happen
1110 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
1111 // connection to the the server, in this test we require confirmation
1112 // before encrypting so the HTTP job will still start.
1113 host_resolver_.set_synchronous_mode(true);
1114 host_resolver_.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
[email protected]5109c1952013-08-20 18:44:101115 HostResolver::RequestInfo info(HostPortPair("www.google.com", 80));
[email protected]11c05872013-08-20 02:04:121116 AddressList address;
[email protected]5109c1952013-08-20 18:44:101117 host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
rtennetibe635732014-10-02 22:51:421118 CompletionCallback(), nullptr, net_log_.bound());
[email protected]11c05872013-08-20 02:04:121119
[email protected]d7599122014-05-24 03:37:231120 CreateSessionWithNextProtos();
[email protected]11c05872013-08-20 02:04:121121 session_->quic_stream_factory()->set_require_confirmation(true);
1122 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
1123
1124 scoped_ptr<HttpNetworkTransaction> trans(
1125 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
1126 TestCompletionCallback callback;
1127 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
1128 EXPECT_EQ(ERR_IO_PENDING, rv);
1129
1130 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
1131 QuicSession::HANDSHAKE_CONFIRMED);
1132 EXPECT_EQ(OK, callback.WaitForResult());
1133}
1134
[email protected]1e960032013-12-20 19:00:201135TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
rchff012122015-07-27 20:01:401136 params_.enable_insecure_quic = true;
[email protected]3316d422013-05-03 21:45:301137 // Alternate-protocol job
1138 scoped_ptr<QuicEncryptedPacket> close(ConstructConnectionClosePacket(1));
1139 MockRead quic_reads[] = {
1140 MockRead(ASYNC, close->data(), close->length()),
1141 MockRead(ASYNC, OK), // EOF
1142 };
1143 StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
rtennetibe635732014-10-02 22:51:421144 nullptr, 0);
[email protected]3316d422013-05-03 21:45:301145 socket_factory_.AddSocketDataProvider(&quic_data);
1146
1147 // Main job which will succeed even though the alternate job fails.
1148 MockRead http_reads[] = {
1149 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
1150 MockRead("hello from http"),
1151 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1152 MockRead(ASYNC, OK)
1153 };
1154
1155 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
rtennetibe635732014-10-02 22:51:421156 nullptr, 0);
[email protected]3316d422013-05-03 21:45:301157 socket_factory_.AddSocketDataProvider(&http_data);
1158
[email protected]d7599122014-05-24 03:37:231159 CreateSessionWithNextProtos();
[email protected]aa9b14d2013-05-10 23:45:191160 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
1161 SendRequestAndExpectHttpResponse("hello from http");
1162 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:301163}
1164
[email protected]1e960032013-12-20 19:00:201165TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
rchff012122015-07-27 20:01:401166 params_.enable_insecure_quic = true;
[email protected]d03a66d2013-05-06 12:55:591167 // Alternate-protocol job
1168 MockRead quic_reads[] = {
1169 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
1170 };
1171 StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
rtennetibe635732014-10-02 22:51:421172 nullptr, 0);
[email protected]d03a66d2013-05-06 12:55:591173 socket_factory_.AddSocketDataProvider(&quic_data);
1174
1175 // Main job which will succeed even though the alternate job fails.
1176 MockRead http_reads[] = {
1177 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
1178 MockRead("hello from http"),
1179 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1180 MockRead(ASYNC, OK)
1181 };
1182
1183 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
rtennetibe635732014-10-02 22:51:421184 nullptr, 0);
[email protected]d03a66d2013-05-06 12:55:591185 socket_factory_.AddSocketDataProvider(&http_data);
1186
[email protected]d7599122014-05-24 03:37:231187 CreateSessionWithNextProtos();
[email protected]d03a66d2013-05-06 12:55:591188
[email protected]aa9b14d2013-05-10 23:45:191189 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
1190 SendRequestAndExpectHttpResponse("hello from http");
1191 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:591192}
1193
[email protected]00c159f2014-05-21 22:38:161194TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
rchff012122015-07-27 20:01:401195 params_.enable_insecure_quic = true;
[email protected]eb71ab62014-05-23 07:57:531196 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:161197 MockRead quic_reads[] = {
1198 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
1199 };
1200 StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
rtennetibe635732014-10-02 22:51:421201 nullptr, 0);
[email protected]00c159f2014-05-21 22:38:161202 socket_factory_.AddSocketDataProvider(&quic_data);
1203
[email protected]eb71ab62014-05-23 07:57:531204 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:161205 MockRead http_reads[] = {
1206 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
1207 };
1208
1209 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
rtennetibe635732014-10-02 22:51:421210 nullptr, 0);
[email protected]00c159f2014-05-21 22:38:161211 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
1212 socket_factory_.AddSocketDataProvider(&http_data);
1213
[email protected]d7599122014-05-24 03:37:231214 CreateSessionWithNextProtos();
[email protected]00c159f2014-05-21 22:38:161215
1216 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
1217 scoped_ptr<HttpNetworkTransaction> trans(
1218 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
1219 TestCompletionCallback callback;
1220 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
1221 EXPECT_EQ(ERR_IO_PENDING, rv);
1222 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, callback.WaitForResult());
1223 ExpectQuicAlternateProtocolMapping();
1224}
1225
[email protected]1e960032013-12-20 19:00:201226TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
rchff012122015-07-27 20:01:401227 params_.enable_insecure_quic = true;
[email protected]77c6c162013-08-17 02:57:451228 // Alternate-protocol job
1229 MockRead quic_reads[] = {
1230 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
1231 };
1232 StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
rtennetibe635732014-10-02 22:51:421233 nullptr, 0);
[email protected]77c6c162013-08-17 02:57:451234 socket_factory_.AddSocketDataProvider(&quic_data);
1235
1236 AddHangingNonAlternateProtocolSocketData();
1237
[email protected]c92c1b52014-05-31 04:16:061238 // Second Alternate-protocol job which will race with the TCP job.
1239 StaticSocketDataProvider quic_data2(quic_reads, arraysize(quic_reads),
rtennetibe635732014-10-02 22:51:421240 nullptr, 0);
[email protected]c92c1b52014-05-31 04:16:061241 socket_factory_.AddSocketDataProvider(&quic_data2);
1242
[email protected]4d283b32013-10-17 12:57:271243 // Final job that will proceed when the QUIC job fails.
1244 MockRead http_reads[] = {
1245 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
1246 MockRead("hello from http"),
1247 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1248 MockRead(ASYNC, OK)
1249 };
1250
1251 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
rtennetibe635732014-10-02 22:51:421252 nullptr, 0);
[email protected]4d283b32013-10-17 12:57:271253 socket_factory_.AddSocketDataProvider(&http_data);
1254
[email protected]d7599122014-05-24 03:37:231255 CreateSessionWithNextProtos();
[email protected]77c6c162013-08-17 02:57:451256
1257 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
1258
[email protected]4d283b32013-10-17 12:57:271259 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:451260
1261 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:271262
rch37de576c2015-05-17 20:28:171263 EXPECT_TRUE(quic_data.AllReadDataConsumed());
1264 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:451265}
1266
[email protected]93b31772014-06-19 08:03:351267TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) {
rchff012122015-07-27 20:01:401268 params_.enable_insecure_quic = true;
[email protected]65768442014-06-06 23:37:031269 // Alternate-protocol job
1270 MockRead quic_reads[] = {
1271 MockRead(ASYNC, ERR_IO_PENDING),
1272 };
1273 StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
rtennetibe635732014-10-02 22:51:421274 nullptr, 0);
[email protected]65768442014-06-06 23:37:031275 socket_factory_.AddSocketDataProvider(&quic_data);
1276
1277 // Main job that will proceed when the QUIC job fails.
1278 MockRead http_reads[] = {
1279 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
1280 MockRead("hello from http"),
1281 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1282 MockRead(ASYNC, OK)
1283 };
1284
1285 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
rtennetibe635732014-10-02 22:51:421286 nullptr, 0);
[email protected]65768442014-06-06 23:37:031287 socket_factory_.AddSocketDataProvider(&http_data);
1288
1289 CreateSessionWithNextProtos();
1290
1291 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
1292
1293 SendRequestAndExpectHttpResponse("hello from http");
1294}
1295
[email protected]eb71ab62014-05-23 07:57:531296TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
rchff012122015-07-27 20:01:401297 params_.enable_insecure_quic = true;
[email protected]4d590c9c2014-05-02 05:14:331298 // Alternate-protocol job will fail before creating a QUIC session.
rtennetibe635732014-10-02 22:51:421299 StaticSocketDataProvider quic_data(nullptr, 0, nullptr, 0);
[email protected]4d590c9c2014-05-02 05:14:331300 quic_data.set_connect_data(MockConnect(SYNCHRONOUS,
1301 ERR_INTERNET_DISCONNECTED));
1302 socket_factory_.AddSocketDataProvider(&quic_data);
1303
1304 // Main job which will succeed even though the alternate job fails.
1305 MockRead http_reads[] = {
1306 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
1307 MockRead("hello from http"),
1308 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1309 MockRead(ASYNC, OK)
1310 };
1311
1312 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
rtennetibe635732014-10-02 22:51:421313 nullptr, 0);
[email protected]4d590c9c2014-05-02 05:14:331314 socket_factory_.AddSocketDataProvider(&http_data);
1315
[email protected]d7599122014-05-24 03:37:231316 CreateSessionWithNextProtos();
[email protected]4d590c9c2014-05-02 05:14:331317 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
1318 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:531319
1320 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:331321}
1322
[email protected]4fee9672014-01-08 14:47:151323TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
rchff012122015-07-27 20:01:401324 params_.enable_insecure_quic = true;
[email protected]4fee9672014-01-08 14:47:151325 MockQuicData mock_quic_data;
rcha5399e02015-04-21 19:32:041326 mock_quic_data.AddSynchronousRead(ConstructConnectionClosePacket(1));
[email protected]92bf17c2014-03-03 21:14:031327 mock_quic_data.AddWrite(
[email protected]66ae5962014-05-22 11:13:051328 ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
[email protected]92bf17c2014-03-03 21:14:031329 GetRequestHeaders("GET", "http", "/")));
1330 mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
rcha5399e02015-04-21 19:32:041331 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:151332
1333 // When the QUIC connection fails, we will try the request again over HTTP.
1334 MockRead http_reads[] = {
1335 MockRead("HTTP/1.1 200 OK\r\n"),
1336 MockRead(kQuicAlternateProtocolHttpHeader),
1337 MockRead("hello world"),
1338 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1339 MockRead(ASYNC, OK)
1340 };
1341
1342 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
rtennetibe635732014-10-02 22:51:421343 nullptr, 0);
[email protected]4fee9672014-01-08 14:47:151344 socket_factory_.AddSocketDataProvider(&http_data);
1345
1346 // In order for a new QUIC session to be established via alternate-protocol
1347 // without racing an HTTP connection, we need the host resolution to happen
1348 // synchronously.
1349 host_resolver_.set_synchronous_mode(true);
1350 host_resolver_.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
1351 HostResolver::RequestInfo info(HostPortPair("www.google.com", 80));
1352 AddressList address;
1353 host_resolver_.Resolve(info,
1354 DEFAULT_PRIORITY,
1355 &address,
1356 CompletionCallback(),
rtennetibe635732014-10-02 22:51:421357 nullptr,
[email protected]4fee9672014-01-08 14:47:151358 net_log_.bound());
1359
[email protected]d7599122014-05-24 03:37:231360 CreateSessionWithNextProtos();
[email protected]4fee9672014-01-08 14:47:151361 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
1362 SendRequestAndExpectHttpResponse("hello world");
1363}
1364
bnc508835902015-05-12 20:10:291365// Test that a secure request over an insecure QUIC connection fails with
1366// the appropriate error code. Note that this never happens in production,
1367// because the handshake (which this test mocks) would fail in this scenario.
1368TEST_P(QuicNetworkTransactionTest, SecureResourceOverInsecureQuic) {
rchff012122015-07-27 20:01:401369 params_.enable_insecure_quic = true;
bncb07c05532015-05-14 19:07:201370 maker_.set_hostname("www.example.org");
bnc508835902015-05-12 20:10:291371 MockQuicData mock_quic_data;
1372 mock_quic_data.AddWrite(
1373 ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
1374 GetRequestHeaders("GET", "https", "/")));
1375 mock_quic_data.AddRead(ConstructResponseHeadersPacket(
1376 1, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK")));
1377 mock_quic_data.AddRead(
1378 ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
1379 mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
1380 mock_quic_data.AddRead(SYNCHRONOUS, 0);
1381 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1382
bncb07c05532015-05-14 19:07:201383 request_.url = GURL("https://www.example.org:443");
bnc508835902015-05-12 20:10:291384 AddHangingNonAlternateProtocolSocketData();
1385 CreateSessionWithNextProtos();
1386 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
1387 scoped_ptr<HttpNetworkTransaction> trans(
1388 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
1389 TestCompletionCallback callback;
1390 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
1391 EXPECT_EQ(ERR_REQUEST_FOR_SECURE_RESOURCE_OVER_INSECURE_QUIC,
1392 callback.GetResult(rv));
1393}
1394
1395TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
rchff012122015-07-27 20:01:401396 params_.enable_insecure_quic = true;
bncb07c05532015-05-14 19:07:201397 maker_.set_hostname("www.example.org");
bnc508835902015-05-12 20:10:291398 MockQuicData mock_quic_data;
1399 mock_quic_data.AddWrite(
1400 ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
1401 GetRequestHeaders("GET", "https", "/")));
1402 mock_quic_data.AddRead(ConstructResponseHeadersPacket(
1403 1, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK")));
1404 mock_quic_data.AddRead(
1405 ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
1406 mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
1407 mock_quic_data.AddRead(SYNCHRONOUS, 0);
1408 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1409
1410 scoped_refptr<X509Certificate> cert(
1411 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
1412 ASSERT_TRUE(cert.get());
bncb07c05532015-05-14 19:07:201413 bool common_name_fallback_used;
1414 EXPECT_TRUE(
1415 cert->VerifyNameMatch("www.example.org", &common_name_fallback_used));
bnc508835902015-05-12 20:10:291416 ProofVerifyDetailsChromium verify_details;
1417 verify_details.cert_verify_result.verified_cert = cert;
bnc20daf9a2015-05-15 17:11:011418 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
bnc508835902015-05-12 20:10:291419
bncb07c05532015-05-14 19:07:201420 request_.url = GURL("https://www.example.org:443");
bnc508835902015-05-12 20:10:291421 AddHangingNonAlternateProtocolSocketData();
1422 CreateSessionWithNextProtos();
1423 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
1424 SendRequestAndExpectQuicResponse("hello!");
1425}
1426
[email protected]61a527782013-02-21 03:58:001427} // namespace test
1428} // namespace net