blob: fecd7d95732aafaca0937512541ae90e8c644a6c [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"
8#include "net/base/mock_cert_verifier.h"
[email protected]61a527782013-02-21 03:58:009#include "net/base/test_completion_callback.h"
[email protected]f2cb3cf2013-03-21 01:40:5310#include "net/dns/mock_host_resolver.h"
[email protected]61a527782013-02-21 03:58:0011#include "net/http/http_auth_handler_factory.h"
12#include "net/http/http_network_session.h"
13#include "net/http/http_network_transaction.h"
14#include "net/http/http_server_properties_impl.h"
15#include "net/http/http_stream.h"
16#include "net/http/http_stream_factory.h"
17#include "net/http/http_transaction_unittest.h"
18#include "net/proxy/proxy_config_service_fixed.h"
19#include "net/proxy/proxy_resolver.h"
20#include "net/proxy/proxy_service.h"
21#include "net/quic/crypto/quic_decrypter.h"
22#include "net/quic/crypto/quic_encrypter.h"
23#include "net/quic/quic_framer.h"
[email protected]ed3fc15d2013-03-08 18:37:4424#include "net/quic/test_tools/crypto_test_utils.h"
[email protected]61a527782013-02-21 03:58:0025#include "net/quic/test_tools/mock_clock.h"
[email protected]e8ff26842013-03-22 21:02:0526#include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
[email protected]61a527782013-02-21 03:58:0027#include "net/quic/test_tools/mock_random.h"
28#include "net/quic/test_tools/quic_test_utils.h"
29#include "net/socket/client_socket_factory.h"
30#include "net/socket/mock_client_socket_pool_manager.h"
31#include "net/socket/socket_test_util.h"
32#include "net/socket/ssl_client_socket.h"
33#include "net/spdy/spdy_frame_builder.h"
34#include "net/spdy/spdy_framer.h"
[email protected]536fd0b2013-03-14 17:41:5735#include "net/ssl/ssl_config_service_defaults.h"
[email protected]61a527782013-02-21 03:58:0036#include "testing/gtest/include/gtest/gtest.h"
37#include "testing/platform_test.h"
38
39//-----------------------------------------------------------------------------
40
41namespace {
42
43// This is the expected return from a current server advertising QUIC.
44static const char kQuicAlternateProtocolHttpHeader[] =
45 "Alternate-Protocol: 443:quic/1\r\n\r\n";
46
47// Returns a vector of NPN protocol strings for negotiating QUIC.
48std::vector<std::string> QuicNextProtos() {
49 std::vector<std::string> protos;
50 protos.push_back("http/1.1");
51 protos.push_back("quic/1");
52 return protos;
53}
54
55} // namespace
56
57namespace net {
58namespace test {
59
60class QuicNetworkTransactionTest : public PlatformTest {
61 protected:
[email protected]1c04f9522013-02-21 20:32:4362 QuicNetworkTransactionTest()
63 : clock_(new MockClock),
64 ssl_config_service_(new SSLConfigServiceDefaults),
65 proxy_service_(ProxyService::CreateDirect()),
66 auth_handler_factory_(
67 HttpAuthHandlerFactory::CreateDefault(&host_resolver_)) {
68 }
[email protected]61a527782013-02-21 03:58:0069
70 virtual void SetUp() {
71 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
72 MessageLoop::current()->RunUntilIdle();
73 }
74
75 virtual void TearDown() {
76 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
77 // Empty the current queue.
78 MessageLoop::current()->RunUntilIdle();
79 PlatformTest::TearDown();
80 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
81 MessageLoop::current()->RunUntilIdle();
82 HttpStreamFactory::set_use_alternate_protocols(false);
83 HttpStreamFactory::SetNextProtos(std::vector<std::string>());
84 }
85
[email protected]61a527782013-02-21 03:58:0086 scoped_ptr<QuicEncryptedPacket> ConstructRstPacket(
87 QuicPacketSequenceNumber num,
88 QuicStreamId stream_id) {
89 QuicPacketHeader header;
90 header.public_header.guid = 0xDEADBEEF;
[email protected]9db443912013-02-25 05:27:0391 header.public_header.reset_flag = false;
92 header.public_header.version_flag = false;
[email protected]61a527782013-02-21 03:58:0093 header.packet_sequence_number = num;
[email protected]9db443912013-02-25 05:27:0394 header.entropy_flag = false;
95 header.fec_flag = false;
96 header.fec_entropy_flag = false;
[email protected]61a527782013-02-21 03:58:0097 header.fec_group = 0;
98
[email protected]9db443912013-02-25 05:27:0399 QuicRstStreamFrame rst(stream_id, QUIC_NO_ERROR);
[email protected]61a527782013-02-21 03:58:00100 return scoped_ptr<QuicEncryptedPacket>(
101 ConstructPacket(header, QuicFrame(&rst)));
102 }
103
104 scoped_ptr<QuicEncryptedPacket> ConstructAckPacket(
105 QuicPacketSequenceNumber largest_received,
106 QuicPacketSequenceNumber least_unacked) {
107 QuicPacketHeader header;
108 header.public_header.guid = 0xDEADBEEF;
[email protected]9db443912013-02-25 05:27:03109 header.public_header.reset_flag = false;
110 header.public_header.version_flag = false;
[email protected]e8ff26842013-03-22 21:02:05111 header.packet_sequence_number = 2;
[email protected]9db443912013-02-25 05:27:03112 header.entropy_flag = false;
113 header.fec_flag = false;
114 header.fec_entropy_flag = false;
[email protected]61a527782013-02-21 03:58:00115 header.fec_group = 0;
116
[email protected]14e8106c2013-03-14 16:25:33117 QuicAckFrame ack(largest_received, QuicTime::Zero(), least_unacked);
[email protected]61a527782013-02-21 03:58:00118
119 QuicCongestionFeedbackFrame feedback;
120 feedback.type = kTCP;
121 feedback.tcp.accumulated_number_of_lost_packets = 0;
122 feedback.tcp.receive_window = 256000;
123
[email protected]5351cc4b2013-03-03 07:22:41124 QuicFramer framer(kQuicVersion1,
125 QuicDecrypter::Create(kNULL),
[email protected]14e8106c2013-03-14 16:25:33126 QuicEncrypter::Create(kNULL),
127 false);
[email protected]61a527782013-02-21 03:58:00128 QuicFrames frames;
129 frames.push_back(QuicFrame(&ack));
130 frames.push_back(QuicFrame(&feedback));
131 scoped_ptr<QuicPacket> packet(
[email protected]9db443912013-02-25 05:27:03132 framer.ConstructFrameDataPacket(header, frames).packet);
133 return scoped_ptr<QuicEncryptedPacket>(
134 framer.EncryptPacket(header.packet_sequence_number, *packet));
[email protected]61a527782013-02-21 03:58:00135 }
136
137 std::string GetRequestString(const std::string& method,
138 const std::string& path) {
139 SpdyHeaderBlock headers;
140 headers[":method"] = method;
141 headers[":host"] = "www.google.com";
142 headers[":path"] = path;
143 headers[":scheme"] = "http";
144 headers[":version"] = "HTTP/1.1";
145 return SerializeHeaderBlock(headers);
146 }
147
148 std::string GetResponseString(const std::string& status,
149 const std::string& body) {
150 SpdyHeaderBlock headers;
151 headers[":status"] = status;
152 headers[":version"] = "HTTP/1.1";
153 headers["content-type"] = "text/plain";
154 return SerializeHeaderBlock(headers) + body;
155 }
156
157 std::string SerializeHeaderBlock(const SpdyHeaderBlock& headers) {
158 size_t len = SpdyFramer::GetSerializedLength(3, &headers);
159 SpdyFrameBuilder builder(len);
160 SpdyFramer::WriteHeaderBlock(&builder, 3, &headers);
161 scoped_ptr<SpdyFrame> frame(builder.take());
162 return std::string(frame->data(), len);
163 }
164
165 // Returns a newly created packet to send kData on stream 1.
166 QuicEncryptedPacket* ConstructDataPacket(
167 QuicPacketSequenceNumber sequence_number,
[email protected]e8ff26842013-03-22 21:02:05168 bool should_include_version,
[email protected]61a527782013-02-21 03:58:00169 bool fin,
170 QuicStreamOffset offset,
171 base::StringPiece data) {
[email protected]e8ff26842013-03-22 21:02:05172 InitializeHeader(sequence_number, should_include_version);
[email protected]61a527782013-02-21 03:58:00173 QuicStreamFrame frame(3, fin, offset, data);
174 return ConstructPacket(header_, QuicFrame(&frame)).release();
175 }
176
177 scoped_ptr<QuicEncryptedPacket> ConstructPacket(
178 const QuicPacketHeader& header,
179 const QuicFrame& frame) {
[email protected]5351cc4b2013-03-03 07:22:41180 QuicFramer framer(kQuicVersion1,
181 QuicDecrypter::Create(kNULL),
[email protected]14e8106c2013-03-14 16:25:33182 QuicEncrypter::Create(kNULL),
183 false);
[email protected]61a527782013-02-21 03:58:00184 QuicFrames frames;
185 frames.push_back(frame);
186 scoped_ptr<QuicPacket> packet(
[email protected]9db443912013-02-25 05:27:03187 framer.ConstructFrameDataPacket(header, frames).packet);
188 return scoped_ptr<QuicEncryptedPacket>(
189 framer.EncryptPacket(header.packet_sequence_number, *packet));
[email protected]61a527782013-02-21 03:58:00190 }
191
[email protected]e8ff26842013-03-22 21:02:05192 void InitializeHeader(QuicPacketSequenceNumber sequence_number,
193 bool should_include_version) {
[email protected]61a527782013-02-21 03:58:00194 header_.public_header.guid = random_generator_.RandUint64();
[email protected]9db443912013-02-25 05:27:03195 header_.public_header.reset_flag = false;
[email protected]e8ff26842013-03-22 21:02:05196 header_.public_header.version_flag = should_include_version;
[email protected]61a527782013-02-21 03:58:00197 header_.packet_sequence_number = sequence_number;
198 header_.fec_group = 0;
[email protected]9db443912013-02-25 05:27:03199 header_.entropy_flag = false;
200 header_.fec_flag = false;
201 header_.fec_entropy_flag = false;
[email protected]61a527782013-02-21 03:58:00202 }
203
204 void CreateSession() {
[email protected]4dca587c2013-03-07 16:54:47205 params_.enable_quic = true;
206 params_.quic_clock = clock_;
207 params_.quic_random = &random_generator_;
[email protected]61a527782013-02-21 03:58:00208 params_.client_socket_factory = &socket_factory_;
[email protected]e8ff26842013-03-22 21:02:05209 params_.quic_crypto_client_stream_factory = &crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:43210 params_.host_resolver = &host_resolver_;
211 params_.cert_verifier = &cert_verifier_;
212 params_.proxy_service = proxy_service_.get();
213 params_.ssl_config_service = ssl_config_service_.get();
214 params_.http_auth_handler_factory = auth_handler_factory_.get();
[email protected]61a527782013-02-21 03:58:00215 params_.http_server_properties = &http_server_properties;
216
217 session_ = new HttpNetworkSession(params_);
218 }
219
220 QuicPacketHeader header_;
221 scoped_refptr<HttpNetworkSession> session_;
222 MockClientSocketFactory socket_factory_;
[email protected]e8ff26842013-03-22 21:02:05223 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:43224 MockClock* clock_; // Owned by QuicStreamFactory after CreateSession.
225 MockHostResolver host_resolver_;
226 MockCertVerifier cert_verifier_;
227 scoped_refptr<SSLConfigServiceDefaults> ssl_config_service_;
228 scoped_ptr<ProxyService> proxy_service_;
229 scoped_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
[email protected]61a527782013-02-21 03:58:00230 MockRandom random_generator_;
231 HttpServerPropertiesImpl http_server_properties;
232 HttpNetworkSession::Params params_;
233};
234
[email protected]4dca587c2013-03-07 16:54:47235TEST_F(QuicNetworkTransactionTest, ForceQuic) {
236 params_.origin_port_to_force_quic_on = 80;
237
238 HttpRequestInfo request;
239 request.method = "GET";
240 request.url = GURL("http://www.google.com/");
241 request.load_flags = 0;
242
[email protected]4dca587c2013-03-07 16:54:47243 scoped_ptr<QuicEncryptedPacket> data(
[email protected]e8ff26842013-03-22 21:02:05244 ConstructDataPacket(1, true, true, 0, GetRequestString("GET", "/")));
245 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0));
[email protected]4dca587c2013-03-07 16:54:47246
247 MockWrite quic_writes[] = {
[email protected]4dca587c2013-03-07 16:54:47248 MockWrite(SYNCHRONOUS, data->data(), data->length()),
249 MockWrite(SYNCHRONOUS, ack->data(), ack->length()),
250 };
251
[email protected]4dca587c2013-03-07 16:54:47252 scoped_ptr<QuicEncryptedPacket> resp(
[email protected]e8ff26842013-03-22 21:02:05253 ConstructDataPacket(
254 1, false, true, 0, GetResponseString("200 OK", "hello!")));
[email protected]4dca587c2013-03-07 16:54:47255 MockRead quic_reads[] = {
[email protected]4dca587c2013-03-07 16:54:47256 MockRead(SYNCHRONOUS, resp->data(), resp->length()),
257 MockRead(ASYNC, OK), // EOF
258 };
259
260 DelayedSocketData quic_data(
261 1, // wait for one write to finish before reading.
262 quic_reads, arraysize(quic_reads),
263 quic_writes, arraysize(quic_writes));
264
265 socket_factory_.AddSocketDataProvider(&quic_data);
266
267 // The non-alternate protocol job needs to hang in order to guarantee that the
268 // alternate-protocol job will "win".
269 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
270 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
271 NULL, 0, NULL, 0);
272 hanging_non_alternate_protocol_socket.set_connect_data(
273 never_finishing_connect);
274 socket_factory_.AddSocketDataProvider(
275 &hanging_non_alternate_protocol_socket);
276
277 TestCompletionCallback callback;
278
279 CreateSession();
280 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]262eec82013-03-19 21:01:36281 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_));
[email protected]4dca587c2013-03-07 16:54:47282
283 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
284 EXPECT_EQ(ERR_IO_PENDING, rv);
285 EXPECT_EQ(OK, callback.WaitForResult());
286
287 const HttpResponseInfo* response = trans->GetResponseInfo();
288 ASSERT_TRUE(response != NULL);
289 ASSERT_TRUE(response->headers != NULL);
290 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
291 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]808957c2013-03-13 03:51:27292 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_QUIC1_SPDY3,
293 response->connection_info);
[email protected]4dca587c2013-03-07 16:54:47294
295 std::string response_data;
296 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
297 EXPECT_EQ("hello!", response_data);
298}
299
300TEST_F(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
301 // Attempt to "force" quic on 443, which will not be honored.
302 params_.origin_port_to_force_quic_on = 443;
303
304 HttpRequestInfo request;
305 request.method = "GET";
306 request.url = GURL("https://www.google.com/");
307 request.load_flags = 0;
308
309 MockRead data_reads[] = {
310 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
311 MockRead("hello world"),
312 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
313 MockRead(ASYNC, OK)
314 };
315
316 StaticSocketDataProvider data(
317 data_reads, arraysize(data_reads), NULL, 0);
318 socket_factory_.AddSocketDataProvider(&data);
319 SSLSocketDataProvider ssl(ASYNC, OK);
320 socket_factory_.AddSSLSocketDataProvider(&ssl);
321
322 TestCompletionCallback callback;
323
324 CreateSession();
325 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]262eec82013-03-19 21:01:36326 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_));
[email protected]4dca587c2013-03-07 16:54:47327
328 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
329 EXPECT_EQ(ERR_IO_PENDING, rv);
330 EXPECT_EQ(OK, callback.WaitForResult());
331
332 const HttpResponseInfo* response = trans->GetResponseInfo();
333 ASSERT_TRUE(response != NULL);
334 ASSERT_TRUE(response->headers != NULL);
335 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
336
337 std::string response_data;
338 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
339 EXPECT_EQ("hello world", response_data);
340}
341
[email protected]61a527782013-02-21 03:58:00342TEST_F(QuicNetworkTransactionTest, UseAlternateProtocolForQuic) {
343 HttpStreamFactory::set_use_alternate_protocols(true);
344 HttpStreamFactory::SetNextProtos(QuicNextProtos());
[email protected]61a527782013-02-21 03:58:00345
346 HttpRequestInfo request;
347 request.method = "GET";
348 request.url = GURL("http://www.google.com/");
349 request.load_flags = 0;
350
351 MockRead data_reads[] = {
352 MockRead("HTTP/1.1 200 OK\r\n"),
353 MockRead(kQuicAlternateProtocolHttpHeader),
354 MockRead("hello world"),
355 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
356 MockRead(ASYNC, OK)
357 };
358
359 StaticSocketDataProvider first_transaction(
360 data_reads, arraysize(data_reads), NULL, 0);
361 socket_factory_.AddSocketDataProvider(&first_transaction);
362
363
[email protected]61a527782013-02-21 03:58:00364 scoped_ptr<QuicEncryptedPacket> data(
[email protected]e8ff26842013-03-22 21:02:05365 ConstructDataPacket(1, true, true, 0, GetRequestString("GET", "/")));
366 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0));
[email protected]61a527782013-02-21 03:58:00367
368 MockWrite quic_writes[] = {
[email protected]61a527782013-02-21 03:58:00369 MockWrite(SYNCHRONOUS, data->data(), data->length()),
370 MockWrite(SYNCHRONOUS, ack->data(), ack->length()),
371 };
372
[email protected]61a527782013-02-21 03:58:00373 scoped_ptr<QuicEncryptedPacket> resp(
[email protected]e8ff26842013-03-22 21:02:05374 ConstructDataPacket(
375 1, false, true, 0, GetResponseString("200 OK", "hello!")));
[email protected]61a527782013-02-21 03:58:00376 MockRead quic_reads[] = {
[email protected]61a527782013-02-21 03:58:00377 MockRead(SYNCHRONOUS, resp->data(), resp->length()),
378 MockRead(ASYNC, OK), // EOF
379 };
380
381 DelayedSocketData quic_data(
382 1, // wait for one write to finish before reading.
383 quic_reads, arraysize(quic_reads),
384 quic_writes, arraysize(quic_writes));
385
386 socket_factory_.AddSocketDataProvider(&quic_data);
387
388 // The non-alternate protocol job needs to hang in order to guarantee that the
389 // alternate-protocol job will "win".
390 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
391 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
392 NULL, 0, NULL, 0);
393 hanging_non_alternate_protocol_socket.set_connect_data(
394 never_finishing_connect);
395 socket_factory_.AddSocketDataProvider(
396 &hanging_non_alternate_protocol_socket);
397
398 TestCompletionCallback callback;
399
400 CreateSession();
401 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]262eec82013-03-19 21:01:36402 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_));
[email protected]61a527782013-02-21 03:58:00403
404 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
405 EXPECT_EQ(ERR_IO_PENDING, rv);
406 EXPECT_EQ(OK, callback.WaitForResult());
407
408 const HttpResponseInfo* response = trans->GetResponseInfo();
409 ASSERT_TRUE(response != NULL);
410 ASSERT_TRUE(response->headers != NULL);
411 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
412
413 std::string response_data;
414 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
415 EXPECT_EQ("hello world", response_data);
416
[email protected]262eec82013-03-19 21:01:36417 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session_));
[email protected]61a527782013-02-21 03:58:00418
419 rv = trans->Start(&request, callback.callback(), BoundNetLog());
420 EXPECT_EQ(ERR_IO_PENDING, rv);
421 EXPECT_EQ(OK, callback.WaitForResult());
422
423 response = trans->GetResponseInfo();
424 ASSERT_TRUE(response != NULL);
425 ASSERT_TRUE(response->headers != NULL);
426 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
427 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]b09e0132013-03-11 20:39:33428 EXPECT_TRUE(response->was_npn_negotiated);
429 EXPECT_EQ("quic/1+spdy/3", response->npn_negotiated_protocol);
[email protected]61a527782013-02-21 03:58:00430
431 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
432 EXPECT_EQ("hello!", response_data);
433}
434
[email protected]ff899c82013-03-12 23:10:50435TEST_F(QuicNetworkTransactionTest, DontUseAlternateProtocolForQuicHttps) {
436 HttpStreamFactory::set_use_alternate_protocols(true);
437 HttpStreamFactory::SetNextProtos(QuicNextProtos());
438
439 HttpRequestInfo request;
440 request.method = "GET";
441 request.url = GURL("https://www.google.com/");
442 request.load_flags = 0;
443
444 MockRead data_reads[] = {
445 MockRead("HTTP/1.1 200 OK\r\n"),
446 MockRead("Content-length: 11\r\n"),
447 MockRead(kQuicAlternateProtocolHttpHeader),
448 MockRead("hello world"),
449
450 MockRead("HTTP/1.1 200 OK\r\n"),
451 MockRead("Content-length: 6\r\n"),
452 MockRead(kQuicAlternateProtocolHttpHeader),
453 MockRead("hello!"),
454 };
455
456 StaticSocketDataProvider first_transaction(
457 data_reads, arraysize(data_reads), NULL, 0);
458 socket_factory_.AddSocketDataProvider(&first_transaction);
459 SSLSocketDataProvider ssl(ASYNC, OK);
460 socket_factory_.AddSSLSocketDataProvider(&ssl);
461
462 TestCompletionCallback callback;
463
464 CreateSession();
465 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]262eec82013-03-19 21:01:36466 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_));
[email protected]ff899c82013-03-12 23:10:50467
468 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
469 EXPECT_EQ(ERR_IO_PENDING, rv);
470 EXPECT_EQ(OK, callback.WaitForResult());
471
472 const HttpResponseInfo* response = trans->GetResponseInfo();
473 ASSERT_TRUE(response != NULL);
474 ASSERT_TRUE(response->headers != NULL);
475 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
476
477 std::string response_data;
478 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
479 EXPECT_EQ("hello world", response_data);
480
[email protected]262eec82013-03-19 21:01:36481 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session_));
[email protected]ff899c82013-03-12 23:10:50482
483 rv = trans->Start(&request, callback.callback(), BoundNetLog());
484 EXPECT_EQ(ERR_IO_PENDING, rv);
485 EXPECT_EQ(OK, callback.WaitForResult());
486
487 response = trans->GetResponseInfo();
488 ASSERT_TRUE(response != NULL);
489 ASSERT_TRUE(response->headers != NULL);
490 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
491 EXPECT_FALSE(response->was_fetched_via_spdy);
492
493 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
494 EXPECT_EQ("hello!", response_data);
495}
496
[email protected]61a527782013-02-21 03:58:00497} // namespace test
498} // namespace net