1 // 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.
7 #include "base/memory/ref_counted.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/memory/scoped_vector.h"
10 #include "base/strings/stringprintf.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "net/base/address_list.h"
13 #include "net/base/io_buffer.h"
14 #include "net/base/net_errors.h"
15 #include "net/base/net_util.h"
16 #include "net/base/request_priority.h"
17 #include "net/dns/host_cache.h"
18 #include "net/dns/mock_host_resolver.h"
19 #include "net/http/http_auth_challenge_tokenizer.h"
20 #include "net/http/http_auth_handler_mock.h"
21 #include "net/http/http_network_session.h"
22 #include "net/http/http_network_transaction.h"
23 #include "net/http/http_request_info.h"
24 #include "net/http/http_server_properties_impl.h"
25 #include "net/proxy/proxy_config_service.h"
26 #include "net/proxy/proxy_service.h"
27 #include "net/socket/client_socket_handle.h"
28 #include "net/socket/client_socket_pool_histograms.h"
29 #include "net/socket/client_socket_pool_manager.h"
30 #include "net/socket/socket_test_util.h"
31 #include "net/ssl/ssl_config_service_defaults.h"
32 #include "testing/gmock/include/gmock/gmock.h"
33 #include "testing/gtest/include/gtest/gtest.h"
41 class SimpleProxyConfigService
: public ProxyConfigService
{
43 virtual void AddObserver(Observer
* observer
) OVERRIDE
{
47 virtual void RemoveObserver(Observer
* observer
) OVERRIDE
{
48 if (observer_
== observer
) {
53 virtual ConfigAvailability
GetLatestProxyConfig(
54 ProxyConfig
* config
) OVERRIDE
{
59 void IncrementConfigId() {
60 config_
.set_id(config_
.id() + 1);
61 observer_
->OnProxyConfigChanged(config_
, ProxyConfigService::CONFIG_VALID
);
69 class HttpPipelinedNetworkTransactionTest
: public testing::Test
{
71 HttpPipelinedNetworkTransactionTest()
73 pool_(1, 1, &histograms_
, &factory_
) {
76 void Initialize(bool force_http_pipelining
) {
77 // Normally, this code could just go in SetUp(). For a few of these tests,
78 // we change the default number of sockets per group. That needs to be done
79 // before we construct the HttpNetworkSession.
80 proxy_config_service_
= new SimpleProxyConfigService();
81 proxy_service_
.reset(new ProxyService(proxy_config_service_
, NULL
, NULL
));
82 ssl_config_
= new SSLConfigServiceDefaults
;
83 auth_handler_factory_
.reset(new HttpAuthHandlerMock::Factory());
85 HttpNetworkSession::Params session_params
;
86 session_params
.client_socket_factory
= &factory_
;
87 session_params
.proxy_service
= proxy_service_
.get();
88 session_params
.host_resolver
= &mock_resolver_
;
89 session_params
.ssl_config_service
= ssl_config_
.get();
90 session_params
.http_auth_handler_factory
= auth_handler_factory_
.get();
91 session_params
.http_server_properties
=
92 http_server_properties_
.GetWeakPtr();
93 session_params
.force_http_pipelining
= force_http_pipelining
;
94 session_params
.http_pipelining_enabled
= true;
95 session_
= new HttpNetworkSession(session_params
);
98 void AddExpectedConnection(MockRead
* reads
, size_t reads_count
,
99 MockWrite
* writes
, size_t writes_count
) {
100 DeterministicSocketData
* data
= new DeterministicSocketData(
101 reads
, reads_count
, writes
, writes_count
);
102 data
->set_connect_data(MockConnect(SYNCHRONOUS
, OK
));
103 if (reads_count
|| writes_count
) {
104 data
->StopAfter(reads_count
+ writes_count
);
106 factory_
.AddSocketDataProvider(data
);
107 data_vector_
.push_back(data
);
110 enum RequestInfoOptions
{
112 REQUEST_MAIN_RESOURCE
,
115 HttpRequestInfo
* GetRequestInfo(
116 const char* filename
, RequestInfoOptions options
= REQUEST_DEFAULT
) {
117 std::string url
= base::StringPrintf("http://localhost/%s", filename
);
118 HttpRequestInfo
* request_info
= new HttpRequestInfo
;
119 request_info
->url
= GURL(url
);
120 request_info
->method
= "GET";
121 if (options
== REQUEST_MAIN_RESOURCE
) {
122 request_info
->load_flags
= LOAD_MAIN_FRAME
;
124 request_info_vector_
.push_back(request_info
);
128 void ExpectResponse(const std::string
& expected
,
129 HttpNetworkTransaction
& transaction
,
131 scoped_refptr
<IOBuffer
> buffer(new IOBuffer(expected
.size()));
132 if (io_mode
== ASYNC
) {
133 EXPECT_EQ(ERR_IO_PENDING
, transaction
.Read(buffer
.get(), expected
.size(),
134 callback_
.callback()));
135 data_vector_
[0]->RunFor(1);
136 EXPECT_EQ(static_cast<int>(expected
.length()), callback_
.WaitForResult());
138 EXPECT_EQ(static_cast<int>(expected
.size()),
139 transaction
.Read(buffer
.get(), expected
.size(),
140 callback_
.callback()));
142 std::string
actual(buffer
->data(), expected
.size());
143 EXPECT_THAT(actual
, StrEq(expected
));
144 EXPECT_EQ(OK
, transaction
.Read(buffer
.get(), expected
.size(),
145 callback_
.callback()));
148 void CompleteTwoRequests(int data_index
, int stop_at_step
) {
149 scoped_ptr
<HttpNetworkTransaction
> one_transaction(
150 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
.get()));
151 TestCompletionCallback one_callback
;
152 EXPECT_EQ(ERR_IO_PENDING
,
153 one_transaction
->Start(GetRequestInfo("one.html"),
154 one_callback
.callback(), BoundNetLog()));
155 EXPECT_EQ(OK
, one_callback
.WaitForResult());
157 HttpNetworkTransaction
two_transaction(DEFAULT_PRIORITY
, session_
.get());
158 TestCompletionCallback two_callback
;
159 EXPECT_EQ(ERR_IO_PENDING
,
160 two_transaction
.Start(GetRequestInfo("two.html"),
161 two_callback
.callback(), BoundNetLog()));
163 TestCompletionCallback one_read_callback
;
164 scoped_refptr
<IOBuffer
> buffer(new IOBuffer(8));
165 EXPECT_EQ(ERR_IO_PENDING
,
166 one_transaction
->Read(buffer
.get(), 8,
167 one_read_callback
.callback()));
169 data_vector_
[data_index
]->SetStop(stop_at_step
);
170 data_vector_
[data_index
]->Run();
171 EXPECT_EQ(8, one_read_callback
.WaitForResult());
172 data_vector_
[data_index
]->SetStop(10);
173 std::string
actual(buffer
->data(), 8);
174 EXPECT_THAT(actual
, StrEq("one.html"));
175 EXPECT_EQ(OK
, one_transaction
->Read(buffer
.get(), 8,
176 one_read_callback
.callback()));
178 EXPECT_EQ(OK
, two_callback
.WaitForResult());
179 ExpectResponse("two.html", two_transaction
, SYNCHRONOUS
);
182 void CompleteFourRequests(RequestInfoOptions options
) {
183 scoped_ptr
<HttpNetworkTransaction
> one_transaction(
184 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
.get()));
185 TestCompletionCallback one_callback
;
186 EXPECT_EQ(ERR_IO_PENDING
,
187 one_transaction
->Start(GetRequestInfo("one.html", options
),
188 one_callback
.callback(), BoundNetLog()));
189 EXPECT_EQ(OK
, one_callback
.WaitForResult());
191 HttpNetworkTransaction
two_transaction(DEFAULT_PRIORITY
, session_
.get());
192 TestCompletionCallback two_callback
;
193 EXPECT_EQ(ERR_IO_PENDING
,
194 two_transaction
.Start(GetRequestInfo("two.html", options
),
195 two_callback
.callback(), BoundNetLog()));
197 HttpNetworkTransaction
three_transaction(DEFAULT_PRIORITY
, session_
.get());
198 TestCompletionCallback three_callback
;
199 EXPECT_EQ(ERR_IO_PENDING
,
200 three_transaction
.Start(GetRequestInfo("three.html", options
),
201 three_callback
.callback(),
204 HttpNetworkTransaction
four_transaction(DEFAULT_PRIORITY
, session_
.get());
205 TestCompletionCallback four_callback
;
206 EXPECT_EQ(ERR_IO_PENDING
,
207 four_transaction
.Start(GetRequestInfo("four.html", options
),
208 four_callback
.callback(), BoundNetLog()));
210 ExpectResponse("one.html", *one_transaction
.get(), SYNCHRONOUS
);
211 EXPECT_EQ(OK
, two_callback
.WaitForResult());
212 ExpectResponse("two.html", two_transaction
, SYNCHRONOUS
);
213 EXPECT_EQ(OK
, three_callback
.WaitForResult());
214 ExpectResponse("three.html", three_transaction
, SYNCHRONOUS
);
216 one_transaction
.reset();
217 EXPECT_EQ(OK
, four_callback
.WaitForResult());
218 ExpectResponse("four.html", four_transaction
, SYNCHRONOUS
);
221 DeterministicMockClientSocketFactory factory_
;
222 ClientSocketPoolHistograms histograms_
;
223 MockTransportClientSocketPool pool_
;
224 ScopedVector
<DeterministicSocketData
> data_vector_
;
225 TestCompletionCallback callback_
;
226 ScopedVector
<HttpRequestInfo
> request_info_vector_
;
228 SimpleProxyConfigService
* proxy_config_service_
;
229 scoped_ptr
<ProxyService
> proxy_service_
;
230 MockHostResolver mock_resolver_
;
231 scoped_refptr
<SSLConfigService
> ssl_config_
;
232 scoped_ptr
<HttpAuthHandlerMock::Factory
> auth_handler_factory_
;
233 HttpServerPropertiesImpl http_server_properties_
;
234 scoped_refptr
<HttpNetworkSession
> session_
;
237 TEST_F(HttpPipelinedNetworkTransactionTest
, OneRequest
) {
240 MockWrite writes
[] = {
241 MockWrite(SYNCHRONOUS
, 0, "GET /test.html HTTP/1.1\r\n"
242 "Host: localhost\r\n"
243 "Connection: keep-alive\r\n\r\n"),
246 MockRead(SYNCHRONOUS
, 1, "HTTP/1.1 200 OK\r\n"),
247 MockRead(SYNCHRONOUS
, 2, "Content-Length: 9\r\n\r\n"),
248 MockRead(SYNCHRONOUS
, 3, "test.html"),
250 AddExpectedConnection(reads
, arraysize(reads
), writes
, arraysize(writes
));
252 HttpNetworkTransaction
transaction(DEFAULT_PRIORITY
, session_
.get());
253 EXPECT_EQ(ERR_IO_PENDING
,
254 transaction
.Start(GetRequestInfo("test.html"), callback_
.callback(),
256 EXPECT_EQ(OK
, callback_
.WaitForResult());
257 ExpectResponse("test.html", transaction
, SYNCHRONOUS
);
260 TEST_F(HttpPipelinedNetworkTransactionTest
, ReusePipeline
) {
263 MockWrite writes
[] = {
264 MockWrite(SYNCHRONOUS
, 0, "GET /one.html HTTP/1.1\r\n"
265 "Host: localhost\r\n"
266 "Connection: keep-alive\r\n\r\n"),
267 MockWrite(SYNCHRONOUS
, 3, "GET /two.html HTTP/1.1\r\n"
268 "Host: localhost\r\n"
269 "Connection: keep-alive\r\n\r\n"),
272 MockRead(SYNCHRONOUS
, 1, "HTTP/1.1 200 OK\r\n"),
273 MockRead(SYNCHRONOUS
, 2, "Content-Length: 8\r\n\r\n"),
274 MockRead(ASYNC
, 4, "one.html"),
275 MockRead(SYNCHRONOUS
, 5, "HTTP/1.1 200 OK\r\n"),
276 MockRead(SYNCHRONOUS
, 6, "Content-Length: 8\r\n\r\n"),
277 MockRead(SYNCHRONOUS
, 7, "two.html"),
279 AddExpectedConnection(reads
, arraysize(reads
), writes
, arraysize(writes
));
281 CompleteTwoRequests(0, 5);
284 TEST_F(HttpPipelinedNetworkTransactionTest
, ReusesOnSpaceAvailable
) {
285 int old_max_sockets
= ClientSocketPoolManager::max_sockets_per_group(
286 HttpNetworkSession::NORMAL_SOCKET_POOL
);
287 ClientSocketPoolManager::set_max_sockets_per_group(
288 HttpNetworkSession::NORMAL_SOCKET_POOL
, 1);
291 MockWrite writes
[] = {
292 MockWrite(SYNCHRONOUS
, 0, "GET /one.html HTTP/1.1\r\n"
293 "Host: localhost\r\n"
294 "Connection: keep-alive\r\n\r\n"),
295 MockWrite(SYNCHRONOUS
, 4, "GET /two.html HTTP/1.1\r\n"
296 "Host: localhost\r\n"
297 "Connection: keep-alive\r\n\r\n"),
298 MockWrite(SYNCHRONOUS
, 7, "GET /three.html HTTP/1.1\r\n"
299 "Host: localhost\r\n"
300 "Connection: keep-alive\r\n\r\n"),
301 MockWrite(SYNCHRONOUS
, 12, "GET /four.html HTTP/1.1\r\n"
302 "Host: localhost\r\n"
303 "Connection: keep-alive\r\n\r\n"),
306 MockRead(SYNCHRONOUS
, 1, "HTTP/1.1 200 OK\r\n"),
307 MockRead(SYNCHRONOUS
, 2, "Content-Length: 8\r\n\r\n"),
308 MockRead(SYNCHRONOUS
, 3, "one.html"),
309 MockRead(SYNCHRONOUS
, 5, "HTTP/1.1 200 OK\r\n"),
310 MockRead(SYNCHRONOUS
, 6, "Content-Length: 8\r\n\r\n"),
311 MockRead(SYNCHRONOUS
, 8, "two.html"),
312 MockRead(SYNCHRONOUS
, 9, "HTTP/1.1 200 OK\r\n"),
313 MockRead(SYNCHRONOUS
, 10, "Content-Length: 10\r\n\r\n"),
314 MockRead(SYNCHRONOUS
, 11, "three.html"),
315 MockRead(SYNCHRONOUS
, 13, "HTTP/1.1 200 OK\r\n"),
316 MockRead(SYNCHRONOUS
, 14, "Content-Length: 9\r\n\r\n"),
317 MockRead(SYNCHRONOUS
, 15, "four.html"),
319 AddExpectedConnection(reads
, arraysize(reads
), writes
, arraysize(writes
));
321 CompleteFourRequests(REQUEST_DEFAULT
);
323 ClientSocketPoolManager::set_max_sockets_per_group(
324 HttpNetworkSession::NORMAL_SOCKET_POOL
, old_max_sockets
);
327 TEST_F(HttpPipelinedNetworkTransactionTest
, WontPipelineMainResource
) {
328 int old_max_sockets
= ClientSocketPoolManager::max_sockets_per_group(
329 HttpNetworkSession::NORMAL_SOCKET_POOL
);
330 ClientSocketPoolManager::set_max_sockets_per_group(
331 HttpNetworkSession::NORMAL_SOCKET_POOL
, 1);
334 MockWrite writes
[] = {
335 MockWrite(SYNCHRONOUS
, 0, "GET /one.html HTTP/1.1\r\n"
336 "Host: localhost\r\n"
337 "Connection: keep-alive\r\n\r\n"),
338 MockWrite(SYNCHRONOUS
, 4, "GET /two.html HTTP/1.1\r\n"
339 "Host: localhost\r\n"
340 "Connection: keep-alive\r\n\r\n"),
341 MockWrite(SYNCHRONOUS
, 8, "GET /three.html HTTP/1.1\r\n"
342 "Host: localhost\r\n"
343 "Connection: keep-alive\r\n\r\n"),
344 MockWrite(SYNCHRONOUS
, 12, "GET /four.html HTTP/1.1\r\n"
345 "Host: localhost\r\n"
346 "Connection: keep-alive\r\n\r\n"),
349 MockRead(SYNCHRONOUS
, 1, "HTTP/1.1 200 OK\r\n"),
350 MockRead(SYNCHRONOUS
, 2, "Content-Length: 8\r\n\r\n"),
351 MockRead(SYNCHRONOUS
, 3, "one.html"),
352 MockRead(SYNCHRONOUS
, 5, "HTTP/1.1 200 OK\r\n"),
353 MockRead(SYNCHRONOUS
, 6, "Content-Length: 8\r\n\r\n"),
354 MockRead(SYNCHRONOUS
, 7, "two.html"),
355 MockRead(SYNCHRONOUS
, 9, "HTTP/1.1 200 OK\r\n"),
356 MockRead(SYNCHRONOUS
, 10, "Content-Length: 10\r\n\r\n"),
357 MockRead(SYNCHRONOUS
, 11, "three.html"),
358 MockRead(SYNCHRONOUS
, 13, "HTTP/1.1 200 OK\r\n"),
359 MockRead(SYNCHRONOUS
, 14, "Content-Length: 9\r\n\r\n"),
360 MockRead(SYNCHRONOUS
, 15, "four.html"),
362 AddExpectedConnection(reads
, arraysize(reads
), writes
, arraysize(writes
));
364 CompleteFourRequests(REQUEST_MAIN_RESOURCE
);
366 ClientSocketPoolManager::set_max_sockets_per_group(
367 HttpNetworkSession::NORMAL_SOCKET_POOL
, old_max_sockets
);
370 TEST_F(HttpPipelinedNetworkTransactionTest
, UnknownSizeEvictsToNewPipeline
) {
373 MockWrite writes
[] = {
374 MockWrite(SYNCHRONOUS
, 0, "GET /one.html HTTP/1.1\r\n"
375 "Host: localhost\r\n"
376 "Connection: keep-alive\r\n\r\n"),
379 MockRead(SYNCHRONOUS
, 1, "HTTP/1.1 200 OK\r\n\r\n"),
380 MockRead(ASYNC
, 2, "one.html"),
381 MockRead(SYNCHRONOUS
, OK
, 3),
383 AddExpectedConnection(reads
, arraysize(reads
), writes
, arraysize(writes
));
385 MockWrite writes2
[] = {
386 MockWrite(SYNCHRONOUS
, 0, "GET /two.html HTTP/1.1\r\n"
387 "Host: localhost\r\n"
388 "Connection: keep-alive\r\n\r\n"),
390 MockRead reads2
[] = {
391 MockRead(SYNCHRONOUS
, 1, "HTTP/1.1 200 OK\r\n"),
392 MockRead(SYNCHRONOUS
, 2, "Content-Length: 8\r\n\r\n"),
393 MockRead(SYNCHRONOUS
, 3, "two.html"),
395 AddExpectedConnection(reads2
, arraysize(reads2
), writes2
, arraysize(writes2
));
397 CompleteTwoRequests(0, 3);
400 TEST_F(HttpPipelinedNetworkTransactionTest
, ConnectionCloseEvictToNewPipeline
) {
403 MockWrite writes
[] = {
404 MockWrite(SYNCHRONOUS
, 0, "GET /one.html HTTP/1.1\r\n"
405 "Host: localhost\r\n"
406 "Connection: keep-alive\r\n\r\n"),
407 MockWrite(SYNCHRONOUS
, 3, "GET /two.html HTTP/1.1\r\n"
408 "Host: localhost\r\n"
409 "Connection: keep-alive\r\n\r\n"),
412 MockRead(SYNCHRONOUS
, 1, "HTTP/1.1 200 OK\r\n"),
413 MockRead(SYNCHRONOUS
, 2, "Content-Length: 8\r\n\r\n"),
414 MockRead(ASYNC
, 4, "one.html"),
415 MockRead(SYNCHRONOUS
, ERR_SOCKET_NOT_CONNECTED
, 5),
417 AddExpectedConnection(reads
, arraysize(reads
), writes
, arraysize(writes
));
419 MockWrite writes2
[] = {
420 MockWrite(SYNCHRONOUS
, 0, "GET /two.html HTTP/1.1\r\n"
421 "Host: localhost\r\n"
422 "Connection: keep-alive\r\n\r\n"),
424 MockRead reads2
[] = {
425 MockRead(SYNCHRONOUS
, 1, "HTTP/1.1 200 OK\r\n"),
426 MockRead(SYNCHRONOUS
, 2, "Content-Length: 8\r\n\r\n"),
427 MockRead(SYNCHRONOUS
, 3, "two.html"),
429 AddExpectedConnection(reads2
, arraysize(reads2
), writes2
, arraysize(writes2
));
431 CompleteTwoRequests(0, 5);
434 TEST_F(HttpPipelinedNetworkTransactionTest
, ErrorEvictsToNewPipeline
) {
437 MockWrite writes
[] = {
438 MockWrite(SYNCHRONOUS
, 0, "GET /one.html HTTP/1.1\r\n"
439 "Host: localhost\r\n"
440 "Connection: keep-alive\r\n\r\n"),
441 MockWrite(SYNCHRONOUS
, 3, "GET /two.html HTTP/1.1\r\n"
442 "Host: localhost\r\n"
443 "Connection: keep-alive\r\n\r\n"),
446 MockRead(SYNCHRONOUS
, 1, "HTTP/1.1 200 OK\r\n\r\n"),
447 MockRead(SYNCHRONOUS
, ERR_FAILED
, 2),
449 AddExpectedConnection(reads
, arraysize(reads
), writes
, arraysize(writes
));
451 MockWrite writes2
[] = {
452 MockWrite(SYNCHRONOUS
, 0, "GET /two.html HTTP/1.1\r\n"
453 "Host: localhost\r\n"
454 "Connection: keep-alive\r\n\r\n"),
456 MockRead reads2
[] = {
457 MockRead(SYNCHRONOUS
, 1, "HTTP/1.1 200 OK\r\n"),
458 MockRead(SYNCHRONOUS
, 2, "Content-Length: 8\r\n\r\n"),
459 MockRead(SYNCHRONOUS
, 3, "two.html"),
461 AddExpectedConnection(reads2
, arraysize(reads2
), writes2
, arraysize(writes2
));
463 HttpNetworkTransaction
one_transaction(DEFAULT_PRIORITY
, session_
.get());
464 TestCompletionCallback one_callback
;
465 EXPECT_EQ(ERR_IO_PENDING
,
466 one_transaction
.Start(GetRequestInfo("one.html"),
467 one_callback
.callback(), BoundNetLog()));
468 EXPECT_EQ(OK
, one_callback
.WaitForResult());
470 HttpNetworkTransaction
two_transaction(DEFAULT_PRIORITY
, session_
.get());
471 TestCompletionCallback two_callback
;
472 EXPECT_EQ(ERR_IO_PENDING
,
473 two_transaction
.Start(GetRequestInfo("two.html"),
474 two_callback
.callback(), BoundNetLog()));
476 scoped_refptr
<IOBuffer
> buffer(new IOBuffer(1));
477 EXPECT_EQ(ERR_FAILED
,
478 one_transaction
.Read(buffer
.get(), 1, callback_
.callback()));
479 EXPECT_EQ(OK
, two_callback
.WaitForResult());
480 ExpectResponse("two.html", two_transaction
, SYNCHRONOUS
);
483 TEST_F(HttpPipelinedNetworkTransactionTest
, SendErrorEvictsToNewPipeline
) {
486 MockWrite writes
[] = {
487 MockWrite(ASYNC
, ERR_FAILED
, 0),
489 AddExpectedConnection(NULL
, 0, writes
, arraysize(writes
));
491 MockWrite writes2
[] = {
492 MockWrite(SYNCHRONOUS
, 0, "GET /two.html HTTP/1.1\r\n"
493 "Host: localhost\r\n"
494 "Connection: keep-alive\r\n\r\n"),
496 MockRead reads2
[] = {
497 MockRead(SYNCHRONOUS
, 1, "HTTP/1.1 200 OK\r\n"),
498 MockRead(SYNCHRONOUS
, 2, "Content-Length: 8\r\n\r\n"),
499 MockRead(SYNCHRONOUS
, 3, "two.html"),
501 AddExpectedConnection(reads2
, arraysize(reads2
), writes2
, arraysize(writes2
));
503 HttpNetworkTransaction
one_transaction(DEFAULT_PRIORITY
, session_
.get());
504 TestCompletionCallback one_callback
;
505 EXPECT_EQ(ERR_IO_PENDING
,
506 one_transaction
.Start(GetRequestInfo("one.html"),
507 one_callback
.callback(), BoundNetLog()));
509 HttpNetworkTransaction
two_transaction(DEFAULT_PRIORITY
, session_
.get());
510 TestCompletionCallback two_callback
;
511 EXPECT_EQ(ERR_IO_PENDING
,
512 two_transaction
.Start(GetRequestInfo("two.html"),
513 two_callback
.callback(), BoundNetLog()));
515 data_vector_
[0]->RunFor(1);
516 EXPECT_EQ(ERR_FAILED
, one_callback
.WaitForResult());
518 EXPECT_EQ(OK
, two_callback
.WaitForResult());
519 ExpectResponse("two.html", two_transaction
, SYNCHRONOUS
);
522 TEST_F(HttpPipelinedNetworkTransactionTest
, RedirectDrained
) {
525 MockWrite writes
[] = {
526 MockWrite(SYNCHRONOUS
, 0, "GET /redirect.html HTTP/1.1\r\n"
527 "Host: localhost\r\n"
528 "Connection: keep-alive\r\n\r\n"),
529 MockWrite(SYNCHRONOUS
, 3, "GET /two.html HTTP/1.1\r\n"
530 "Host: localhost\r\n"
531 "Connection: keep-alive\r\n\r\n"),
534 MockRead(SYNCHRONOUS
, 1, "HTTP/1.1 302 OK\r\n"),
535 MockRead(SYNCHRONOUS
, 2, "Content-Length: 8\r\n\r\n"),
536 MockRead(ASYNC
, 4, "redirect"),
537 MockRead(SYNCHRONOUS
, 5, "HTTP/1.1 200 OK\r\n"),
538 MockRead(SYNCHRONOUS
, 6, "Content-Length: 8\r\n\r\n"),
539 MockRead(SYNCHRONOUS
, 7, "two.html"),
541 AddExpectedConnection(reads
, arraysize(reads
), writes
, arraysize(writes
));
543 scoped_ptr
<HttpNetworkTransaction
> one_transaction(
544 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
.get()));
545 TestCompletionCallback one_callback
;
546 EXPECT_EQ(ERR_IO_PENDING
,
547 one_transaction
->Start(GetRequestInfo("redirect.html"),
548 one_callback
.callback(), BoundNetLog()));
549 EXPECT_EQ(OK
, one_callback
.WaitForResult());
551 HttpNetworkTransaction
two_transaction(DEFAULT_PRIORITY
, session_
.get());
552 TestCompletionCallback two_callback
;
553 EXPECT_EQ(ERR_IO_PENDING
,
554 two_transaction
.Start(GetRequestInfo("two.html"),
555 two_callback
.callback(), BoundNetLog()));
557 one_transaction
.reset();
558 data_vector_
[0]->RunFor(2);
559 data_vector_
[0]->SetStop(10);
561 EXPECT_EQ(OK
, two_callback
.WaitForResult());
562 ExpectResponse("two.html", two_transaction
, SYNCHRONOUS
);
565 TEST_F(HttpPipelinedNetworkTransactionTest
, BasicHttpAuthentication
) {
568 MockWrite writes
[] = {
569 MockWrite(SYNCHRONOUS
, 0, "GET /one.html HTTP/1.1\r\n"
570 "Host: localhost\r\n"
571 "Connection: keep-alive\r\n\r\n"),
572 MockWrite(SYNCHRONOUS
, 5, "GET /one.html HTTP/1.1\r\n"
573 "Host: localhost\r\n"
574 "Connection: keep-alive\r\n"
575 "Authorization: auth_token\r\n\r\n"),
578 MockRead(SYNCHRONOUS
, 1, "HTTP/1.1 401 Authentication Required\r\n"),
579 MockRead(SYNCHRONOUS
, 2,
580 "WWW-Authenticate: Basic realm=\"Secure Area\"\r\n"),
581 MockRead(SYNCHRONOUS
, 3, "Content-Length: 20\r\n\r\n"),
582 MockRead(SYNCHRONOUS
, 4, "needs authentication"),
583 MockRead(SYNCHRONOUS
, 6, "HTTP/1.1 200 OK\r\n"),
584 MockRead(SYNCHRONOUS
, 7, "Content-Length: 8\r\n\r\n"),
585 MockRead(SYNCHRONOUS
, 8, "one.html"),
587 AddExpectedConnection(reads
, arraysize(reads
), writes
, arraysize(writes
));
589 HttpAuthHandlerMock
* mock_auth
= new HttpAuthHandlerMock
;
590 std::string challenge_text
= "Basic";
591 HttpAuthChallengeTokenizer
challenge(challenge_text
.begin(),
592 challenge_text
.end());
593 GURL
origin("localhost");
594 EXPECT_TRUE(mock_auth
->InitFromChallenge(&challenge
,
595 HttpAuth::AUTH_SERVER
,
598 auth_handler_factory_
->AddMockHandler(mock_auth
, HttpAuth::AUTH_SERVER
);
600 HttpNetworkTransaction
transaction(DEFAULT_PRIORITY
, session_
.get());
601 EXPECT_EQ(ERR_IO_PENDING
,
602 transaction
.Start(GetRequestInfo("one.html"),
603 callback_
.callback(),
605 EXPECT_EQ(OK
, callback_
.WaitForResult());
607 AuthCredentials
credentials(base::ASCIIToUTF16("user"),
608 base::ASCIIToUTF16("pass"));
609 EXPECT_EQ(OK
, transaction
.RestartWithAuth(credentials
, callback_
.callback()));
611 ExpectResponse("one.html", transaction
, SYNCHRONOUS
);
614 TEST_F(HttpPipelinedNetworkTransactionTest
, OldVersionDisablesPipelining
) {
617 MockWrite writes
[] = {
618 MockWrite(SYNCHRONOUS
, 0, "GET /pipelined.html HTTP/1.1\r\n"
619 "Host: localhost\r\n"
620 "Connection: keep-alive\r\n\r\n"),
623 MockRead(SYNCHRONOUS
, 1, "HTTP/1.0 200 OK\r\n"),
624 MockRead(SYNCHRONOUS
, 2, "Content-Length: 14\r\n\r\n"),
625 MockRead(SYNCHRONOUS
, 3, "pipelined.html"),
627 AddExpectedConnection(reads
, arraysize(reads
), writes
, arraysize(writes
));
629 MockWrite writes2
[] = {
630 MockWrite(SYNCHRONOUS
, 0, "GET /one.html HTTP/1.1\r\n"
631 "Host: localhost\r\n"
632 "Connection: keep-alive\r\n\r\n"),
634 MockRead reads2
[] = {
635 MockRead(SYNCHRONOUS
, 1, "HTTP/1.1 200 OK\r\n"),
636 MockRead(SYNCHRONOUS
, 2, "Content-Length: 8\r\n\r\n"),
637 MockRead(ASYNC
, 3, "one.html"),
638 MockRead(SYNCHRONOUS
, OK
, 4),
640 AddExpectedConnection(reads2
, arraysize(reads2
), writes2
, arraysize(writes2
));
642 MockWrite writes3
[] = {
643 MockWrite(SYNCHRONOUS
, 0, "GET /two.html HTTP/1.1\r\n"
644 "Host: localhost\r\n"
645 "Connection: keep-alive\r\n\r\n"),
647 MockRead reads3
[] = {
648 MockRead(SYNCHRONOUS
, 1, "HTTP/1.1 200 OK\r\n"),
649 MockRead(SYNCHRONOUS
, 2, "Content-Length: 8\r\n\r\n"),
650 MockRead(SYNCHRONOUS
, 3, "two.html"),
651 MockRead(SYNCHRONOUS
, OK
, 4),
653 AddExpectedConnection(reads3
, arraysize(reads3
), writes3
, arraysize(writes3
));
655 HttpNetworkTransaction
one_transaction(DEFAULT_PRIORITY
, session_
.get());
656 TestCompletionCallback one_callback
;
657 EXPECT_EQ(ERR_IO_PENDING
,
658 one_transaction
.Start(GetRequestInfo("pipelined.html"),
659 one_callback
.callback(), BoundNetLog()));
660 EXPECT_EQ(OK
, one_callback
.WaitForResult());
661 ExpectResponse("pipelined.html", one_transaction
, SYNCHRONOUS
);
663 CompleteTwoRequests(1, 4);
666 TEST_F(HttpPipelinedNetworkTransactionTest
, PipelinesImmediatelyIfKnownGood
) {
667 // The first request gets us an HTTP/1.1. The next 3 test pipelining. When the
668 // 3rd request completes, we know pipelining is safe. After the first 4
669 // complete, the 5th and 6th should then be immediately sent pipelined on a
670 // new HttpPipelinedConnection.
671 int old_max_sockets
= ClientSocketPoolManager::max_sockets_per_group(
672 HttpNetworkSession::NORMAL_SOCKET_POOL
);
673 ClientSocketPoolManager::set_max_sockets_per_group(
674 HttpNetworkSession::NORMAL_SOCKET_POOL
, 1);
677 MockWrite writes
[] = {
678 MockWrite(SYNCHRONOUS
, 0, "GET /one.html HTTP/1.1\r\n"
679 "Host: localhost\r\n"
680 "Connection: keep-alive\r\n\r\n"),
681 MockWrite(SYNCHRONOUS
, 4, "GET /two.html HTTP/1.1\r\n"
682 "Host: localhost\r\n"
683 "Connection: keep-alive\r\n\r\n"),
684 MockWrite(SYNCHRONOUS
, 7, "GET /three.html HTTP/1.1\r\n"
685 "Host: localhost\r\n"
686 "Connection: keep-alive\r\n\r\n"),
687 MockWrite(SYNCHRONOUS
, 12, "GET /four.html HTTP/1.1\r\n"
688 "Host: localhost\r\n"
689 "Connection: keep-alive\r\n\r\n"),
690 MockWrite(SYNCHRONOUS
, 16, "GET /second-pipeline-one.html HTTP/1.1\r\n"
691 "Host: localhost\r\n"
692 "Connection: keep-alive\r\n\r\n"),
693 MockWrite(SYNCHRONOUS
, 17, "GET /second-pipeline-two.html HTTP/1.1\r\n"
694 "Host: localhost\r\n"
695 "Connection: keep-alive\r\n\r\n"),
698 MockRead(SYNCHRONOUS
, 1, "HTTP/1.1 200 OK\r\n"),
699 MockRead(SYNCHRONOUS
, 2, "Content-Length: 8\r\n\r\n"),
700 MockRead(SYNCHRONOUS
, 3, "one.html"),
701 MockRead(SYNCHRONOUS
, 5, "HTTP/1.1 200 OK\r\n"),
702 MockRead(SYNCHRONOUS
, 6, "Content-Length: 8\r\n\r\n"),
703 MockRead(SYNCHRONOUS
, 8, "two.html"),
704 MockRead(SYNCHRONOUS
, 9, "HTTP/1.1 200 OK\r\n"),
705 MockRead(SYNCHRONOUS
, 10, "Content-Length: 10\r\n\r\n"),
706 MockRead(SYNCHRONOUS
, 11, "three.html"),
707 MockRead(SYNCHRONOUS
, 13, "HTTP/1.1 200 OK\r\n"),
708 MockRead(SYNCHRONOUS
, 14, "Content-Length: 9\r\n\r\n"),
709 MockRead(SYNCHRONOUS
, 15, "four.html"),
710 MockRead(ASYNC
, 18, "HTTP/1.1 200 OK\r\n"),
711 MockRead(ASYNC
, 19, "Content-Length: 24\r\n\r\n"),
712 MockRead(SYNCHRONOUS
, 20, "second-pipeline-one.html"),
713 MockRead(SYNCHRONOUS
, 21, "HTTP/1.1 200 OK\r\n"),
714 MockRead(SYNCHRONOUS
, 22, "Content-Length: 24\r\n\r\n"),
715 MockRead(SYNCHRONOUS
, 23, "second-pipeline-two.html"),
717 AddExpectedConnection(reads
, arraysize(reads
), writes
, arraysize(writes
));
719 CompleteFourRequests(REQUEST_DEFAULT
);
721 HttpNetworkTransaction
second_one_transaction(
722 DEFAULT_PRIORITY
, session_
.get());
723 TestCompletionCallback second_one_callback
;
724 EXPECT_EQ(ERR_IO_PENDING
,
725 second_one_transaction
.Start(
726 GetRequestInfo("second-pipeline-one.html"),
727 second_one_callback
.callback(), BoundNetLog()));
728 base::MessageLoop::current()->RunUntilIdle();
730 HttpNetworkTransaction
second_two_transaction(
731 DEFAULT_PRIORITY
, session_
.get());
732 TestCompletionCallback second_two_callback
;
733 EXPECT_EQ(ERR_IO_PENDING
,
734 second_two_transaction
.Start(
735 GetRequestInfo("second-pipeline-two.html"),
736 second_two_callback
.callback(), BoundNetLog()));
738 data_vector_
[0]->RunFor(3);
739 EXPECT_EQ(OK
, second_one_callback
.WaitForResult());
740 data_vector_
[0]->StopAfter(100);
741 ExpectResponse("second-pipeline-one.html", second_one_transaction
,
743 EXPECT_EQ(OK
, second_two_callback
.WaitForResult());
744 ExpectResponse("second-pipeline-two.html", second_two_transaction
,
747 ClientSocketPoolManager::set_max_sockets_per_group(
748 HttpNetworkSession::NORMAL_SOCKET_POOL
, old_max_sockets
);
751 class DataRunnerObserver
: public base::MessageLoop::TaskObserver
{
753 DataRunnerObserver(DeterministicSocketData
* data
, int run_before_task
)
755 run_before_task_(run_before_task
),
758 virtual void WillProcessTask(const base::PendingTask
& pending_task
) OVERRIDE
{
760 if (current_task_
== run_before_task_
) {
762 base::MessageLoop::current()->RemoveTaskObserver(this);
766 virtual void DidProcessTask(const base::PendingTask
& pending_task
) OVERRIDE
{}
769 DeterministicSocketData
* data_
;
770 int run_before_task_
;
774 TEST_F(HttpPipelinedNetworkTransactionTest
, OpenPipelinesWhileBinding
) {
775 // There was a racy crash in the pipelining code. This test recreates that
776 // race. The steps are:
777 // 1. The first request starts a pipeline and requests headers.
778 // 2. HttpStreamFactoryImpl::Job tries to bind a pending request to a new
779 // pipeline and queues a task to do so.
780 // 3. Before that task runs, the first request receives its headers and
781 // determines this host is probably capable of pipelining.
782 // 4. All of the hosts' pipelines are notified they have capacity in a loop.
783 // 5. On the first iteration, the first pipeline is opened up to accept new
784 // requests and steals the request from step #2.
785 // 6. The pipeline from #2 is deleted because it has no streams.
786 // 7. On the second iteration, the host tries to notify the pipeline from step
787 // #2 that it has capacity. This is a use-after-free.
790 MockWrite writes
[] = {
791 MockWrite(SYNCHRONOUS
, 0, "GET /one.html HTTP/1.1\r\n"
792 "Host: localhost\r\n"
793 "Connection: keep-alive\r\n\r\n"),
794 MockWrite(ASYNC
, 3, "GET /two.html HTTP/1.1\r\n"
795 "Host: localhost\r\n"
796 "Connection: keep-alive\r\n\r\n"),
799 MockRead(SYNCHRONOUS
, 1, "HTTP/1.1 200 OK\r\n"),
800 MockRead(ASYNC
, 2, "Content-Length: 8\r\n\r\n"),
801 MockRead(SYNCHRONOUS
, 4, "one.html"),
802 MockRead(SYNCHRONOUS
, 5, "HTTP/1.1 200 OK\r\n"),
803 MockRead(SYNCHRONOUS
, 6, "Content-Length: 8\r\n\r\n"),
804 MockRead(SYNCHRONOUS
, 7, "two.html"),
806 AddExpectedConnection(reads
, arraysize(reads
), writes
, arraysize(writes
));
808 AddExpectedConnection(NULL
, 0, NULL
, 0);
810 HttpNetworkTransaction
one_transaction(DEFAULT_PRIORITY
, session_
.get());
811 TestCompletionCallback one_callback
;
812 EXPECT_EQ(ERR_IO_PENDING
,
813 one_transaction
.Start(GetRequestInfo("one.html"),
814 one_callback
.callback(), BoundNetLog()));
816 data_vector_
[0]->SetStop(2);
817 data_vector_
[0]->Run();
819 HttpNetworkTransaction
two_transaction(DEFAULT_PRIORITY
, session_
.get());
820 TestCompletionCallback two_callback
;
821 EXPECT_EQ(ERR_IO_PENDING
,
822 two_transaction
.Start(GetRequestInfo("two.html"),
823 two_callback
.callback(), BoundNetLog()));
824 // Posted tasks should be:
825 // 1. MockHostResolverBase::ResolveNow
826 // 2. HttpStreamFactoryImpl::Job::OnStreamReadyCallback for job 1
827 // 3. HttpStreamFactoryImpl::Job::OnStreamReadyCallback for job 2
829 // We need to make sure that the response that triggers OnPipelineFeedback(OK)
830 // is called in between when task #3 is scheduled and when it runs. The
831 // DataRunnerObserver does that.
832 DataRunnerObserver
observer(data_vector_
[0], 3);
833 base::MessageLoop::current()->AddTaskObserver(&observer
);
834 data_vector_
[0]->SetStop(4);
835 base::MessageLoop::current()->RunUntilIdle();
836 data_vector_
[0]->SetStop(10);
838 EXPECT_EQ(OK
, one_callback
.WaitForResult());
839 ExpectResponse("one.html", one_transaction
, SYNCHRONOUS
);
840 EXPECT_EQ(OK
, two_callback
.WaitForResult());
841 ExpectResponse("two.html", two_transaction
, SYNCHRONOUS
);
844 TEST_F(HttpPipelinedNetworkTransactionTest
, ProxyChangesWhileConnecting
) {
847 DeterministicSocketData
data(NULL
, 0, NULL
, 0);
848 data
.set_connect_data(MockConnect(ASYNC
, ERR_CONNECTION_REFUSED
));
849 factory_
.AddSocketDataProvider(&data
);
851 DeterministicSocketData
data2(NULL
, 0, NULL
, 0);
852 data2
.set_connect_data(MockConnect(ASYNC
, ERR_FAILED
));
853 factory_
.AddSocketDataProvider(&data2
);
855 HttpNetworkTransaction
transaction(DEFAULT_PRIORITY
, session_
.get());
856 EXPECT_EQ(ERR_IO_PENDING
,
857 transaction
.Start(GetRequestInfo("test.html"), callback_
.callback(),
860 proxy_config_service_
->IncrementConfigId();
862 EXPECT_EQ(ERR_FAILED
, callback_
.WaitForResult());
865 TEST_F(HttpPipelinedNetworkTransactionTest
, ForcedPipelineSharesConnection
) {
868 MockWrite writes
[] = {
869 MockWrite(ASYNC
, 0, "GET /one.html HTTP/1.1\r\n"
870 "Host: localhost\r\n"
871 "Connection: keep-alive\r\n\r\n"
872 "GET /two.html HTTP/1.1\r\n"
873 "Host: localhost\r\n"
874 "Connection: keep-alive\r\n\r\n"),
877 MockRead(ASYNC
, 1, "HTTP/1.1 200 OK\r\n"),
878 MockRead(ASYNC
, 2, "Content-Length: 8\r\n\r\n"),
879 MockRead(ASYNC
, 3, "one.html"),
880 MockRead(ASYNC
, 4, "HTTP/1.1 200 OK\r\n"),
881 MockRead(ASYNC
, 5, "Content-Length: 8\r\n\r\n"),
882 MockRead(ASYNC
, 6, "two.html"),
884 AddExpectedConnection(reads
, arraysize(reads
), writes
, arraysize(writes
));
886 scoped_ptr
<HttpNetworkTransaction
> one_transaction(
887 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
.get()));
888 TestCompletionCallback one_callback
;
889 EXPECT_EQ(ERR_IO_PENDING
,
890 one_transaction
->Start(GetRequestInfo("one.html"),
891 one_callback
.callback(), BoundNetLog()));
893 HttpNetworkTransaction
two_transaction(DEFAULT_PRIORITY
, session_
.get());
894 TestCompletionCallback two_callback
;
895 EXPECT_EQ(ERR_IO_PENDING
,
896 two_transaction
.Start(GetRequestInfo("two.html"),
897 two_callback
.callback(), BoundNetLog()));
899 data_vector_
[0]->RunFor(3); // Send + 2 lines of headers.
900 EXPECT_EQ(OK
, one_callback
.WaitForResult());
901 ExpectResponse("one.html", *one_transaction
.get(), ASYNC
);
902 one_transaction
.reset();
904 data_vector_
[0]->RunFor(2); // 2 lines of headers.
905 EXPECT_EQ(OK
, two_callback
.WaitForResult());
906 ExpectResponse("two.html", two_transaction
, ASYNC
);
909 TEST_F(HttpPipelinedNetworkTransactionTest
,
910 ForcedPipelineConnectionErrorFailsBoth
) {
913 DeterministicSocketData
data(NULL
, 0, NULL
, 0);
914 data
.set_connect_data(MockConnect(ASYNC
, ERR_FAILED
));
915 factory_
.AddSocketDataProvider(&data
);
917 scoped_ptr
<HttpNetworkTransaction
> one_transaction(
918 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
.get()));
919 TestCompletionCallback one_callback
;
920 EXPECT_EQ(ERR_IO_PENDING
,
921 one_transaction
->Start(GetRequestInfo("one.html"),
922 one_callback
.callback(), BoundNetLog()));
924 HttpNetworkTransaction
two_transaction(DEFAULT_PRIORITY
, session_
.get());
925 TestCompletionCallback two_callback
;
926 EXPECT_EQ(ERR_IO_PENDING
,
927 two_transaction
.Start(GetRequestInfo("two.html"),
928 two_callback
.callback(), BoundNetLog()));
931 EXPECT_EQ(ERR_FAILED
, one_callback
.WaitForResult());
932 EXPECT_EQ(ERR_FAILED
, two_callback
.WaitForResult());
935 TEST_F(HttpPipelinedNetworkTransactionTest
, ForcedPipelineEvictionIsFatal
) {
938 MockWrite writes
[] = {
939 MockWrite(ASYNC
, 0, "GET /one.html HTTP/1.1\r\n"
940 "Host: localhost\r\n"
941 "Connection: keep-alive\r\n\r\n"
942 "GET /two.html HTTP/1.1\r\n"
943 "Host: localhost\r\n"
944 "Connection: keep-alive\r\n\r\n"),
947 MockRead(ASYNC
, ERR_FAILED
, 1),
949 AddExpectedConnection(reads
, arraysize(reads
), writes
, arraysize(writes
));
951 scoped_ptr
<HttpNetworkTransaction
> one_transaction(
952 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
.get()));
953 TestCompletionCallback one_callback
;
954 EXPECT_EQ(ERR_IO_PENDING
,
955 one_transaction
->Start(GetRequestInfo("one.html"),
956 one_callback
.callback(), BoundNetLog()));
958 HttpNetworkTransaction
two_transaction(DEFAULT_PRIORITY
, session_
.get());
959 TestCompletionCallback two_callback
;
960 EXPECT_EQ(ERR_IO_PENDING
,
961 two_transaction
.Start(GetRequestInfo("two.html"),
962 two_callback
.callback(), BoundNetLog()));
964 data_vector_
[0]->RunFor(2);
965 EXPECT_EQ(ERR_FAILED
, one_callback
.WaitForResult());
966 one_transaction
.reset();
967 EXPECT_EQ(ERR_PIPELINE_EVICTION
, two_callback
.WaitForResult());
970 TEST_F(HttpPipelinedNetworkTransactionTest
, ForcedPipelineOrder
) {
973 MockWrite writes
[] = {
975 "GET /one.html HTTP/1.1\r\n"
976 "Host: localhost\r\n"
977 "Connection: keep-alive\r\n\r\n"
978 "GET /two.html HTTP/1.1\r\n"
979 "Host: localhost\r\n"
980 "Connection: keep-alive\r\n\r\n"
981 "GET /three.html HTTP/1.1\r\n"
982 "Host: localhost\r\n"
983 "Connection: keep-alive\r\n\r\n"
984 "GET /four.html HTTP/1.1\r\n"
985 "Host: localhost\r\n"
986 "Connection: keep-alive\r\n\r\n"
990 MockRead(ASYNC
, ERR_FAILED
, 1),
992 DeterministicSocketData
data(
993 reads
, arraysize(reads
), writes
, arraysize(writes
));
994 data
.set_connect_data(MockConnect(ASYNC
, OK
));
995 factory_
.AddSocketDataProvider(&data
);
997 scoped_ptr
<HttpNetworkTransaction
> one_transaction(
998 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
.get()));
999 TestCompletionCallback one_callback
;
1000 EXPECT_EQ(ERR_IO_PENDING
,
1001 one_transaction
->Start(GetRequestInfo("one.html"),
1002 one_callback
.callback(), BoundNetLog()));
1004 scoped_ptr
<HttpNetworkTransaction
> two_transaction(
1005 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
.get()));
1006 TestCompletionCallback two_callback
;
1007 EXPECT_EQ(ERR_IO_PENDING
,
1008 two_transaction
->Start(GetRequestInfo("two.html"),
1009 two_callback
.callback(), BoundNetLog()));
1011 scoped_ptr
<HttpNetworkTransaction
> three_transaction(
1012 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
.get()));
1013 TestCompletionCallback three_callback
;
1014 EXPECT_EQ(ERR_IO_PENDING
,
1015 three_transaction
->Start(GetRequestInfo("three.html"),
1016 three_callback
.callback(), BoundNetLog()));
1018 scoped_ptr
<HttpNetworkTransaction
> four_transaction(
1019 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
.get()));
1020 TestCompletionCallback four_callback
;
1021 EXPECT_EQ(ERR_IO_PENDING
,
1022 four_transaction
->Start(GetRequestInfo("four.html"),
1023 four_callback
.callback(), BoundNetLog()));
1026 EXPECT_EQ(ERR_FAILED
, one_callback
.WaitForResult());
1027 one_transaction
.reset();
1028 EXPECT_EQ(ERR_PIPELINE_EVICTION
, two_callback
.WaitForResult());
1029 two_transaction
.reset();
1030 EXPECT_EQ(ERR_PIPELINE_EVICTION
, three_callback
.WaitForResult());
1031 three_transaction
.reset();
1032 EXPECT_EQ(ERR_PIPELINE_EVICTION
, four_callback
.WaitForResult());
1035 } // anonymous namespace