blob: 10c1ad9aeb2bdfb4ee4a2ff44d59ad06cdb93a06 [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"
9#include "net/base/mock_host_resolver.h"
10#include "net/base/ssl_config_service_defaults.h"
11#include "net/base/test_completion_callback.h"
12#include "net/http/http_auth_handler_factory.h"
13#include "net/http/http_network_session.h"
14#include "net/http/http_network_transaction.h"
15#include "net/http/http_server_properties_impl.h"
16#include "net/http/http_stream.h"
17#include "net/http/http_stream_factory.h"
18#include "net/http/http_transaction_unittest.h"
19#include "net/proxy/proxy_config_service_fixed.h"
20#include "net/proxy/proxy_resolver.h"
21#include "net/proxy/proxy_service.h"
22#include "net/quic/crypto/quic_decrypter.h"
23#include "net/quic/crypto/quic_encrypter.h"
24#include "net/quic/quic_framer.h"
[email protected]ed3fc15d2013-03-08 18:37:4425#include "net/quic/test_tools/crypto_test_utils.h"
[email protected]61a527782013-02-21 03:58:0026#include "net/quic/test_tools/mock_clock.h"
27#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"
35#include "testing/gtest/include/gtest/gtest.h"
36#include "testing/platform_test.h"
37
38//-----------------------------------------------------------------------------
39
40namespace {
41
42// This is the expected return from a current server advertising QUIC.
43static const char kQuicAlternateProtocolHttpHeader[] =
44 "Alternate-Protocol: 443:quic/1\r\n\r\n";
45
46// Returns a vector of NPN protocol strings for negotiating QUIC.
47std::vector<std::string> QuicNextProtos() {
48 std::vector<std::string> protos;
49 protos.push_back("http/1.1");
50 protos.push_back("quic/1");
51 return protos;
52}
53
54} // namespace
55
56namespace net {
57namespace test {
58
59class QuicNetworkTransactionTest : public PlatformTest {
60 protected:
[email protected]1c04f9522013-02-21 20:32:4361 QuicNetworkTransactionTest()
62 : clock_(new MockClock),
63 ssl_config_service_(new SSLConfigServiceDefaults),
64 proxy_service_(ProxyService::CreateDirect()),
65 auth_handler_factory_(
66 HttpAuthHandlerFactory::CreateDefault(&host_resolver_)) {
67 }
[email protected]61a527782013-02-21 03:58:0068
69 virtual void SetUp() {
70 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
71 MessageLoop::current()->RunUntilIdle();
72 }
73
74 virtual void TearDown() {
75 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
76 // Empty the current queue.
77 MessageLoop::current()->RunUntilIdle();
78 PlatformTest::TearDown();
79 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
80 MessageLoop::current()->RunUntilIdle();
81 HttpStreamFactory::set_use_alternate_protocols(false);
82 HttpStreamFactory::SetNextProtos(std::vector<std::string>());
83 }
84
85 // TODO(rch): factor these Construct* methods out into a test helper class.
86 scoped_ptr<QuicEncryptedPacket> ConstructChlo() {
87 const std::string host = "www.google.com";
88 scoped_ptr<QuicPacket> chlo(ConstructClientHelloPacket(0xDEADBEEF,
89 clock_,
90 &random_generator_,
[email protected]14e8106c2013-03-14 16:25:3391 host,
92 true));
[email protected]5351cc4b2013-03-03 07:22:4193 QuicFramer framer(kQuicVersion1,
94 QuicDecrypter::Create(kNULL),
[email protected]14e8106c2013-03-14 16:25:3395 QuicEncrypter::Create(kNULL),
96 false);
[email protected]9db443912013-02-25 05:27:0397 return scoped_ptr<QuicEncryptedPacket>(framer.EncryptPacket(1, *chlo));
[email protected]61a527782013-02-21 03:58:0098 }
99
100 scoped_ptr<QuicEncryptedPacket> ConstructShlo() {
[email protected]ed3fc15d2013-03-08 18:37:44101 const std::string host = "www.google.com";
102 scoped_ptr<QuicPacket> shlo(ConstructServerHelloPacket(0xDEADBEEF,
103 clock_,
104 &random_generator_,
105 host));
[email protected]5351cc4b2013-03-03 07:22:41106 QuicFramer framer(kQuicVersion1,
107 QuicDecrypter::Create(kNULL),
[email protected]14e8106c2013-03-14 16:25:33108 QuicEncrypter::Create(kNULL),
109 false);
[email protected]9db443912013-02-25 05:27:03110 return scoped_ptr<QuicEncryptedPacket>(framer.EncryptPacket(1, *shlo));
[email protected]61a527782013-02-21 03:58:00111 }
112
113 scoped_ptr<QuicEncryptedPacket> ConstructRstPacket(
114 QuicPacketSequenceNumber num,
115 QuicStreamId stream_id) {
116 QuicPacketHeader header;
117 header.public_header.guid = 0xDEADBEEF;
[email protected]9db443912013-02-25 05:27:03118 header.public_header.reset_flag = false;
119 header.public_header.version_flag = false;
[email protected]61a527782013-02-21 03:58:00120 header.packet_sequence_number = num;
[email protected]9db443912013-02-25 05:27:03121 header.entropy_flag = false;
122 header.fec_flag = false;
123 header.fec_entropy_flag = false;
[email protected]61a527782013-02-21 03:58:00124 header.fec_group = 0;
125
[email protected]9db443912013-02-25 05:27:03126 QuicRstStreamFrame rst(stream_id, QUIC_NO_ERROR);
[email protected]61a527782013-02-21 03:58:00127 return scoped_ptr<QuicEncryptedPacket>(
128 ConstructPacket(header, QuicFrame(&rst)));
129 }
130
131 scoped_ptr<QuicEncryptedPacket> ConstructAckPacket(
132 QuicPacketSequenceNumber largest_received,
133 QuicPacketSequenceNumber least_unacked) {
134 QuicPacketHeader header;
135 header.public_header.guid = 0xDEADBEEF;
[email protected]9db443912013-02-25 05:27:03136 header.public_header.reset_flag = false;
137 header.public_header.version_flag = false;
[email protected]61a527782013-02-21 03:58:00138 header.packet_sequence_number = 3;
[email protected]9db443912013-02-25 05:27:03139 header.entropy_flag = false;
140 header.fec_flag = false;
141 header.fec_entropy_flag = false;
[email protected]61a527782013-02-21 03:58:00142 header.fec_group = 0;
143
[email protected]14e8106c2013-03-14 16:25:33144 QuicAckFrame ack(largest_received, QuicTime::Zero(), least_unacked);
[email protected]61a527782013-02-21 03:58:00145
146 QuicCongestionFeedbackFrame feedback;
147 feedback.type = kTCP;
148 feedback.tcp.accumulated_number_of_lost_packets = 0;
149 feedback.tcp.receive_window = 256000;
150
[email protected]5351cc4b2013-03-03 07:22:41151 QuicFramer framer(kQuicVersion1,
152 QuicDecrypter::Create(kNULL),
[email protected]14e8106c2013-03-14 16:25:33153 QuicEncrypter::Create(kNULL),
154 false);
[email protected]61a527782013-02-21 03:58:00155 QuicFrames frames;
156 frames.push_back(QuicFrame(&ack));
157 frames.push_back(QuicFrame(&feedback));
158 scoped_ptr<QuicPacket> packet(
[email protected]9db443912013-02-25 05:27:03159 framer.ConstructFrameDataPacket(header, frames).packet);
160 return scoped_ptr<QuicEncryptedPacket>(
161 framer.EncryptPacket(header.packet_sequence_number, *packet));
[email protected]61a527782013-02-21 03:58:00162 }
163
164 std::string GetRequestString(const std::string& method,
165 const std::string& path) {
166 SpdyHeaderBlock headers;
167 headers[":method"] = method;
168 headers[":host"] = "www.google.com";
169 headers[":path"] = path;
170 headers[":scheme"] = "http";
171 headers[":version"] = "HTTP/1.1";
172 return SerializeHeaderBlock(headers);
173 }
174
175 std::string GetResponseString(const std::string& status,
176 const std::string& body) {
177 SpdyHeaderBlock headers;
178 headers[":status"] = status;
179 headers[":version"] = "HTTP/1.1";
180 headers["content-type"] = "text/plain";
181 return SerializeHeaderBlock(headers) + body;
182 }
183
184 std::string SerializeHeaderBlock(const SpdyHeaderBlock& headers) {
185 size_t len = SpdyFramer::GetSerializedLength(3, &headers);
186 SpdyFrameBuilder builder(len);
187 SpdyFramer::WriteHeaderBlock(&builder, 3, &headers);
188 scoped_ptr<SpdyFrame> frame(builder.take());
189 return std::string(frame->data(), len);
190 }
191
192 // Returns a newly created packet to send kData on stream 1.
193 QuicEncryptedPacket* ConstructDataPacket(
194 QuicPacketSequenceNumber sequence_number,
195 bool fin,
196 QuicStreamOffset offset,
197 base::StringPiece data) {
198 InitializeHeader(sequence_number);
199 QuicStreamFrame frame(3, fin, offset, data);
200 return ConstructPacket(header_, QuicFrame(&frame)).release();
201 }
202
203 scoped_ptr<QuicEncryptedPacket> ConstructPacket(
204 const QuicPacketHeader& header,
205 const QuicFrame& frame) {
[email protected]5351cc4b2013-03-03 07:22:41206 QuicFramer framer(kQuicVersion1,
207 QuicDecrypter::Create(kNULL),
[email protected]14e8106c2013-03-14 16:25:33208 QuicEncrypter::Create(kNULL),
209 false);
[email protected]61a527782013-02-21 03:58:00210 QuicFrames frames;
211 frames.push_back(frame);
212 scoped_ptr<QuicPacket> packet(
[email protected]9db443912013-02-25 05:27:03213 framer.ConstructFrameDataPacket(header, frames).packet);
214 return scoped_ptr<QuicEncryptedPacket>(
215 framer.EncryptPacket(header.packet_sequence_number, *packet));
[email protected]61a527782013-02-21 03:58:00216 }
217
218 void InitializeHeader(QuicPacketSequenceNumber sequence_number) {
219 header_.public_header.guid = random_generator_.RandUint64();
[email protected]9db443912013-02-25 05:27:03220 header_.public_header.reset_flag = false;
221 header_.public_header.version_flag = false;
[email protected]61a527782013-02-21 03:58:00222 header_.packet_sequence_number = sequence_number;
223 header_.fec_group = 0;
[email protected]9db443912013-02-25 05:27:03224 header_.entropy_flag = false;
225 header_.fec_flag = false;
226 header_.fec_entropy_flag = false;
[email protected]61a527782013-02-21 03:58:00227 }
228
229 void CreateSession() {
[email protected]4dca587c2013-03-07 16:54:47230 params_.enable_quic = true;
231 params_.quic_clock = clock_;
232 params_.quic_random = &random_generator_;
[email protected]61a527782013-02-21 03:58:00233 params_.client_socket_factory = &socket_factory_;
[email protected]1c04f9522013-02-21 20:32:43234 params_.host_resolver = &host_resolver_;
235 params_.cert_verifier = &cert_verifier_;
236 params_.proxy_service = proxy_service_.get();
237 params_.ssl_config_service = ssl_config_service_.get();
238 params_.http_auth_handler_factory = auth_handler_factory_.get();
[email protected]61a527782013-02-21 03:58:00239 params_.http_server_properties = &http_server_properties;
240
241 session_ = new HttpNetworkSession(params_);
242 }
243
244 QuicPacketHeader header_;
245 scoped_refptr<HttpNetworkSession> session_;
246 MockClientSocketFactory socket_factory_;
[email protected]1c04f9522013-02-21 20:32:43247 MockClock* clock_; // Owned by QuicStreamFactory after CreateSession.
248 MockHostResolver host_resolver_;
249 MockCertVerifier cert_verifier_;
250 scoped_refptr<SSLConfigServiceDefaults> ssl_config_service_;
251 scoped_ptr<ProxyService> proxy_service_;
252 scoped_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
[email protected]61a527782013-02-21 03:58:00253 MockRandom random_generator_;
254 HttpServerPropertiesImpl http_server_properties;
255 HttpNetworkSession::Params params_;
256};
257
[email protected]4dca587c2013-03-07 16:54:47258TEST_F(QuicNetworkTransactionTest, ForceQuic) {
259 params_.origin_port_to_force_quic_on = 80;
260
261 HttpRequestInfo request;
262 request.method = "GET";
263 request.url = GURL("http://www.google.com/");
264 request.load_flags = 0;
265
266 scoped_ptr<QuicEncryptedPacket> chlo(ConstructChlo());
267 scoped_ptr<QuicEncryptedPacket> data(
268 ConstructDataPacket(2, true, 0, GetRequestString("GET", "/")));
269 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(2, 1));
270
271 MockWrite quic_writes[] = {
272 MockWrite(SYNCHRONOUS, chlo->data(), chlo->length()),
273 MockWrite(SYNCHRONOUS, data->data(), data->length()),
274 MockWrite(SYNCHRONOUS, ack->data(), ack->length()),
275 };
276
277 scoped_ptr<QuicEncryptedPacket> shlo(ConstructShlo());
278 scoped_ptr<QuicEncryptedPacket> resp(
279 ConstructDataPacket(2, true, 0, GetResponseString("200 OK", "hello!")));
280 MockRead quic_reads[] = {
281 MockRead(SYNCHRONOUS, shlo->data(), shlo->length()),
282 MockRead(SYNCHRONOUS, resp->data(), resp->length()),
283 MockRead(ASYNC, OK), // EOF
284 };
285
286 DelayedSocketData quic_data(
287 1, // wait for one write to finish before reading.
288 quic_reads, arraysize(quic_reads),
289 quic_writes, arraysize(quic_writes));
290
291 socket_factory_.AddSocketDataProvider(&quic_data);
292
293 // The non-alternate protocol job needs to hang in order to guarantee that the
294 // alternate-protocol job will "win".
295 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
296 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
297 NULL, 0, NULL, 0);
298 hanging_non_alternate_protocol_socket.set_connect_data(
299 never_finishing_connect);
300 socket_factory_.AddSocketDataProvider(
301 &hanging_non_alternate_protocol_socket);
302
303 TestCompletionCallback callback;
304
305 CreateSession();
306 scoped_ptr<HttpNetworkTransaction> trans(
307 new HttpNetworkTransaction(session_));
308
309 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
310 EXPECT_EQ(ERR_IO_PENDING, rv);
311 EXPECT_EQ(OK, callback.WaitForResult());
312
313 const HttpResponseInfo* response = trans->GetResponseInfo();
314 ASSERT_TRUE(response != NULL);
315 ASSERT_TRUE(response->headers != NULL);
316 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
317 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]808957c2013-03-13 03:51:27318 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_QUIC1_SPDY3,
319 response->connection_info);
[email protected]4dca587c2013-03-07 16:54:47320
321 std::string response_data;
322 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
323 EXPECT_EQ("hello!", response_data);
324}
325
326TEST_F(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
327 // Attempt to "force" quic on 443, which will not be honored.
328 params_.origin_port_to_force_quic_on = 443;
329
330 HttpRequestInfo request;
331 request.method = "GET";
332 request.url = GURL("https://www.google.com/");
333 request.load_flags = 0;
334
335 MockRead data_reads[] = {
336 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
337 MockRead("hello world"),
338 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
339 MockRead(ASYNC, OK)
340 };
341
342 StaticSocketDataProvider data(
343 data_reads, arraysize(data_reads), NULL, 0);
344 socket_factory_.AddSocketDataProvider(&data);
345 SSLSocketDataProvider ssl(ASYNC, OK);
346 socket_factory_.AddSSLSocketDataProvider(&ssl);
347
348 TestCompletionCallback callback;
349
350 CreateSession();
351 scoped_ptr<HttpNetworkTransaction> trans(
352 new HttpNetworkTransaction(session_));
353
354 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
355 EXPECT_EQ(ERR_IO_PENDING, rv);
356 EXPECT_EQ(OK, callback.WaitForResult());
357
358 const HttpResponseInfo* response = trans->GetResponseInfo();
359 ASSERT_TRUE(response != NULL);
360 ASSERT_TRUE(response->headers != NULL);
361 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
362
363 std::string response_data;
364 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
365 EXPECT_EQ("hello world", response_data);
366}
367
[email protected]61a527782013-02-21 03:58:00368TEST_F(QuicNetworkTransactionTest, UseAlternateProtocolForQuic) {
369 HttpStreamFactory::set_use_alternate_protocols(true);
370 HttpStreamFactory::SetNextProtos(QuicNextProtos());
[email protected]61a527782013-02-21 03:58:00371
372 HttpRequestInfo request;
373 request.method = "GET";
374 request.url = GURL("http://www.google.com/");
375 request.load_flags = 0;
376
377 MockRead data_reads[] = {
378 MockRead("HTTP/1.1 200 OK\r\n"),
379 MockRead(kQuicAlternateProtocolHttpHeader),
380 MockRead("hello world"),
381 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
382 MockRead(ASYNC, OK)
383 };
384
385 StaticSocketDataProvider first_transaction(
386 data_reads, arraysize(data_reads), NULL, 0);
387 socket_factory_.AddSocketDataProvider(&first_transaction);
388
389
390 scoped_ptr<QuicEncryptedPacket> chlo(ConstructChlo());
391 scoped_ptr<QuicEncryptedPacket> data(
392 ConstructDataPacket(2, true, 0, GetRequestString("GET", "/")));
393 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(2, 1));
394
395 MockWrite quic_writes[] = {
396 MockWrite(SYNCHRONOUS, chlo->data(), chlo->length()),
397 MockWrite(SYNCHRONOUS, data->data(), data->length()),
398 MockWrite(SYNCHRONOUS, ack->data(), ack->length()),
399 };
400
401 scoped_ptr<QuicEncryptedPacket> shlo(ConstructShlo());
402 scoped_ptr<QuicEncryptedPacket> resp(
403 ConstructDataPacket(2, true, 0, GetResponseString("200 OK", "hello!")));
404 MockRead quic_reads[] = {
405 MockRead(SYNCHRONOUS, shlo->data(), shlo->length()),
406 MockRead(SYNCHRONOUS, resp->data(), resp->length()),
407 MockRead(ASYNC, OK), // EOF
408 };
409
410 DelayedSocketData quic_data(
411 1, // wait for one write to finish before reading.
412 quic_reads, arraysize(quic_reads),
413 quic_writes, arraysize(quic_writes));
414
415 socket_factory_.AddSocketDataProvider(&quic_data);
416
417 // The non-alternate protocol job needs to hang in order to guarantee that the
418 // alternate-protocol job will "win".
419 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
420 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
421 NULL, 0, NULL, 0);
422 hanging_non_alternate_protocol_socket.set_connect_data(
423 never_finishing_connect);
424 socket_factory_.AddSocketDataProvider(
425 &hanging_non_alternate_protocol_socket);
426
427 TestCompletionCallback callback;
428
429 CreateSession();
430 scoped_ptr<HttpNetworkTransaction> trans(
431 new HttpNetworkTransaction(session_));
432
433 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
434 EXPECT_EQ(ERR_IO_PENDING, rv);
435 EXPECT_EQ(OK, callback.WaitForResult());
436
437 const HttpResponseInfo* response = trans->GetResponseInfo();
438 ASSERT_TRUE(response != NULL);
439 ASSERT_TRUE(response->headers != NULL);
440 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
441
442 std::string response_data;
443 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
444 EXPECT_EQ("hello world", response_data);
445
446 trans.reset(new HttpNetworkTransaction(session_));
447
448 rv = trans->Start(&request, callback.callback(), BoundNetLog());
449 EXPECT_EQ(ERR_IO_PENDING, rv);
450 EXPECT_EQ(OK, callback.WaitForResult());
451
452 response = trans->GetResponseInfo();
453 ASSERT_TRUE(response != NULL);
454 ASSERT_TRUE(response->headers != NULL);
455 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
456 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]b09e0132013-03-11 20:39:33457 EXPECT_TRUE(response->was_npn_negotiated);
458 EXPECT_EQ("quic/1+spdy/3", response->npn_negotiated_protocol);
[email protected]61a527782013-02-21 03:58:00459
460 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
461 EXPECT_EQ("hello!", response_data);
462}
463
[email protected]ff899c82013-03-12 23:10:50464TEST_F(QuicNetworkTransactionTest, DontUseAlternateProtocolForQuicHttps) {
465 HttpStreamFactory::set_use_alternate_protocols(true);
466 HttpStreamFactory::SetNextProtos(QuicNextProtos());
467
468 HttpRequestInfo request;
469 request.method = "GET";
470 request.url = GURL("https://www.google.com/");
471 request.load_flags = 0;
472
473 MockRead data_reads[] = {
474 MockRead("HTTP/1.1 200 OK\r\n"),
475 MockRead("Content-length: 11\r\n"),
476 MockRead(kQuicAlternateProtocolHttpHeader),
477 MockRead("hello world"),
478
479 MockRead("HTTP/1.1 200 OK\r\n"),
480 MockRead("Content-length: 6\r\n"),
481 MockRead(kQuicAlternateProtocolHttpHeader),
482 MockRead("hello!"),
483 };
484
485 StaticSocketDataProvider first_transaction(
486 data_reads, arraysize(data_reads), NULL, 0);
487 socket_factory_.AddSocketDataProvider(&first_transaction);
488 SSLSocketDataProvider ssl(ASYNC, OK);
489 socket_factory_.AddSSLSocketDataProvider(&ssl);
490
491 TestCompletionCallback callback;
492
493 CreateSession();
494 scoped_ptr<HttpNetworkTransaction> trans(
495 new HttpNetworkTransaction(session_));
496
497 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
498 EXPECT_EQ(ERR_IO_PENDING, rv);
499 EXPECT_EQ(OK, callback.WaitForResult());
500
501 const HttpResponseInfo* response = trans->GetResponseInfo();
502 ASSERT_TRUE(response != NULL);
503 ASSERT_TRUE(response->headers != NULL);
504 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
505
506 std::string response_data;
507 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
508 EXPECT_EQ("hello world", response_data);
509
510 trans.reset(new HttpNetworkTransaction(session_));
511
512 rv = trans->Start(&request, callback.callback(), BoundNetLog());
513 EXPECT_EQ(ERR_IO_PENDING, rv);
514 EXPECT_EQ(OK, callback.WaitForResult());
515
516 response = trans->GetResponseInfo();
517 ASSERT_TRUE(response != NULL);
518 ASSERT_TRUE(response->headers != NULL);
519 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
520 EXPECT_FALSE(response->was_fetched_via_spdy);
521
522 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
523 EXPECT_EQ("hello!", response_data);
524}
525
[email protected]61a527782013-02-21 03:58:00526} // namespace test
527} // namespace net