blob: a52b867ad2736154ca36c50ba4a4ab23b8f7b306 [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
5#include "base/basictypes.h"
6#include "base/compiler_specific.h"
7#include "base/memory/scoped_ptr.h"
[email protected]98b20ce2013-05-10 05:55:268#include "base/stl_util.h"
9#include "net/base/capturing_net_log.h"
10#include "net/base/net_log_unittest.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"
20#include "net/http/http_transaction_unittest.h"
[email protected]b1c988b2013-06-13 06:48:1121#include "net/http/transport_security_state.h"
[email protected]61a527782013-02-21 03:58:0022#include "net/proxy/proxy_config_service_fixed.h"
23#include "net/proxy/proxy_resolver.h"
24#include "net/proxy/proxy_service.h"
25#include "net/quic/crypto/quic_decrypter.h"
26#include "net/quic/crypto/quic_encrypter.h"
27#include "net/quic/quic_framer.h"
[email protected]ed3fc15d2013-03-08 18:37:4428#include "net/quic/test_tools/crypto_test_utils.h"
[email protected]61a527782013-02-21 03:58:0029#include "net/quic/test_tools/mock_clock.h"
[email protected]e8ff26842013-03-22 21:02:0530#include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
[email protected]61a527782013-02-21 03:58:0031#include "net/quic/test_tools/mock_random.h"
32#include "net/quic/test_tools/quic_test_utils.h"
33#include "net/socket/client_socket_factory.h"
34#include "net/socket/mock_client_socket_pool_manager.h"
35#include "net/socket/socket_test_util.h"
36#include "net/socket/ssl_client_socket.h"
37#include "net/spdy/spdy_frame_builder.h"
38#include "net/spdy/spdy_framer.h"
[email protected]536fd0b2013-03-14 17:41:5739#include "net/ssl/ssl_config_service_defaults.h"
[email protected]61a527782013-02-21 03:58:0040#include "testing/gtest/include/gtest/gtest.h"
41#include "testing/platform_test.h"
42
43//-----------------------------------------------------------------------------
44
45namespace {
46
47// This is the expected return from a current server advertising QUIC.
48static const char kQuicAlternateProtocolHttpHeader[] =
[email protected]4ff65372013-06-21 05:45:4649 "Alternate-Protocol: 80:quic\r\n\r\n";
[email protected]6d1b4ed2013-07-10 03:57:5450static const char kQuicAlternateProtocolHttpsHeader[] =
51 "Alternate-Protocol: 443:quic\r\n\r\n";
[email protected]61a527782013-02-21 03:58:0052} // namespace
53
54namespace net {
55namespace test {
56
57class QuicNetworkTransactionTest : public PlatformTest {
58 protected:
[email protected]1c04f9522013-02-21 20:32:4359 QuicNetworkTransactionTest()
60 : clock_(new MockClock),
61 ssl_config_service_(new SSLConfigServiceDefaults),
62 proxy_service_(ProxyService::CreateDirect()),
[email protected]c244c5a12013-05-07 20:55:0463 compressor_(new QuicSpdyCompressor()),
[email protected]1c04f9522013-02-21 20:32:4364 auth_handler_factory_(
[email protected]dda75ab2013-06-22 22:43:3065 HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
66 hanging_data_(NULL, 0, NULL, 0) {
[email protected]aa9b14d2013-05-10 23:45:1967 request_.method = "GET";
68 request_.url = GURL("http://www.google.com/");
69 request_.load_flags = 0;
[email protected]1c04f9522013-02-21 20:32:4370 }
[email protected]61a527782013-02-21 03:58:0071
72 virtual void SetUp() {
73 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:3474 base::MessageLoop::current()->RunUntilIdle();
[email protected]61a527782013-02-21 03:58:0075 }
76
77 virtual void TearDown() {
78 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
79 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:3480 base::MessageLoop::current()->RunUntilIdle();
[email protected]61a527782013-02-21 03:58:0081 PlatformTest::TearDown();
82 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:3483 base::MessageLoop::current()->RunUntilIdle();
[email protected]61a527782013-02-21 03:58:0084 HttpStreamFactory::set_use_alternate_protocols(false);
[email protected]0ce3af82013-07-22 16:17:1685 HttpStreamFactory::SetNextProtos(std::vector<NextProto>());
[email protected]61a527782013-02-21 03:58:0086 }
87
[email protected]61a527782013-02-21 03:58:0088 scoped_ptr<QuicEncryptedPacket> ConstructRstPacket(
89 QuicPacketSequenceNumber num,
90 QuicStreamId stream_id) {
91 QuicPacketHeader header;
92 header.public_header.guid = 0xDEADBEEF;
[email protected]9db443912013-02-25 05:27:0393 header.public_header.reset_flag = false;
94 header.public_header.version_flag = false;
[email protected]61a527782013-02-21 03:58:0095 header.packet_sequence_number = num;
[email protected]9db443912013-02-25 05:27:0396 header.entropy_flag = false;
97 header.fec_flag = false;
[email protected]61a527782013-02-21 03:58:0098 header.fec_group = 0;
99
[email protected]74bda142013-03-31 02:49:11100 QuicRstStreamFrame rst(stream_id, QUIC_STREAM_NO_ERROR);
[email protected]61a527782013-02-21 03:58:00101 return scoped_ptr<QuicEncryptedPacket>(
102 ConstructPacket(header, QuicFrame(&rst)));
103 }
104
[email protected]3316d422013-05-03 21:45:30105 scoped_ptr<QuicEncryptedPacket> ConstructConnectionClosePacket(
106 QuicPacketSequenceNumber num) {
107 QuicPacketHeader header;
108 header.public_header.guid = 0xDEADBEEF;
109 header.public_header.reset_flag = false;
110 header.public_header.version_flag = false;
111 header.packet_sequence_number = num;
112 header.entropy_flag = false;
113 header.fec_flag = false;
[email protected]3316d422013-05-03 21:45:30114 header.fec_group = 0;
115
116 QuicAckFrame ack_frame(0, QuicTime::Zero(), 0);
117 QuicConnectionCloseFrame close;
118 close.error_code = QUIC_CRYPTO_VERSION_NOT_SUPPORTED;
119 close.error_details = "Time to panic!";
120 close.ack_frame = ack_frame;
121 return scoped_ptr<QuicEncryptedPacket>(
122 ConstructPacket(header, QuicFrame(&close)));
123 }
124
[email protected]61a527782013-02-21 03:58:00125 scoped_ptr<QuicEncryptedPacket> ConstructAckPacket(
126 QuicPacketSequenceNumber largest_received,
127 QuicPacketSequenceNumber least_unacked) {
128 QuicPacketHeader header;
129 header.public_header.guid = 0xDEADBEEF;
[email protected]9db443912013-02-25 05:27:03130 header.public_header.reset_flag = false;
131 header.public_header.version_flag = false;
[email protected]e8ff26842013-03-22 21:02:05132 header.packet_sequence_number = 2;
[email protected]9db443912013-02-25 05:27:03133 header.entropy_flag = false;
134 header.fec_flag = false;
[email protected]61a527782013-02-21 03:58:00135 header.fec_group = 0;
136
[email protected]14e8106c2013-03-14 16:25:33137 QuicAckFrame ack(largest_received, QuicTime::Zero(), least_unacked);
[email protected]61a527782013-02-21 03:58:00138
139 QuicCongestionFeedbackFrame feedback;
140 feedback.type = kTCP;
141 feedback.tcp.accumulated_number_of_lost_packets = 0;
142 feedback.tcp.receive_window = 256000;
143
[email protected]8ba81212013-05-03 13:11:48144 QuicFramer framer(kQuicVersion1, QuicTime::Zero(), false);
[email protected]61a527782013-02-21 03:58:00145 QuicFrames frames;
146 frames.push_back(QuicFrame(&ack));
147 frames.push_back(QuicFrame(&feedback));
148 scoped_ptr<QuicPacket> packet(
[email protected]9db443912013-02-25 05:27:03149 framer.ConstructFrameDataPacket(header, frames).packet);
[email protected]8ba81212013-05-03 13:11:48150 return scoped_ptr<QuicEncryptedPacket>(framer.EncryptPacket(
151 ENCRYPTION_NONE, header.packet_sequence_number, *packet));
[email protected]61a527782013-02-21 03:58:00152 }
153
154 std::string GetRequestString(const std::string& method,
[email protected]6d1b4ed2013-07-10 03:57:54155 const std::string& scheme,
[email protected]61a527782013-02-21 03:58:00156 const std::string& path) {
157 SpdyHeaderBlock headers;
158 headers[":method"] = method;
159 headers[":host"] = "www.google.com";
160 headers[":path"] = path;
[email protected]6d1b4ed2013-07-10 03:57:54161 headers[":scheme"] = scheme;
[email protected]61a527782013-02-21 03:58:00162 headers[":version"] = "HTTP/1.1";
163 return SerializeHeaderBlock(headers);
164 }
165
166 std::string GetResponseString(const std::string& status,
167 const std::string& body) {
168 SpdyHeaderBlock headers;
169 headers[":status"] = status;
170 headers[":version"] = "HTTP/1.1";
171 headers["content-type"] = "text/plain";
[email protected]c244c5a12013-05-07 20:55:04172 return compressor_->CompressHeaders(headers) + body;
[email protected]61a527782013-02-21 03:58:00173 }
174
175 std::string SerializeHeaderBlock(const SpdyHeaderBlock& headers) {
[email protected]821555c2013-05-16 20:20:17176 QuicSpdyCompressor compressor;
177 return compressor.CompressHeaders(headers);
[email protected]61a527782013-02-21 03:58:00178 }
179
180 // Returns a newly created packet to send kData on stream 1.
181 QuicEncryptedPacket* ConstructDataPacket(
182 QuicPacketSequenceNumber sequence_number,
[email protected]98b20ce2013-05-10 05:55:26183 QuicStreamId stream_id,
[email protected]e8ff26842013-03-22 21:02:05184 bool should_include_version,
[email protected]61a527782013-02-21 03:58:00185 bool fin,
186 QuicStreamOffset offset,
187 base::StringPiece data) {
[email protected]e8ff26842013-03-22 21:02:05188 InitializeHeader(sequence_number, should_include_version);
[email protected]98b20ce2013-05-10 05:55:26189 QuicStreamFrame frame(stream_id, fin, offset, data);
[email protected]61a527782013-02-21 03:58:00190 return ConstructPacket(header_, QuicFrame(&frame)).release();
191 }
192
193 scoped_ptr<QuicEncryptedPacket> ConstructPacket(
194 const QuicPacketHeader& header,
195 const QuicFrame& frame) {
[email protected]8ba81212013-05-03 13:11:48196 QuicFramer framer(kQuicVersion1, QuicTime::Zero(), false);
[email protected]61a527782013-02-21 03:58:00197 QuicFrames frames;
198 frames.push_back(frame);
199 scoped_ptr<QuicPacket> packet(
[email protected]9db443912013-02-25 05:27:03200 framer.ConstructFrameDataPacket(header, frames).packet);
[email protected]8ba81212013-05-03 13:11:48201 return scoped_ptr<QuicEncryptedPacket>(framer.EncryptPacket(
202 ENCRYPTION_NONE, header.packet_sequence_number, *packet));
[email protected]61a527782013-02-21 03:58:00203 }
204
[email protected]e8ff26842013-03-22 21:02:05205 void InitializeHeader(QuicPacketSequenceNumber sequence_number,
206 bool should_include_version) {
[email protected]61a527782013-02-21 03:58:00207 header_.public_header.guid = random_generator_.RandUint64();
[email protected]9db443912013-02-25 05:27:03208 header_.public_header.reset_flag = false;
[email protected]e8ff26842013-03-22 21:02:05209 header_.public_header.version_flag = should_include_version;
[email protected]61a527782013-02-21 03:58:00210 header_.packet_sequence_number = sequence_number;
211 header_.fec_group = 0;
[email protected]9db443912013-02-25 05:27:03212 header_.entropy_flag = false;
213 header_.fec_flag = false;
[email protected]61a527782013-02-21 03:58:00214 }
215
216 void CreateSession() {
[email protected]dda75ab2013-06-22 22:43:30217 CreateSessionWithFactory(&socket_factory_);
218 }
219
220 void CreateSessionWithFactory(ClientSocketFactory* socket_factory) {
[email protected]4dca587c2013-03-07 16:54:47221 params_.enable_quic = true;
222 params_.quic_clock = clock_;
223 params_.quic_random = &random_generator_;
[email protected]dda75ab2013-06-22 22:43:30224 params_.client_socket_factory = socket_factory;
[email protected]e8ff26842013-03-22 21:02:05225 params_.quic_crypto_client_stream_factory = &crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:43226 params_.host_resolver = &host_resolver_;
227 params_.cert_verifier = &cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:11228 params_.transport_security_state = &transport_security_state_;
[email protected]1c04f9522013-02-21 20:32:43229 params_.proxy_service = proxy_service_.get();
230 params_.ssl_config_service = ssl_config_service_.get();
231 params_.http_auth_handler_factory = auth_handler_factory_.get();
[email protected]30d4c022013-07-18 22:58:16232 params_.http_server_properties = http_server_properties.GetWeakPtr();
[email protected]61a527782013-02-21 03:58:00233
234 session_ = new HttpNetworkSession(params_);
235 }
236
[email protected]aa9b14d2013-05-10 23:45:19237 void CheckWasQuicResponse(const scoped_ptr<HttpNetworkTransaction>& trans) {
238 const HttpResponseInfo* response = trans->GetResponseInfo();
239 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:50240 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]aa9b14d2013-05-10 23:45:19241 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
242 EXPECT_TRUE(response->was_fetched_via_spdy);
243 EXPECT_TRUE(response->was_npn_negotiated);
244 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_QUIC1_SPDY3,
245 response->connection_info);
246 }
247
248 void CheckWasHttpResponse(const scoped_ptr<HttpNetworkTransaction>& trans) {
249 const HttpResponseInfo* response = trans->GetResponseInfo();
250 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:50251 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]aa9b14d2013-05-10 23:45:19252 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
253 EXPECT_FALSE(response->was_fetched_via_spdy);
254 EXPECT_FALSE(response->was_npn_negotiated);
255 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1,
256 response->connection_info);
257 }
258
259 void CheckResponseData(HttpNetworkTransaction* trans,
260 const std::string& expected) {
261 std::string response_data;
262 ASSERT_EQ(OK, ReadTransaction(trans, &response_data));
263 EXPECT_EQ(expected, response_data);
264 }
265
266 void RunTransaction(HttpNetworkTransaction* trans) {
267 TestCompletionCallback callback;
268 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
269 EXPECT_EQ(ERR_IO_PENDING, rv);
270 EXPECT_EQ(OK, callback.WaitForResult());
271 }
272
273 void SendRequestAndExpectHttpResponse(const std::string& expected) {
274 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:50275 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
[email protected]aa9b14d2013-05-10 23:45:19276 RunTransaction(trans.get());
277 CheckWasHttpResponse(trans);
278 CheckResponseData(trans.get(), expected);
279 }
280
281 void SendRequestAndExpectQuicResponse(const std::string& expected) {
282 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:50283 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
[email protected]aa9b14d2013-05-10 23:45:19284 RunTransaction(trans.get());
285 CheckWasQuicResponse(trans);
286 CheckResponseData(trans.get(), expected);
287 }
288
289 void AddQuicAlternateProtocolMapping(
290 MockCryptoClientStream::HandshakeMode handshake_mode) {
291 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
292 session_->http_server_properties()->SetAlternateProtocol(
293 HostPortPair::FromURL(request_.url), 80, QUIC);
294 }
295
296 void ExpectBrokenAlternateProtocolMapping() {
297 ASSERT_TRUE(session_->http_server_properties()->HasAlternateProtocol(
298 HostPortPair::FromURL(request_.url)));
299 const PortAlternateProtocolPair alternate =
300 session_->http_server_properties()->GetAlternateProtocol(
301 HostPortPair::FromURL(request_.url));
302 EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol);
303 }
304
305 void AddHangingNonAlternateProtocolSocketData() {
[email protected]dda75ab2013-06-22 22:43:30306 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
307 hanging_data_.set_connect_data(hanging_connect);
308 socket_factory_.AddSocketDataProvider(&hanging_data_);
[email protected]aa9b14d2013-05-10 23:45:19309 }
310
[email protected]61a527782013-02-21 03:58:00311 QuicPacketHeader header_;
312 scoped_refptr<HttpNetworkSession> session_;
313 MockClientSocketFactory socket_factory_;
[email protected]e8ff26842013-03-22 21:02:05314 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:43315 MockClock* clock_; // Owned by QuicStreamFactory after CreateSession.
316 MockHostResolver host_resolver_;
317 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:11318 TransportSecurityState transport_security_state_;
[email protected]1c04f9522013-02-21 20:32:43319 scoped_refptr<SSLConfigServiceDefaults> ssl_config_service_;
320 scoped_ptr<ProxyService> proxy_service_;
[email protected]c244c5a12013-05-07 20:55:04321 scoped_ptr<QuicSpdyCompressor> compressor_;
[email protected]1c04f9522013-02-21 20:32:43322 scoped_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
[email protected]61a527782013-02-21 03:58:00323 MockRandom random_generator_;
324 HttpServerPropertiesImpl http_server_properties;
325 HttpNetworkSession::Params params_;
[email protected]aa9b14d2013-05-10 23:45:19326 HttpRequestInfo request_;
327 CapturingBoundNetLog net_log_;
[email protected]dda75ab2013-06-22 22:43:30328 StaticSocketDataProvider hanging_data_;
[email protected]61a527782013-02-21 03:58:00329};
330
[email protected]4dca587c2013-03-07 16:54:47331TEST_F(QuicNetworkTransactionTest, ForceQuic) {
[email protected]49e85332013-06-04 04:18:03332 params_.origin_to_force_quic_on =
333 HostPortPair::FromString("www.google.com:80");
[email protected]4dca587c2013-03-07 16:54:47334
[email protected]98b20ce2013-05-10 05:55:26335 QuicStreamId stream_id = 3;
[email protected]aa9b14d2013-05-10 23:45:19336 scoped_ptr<QuicEncryptedPacket> req(
[email protected]98b20ce2013-05-10 05:55:26337 ConstructDataPacket(1, stream_id, true, true, 0,
[email protected]6d1b4ed2013-07-10 03:57:54338 GetRequestString("GET", "http", "/")));
[email protected]e8ff26842013-03-22 21:02:05339 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0));
[email protected]4dca587c2013-03-07 16:54:47340
341 MockWrite quic_writes[] = {
[email protected]aa9b14d2013-05-10 23:45:19342 MockWrite(SYNCHRONOUS, req->data(), req->length()),
[email protected]4dca587c2013-03-07 16:54:47343 MockWrite(SYNCHRONOUS, ack->data(), ack->length()),
344 };
345
[email protected]4dca587c2013-03-07 16:54:47346 scoped_ptr<QuicEncryptedPacket> resp(
[email protected]e8ff26842013-03-22 21:02:05347 ConstructDataPacket(
[email protected]98b20ce2013-05-10 05:55:26348 1, stream_id, false, true, 0, GetResponseString("200 OK", "hello!")));
[email protected]4dca587c2013-03-07 16:54:47349 MockRead quic_reads[] = {
[email protected]4dca587c2013-03-07 16:54:47350 MockRead(SYNCHRONOUS, resp->data(), resp->length()),
351 MockRead(ASYNC, OK), // EOF
352 };
353
354 DelayedSocketData quic_data(
355 1, // wait for one write to finish before reading.
356 quic_reads, arraysize(quic_reads),
357 quic_writes, arraysize(quic_writes));
358
359 socket_factory_.AddSocketDataProvider(&quic_data);
360
[email protected]aa9b14d2013-05-10 23:45:19361 // The non-alternate protocol job needs to hang in order to guarantee that
362 // the alternate-protocol job will "win".
363 AddHangingNonAlternateProtocolSocketData();
[email protected]4dca587c2013-03-07 16:54:47364
365 CreateSession();
[email protected]4dca587c2013-03-07 16:54:47366
[email protected]aa9b14d2013-05-10 23:45:19367 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:47368
[email protected]98b20ce2013-05-10 05:55:26369 // Check that the NetLog was filled reasonably.
370 net::CapturingNetLog::CapturedEntryList entries;
[email protected]aa9b14d2013-05-10 23:45:19371 net_log_.GetEntries(&entries);
[email protected]98b20ce2013-05-10 05:55:26372 EXPECT_LT(0u, entries.size());
373
374 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
375 int pos = net::ExpectLogContainsSomewhere(
376 entries, 0,
377 net::NetLog::TYPE_QUIC_SESSION_PACKET_RECEIVED,
378 net::NetLog::PHASE_NONE);
379 EXPECT_LT(0, pos);
380
381 // ... and also a TYPE_QUIC_SESSION_PACKET_HEADER_RECEIVED.
382 pos = net::ExpectLogContainsSomewhere(
383 entries, 0,
384 net::NetLog::TYPE_QUIC_SESSION_PACKET_HEADER_RECEIVED,
385 net::NetLog::PHASE_NONE);
386 EXPECT_LT(0, pos);
387
388 std::string packet_sequence_number;
389 ASSERT_TRUE(entries[pos].GetStringValue(
390 "packet_sequence_number", &packet_sequence_number));
391 EXPECT_EQ("1", packet_sequence_number);
392
393 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
394 pos = net::ExpectLogContainsSomewhere(
395 entries, 0,
396 net::NetLog::TYPE_QUIC_SESSION_STREAM_FRAME_RECEIVED,
397 net::NetLog::PHASE_NONE);
398 EXPECT_LT(0, pos);
399
400 int log_stream_id;
401 ASSERT_TRUE(entries[pos].GetIntegerValue("stream_id", &log_stream_id));
402 EXPECT_EQ(stream_id, static_cast<QuicStreamId>(log_stream_id));
[email protected]4dca587c2013-03-07 16:54:47403}
404
[email protected]cebe3282013-05-22 23:49:30405TEST_F(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
[email protected]49e85332013-06-04 04:18:03406 params_.origin_to_force_quic_on =
407 HostPortPair::FromString("www.google.com:80");
[email protected]cebe3282013-05-22 23:49:30408
409 MockRead quic_reads[] = {
410 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
411 };
412 StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
413 NULL, 0);
414 socket_factory_.AddSocketDataProvider(&quic_data);
415
416 CreateSession();
417
418 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:50419 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
[email protected]cebe3282013-05-22 23:49:30420 TestCompletionCallback callback;
421 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
422 EXPECT_EQ(ERR_IO_PENDING, rv);
423 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, callback.WaitForResult());
424}
425
[email protected]4dca587c2013-03-07 16:54:47426TEST_F(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
427 // Attempt to "force" quic on 443, which will not be honored.
[email protected]49e85332013-06-04 04:18:03428 params_.origin_to_force_quic_on =
429 HostPortPair::FromString("www.google.com:443");
[email protected]4dca587c2013-03-07 16:54:47430
[email protected]aa9b14d2013-05-10 23:45:19431 MockRead http_reads[] = {
[email protected]4dca587c2013-03-07 16:54:47432 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
433 MockRead("hello world"),
434 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
435 MockRead(ASYNC, OK)
436 };
437
[email protected]aa9b14d2013-05-10 23:45:19438 StaticSocketDataProvider data(http_reads, arraysize(http_reads), NULL, 0);
[email protected]4dca587c2013-03-07 16:54:47439 socket_factory_.AddSocketDataProvider(&data);
440 SSLSocketDataProvider ssl(ASYNC, OK);
441 socket_factory_.AddSSLSocketDataProvider(&ssl);
442
[email protected]4dca587c2013-03-07 16:54:47443 CreateSession();
[email protected]4dca587c2013-03-07 16:54:47444
[email protected]aa9b14d2013-05-10 23:45:19445 SendRequestAndExpectHttpResponse("hello world");
[email protected]4dca587c2013-03-07 16:54:47446}
447
[email protected]61a527782013-02-21 03:58:00448TEST_F(QuicNetworkTransactionTest, UseAlternateProtocolForQuic) {
[email protected]4ff65372013-06-21 05:45:46449 HttpStreamFactory::EnableNpnSpdy(); // Enables QUIC too.
[email protected]61a527782013-02-21 03:58:00450
[email protected]aa9b14d2013-05-10 23:45:19451 MockRead http_reads[] = {
[email protected]61a527782013-02-21 03:58:00452 MockRead("HTTP/1.1 200 OK\r\n"),
453 MockRead(kQuicAlternateProtocolHttpHeader),
454 MockRead("hello world"),
455 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
456 MockRead(ASYNC, OK)
457 };
458
[email protected]aa9b14d2013-05-10 23:45:19459 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
460 NULL, 0);
461 socket_factory_.AddSocketDataProvider(&http_data);
[email protected]61a527782013-02-21 03:58:00462
[email protected]aa9b14d2013-05-10 23:45:19463 scoped_ptr<QuicEncryptedPacket> req(
[email protected]6d1b4ed2013-07-10 03:57:54464 ConstructDataPacket(1, 3, true, true, 0,
465 GetRequestString("GET", "http", "/")));
[email protected]e8ff26842013-03-22 21:02:05466 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0));
[email protected]61a527782013-02-21 03:58:00467
468 MockWrite quic_writes[] = {
[email protected]aa9b14d2013-05-10 23:45:19469 MockWrite(SYNCHRONOUS, req->data(), req->length()),
[email protected]61a527782013-02-21 03:58:00470 MockWrite(SYNCHRONOUS, ack->data(), ack->length()),
471 };
472
[email protected]61a527782013-02-21 03:58:00473 scoped_ptr<QuicEncryptedPacket> resp(
[email protected]e8ff26842013-03-22 21:02:05474 ConstructDataPacket(
[email protected]98b20ce2013-05-10 05:55:26475 1, 3, false, true, 0, GetResponseString("200 OK", "hello!")));
[email protected]61a527782013-02-21 03:58:00476 MockRead quic_reads[] = {
[email protected]61a527782013-02-21 03:58:00477 MockRead(SYNCHRONOUS, resp->data(), resp->length()),
478 MockRead(ASYNC, OK), // EOF
479 };
480
481 DelayedSocketData quic_data(
482 1, // wait for one write to finish before reading.
483 quic_reads, arraysize(quic_reads),
484 quic_writes, arraysize(quic_writes));
485
486 socket_factory_.AddSocketDataProvider(&quic_data);
487
[email protected]aa9b14d2013-05-10 23:45:19488 // The non-alternate protocol job needs to hang in order to guarantee that
489 // the alternate-protocol job will "win".
490 AddHangingNonAlternateProtocolSocketData();
[email protected]61a527782013-02-21 03:58:00491
492 CreateSession();
[email protected]61a527782013-02-21 03:58:00493
[email protected]aa9b14d2013-05-10 23:45:19494 SendRequestAndExpectHttpResponse("hello world");
495 SendRequestAndExpectQuicResponse("hello!");
[email protected]61a527782013-02-21 03:58:00496}
497
[email protected]6d1b4ed2013-07-10 03:57:54498TEST_F(QuicNetworkTransactionTest, UseAlternateProtocolForQuicForHttps) {
499 params_.origin_to_force_quic_on =
500 HostPortPair::FromString("www.google.com:443");
501 params_.enable_quic_https = true;
502 HttpStreamFactory::EnableNpnSpdy(); // Enables QUIC too.
503
504 MockRead http_reads[] = {
505 MockRead("HTTP/1.1 200 OK\r\n"),
506 MockRead(kQuicAlternateProtocolHttpsHeader),
507 MockRead("hello world"),
508 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
509 MockRead(ASYNC, OK)
510 };
511
512 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
513 NULL, 0);
514 socket_factory_.AddSocketDataProvider(&http_data);
515
516 scoped_ptr<QuicEncryptedPacket> req(
517 ConstructDataPacket(1, 3, true, true, 0,
518 GetRequestString("GET", "https", "/")));
519 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0));
520
521 MockWrite quic_writes[] = {
522 MockWrite(SYNCHRONOUS, req->data(), req->length()),
523 MockWrite(SYNCHRONOUS, ack->data(), ack->length()),
524 };
525
526 scoped_ptr<QuicEncryptedPacket> resp(
527 ConstructDataPacket(
528 1, 3, false, true, 0, GetResponseString("200 OK", "hello!")));
529 MockRead quic_reads[] = {
530 MockRead(SYNCHRONOUS, resp->data(), resp->length()),
531 MockRead(ASYNC, OK), // EOF
532 };
533
534 DelayedSocketData quic_data(
535 1, // wait for one write to finish before reading.
536 quic_reads, arraysize(quic_reads),
537 quic_writes, arraysize(quic_writes));
538
539 socket_factory_.AddSocketDataProvider(&quic_data);
540
541 // The non-alternate protocol job needs to hang in order to guarantee that
542 // the alternate-protocol job will "win".
543 AddHangingNonAlternateProtocolSocketData();
544
545 CreateSession();
546
547 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
548 SendRequestAndExpectHttpResponse("hello world");
549}
550
[email protected]dda75ab2013-06-22 22:43:30551TEST_F(QuicNetworkTransactionTest, HungAlternateProtocol) {
552 HttpStreamFactory::EnableNpnSpdy(); // Enables QUIC too.
553 crypto_client_stream_factory_.set_handshake_mode(
554 MockCryptoClientStream::COLD_START);
555
556 MockWrite http_writes[] = {
557 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
558 MockWrite(SYNCHRONOUS, 1, "Host: www.google.com\r\n"),
559 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")
560 };
561
562 MockRead http_reads[] = {
563 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
564 MockRead(SYNCHRONOUS, 4, kQuicAlternateProtocolHttpHeader),
565 MockRead(SYNCHRONOUS, 5, "hello world"),
566 MockRead(SYNCHRONOUS, OK, 6)
567 };
568
569 DeterministicMockClientSocketFactory socket_factory;
570
571 DeterministicSocketData http_data(http_reads, arraysize(http_reads),
572 http_writes, arraysize(http_writes));
573 socket_factory.AddSocketDataProvider(&http_data);
574
575 // The QUIC transaction will not be allowed to complete.
576 MockWrite quic_writes[] = {
577 MockWrite(ASYNC, ERR_IO_PENDING, 0)
578 };
579 MockRead quic_reads[] = {
580 MockRead(ASYNC, ERR_IO_PENDING, 1),
581 };
582 DeterministicSocketData quic_data(quic_reads, arraysize(quic_reads),
583 quic_writes, arraysize(quic_writes));
584 socket_factory.AddSocketDataProvider(&quic_data);
585
586 // The HTTP transaction will complete.
587 DeterministicSocketData http_data2(http_reads, arraysize(http_reads),
588 http_writes, arraysize(http_writes));
589 socket_factory.AddSocketDataProvider(&http_data2);
590
591 CreateSessionWithFactory(&socket_factory);
592
593 // Run the first request.
594 http_data.StopAfter(arraysize(http_reads) + arraysize(http_writes));
595 SendRequestAndExpectHttpResponse("hello world");
596 ASSERT_TRUE(http_data.at_read_eof());
597 ASSERT_TRUE(http_data.at_write_eof());
598
599 // Now run the second request in which the QUIC socket hangs,
600 // and verify the the transaction continues over HTTP.
601 http_data2.StopAfter(arraysize(http_reads) + arraysize(http_writes));
602 SendRequestAndExpectHttpResponse("hello world");
603
604 ASSERT_TRUE(http_data2.at_read_eof());
605 ASSERT_TRUE(http_data2.at_write_eof());
606 ASSERT_TRUE(!quic_data.at_read_eof());
607 ASSERT_TRUE(!quic_data.at_write_eof());
608}
609
[email protected]3a120a6b2013-06-25 01:08:27610TEST_F(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
[email protected]4ff65372013-06-21 05:45:46611 HttpStreamFactory::EnableNpnSpdy(); // Enables QUIC too.
[email protected]8ba81212013-05-03 13:11:48612
[email protected]aa9b14d2013-05-10 23:45:19613 scoped_ptr<QuicEncryptedPacket> req(
[email protected]6d1b4ed2013-07-10 03:57:54614 ConstructDataPacket(1, 3, true, true, 0,
615 GetRequestString("GET", "http", "/")));
[email protected]8ba81212013-05-03 13:11:48616 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0));
617
618 MockWrite quic_writes[] = {
[email protected]aa9b14d2013-05-10 23:45:19619 MockWrite(SYNCHRONOUS, req->data(), req->length()),
[email protected]8ba81212013-05-03 13:11:48620 MockWrite(SYNCHRONOUS, ack->data(), ack->length()),
621 };
622
623 scoped_ptr<QuicEncryptedPacket> resp(
624 ConstructDataPacket(
[email protected]98b20ce2013-05-10 05:55:26625 1, 3, false, true, 0, GetResponseString("200 OK", "hello!")));
[email protected]8ba81212013-05-03 13:11:48626 MockRead quic_reads[] = {
627 MockRead(SYNCHRONOUS, resp->data(), resp->length()),
628 MockRead(ASYNC, OK), // EOF
629 };
630
631 DelayedSocketData quic_data(
632 1, // wait for one write to finish before reading.
633 quic_reads, arraysize(quic_reads),
634 quic_writes, arraysize(quic_writes));
635
636 socket_factory_.AddSocketDataProvider(&quic_data);
637
[email protected]3a120a6b2013-06-25 01:08:27638 // The non-alternate protocol job needs to hang in order to guarantee that
639 // the alternate-protocol job will "win".
[email protected]dda75ab2013-06-22 22:43:30640 AddHangingNonAlternateProtocolSocketData();
641
[email protected]8ba81212013-05-03 13:11:48642 CreateSession();
[email protected]aa9b14d2013-05-10 23:45:19643 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
644 SendRequestAndExpectQuicResponse("hello!");
[email protected]8ba81212013-05-03 13:11:48645}
646
[email protected]3a120a6b2013-06-25 01:08:27647TEST_F(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
648 HttpStreamFactory::EnableNpnSpdy(); // Enables QUIC too.
649
650 scoped_ptr<QuicEncryptedPacket> req(
[email protected]6d1b4ed2013-07-10 03:57:54651 ConstructDataPacket(1, 3, true, true, 0,
652 GetRequestString("GET", "http", "/")));
[email protected]3a120a6b2013-06-25 01:08:27653 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0));
654
655 MockWrite quic_writes[] = {
656 MockWrite(SYNCHRONOUS, req->data(), req->length()),
657 MockWrite(SYNCHRONOUS, ack->data(), ack->length()),
658 };
659
660 scoped_ptr<QuicEncryptedPacket> resp(
661 ConstructDataPacket(
662 1, 3, false, true, 0, GetResponseString("200 OK", "hello!")));
663 MockRead quic_reads[] = {
664 MockRead(SYNCHRONOUS, resp->data(), resp->length()),
665 MockRead(ASYNC, OK), // EOF
666 };
667
668 DelayedSocketData quic_data(
669 1, // wait for one write to finish before reading.
670 quic_reads, arraysize(quic_reads),
671 quic_writes, arraysize(quic_writes));
672
673 socket_factory_.AddSocketDataProvider(&quic_data);
674
675 // In order for a new QUIC session to be established via alternate-protocol
676 // without racing an HTTP connection, we need the host resolution to happen
677 // synchronously.
678 host_resolver_.set_synchronous_mode(true);
679 host_resolver_.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
680 HostResolver::RequestInfo info(HostPortPair("www.google.com", 80));
681 AddressList address;
682 host_resolver_.Resolve(info, &address, CompletionCallback(), NULL,
683 net_log_.bound());
684
685 CreateSession();
686 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
687 SendRequestAndExpectQuicResponse("hello!");
688}
689
[email protected]3316d422013-05-03 21:45:30690TEST_F(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]4ff65372013-06-21 05:45:46691 HttpStreamFactory::EnableNpnSpdy(); // Enables QUIC too.
[email protected]3316d422013-05-03 21:45:30692
[email protected]3316d422013-05-03 21:45:30693 // Alternate-protocol job
694 scoped_ptr<QuicEncryptedPacket> close(ConstructConnectionClosePacket(1));
695 MockRead quic_reads[] = {
696 MockRead(ASYNC, close->data(), close->length()),
697 MockRead(ASYNC, OK), // EOF
698 };
699 StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
700 NULL, 0);
701 socket_factory_.AddSocketDataProvider(&quic_data);
702
703 // Main job which will succeed even though the alternate job fails.
704 MockRead http_reads[] = {
705 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
706 MockRead("hello from http"),
707 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
708 MockRead(ASYNC, OK)
709 };
710
711 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
712 NULL, 0);
713 socket_factory_.AddSocketDataProvider(&http_data);
714
[email protected]3316d422013-05-03 21:45:30715 CreateSession();
[email protected]aa9b14d2013-05-10 23:45:19716 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
717 SendRequestAndExpectHttpResponse("hello from http");
718 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:30719}
720
[email protected]d03a66d2013-05-06 12:55:59721TEST_F(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]4ff65372013-06-21 05:45:46722 HttpStreamFactory::EnableNpnSpdy(); // Enables QUIC too.
[email protected]d03a66d2013-05-06 12:55:59723
[email protected]d03a66d2013-05-06 12:55:59724 // Alternate-protocol job
725 MockRead quic_reads[] = {
726 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
727 };
728 StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
729 NULL, 0);
730 socket_factory_.AddSocketDataProvider(&quic_data);
731
732 // Main job which will succeed even though the alternate job fails.
733 MockRead http_reads[] = {
734 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
735 MockRead("hello from http"),
736 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
737 MockRead(ASYNC, OK)
738 };
739
740 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
741 NULL, 0);
742 socket_factory_.AddSocketDataProvider(&http_data);
743
[email protected]d03a66d2013-05-06 12:55:59744 CreateSession();
[email protected]d03a66d2013-05-06 12:55:59745
[email protected]aa9b14d2013-05-10 23:45:19746 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
747 SendRequestAndExpectHttpResponse("hello from http");
748 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:59749}
750
[email protected]61a527782013-02-21 03:58:00751} // namespace test
752} // namespace net