blob: 53e69eed35a12146d8d82f7cc8c71b2e9bb1916b [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]61a527782013-02-21 03:58:0050
51} // namespace
52
53namespace net {
54namespace test {
55
56class QuicNetworkTransactionTest : public PlatformTest {
57 protected:
[email protected]1c04f9522013-02-21 20:32:4358 QuicNetworkTransactionTest()
59 : clock_(new MockClock),
60 ssl_config_service_(new SSLConfigServiceDefaults),
61 proxy_service_(ProxyService::CreateDirect()),
[email protected]c244c5a12013-05-07 20:55:0462 compressor_(new QuicSpdyCompressor()),
[email protected]1c04f9522013-02-21 20:32:4363 auth_handler_factory_(
[email protected]dda75ab2013-06-22 22:43:3064 HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
65 hanging_data_(NULL, 0, NULL, 0) {
[email protected]aa9b14d2013-05-10 23:45:1966 request_.method = "GET";
67 request_.url = GURL("http://www.google.com/");
68 request_.load_flags = 0;
[email protected]1c04f9522013-02-21 20:32:4369 }
[email protected]61a527782013-02-21 03:58:0070
71 virtual void SetUp() {
72 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:3473 base::MessageLoop::current()->RunUntilIdle();
[email protected]61a527782013-02-21 03:58:0074 }
75
76 virtual void TearDown() {
77 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
78 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:3479 base::MessageLoop::current()->RunUntilIdle();
[email protected]61a527782013-02-21 03:58:0080 PlatformTest::TearDown();
81 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:3482 base::MessageLoop::current()->RunUntilIdle();
[email protected]61a527782013-02-21 03:58:0083 HttpStreamFactory::set_use_alternate_protocols(false);
84 HttpStreamFactory::SetNextProtos(std::vector<std::string>());
85 }
86
[email protected]61a527782013-02-21 03:58:0087 scoped_ptr<QuicEncryptedPacket> ConstructRstPacket(
88 QuicPacketSequenceNumber num,
89 QuicStreamId stream_id) {
90 QuicPacketHeader header;
91 header.public_header.guid = 0xDEADBEEF;
[email protected]9db443912013-02-25 05:27:0392 header.public_header.reset_flag = false;
93 header.public_header.version_flag = false;
[email protected]61a527782013-02-21 03:58:0094 header.packet_sequence_number = num;
[email protected]9db443912013-02-25 05:27:0395 header.entropy_flag = false;
96 header.fec_flag = false;
[email protected]61a527782013-02-21 03:58:0097 header.fec_group = 0;
98
[email protected]74bda142013-03-31 02:49:1199 QuicRstStreamFrame rst(stream_id, QUIC_STREAM_NO_ERROR);
[email protected]61a527782013-02-21 03:58:00100 return scoped_ptr<QuicEncryptedPacket>(
101 ConstructPacket(header, QuicFrame(&rst)));
102 }
103
[email protected]3316d422013-05-03 21:45:30104 scoped_ptr<QuicEncryptedPacket> ConstructConnectionClosePacket(
105 QuicPacketSequenceNumber num) {
106 QuicPacketHeader header;
107 header.public_header.guid = 0xDEADBEEF;
108 header.public_header.reset_flag = false;
109 header.public_header.version_flag = false;
110 header.packet_sequence_number = num;
111 header.entropy_flag = false;
112 header.fec_flag = false;
[email protected]3316d422013-05-03 21:45:30113 header.fec_group = 0;
114
115 QuicAckFrame ack_frame(0, QuicTime::Zero(), 0);
116 QuicConnectionCloseFrame close;
117 close.error_code = QUIC_CRYPTO_VERSION_NOT_SUPPORTED;
118 close.error_details = "Time to panic!";
119 close.ack_frame = ack_frame;
120 return scoped_ptr<QuicEncryptedPacket>(
121 ConstructPacket(header, QuicFrame(&close)));
122 }
123
[email protected]61a527782013-02-21 03:58:00124 scoped_ptr<QuicEncryptedPacket> ConstructAckPacket(
125 QuicPacketSequenceNumber largest_received,
126 QuicPacketSequenceNumber least_unacked) {
127 QuicPacketHeader header;
128 header.public_header.guid = 0xDEADBEEF;
[email protected]9db443912013-02-25 05:27:03129 header.public_header.reset_flag = false;
130 header.public_header.version_flag = false;
[email protected]e8ff26842013-03-22 21:02:05131 header.packet_sequence_number = 2;
[email protected]9db443912013-02-25 05:27:03132 header.entropy_flag = false;
133 header.fec_flag = false;
[email protected]61a527782013-02-21 03:58:00134 header.fec_group = 0;
135
[email protected]14e8106c2013-03-14 16:25:33136 QuicAckFrame ack(largest_received, QuicTime::Zero(), least_unacked);
[email protected]61a527782013-02-21 03:58:00137
138 QuicCongestionFeedbackFrame feedback;
139 feedback.type = kTCP;
140 feedback.tcp.accumulated_number_of_lost_packets = 0;
141 feedback.tcp.receive_window = 256000;
142
[email protected]8ba81212013-05-03 13:11:48143 QuicFramer framer(kQuicVersion1, QuicTime::Zero(), false);
[email protected]61a527782013-02-21 03:58:00144 QuicFrames frames;
145 frames.push_back(QuicFrame(&ack));
146 frames.push_back(QuicFrame(&feedback));
147 scoped_ptr<QuicPacket> packet(
[email protected]9db443912013-02-25 05:27:03148 framer.ConstructFrameDataPacket(header, frames).packet);
[email protected]8ba81212013-05-03 13:11:48149 return scoped_ptr<QuicEncryptedPacket>(framer.EncryptPacket(
150 ENCRYPTION_NONE, header.packet_sequence_number, *packet));
[email protected]61a527782013-02-21 03:58:00151 }
152
153 std::string GetRequestString(const std::string& method,
154 const std::string& path) {
155 SpdyHeaderBlock headers;
156 headers[":method"] = method;
157 headers[":host"] = "www.google.com";
158 headers[":path"] = path;
159 headers[":scheme"] = "http";
160 headers[":version"] = "HTTP/1.1";
161 return SerializeHeaderBlock(headers);
162 }
163
164 std::string GetResponseString(const std::string& status,
165 const std::string& body) {
166 SpdyHeaderBlock headers;
167 headers[":status"] = status;
168 headers[":version"] = "HTTP/1.1";
169 headers["content-type"] = "text/plain";
[email protected]c244c5a12013-05-07 20:55:04170 return compressor_->CompressHeaders(headers) + body;
[email protected]61a527782013-02-21 03:58:00171 }
172
173 std::string SerializeHeaderBlock(const SpdyHeaderBlock& headers) {
[email protected]821555c2013-05-16 20:20:17174 QuicSpdyCompressor compressor;
175 return compressor.CompressHeaders(headers);
[email protected]61a527782013-02-21 03:58:00176 }
177
178 // Returns a newly created packet to send kData on stream 1.
179 QuicEncryptedPacket* ConstructDataPacket(
180 QuicPacketSequenceNumber sequence_number,
[email protected]98b20ce2013-05-10 05:55:26181 QuicStreamId stream_id,
[email protected]e8ff26842013-03-22 21:02:05182 bool should_include_version,
[email protected]61a527782013-02-21 03:58:00183 bool fin,
184 QuicStreamOffset offset,
185 base::StringPiece data) {
[email protected]e8ff26842013-03-22 21:02:05186 InitializeHeader(sequence_number, should_include_version);
[email protected]98b20ce2013-05-10 05:55:26187 QuicStreamFrame frame(stream_id, fin, offset, data);
[email protected]61a527782013-02-21 03:58:00188 return ConstructPacket(header_, QuicFrame(&frame)).release();
189 }
190
191 scoped_ptr<QuicEncryptedPacket> ConstructPacket(
192 const QuicPacketHeader& header,
193 const QuicFrame& frame) {
[email protected]8ba81212013-05-03 13:11:48194 QuicFramer framer(kQuicVersion1, QuicTime::Zero(), false);
[email protected]61a527782013-02-21 03:58:00195 QuicFrames frames;
196 frames.push_back(frame);
197 scoped_ptr<QuicPacket> packet(
[email protected]9db443912013-02-25 05:27:03198 framer.ConstructFrameDataPacket(header, frames).packet);
[email protected]8ba81212013-05-03 13:11:48199 return scoped_ptr<QuicEncryptedPacket>(framer.EncryptPacket(
200 ENCRYPTION_NONE, header.packet_sequence_number, *packet));
[email protected]61a527782013-02-21 03:58:00201 }
202
[email protected]e8ff26842013-03-22 21:02:05203 void InitializeHeader(QuicPacketSequenceNumber sequence_number,
204 bool should_include_version) {
[email protected]61a527782013-02-21 03:58:00205 header_.public_header.guid = random_generator_.RandUint64();
[email protected]9db443912013-02-25 05:27:03206 header_.public_header.reset_flag = false;
[email protected]e8ff26842013-03-22 21:02:05207 header_.public_header.version_flag = should_include_version;
[email protected]61a527782013-02-21 03:58:00208 header_.packet_sequence_number = sequence_number;
209 header_.fec_group = 0;
[email protected]9db443912013-02-25 05:27:03210 header_.entropy_flag = false;
211 header_.fec_flag = false;
[email protected]61a527782013-02-21 03:58:00212 }
213
214 void CreateSession() {
[email protected]dda75ab2013-06-22 22:43:30215 CreateSessionWithFactory(&socket_factory_);
216 }
217
218 void CreateSessionWithFactory(ClientSocketFactory* socket_factory) {
[email protected]4dca587c2013-03-07 16:54:47219 params_.enable_quic = true;
220 params_.quic_clock = clock_;
221 params_.quic_random = &random_generator_;
[email protected]dda75ab2013-06-22 22:43:30222 params_.client_socket_factory = socket_factory;
[email protected]e8ff26842013-03-22 21:02:05223 params_.quic_crypto_client_stream_factory = &crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:43224 params_.host_resolver = &host_resolver_;
225 params_.cert_verifier = &cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:11226 params_.transport_security_state = &transport_security_state_;
[email protected]1c04f9522013-02-21 20:32:43227 params_.proxy_service = proxy_service_.get();
228 params_.ssl_config_service = ssl_config_service_.get();
229 params_.http_auth_handler_factory = auth_handler_factory_.get();
[email protected]61a527782013-02-21 03:58:00230 params_.http_server_properties = &http_server_properties;
231
232 session_ = new HttpNetworkSession(params_);
233 }
234
[email protected]aa9b14d2013-05-10 23:45:19235 void CheckWasQuicResponse(const scoped_ptr<HttpNetworkTransaction>& trans) {
236 const HttpResponseInfo* response = trans->GetResponseInfo();
237 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:50238 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]aa9b14d2013-05-10 23:45:19239 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
240 EXPECT_TRUE(response->was_fetched_via_spdy);
241 EXPECT_TRUE(response->was_npn_negotiated);
242 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_QUIC1_SPDY3,
243 response->connection_info);
244 }
245
246 void CheckWasHttpResponse(const scoped_ptr<HttpNetworkTransaction>& trans) {
247 const HttpResponseInfo* response = trans->GetResponseInfo();
248 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:50249 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]aa9b14d2013-05-10 23:45:19250 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
251 EXPECT_FALSE(response->was_fetched_via_spdy);
252 EXPECT_FALSE(response->was_npn_negotiated);
253 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1,
254 response->connection_info);
255 }
256
257 void CheckResponseData(HttpNetworkTransaction* trans,
258 const std::string& expected) {
259 std::string response_data;
260 ASSERT_EQ(OK, ReadTransaction(trans, &response_data));
261 EXPECT_EQ(expected, response_data);
262 }
263
264 void RunTransaction(HttpNetworkTransaction* trans) {
265 TestCompletionCallback callback;
266 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
267 EXPECT_EQ(ERR_IO_PENDING, rv);
268 EXPECT_EQ(OK, callback.WaitForResult());
269 }
270
271 void SendRequestAndExpectHttpResponse(const std::string& expected) {
272 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:50273 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
[email protected]aa9b14d2013-05-10 23:45:19274 RunTransaction(trans.get());
275 CheckWasHttpResponse(trans);
276 CheckResponseData(trans.get(), expected);
277 }
278
279 void SendRequestAndExpectQuicResponse(const std::string& expected) {
280 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:50281 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
[email protected]aa9b14d2013-05-10 23:45:19282 RunTransaction(trans.get());
283 CheckWasQuicResponse(trans);
284 CheckResponseData(trans.get(), expected);
285 }
286
287 void AddQuicAlternateProtocolMapping(
288 MockCryptoClientStream::HandshakeMode handshake_mode) {
289 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
290 session_->http_server_properties()->SetAlternateProtocol(
291 HostPortPair::FromURL(request_.url), 80, QUIC);
292 }
293
294 void ExpectBrokenAlternateProtocolMapping() {
295 ASSERT_TRUE(session_->http_server_properties()->HasAlternateProtocol(
296 HostPortPair::FromURL(request_.url)));
297 const PortAlternateProtocolPair alternate =
298 session_->http_server_properties()->GetAlternateProtocol(
299 HostPortPair::FromURL(request_.url));
300 EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol);
301 }
302
303 void AddHangingNonAlternateProtocolSocketData() {
[email protected]dda75ab2013-06-22 22:43:30304 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
305 hanging_data_.set_connect_data(hanging_connect);
306 socket_factory_.AddSocketDataProvider(&hanging_data_);
[email protected]aa9b14d2013-05-10 23:45:19307 }
308
[email protected]61a527782013-02-21 03:58:00309 QuicPacketHeader header_;
310 scoped_refptr<HttpNetworkSession> session_;
311 MockClientSocketFactory socket_factory_;
[email protected]e8ff26842013-03-22 21:02:05312 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:43313 MockClock* clock_; // Owned by QuicStreamFactory after CreateSession.
314 MockHostResolver host_resolver_;
315 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:11316 TransportSecurityState transport_security_state_;
[email protected]1c04f9522013-02-21 20:32:43317 scoped_refptr<SSLConfigServiceDefaults> ssl_config_service_;
318 scoped_ptr<ProxyService> proxy_service_;
[email protected]c244c5a12013-05-07 20:55:04319 scoped_ptr<QuicSpdyCompressor> compressor_;
[email protected]1c04f9522013-02-21 20:32:43320 scoped_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
[email protected]61a527782013-02-21 03:58:00321 MockRandom random_generator_;
322 HttpServerPropertiesImpl http_server_properties;
323 HttpNetworkSession::Params params_;
[email protected]aa9b14d2013-05-10 23:45:19324 HttpRequestInfo request_;
325 CapturingBoundNetLog net_log_;
[email protected]dda75ab2013-06-22 22:43:30326 StaticSocketDataProvider hanging_data_;
[email protected]61a527782013-02-21 03:58:00327};
328
[email protected]4dca587c2013-03-07 16:54:47329TEST_F(QuicNetworkTransactionTest, ForceQuic) {
[email protected]49e85332013-06-04 04:18:03330 params_.origin_to_force_quic_on =
331 HostPortPair::FromString("www.google.com:80");
[email protected]4dca587c2013-03-07 16:54:47332
[email protected]98b20ce2013-05-10 05:55:26333 QuicStreamId stream_id = 3;
[email protected]aa9b14d2013-05-10 23:45:19334 scoped_ptr<QuicEncryptedPacket> req(
[email protected]98b20ce2013-05-10 05:55:26335 ConstructDataPacket(1, stream_id, true, true, 0,
336 GetRequestString("GET", "/")));
[email protected]e8ff26842013-03-22 21:02:05337 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0));
[email protected]4dca587c2013-03-07 16:54:47338
339 MockWrite quic_writes[] = {
[email protected]aa9b14d2013-05-10 23:45:19340 MockWrite(SYNCHRONOUS, req->data(), req->length()),
[email protected]4dca587c2013-03-07 16:54:47341 MockWrite(SYNCHRONOUS, ack->data(), ack->length()),
342 };
343
[email protected]4dca587c2013-03-07 16:54:47344 scoped_ptr<QuicEncryptedPacket> resp(
[email protected]e8ff26842013-03-22 21:02:05345 ConstructDataPacket(
[email protected]98b20ce2013-05-10 05:55:26346 1, stream_id, false, true, 0, GetResponseString("200 OK", "hello!")));
[email protected]4dca587c2013-03-07 16:54:47347 MockRead quic_reads[] = {
[email protected]4dca587c2013-03-07 16:54:47348 MockRead(SYNCHRONOUS, resp->data(), resp->length()),
349 MockRead(ASYNC, OK), // EOF
350 };
351
352 DelayedSocketData quic_data(
353 1, // wait for one write to finish before reading.
354 quic_reads, arraysize(quic_reads),
355 quic_writes, arraysize(quic_writes));
356
357 socket_factory_.AddSocketDataProvider(&quic_data);
358
[email protected]aa9b14d2013-05-10 23:45:19359 // The non-alternate protocol job needs to hang in order to guarantee that
360 // the alternate-protocol job will "win".
361 AddHangingNonAlternateProtocolSocketData();
[email protected]4dca587c2013-03-07 16:54:47362
363 CreateSession();
[email protected]4dca587c2013-03-07 16:54:47364
[email protected]aa9b14d2013-05-10 23:45:19365 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:47366
[email protected]98b20ce2013-05-10 05:55:26367 // Check that the NetLog was filled reasonably.
368 net::CapturingNetLog::CapturedEntryList entries;
[email protected]aa9b14d2013-05-10 23:45:19369 net_log_.GetEntries(&entries);
[email protected]98b20ce2013-05-10 05:55:26370 EXPECT_LT(0u, entries.size());
371
372 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
373 int pos = net::ExpectLogContainsSomewhere(
374 entries, 0,
375 net::NetLog::TYPE_QUIC_SESSION_PACKET_RECEIVED,
376 net::NetLog::PHASE_NONE);
377 EXPECT_LT(0, pos);
378
379 // ... and also a TYPE_QUIC_SESSION_PACKET_HEADER_RECEIVED.
380 pos = net::ExpectLogContainsSomewhere(
381 entries, 0,
382 net::NetLog::TYPE_QUIC_SESSION_PACKET_HEADER_RECEIVED,
383 net::NetLog::PHASE_NONE);
384 EXPECT_LT(0, pos);
385
386 std::string packet_sequence_number;
387 ASSERT_TRUE(entries[pos].GetStringValue(
388 "packet_sequence_number", &packet_sequence_number));
389 EXPECT_EQ("1", packet_sequence_number);
390
391 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
392 pos = net::ExpectLogContainsSomewhere(
393 entries, 0,
394 net::NetLog::TYPE_QUIC_SESSION_STREAM_FRAME_RECEIVED,
395 net::NetLog::PHASE_NONE);
396 EXPECT_LT(0, pos);
397
398 int log_stream_id;
399 ASSERT_TRUE(entries[pos].GetIntegerValue("stream_id", &log_stream_id));
400 EXPECT_EQ(stream_id, static_cast<QuicStreamId>(log_stream_id));
[email protected]4dca587c2013-03-07 16:54:47401}
402
[email protected]cebe3282013-05-22 23:49:30403TEST_F(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
[email protected]49e85332013-06-04 04:18:03404 params_.origin_to_force_quic_on =
405 HostPortPair::FromString("www.google.com:80");
[email protected]cebe3282013-05-22 23:49:30406
407 MockRead quic_reads[] = {
408 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
409 };
410 StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
411 NULL, 0);
412 socket_factory_.AddSocketDataProvider(&quic_data);
413
414 CreateSession();
415
416 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:50417 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
[email protected]cebe3282013-05-22 23:49:30418 TestCompletionCallback callback;
419 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
420 EXPECT_EQ(ERR_IO_PENDING, rv);
421 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, callback.WaitForResult());
422}
423
[email protected]4dca587c2013-03-07 16:54:47424TEST_F(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
425 // Attempt to "force" quic on 443, which will not be honored.
[email protected]49e85332013-06-04 04:18:03426 params_.origin_to_force_quic_on =
427 HostPortPair::FromString("www.google.com:443");
[email protected]4dca587c2013-03-07 16:54:47428
[email protected]aa9b14d2013-05-10 23:45:19429 MockRead http_reads[] = {
[email protected]4dca587c2013-03-07 16:54:47430 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
431 MockRead("hello world"),
432 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
433 MockRead(ASYNC, OK)
434 };
435
[email protected]aa9b14d2013-05-10 23:45:19436 StaticSocketDataProvider data(http_reads, arraysize(http_reads), NULL, 0);
[email protected]4dca587c2013-03-07 16:54:47437 socket_factory_.AddSocketDataProvider(&data);
438 SSLSocketDataProvider ssl(ASYNC, OK);
439 socket_factory_.AddSSLSocketDataProvider(&ssl);
440
[email protected]4dca587c2013-03-07 16:54:47441 CreateSession();
[email protected]4dca587c2013-03-07 16:54:47442
[email protected]aa9b14d2013-05-10 23:45:19443 SendRequestAndExpectHttpResponse("hello world");
[email protected]4dca587c2013-03-07 16:54:47444}
445
[email protected]61a527782013-02-21 03:58:00446TEST_F(QuicNetworkTransactionTest, UseAlternateProtocolForQuic) {
[email protected]4ff65372013-06-21 05:45:46447 HttpStreamFactory::EnableNpnSpdy(); // Enables QUIC too.
[email protected]61a527782013-02-21 03:58:00448
[email protected]aa9b14d2013-05-10 23:45:19449 MockRead http_reads[] = {
[email protected]61a527782013-02-21 03:58:00450 MockRead("HTTP/1.1 200 OK\r\n"),
451 MockRead(kQuicAlternateProtocolHttpHeader),
452 MockRead("hello world"),
453 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
454 MockRead(ASYNC, OK)
455 };
456
[email protected]aa9b14d2013-05-10 23:45:19457 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
458 NULL, 0);
459 socket_factory_.AddSocketDataProvider(&http_data);
[email protected]61a527782013-02-21 03:58:00460
[email protected]aa9b14d2013-05-10 23:45:19461 scoped_ptr<QuicEncryptedPacket> req(
[email protected]98b20ce2013-05-10 05:55:26462 ConstructDataPacket(1, 3, true, true, 0, GetRequestString("GET", "/")));
[email protected]e8ff26842013-03-22 21:02:05463 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0));
[email protected]61a527782013-02-21 03:58:00464
465 MockWrite quic_writes[] = {
[email protected]aa9b14d2013-05-10 23:45:19466 MockWrite(SYNCHRONOUS, req->data(), req->length()),
[email protected]61a527782013-02-21 03:58:00467 MockWrite(SYNCHRONOUS, ack->data(), ack->length()),
468 };
469
[email protected]61a527782013-02-21 03:58:00470 scoped_ptr<QuicEncryptedPacket> resp(
[email protected]e8ff26842013-03-22 21:02:05471 ConstructDataPacket(
[email protected]98b20ce2013-05-10 05:55:26472 1, 3, false, true, 0, GetResponseString("200 OK", "hello!")));
[email protected]61a527782013-02-21 03:58:00473 MockRead quic_reads[] = {
[email protected]61a527782013-02-21 03:58:00474 MockRead(SYNCHRONOUS, resp->data(), resp->length()),
475 MockRead(ASYNC, OK), // EOF
476 };
477
478 DelayedSocketData quic_data(
479 1, // wait for one write to finish before reading.
480 quic_reads, arraysize(quic_reads),
481 quic_writes, arraysize(quic_writes));
482
483 socket_factory_.AddSocketDataProvider(&quic_data);
484
[email protected]aa9b14d2013-05-10 23:45:19485 // The non-alternate protocol job needs to hang in order to guarantee that
486 // the alternate-protocol job will "win".
487 AddHangingNonAlternateProtocolSocketData();
[email protected]61a527782013-02-21 03:58:00488
489 CreateSession();
[email protected]61a527782013-02-21 03:58:00490
[email protected]aa9b14d2013-05-10 23:45:19491 SendRequestAndExpectHttpResponse("hello world");
492 SendRequestAndExpectQuicResponse("hello!");
[email protected]61a527782013-02-21 03:58:00493}
494
[email protected]dda75ab2013-06-22 22:43:30495TEST_F(QuicNetworkTransactionTest, HungAlternateProtocol) {
496 HttpStreamFactory::EnableNpnSpdy(); // Enables QUIC too.
497 crypto_client_stream_factory_.set_handshake_mode(
498 MockCryptoClientStream::COLD_START);
499
500 MockWrite http_writes[] = {
501 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
502 MockWrite(SYNCHRONOUS, 1, "Host: www.google.com\r\n"),
503 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")
504 };
505
506 MockRead http_reads[] = {
507 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
508 MockRead(SYNCHRONOUS, 4, kQuicAlternateProtocolHttpHeader),
509 MockRead(SYNCHRONOUS, 5, "hello world"),
510 MockRead(SYNCHRONOUS, OK, 6)
511 };
512
513 DeterministicMockClientSocketFactory socket_factory;
514
515 DeterministicSocketData http_data(http_reads, arraysize(http_reads),
516 http_writes, arraysize(http_writes));
517 socket_factory.AddSocketDataProvider(&http_data);
518
519 // The QUIC transaction will not be allowed to complete.
520 MockWrite quic_writes[] = {
521 MockWrite(ASYNC, ERR_IO_PENDING, 0)
522 };
523 MockRead quic_reads[] = {
524 MockRead(ASYNC, ERR_IO_PENDING, 1),
525 };
526 DeterministicSocketData quic_data(quic_reads, arraysize(quic_reads),
527 quic_writes, arraysize(quic_writes));
528 socket_factory.AddSocketDataProvider(&quic_data);
529
530 // The HTTP transaction will complete.
531 DeterministicSocketData http_data2(http_reads, arraysize(http_reads),
532 http_writes, arraysize(http_writes));
533 socket_factory.AddSocketDataProvider(&http_data2);
534
535 CreateSessionWithFactory(&socket_factory);
536
537 // Run the first request.
538 http_data.StopAfter(arraysize(http_reads) + arraysize(http_writes));
539 SendRequestAndExpectHttpResponse("hello world");
540 ASSERT_TRUE(http_data.at_read_eof());
541 ASSERT_TRUE(http_data.at_write_eof());
542
543 // Now run the second request in which the QUIC socket hangs,
544 // and verify the the transaction continues over HTTP.
545 http_data2.StopAfter(arraysize(http_reads) + arraysize(http_writes));
546 SendRequestAndExpectHttpResponse("hello world");
547
548 ASSERT_TRUE(http_data2.at_read_eof());
549 ASSERT_TRUE(http_data2.at_write_eof());
550 ASSERT_TRUE(!quic_data.at_read_eof());
551 ASSERT_TRUE(!quic_data.at_write_eof());
552}
553
[email protected]ff899c82013-03-12 23:10:50554TEST_F(QuicNetworkTransactionTest, DontUseAlternateProtocolForQuicHttps) {
[email protected]4ff65372013-06-21 05:45:46555 HttpStreamFactory::EnableNpnSpdy(); // Enables QUIC too.
[email protected]ff899c82013-03-12 23:10:50556
[email protected]aa9b14d2013-05-10 23:45:19557 MockRead http_reads[] = {
[email protected]ff899c82013-03-12 23:10:50558 MockRead("HTTP/1.1 200 OK\r\n"),
559 MockRead("Content-length: 11\r\n"),
560 MockRead(kQuicAlternateProtocolHttpHeader),
561 MockRead("hello world"),
562
563 MockRead("HTTP/1.1 200 OK\r\n"),
564 MockRead("Content-length: 6\r\n"),
565 MockRead(kQuicAlternateProtocolHttpHeader),
566 MockRead("hello!"),
567 };
568
[email protected]aa9b14d2013-05-10 23:45:19569 StaticSocketDataProvider data(http_reads, arraysize(http_reads), NULL, 0);
570 socket_factory_.AddSocketDataProvider(&data);
[email protected]ff899c82013-03-12 23:10:50571 SSLSocketDataProvider ssl(ASYNC, OK);
572 socket_factory_.AddSSLSocketDataProvider(&ssl);
573
[email protected]aa9b14d2013-05-10 23:45:19574 request_.url = GURL("https://www.google.com/");
[email protected]ff899c82013-03-12 23:10:50575
576 CreateSession();
[email protected]ff899c82013-03-12 23:10:50577
[email protected]aa9b14d2013-05-10 23:45:19578 SendRequestAndExpectHttpResponse("hello world");
579 SendRequestAndExpectHttpResponse("hello!");
[email protected]ff899c82013-03-12 23:10:50580}
581
[email protected]3a120a6b2013-06-25 01:08:27582TEST_F(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
[email protected]4ff65372013-06-21 05:45:46583 HttpStreamFactory::EnableNpnSpdy(); // Enables QUIC too.
[email protected]8ba81212013-05-03 13:11:48584
[email protected]aa9b14d2013-05-10 23:45:19585 scoped_ptr<QuicEncryptedPacket> req(
[email protected]98b20ce2013-05-10 05:55:26586 ConstructDataPacket(1, 3, true, true, 0, GetRequestString("GET", "/")));
[email protected]8ba81212013-05-03 13:11:48587 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0));
588
589 MockWrite quic_writes[] = {
[email protected]aa9b14d2013-05-10 23:45:19590 MockWrite(SYNCHRONOUS, req->data(), req->length()),
[email protected]8ba81212013-05-03 13:11:48591 MockWrite(SYNCHRONOUS, ack->data(), ack->length()),
592 };
593
594 scoped_ptr<QuicEncryptedPacket> resp(
595 ConstructDataPacket(
[email protected]98b20ce2013-05-10 05:55:26596 1, 3, false, true, 0, GetResponseString("200 OK", "hello!")));
[email protected]8ba81212013-05-03 13:11:48597 MockRead quic_reads[] = {
598 MockRead(SYNCHRONOUS, resp->data(), resp->length()),
599 MockRead(ASYNC, OK), // EOF
600 };
601
602 DelayedSocketData quic_data(
603 1, // wait for one write to finish before reading.
604 quic_reads, arraysize(quic_reads),
605 quic_writes, arraysize(quic_writes));
606
607 socket_factory_.AddSocketDataProvider(&quic_data);
608
[email protected]3a120a6b2013-06-25 01:08:27609 // The non-alternate protocol job needs to hang in order to guarantee that
610 // the alternate-protocol job will "win".
[email protected]dda75ab2013-06-22 22:43:30611 AddHangingNonAlternateProtocolSocketData();
612
[email protected]8ba81212013-05-03 13:11:48613 CreateSession();
[email protected]aa9b14d2013-05-10 23:45:19614 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
615 SendRequestAndExpectQuicResponse("hello!");
[email protected]8ba81212013-05-03 13:11:48616}
617
[email protected]3a120a6b2013-06-25 01:08:27618TEST_F(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
619 HttpStreamFactory::EnableNpnSpdy(); // Enables QUIC too.
620
621 scoped_ptr<QuicEncryptedPacket> req(
622 ConstructDataPacket(1, 3, true, true, 0, GetRequestString("GET", "/")));
623 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0));
624
625 MockWrite quic_writes[] = {
626 MockWrite(SYNCHRONOUS, req->data(), req->length()),
627 MockWrite(SYNCHRONOUS, ack->data(), ack->length()),
628 };
629
630 scoped_ptr<QuicEncryptedPacket> resp(
631 ConstructDataPacket(
632 1, 3, false, true, 0, GetResponseString("200 OK", "hello!")));
633 MockRead quic_reads[] = {
634 MockRead(SYNCHRONOUS, resp->data(), resp->length()),
635 MockRead(ASYNC, OK), // EOF
636 };
637
638 DelayedSocketData quic_data(
639 1, // wait for one write to finish before reading.
640 quic_reads, arraysize(quic_reads),
641 quic_writes, arraysize(quic_writes));
642
643 socket_factory_.AddSocketDataProvider(&quic_data);
644
645 // In order for a new QUIC session to be established via alternate-protocol
646 // without racing an HTTP connection, we need the host resolution to happen
647 // synchronously.
648 host_resolver_.set_synchronous_mode(true);
649 host_resolver_.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
650 HostResolver::RequestInfo info(HostPortPair("www.google.com", 80));
651 AddressList address;
652 host_resolver_.Resolve(info, &address, CompletionCallback(), NULL,
653 net_log_.bound());
654
655 CreateSession();
656 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
657 SendRequestAndExpectQuicResponse("hello!");
658}
659
[email protected]3316d422013-05-03 21:45:30660TEST_F(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]4ff65372013-06-21 05:45:46661 HttpStreamFactory::EnableNpnSpdy(); // Enables QUIC too.
[email protected]3316d422013-05-03 21:45:30662
[email protected]3316d422013-05-03 21:45:30663 // Alternate-protocol job
664 scoped_ptr<QuicEncryptedPacket> close(ConstructConnectionClosePacket(1));
665 MockRead quic_reads[] = {
666 MockRead(ASYNC, close->data(), close->length()),
667 MockRead(ASYNC, OK), // EOF
668 };
669 StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
670 NULL, 0);
671 socket_factory_.AddSocketDataProvider(&quic_data);
672
673 // Main job which will succeed even though the alternate job fails.
674 MockRead http_reads[] = {
675 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
676 MockRead("hello from http"),
677 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
678 MockRead(ASYNC, OK)
679 };
680
681 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
682 NULL, 0);
683 socket_factory_.AddSocketDataProvider(&http_data);
684
[email protected]3316d422013-05-03 21:45:30685 CreateSession();
[email protected]aa9b14d2013-05-10 23:45:19686 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
687 SendRequestAndExpectHttpResponse("hello from http");
688 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:30689}
690
[email protected]d03a66d2013-05-06 12:55:59691TEST_F(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]4ff65372013-06-21 05:45:46692 HttpStreamFactory::EnableNpnSpdy(); // Enables QUIC too.
[email protected]d03a66d2013-05-06 12:55:59693
[email protected]d03a66d2013-05-06 12:55:59694 // Alternate-protocol job
695 MockRead quic_reads[] = {
696 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
697 };
698 StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
699 NULL, 0);
700 socket_factory_.AddSocketDataProvider(&quic_data);
701
702 // Main job which will succeed even though the alternate job fails.
703 MockRead http_reads[] = {
704 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
705 MockRead("hello from http"),
706 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
707 MockRead(ASYNC, OK)
708 };
709
710 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
711 NULL, 0);
712 socket_factory_.AddSocketDataProvider(&http_data);
713
[email protected]d03a66d2013-05-06 12:55:59714 CreateSession();
[email protected]d03a66d2013-05-06 12:55:59715
[email protected]aa9b14d2013-05-10 23:45:19716 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
717 SendRequestAndExpectHttpResponse("hello from http");
718 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:59719}
720
[email protected]61a527782013-02-21 03:58:00721} // namespace test
722} // namespace net