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.
5 #include "net/http/http_pipelined_connection_impl.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/memory/scoped_vector.h"
12 #include "net/base/capturing_net_log.h"
13 #include "net/base/io_buffer.h"
14 #include "net/base/load_timing_info.h"
15 #include "net/base/load_timing_info_test_util.h"
16 #include "net/base/net_errors.h"
17 #include "net/base/request_priority.h"
18 #include "net/http/http_pipelined_stream.h"
19 #include "net/socket/client_socket_handle.h"
20 #include "net/socket/client_socket_pool_histograms.h"
21 #include "net/socket/socket_test_util.h"
22 #include "testing/gmock/include/gmock/gmock.h"
23 #include "testing/gtest/include/gtest/gtest.h"
26 using testing::NiceMock
;
31 class DummySocketParams
: public base::RefCounted
<DummySocketParams
> {
33 friend class base::RefCounted
<DummySocketParams
>;
34 ~DummySocketParams() {}
37 REGISTER_SOCKET_PARAMS_FOR_POOL(MockTransportClientSocketPool
,
42 // Tests the load timing of a stream that's connected and is not the first
43 // request sent on a connection.
44 void TestLoadTimingReused(const HttpStream
& stream
) {
45 LoadTimingInfo load_timing_info
;
46 EXPECT_TRUE(stream
.GetLoadTimingInfo(&load_timing_info
));
48 EXPECT_TRUE(load_timing_info
.socket_reused
);
49 EXPECT_NE(NetLog::Source::kInvalidId
, load_timing_info
.socket_log_id
);
51 ExpectConnectTimingHasNoTimes(load_timing_info
.connect_timing
);
52 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info
);
55 // Tests the load timing of a stream that's connected and using a fresh
57 void TestLoadTimingNotReused(const HttpStream
& stream
) {
58 LoadTimingInfo load_timing_info
;
59 EXPECT_TRUE(stream
.GetLoadTimingInfo(&load_timing_info
));
61 EXPECT_FALSE(load_timing_info
.socket_reused
);
62 EXPECT_NE(NetLog::Source::kInvalidId
, load_timing_info
.socket_log_id
);
64 ExpectConnectTimingHasTimes(load_timing_info
.connect_timing
,
65 CONNECT_TIMING_HAS_DNS_TIMES
);
66 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info
);
69 class MockPipelineDelegate
: public HttpPipelinedConnection::Delegate
{
71 MOCK_METHOD1(OnPipelineHasCapacity
, void(HttpPipelinedConnection
* pipeline
));
72 MOCK_METHOD2(OnPipelineFeedback
, void(
73 HttpPipelinedConnection
* pipeline
,
74 HttpPipelinedConnection::Feedback feedback
));
77 class SuddenCloseObserver
: public base::MessageLoop::TaskObserver
{
79 SuddenCloseObserver(HttpStream
* stream
, int close_before_task
)
81 close_before_task_(close_before_task
),
84 virtual void WillProcessTask(const base::PendingTask
& pending_task
) OVERRIDE
{
86 if (current_task_
== close_before_task_
) {
87 stream_
->Close(false);
88 base::MessageLoop::current()->RemoveTaskObserver(this);
92 virtual void DidProcessTask(const base::PendingTask
& pending_task
) OVERRIDE
{}
96 int close_before_task_
;
100 class HttpPipelinedConnectionImplTest
: public testing::Test
{
102 HttpPipelinedConnectionImplTest()
104 pool_(1, 1, &histograms_
, &factory_
),
105 origin_("host", 123) {
109 base::MessageLoop::current()->RunUntilIdle();
112 void Initialize(MockRead
* reads
, size_t reads_count
,
113 MockWrite
* writes
, size_t writes_count
) {
114 data_
.reset(new DeterministicSocketData(reads
, reads_count
,
115 writes
, writes_count
));
116 data_
->set_connect_data(MockConnect(SYNCHRONOUS
, OK
));
117 if (reads_count
|| writes_count
) {
118 data_
->StopAfter(reads_count
+ writes_count
);
120 factory_
.AddSocketDataProvider(data_
.get());
121 scoped_refptr
<DummySocketParams
> params
;
122 ClientSocketHandle
* connection
= new ClientSocketHandle
;
123 // Only give the connection a real NetLog to make sure that LoadTiming uses
124 // the connection's ID, rather than the pipeline's. Since pipelines are
125 // destroyed when they've responded to all requests, but the connection
126 // lives on, this is an important behavior.
127 connection
->Init("a", params
, MEDIUM
, CompletionCallback(), &pool_
,
129 pipeline_
.reset(new HttpPipelinedConnectionImpl(
130 connection
, &delegate_
, origin_
, ssl_config_
, proxy_info_
,
131 BoundNetLog(), false, kProtoUnknown
));
134 HttpRequestInfo
* GetRequestInfo(const std::string
& filename
) {
135 HttpRequestInfo
* request_info
= new HttpRequestInfo
;
136 request_info
->url
= GURL("http://localhost/" + filename
);
137 request_info
->method
= "GET";
138 request_info_vector_
.push_back(request_info
);
142 HttpStream
* NewTestStream(const std::string
& filename
) {
143 HttpStream
* stream
= pipeline_
->CreateNewStream();
144 HttpRequestInfo
* request_info
= GetRequestInfo(filename
);
145 int rv
= stream
->InitializeStream(
146 request_info
, DEFAULT_PRIORITY
, BoundNetLog(), CompletionCallback());
151 void ExpectResponse(const std::string
& expected
,
152 scoped_ptr
<HttpStream
>& stream
, bool async
) {
153 scoped_refptr
<IOBuffer
> buffer(new IOBuffer(expected
.size()));
156 EXPECT_EQ(ERR_IO_PENDING
,
157 stream
->ReadResponseBody(buffer
.get(), expected
.size(),
158 callback_
.callback()));
160 EXPECT_EQ(static_cast<int>(expected
.size()), callback_
.WaitForResult());
162 EXPECT_EQ(static_cast<int>(expected
.size()),
163 stream
->ReadResponseBody(buffer
.get(), expected
.size(),
164 callback_
.callback()));
166 std::string
actual(buffer
->data(), expected
.size());
167 EXPECT_THAT(actual
, StrEq(expected
));
170 void TestSyncRequest(scoped_ptr
<HttpStream
>& stream
,
171 const std::string
& filename
) {
172 HttpRequestHeaders headers
;
173 HttpResponseInfo response
;
174 EXPECT_EQ(OK
, stream
->SendRequest(headers
, &response
,
175 callback_
.callback()));
176 EXPECT_EQ(OK
, stream
->ReadResponseHeaders(callback_
.callback()));
177 ExpectResponse(filename
, stream
, false);
179 stream
->Close(false);
182 CapturingBoundNetLog net_log_
;
183 DeterministicMockClientSocketFactory factory_
;
184 ClientSocketPoolHistograms histograms_
;
185 MockTransportClientSocketPool pool_
;
186 scoped_ptr
<DeterministicSocketData
> data_
;
188 HostPortPair origin_
;
189 SSLConfig ssl_config_
;
190 ProxyInfo proxy_info_
;
191 NiceMock
<MockPipelineDelegate
> delegate_
;
192 TestCompletionCallback callback_
;
193 scoped_ptr
<HttpPipelinedConnectionImpl
> pipeline_
;
194 ScopedVector
<HttpRequestInfo
> request_info_vector_
;
197 TEST_F(HttpPipelinedConnectionImplTest
, PipelineNotUsed
) {
198 Initialize(NULL
, 0, NULL
, 0);
201 TEST_F(HttpPipelinedConnectionImplTest
, StreamNotUsed
) {
202 Initialize(NULL
, 0, NULL
, 0);
204 scoped_ptr
<HttpStream
> stream(pipeline_
->CreateNewStream());
206 stream
->Close(false);
209 TEST_F(HttpPipelinedConnectionImplTest
, StreamBoundButNotUsed
) {
210 Initialize(NULL
, 0, NULL
, 0);
212 scoped_ptr
<HttpStream
> stream(NewTestStream("ok.html"));
214 TestLoadTimingNotReused(*stream
);
215 stream
->Close(false);
216 TestLoadTimingNotReused(*stream
);
219 TEST_F(HttpPipelinedConnectionImplTest
, SyncSingleRequest
) {
220 MockWrite writes
[] = {
221 MockWrite(SYNCHRONOUS
, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
224 MockRead(SYNCHRONOUS
, 1, "HTTP/1.1 200 OK\r\n"),
225 MockRead(SYNCHRONOUS
, 2, "Content-Length: 7\r\n\r\n"),
226 MockRead(SYNCHRONOUS
, 3, "ok.html"),
228 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
230 scoped_ptr
<HttpStream
> stream(NewTestStream("ok.html"));
231 TestLoadTimingNotReused(*stream
);
232 TestSyncRequest(stream
, "ok.html");
233 TestLoadTimingNotReused(*stream
);
236 TEST_F(HttpPipelinedConnectionImplTest
, AsyncSingleRequest
) {
237 MockWrite writes
[] = {
238 MockWrite(ASYNC
, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
241 MockRead(ASYNC
, 1, "HTTP/1.1 200 OK\r\n"),
242 MockRead(ASYNC
, 2, "Content-Length: 7\r\n\r\n"),
243 MockRead(ASYNC
, 3, "ok.html"),
245 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
247 scoped_ptr
<HttpStream
> stream(NewTestStream("ok.html"));
249 HttpRequestHeaders headers
;
250 HttpResponseInfo response
;
251 EXPECT_EQ(ERR_IO_PENDING
, stream
->SendRequest(headers
, &response
,
252 callback_
.callback()));
254 EXPECT_LE(OK
, callback_
.WaitForResult());
255 TestLoadTimingNotReused(*stream
);
257 EXPECT_EQ(ERR_IO_PENDING
, stream
->ReadResponseHeaders(callback_
.callback()));
259 EXPECT_LE(OK
, callback_
.WaitForResult());
260 TestLoadTimingNotReused(*stream
);
262 ExpectResponse("ok.html", stream
, true);
263 TestLoadTimingNotReused(*stream
);
265 stream
->Close(false);
268 TEST_F(HttpPipelinedConnectionImplTest
, LockStepAsyncRequests
) {
269 MockWrite writes
[] = {
270 MockWrite(ASYNC
, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
271 MockWrite(ASYNC
, 1, "GET /ko.html HTTP/1.1\r\n\r\n"),
274 MockRead(ASYNC
, 2, "HTTP/1.1 200 OK\r\n"),
275 MockRead(ASYNC
, 3, "Content-Length: 7\r\n\r\n"),
276 MockRead(ASYNC
, 4, "ok.html"),
277 MockRead(ASYNC
, 5, "HTTP/1.1 200 OK\r\n"),
278 MockRead(ASYNC
, 6, "Content-Length: 7\r\n\r\n"),
279 MockRead(ASYNC
, 7, "ko.html"),
281 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
283 scoped_ptr
<HttpStream
> stream1(NewTestStream("ok.html"));
284 scoped_ptr
<HttpStream
> stream2(NewTestStream("ko.html"));
286 HttpRequestHeaders headers1
;
287 HttpResponseInfo response1
;
288 EXPECT_EQ(ERR_IO_PENDING
, stream1
->SendRequest(headers1
, &response1
,
289 callback_
.callback()));
290 TestLoadTimingNotReused(*stream1
);
292 HttpRequestHeaders headers2
;
293 HttpResponseInfo response2
;
294 EXPECT_EQ(ERR_IO_PENDING
, stream2
->SendRequest(headers2
, &response2
,
295 callback_
.callback()));
296 TestLoadTimingReused(*stream2
);
299 EXPECT_LE(OK
, callback_
.WaitForResult());
301 EXPECT_LE(OK
, callback_
.WaitForResult());
303 EXPECT_EQ(ERR_IO_PENDING
, stream1
->ReadResponseHeaders(callback_
.callback()));
304 EXPECT_EQ(ERR_IO_PENDING
, stream2
->ReadResponseHeaders(callback_
.callback()));
307 EXPECT_LE(OK
, callback_
.WaitForResult());
309 ExpectResponse("ok.html", stream1
, true);
311 TestLoadTimingNotReused(*stream1
);
312 LoadTimingInfo load_timing_info1
;
313 EXPECT_TRUE(stream1
->GetLoadTimingInfo(&load_timing_info1
));
314 stream1
->Close(false);
317 EXPECT_LE(OK
, callback_
.WaitForResult());
319 ExpectResponse("ko.html", stream2
, true);
321 TestLoadTimingReused(*stream2
);
322 LoadTimingInfo load_timing_info2
;
323 EXPECT_TRUE(stream2
->GetLoadTimingInfo(&load_timing_info2
));
324 EXPECT_EQ(load_timing_info1
.socket_log_id
,
325 load_timing_info2
.socket_log_id
);
326 stream2
->Close(false);
329 TEST_F(HttpPipelinedConnectionImplTest
, TwoResponsesInOnePacket
) {
330 MockWrite writes
[] = {
331 MockWrite(SYNCHRONOUS
, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
332 MockWrite(SYNCHRONOUS
, 1, "GET /ko.html HTTP/1.1\r\n\r\n"),
335 MockRead(SYNCHRONOUS
, 2,
336 "HTTP/1.1 200 OK\r\n"
337 "Content-Length: 7\r\n\r\n"
339 "HTTP/1.1 200 OK\r\n"
340 "Content-Length: 7\r\n\r\n"
343 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
345 scoped_ptr
<HttpStream
> stream1(NewTestStream("ok.html"));
346 scoped_ptr
<HttpStream
> stream2(NewTestStream("ko.html"));
348 HttpRequestHeaders headers1
;
349 HttpResponseInfo response1
;
350 EXPECT_EQ(OK
, stream1
->SendRequest(headers1
,
351 &response1
, callback_
.callback()));
352 HttpRequestHeaders headers2
;
353 HttpResponseInfo response2
;
354 EXPECT_EQ(OK
, stream2
->SendRequest(headers2
,
355 &response2
, callback_
.callback()));
357 EXPECT_EQ(OK
, stream1
->ReadResponseHeaders(callback_
.callback()));
358 ExpectResponse("ok.html", stream1
, false);
359 stream1
->Close(false);
361 EXPECT_EQ(OK
, stream2
->ReadResponseHeaders(callback_
.callback()));
362 ExpectResponse("ko.html", stream2
, false);
363 stream2
->Close(false);
366 TEST_F(HttpPipelinedConnectionImplTest
, SendOrderSwapped
) {
367 MockWrite writes
[] = {
368 MockWrite(SYNCHRONOUS
, 0, "GET /ko.html HTTP/1.1\r\n\r\n"),
369 MockWrite(SYNCHRONOUS
, 4, "GET /ok.html HTTP/1.1\r\n\r\n"),
372 MockRead(SYNCHRONOUS
, 1, "HTTP/1.1 200 OK\r\n"),
373 MockRead(SYNCHRONOUS
, 2, "Content-Length: 7\r\n\r\n"),
374 MockRead(SYNCHRONOUS
, 3, "ko.html"),
375 MockRead(SYNCHRONOUS
, 5, "HTTP/1.1 200 OK\r\n"),
376 MockRead(SYNCHRONOUS
, 6, "Content-Length: 7\r\n\r\n"),
377 MockRead(SYNCHRONOUS
, 7, "ok.html"),
379 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
381 scoped_ptr
<HttpStream
> stream1(NewTestStream("ok.html"));
382 scoped_ptr
<HttpStream
> stream2(NewTestStream("ko.html"));
384 TestSyncRequest(stream2
, "ko.html");
385 TestSyncRequest(stream1
, "ok.html");
386 TestLoadTimingNotReused(*stream1
);
387 TestLoadTimingReused(*stream2
);
390 TEST_F(HttpPipelinedConnectionImplTest
, ReadOrderSwapped
) {
391 MockWrite writes
[] = {
392 MockWrite(SYNCHRONOUS
, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
393 MockWrite(SYNCHRONOUS
, 1, "GET /ko.html HTTP/1.1\r\n\r\n"),
396 MockRead(SYNCHRONOUS
, 2, "HTTP/1.1 200 OK\r\n"),
397 MockRead(SYNCHRONOUS
, 3, "Content-Length: 7\r\n\r\n"),
398 MockRead(SYNCHRONOUS
, 4, "ok.html"),
399 MockRead(SYNCHRONOUS
, 5, "HTTP/1.1 200 OK\r\n"),
400 MockRead(SYNCHRONOUS
, 6, "Content-Length: 7\r\n\r\n"),
401 MockRead(SYNCHRONOUS
, 7, "ko.html"),
403 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
405 scoped_ptr
<HttpStream
> stream1(NewTestStream("ok.html"));
406 scoped_ptr
<HttpStream
> stream2(NewTestStream("ko.html"));
408 HttpRequestHeaders headers1
;
409 HttpResponseInfo response1
;
410 EXPECT_EQ(OK
, stream1
->SendRequest(headers1
,
411 &response1
, callback_
.callback()));
413 HttpRequestHeaders headers2
;
414 HttpResponseInfo response2
;
415 EXPECT_EQ(OK
, stream2
->SendRequest(headers2
,
416 &response2
, callback_
.callback()));
418 EXPECT_EQ(ERR_IO_PENDING
, stream2
->ReadResponseHeaders(callback_
.callback()));
420 EXPECT_EQ(OK
, stream1
->ReadResponseHeaders(callback_
.callback()));
421 ExpectResponse("ok.html", stream1
, false);
423 stream1
->Close(false);
425 EXPECT_LE(OK
, callback_
.WaitForResult());
426 ExpectResponse("ko.html", stream2
, false);
428 stream2
->Close(false);
431 TEST_F(HttpPipelinedConnectionImplTest
, SendWhileReading
) {
432 MockWrite writes
[] = {
433 MockWrite(SYNCHRONOUS
, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
434 MockWrite(SYNCHRONOUS
, 3, "GET /ko.html HTTP/1.1\r\n\r\n"),
437 MockRead(SYNCHRONOUS
, 1, "HTTP/1.1 200 OK\r\n"),
438 MockRead(SYNCHRONOUS
, 2, "Content-Length: 7\r\n\r\n"),
439 MockRead(SYNCHRONOUS
, 4, "ok.html"),
440 MockRead(SYNCHRONOUS
, 5, "HTTP/1.1 200 OK\r\n"),
441 MockRead(SYNCHRONOUS
, 6, "Content-Length: 7\r\n\r\n"),
442 MockRead(SYNCHRONOUS
, 7, "ko.html"),
444 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
446 scoped_ptr
<HttpStream
> stream1(NewTestStream("ok.html"));
447 scoped_ptr
<HttpStream
> stream2(NewTestStream("ko.html"));
449 HttpRequestHeaders headers1
;
450 HttpResponseInfo response1
;
451 EXPECT_EQ(OK
, stream1
->SendRequest(headers1
,
452 &response1
, callback_
.callback()));
453 EXPECT_EQ(OK
, stream1
->ReadResponseHeaders(callback_
.callback()));
455 HttpRequestHeaders headers2
;
456 HttpResponseInfo response2
;
457 EXPECT_EQ(OK
, stream2
->SendRequest(headers2
,
458 &response2
, callback_
.callback()));
460 ExpectResponse("ok.html", stream1
, false);
461 stream1
->Close(false);
463 EXPECT_EQ(OK
, stream2
->ReadResponseHeaders(callback_
.callback()));
464 ExpectResponse("ko.html", stream2
, false);
465 stream2
->Close(false);
468 TEST_F(HttpPipelinedConnectionImplTest
, AsyncSendWhileAsyncReadBlocked
) {
469 MockWrite writes
[] = {
470 MockWrite(SYNCHRONOUS
, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
471 MockWrite(ASYNC
, 3, "GET /ko.html HTTP/1.1\r\n\r\n"),
474 MockRead(SYNCHRONOUS
, 1, "HTTP/1.1 200 OK\r\n"),
475 MockRead(SYNCHRONOUS
, 2, "Content-Length: 7\r\n\r\n"),
476 MockRead(ASYNC
, 4, "ok.html"),
477 MockRead(SYNCHRONOUS
, 5, "HTTP/1.1 200 OK\r\n"),
478 MockRead(SYNCHRONOUS
, 6, "Content-Length: 7\r\n\r\n"),
479 MockRead(SYNCHRONOUS
, 7, "ko.html"),
481 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
483 scoped_ptr
<HttpStream
> stream1(NewTestStream("ok.html"));
484 scoped_ptr
<HttpStream
> stream2(NewTestStream("ko.html"));
486 HttpRequestHeaders headers1
;
487 HttpResponseInfo response1
;
488 EXPECT_EQ(OK
, stream1
->SendRequest(headers1
,
489 &response1
, callback_
.callback()));
490 EXPECT_EQ(OK
, stream1
->ReadResponseHeaders(callback_
.callback()));
491 TestCompletionCallback callback1
;
492 std::string expected
= "ok.html";
493 scoped_refptr
<IOBuffer
> buffer(new IOBuffer(expected
.size()));
494 EXPECT_EQ(ERR_IO_PENDING
,
495 stream1
->ReadResponseBody(buffer
.get(), expected
.size(),
496 callback1
.callback()));
498 HttpRequestHeaders headers2
;
499 HttpResponseInfo response2
;
500 TestCompletionCallback callback2
;
501 EXPECT_EQ(ERR_IO_PENDING
, stream2
->SendRequest(headers2
, &response2
,
502 callback2
.callback()));
505 EXPECT_LE(OK
, callback2
.WaitForResult());
506 EXPECT_EQ(ERR_IO_PENDING
, stream2
->ReadResponseHeaders(callback2
.callback()));
509 EXPECT_EQ(static_cast<int>(expected
.size()), callback1
.WaitForResult());
510 std::string
actual(buffer
->data(), expected
.size());
511 EXPECT_THAT(actual
, StrEq(expected
));
512 stream1
->Close(false);
515 EXPECT_LE(OK
, callback2
.WaitForResult());
516 ExpectResponse("ko.html", stream2
, false);
517 stream2
->Close(false);
520 TEST_F(HttpPipelinedConnectionImplTest
, UnusedStreamAllowsLaterUse
) {
521 MockWrite writes
[] = {
522 MockWrite(SYNCHRONOUS
, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
525 MockRead(SYNCHRONOUS
, 1, "HTTP/1.1 200 OK\r\n"),
526 MockRead(SYNCHRONOUS
, 2, "Content-Length: 7\r\n\r\n"),
527 MockRead(SYNCHRONOUS
, 3, "ok.html"),
529 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
531 scoped_ptr
<HttpStream
> unused_stream(NewTestStream("unused.html"));
532 unused_stream
->Close(false);
534 scoped_ptr
<HttpStream
> later_stream(NewTestStream("ok.html"));
535 TestSyncRequest(later_stream
, "ok.html");
538 TEST_F(HttpPipelinedConnectionImplTest
, UnsentStreamAllowsLaterUse
) {
539 MockWrite writes
[] = {
540 MockWrite(ASYNC
, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
541 MockWrite(SYNCHRONOUS
, 4, "GET /ko.html HTTP/1.1\r\n\r\n"),
544 MockRead(ASYNC
, 1, "HTTP/1.1 200 OK\r\n"),
545 MockRead(ASYNC
, 2, "Content-Length: 7\r\n\r\n"),
546 MockRead(ASYNC
, 3, "ok.html"),
547 MockRead(SYNCHRONOUS
, 5, "HTTP/1.1 200 OK\r\n"),
548 MockRead(SYNCHRONOUS
, 6, "Content-Length: 7\r\n\r\n"),
549 MockRead(SYNCHRONOUS
, 7, "ko.html"),
551 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
553 scoped_ptr
<HttpStream
> stream(NewTestStream("ok.html"));
555 HttpRequestHeaders headers
;
556 HttpResponseInfo response
;
557 EXPECT_EQ(ERR_IO_PENDING
, stream
->SendRequest(headers
, &response
,
558 callback_
.callback()));
560 scoped_ptr
<HttpStream
> unsent_stream(NewTestStream("unsent.html"));
561 HttpRequestHeaders unsent_headers
;
562 HttpResponseInfo unsent_response
;
563 EXPECT_EQ(ERR_IO_PENDING
, unsent_stream
->SendRequest(unsent_headers
,
565 callback_
.callback()));
566 unsent_stream
->Close(false);
569 EXPECT_LE(OK
, callback_
.WaitForResult());
571 EXPECT_EQ(ERR_IO_PENDING
, stream
->ReadResponseHeaders(callback_
.callback()));
573 EXPECT_LE(OK
, callback_
.WaitForResult());
575 ExpectResponse("ok.html", stream
, true);
577 stream
->Close(false);
580 scoped_ptr
<HttpStream
> later_stream(NewTestStream("ko.html"));
581 TestSyncRequest(later_stream
, "ko.html");
584 TEST_F(HttpPipelinedConnectionImplTest
, FailedSend
) {
585 MockWrite writes
[] = {
586 MockWrite(ASYNC
, ERR_FAILED
),
588 Initialize(NULL
, 0, writes
, arraysize(writes
));
590 scoped_ptr
<HttpStream
> failed_stream(NewTestStream("ok.html"));
591 scoped_ptr
<HttpStream
> evicted_stream(NewTestStream("evicted.html"));
592 scoped_ptr
<HttpStream
> closed_stream(NewTestStream("closed.html"));
593 scoped_ptr
<HttpStream
> rejected_stream(NewTestStream("rejected.html"));
595 HttpRequestHeaders headers
;
596 HttpResponseInfo response
;
597 TestCompletionCallback failed_callback
;
598 EXPECT_EQ(ERR_IO_PENDING
,
599 failed_stream
->SendRequest(headers
, &response
,
600 failed_callback
.callback()));
601 TestCompletionCallback evicted_callback
;
602 EXPECT_EQ(ERR_IO_PENDING
,
603 evicted_stream
->SendRequest(headers
, &response
,
604 evicted_callback
.callback()));
605 EXPECT_EQ(ERR_IO_PENDING
, closed_stream
->SendRequest(headers
, &response
,
606 callback_
.callback()));
607 closed_stream
->Close(false);
610 EXPECT_EQ(ERR_FAILED
, failed_callback
.WaitForResult());
611 EXPECT_EQ(ERR_PIPELINE_EVICTION
, evicted_callback
.WaitForResult());
612 EXPECT_EQ(ERR_PIPELINE_EVICTION
,
613 rejected_stream
->SendRequest(headers
, &response
,
614 callback_
.callback()));
616 failed_stream
->Close(true);
617 evicted_stream
->Close(true);
618 rejected_stream
->Close(true);
621 TEST_F(HttpPipelinedConnectionImplTest
, ConnectionSuddenlyClosedAfterResponse
) {
622 MockWrite writes
[] = {
623 MockWrite(SYNCHRONOUS
, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
624 MockWrite(SYNCHRONOUS
, 1, "GET /read_evicted.html HTTP/1.1\r\n\r\n"),
625 MockWrite(SYNCHRONOUS
, 2, "GET /read_rejected.html HTTP/1.1\r\n\r\n"),
626 MockWrite(ASYNC
, ERR_SOCKET_NOT_CONNECTED
, 5),
629 MockRead(SYNCHRONOUS
, 3, "HTTP/1.1 200 OK\r\n\r\n"),
630 MockRead(SYNCHRONOUS
, 4, "ok.html"),
631 MockRead(ASYNC
, OK
, 6), // Connection closed message. Not read before the
632 // ERR_SOCKET_NOT_CONNECTED.
634 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
636 scoped_ptr
<HttpStream
> closed_stream(NewTestStream("ok.html"));
637 scoped_ptr
<HttpStream
> read_evicted_stream(
638 NewTestStream("read_evicted.html"));
639 scoped_ptr
<HttpStream
> read_rejected_stream(
640 NewTestStream("read_rejected.html"));
641 scoped_ptr
<HttpStream
> send_closed_stream(
642 NewTestStream("send_closed.html"));
643 scoped_ptr
<HttpStream
> send_evicted_stream(
644 NewTestStream("send_evicted.html"));
645 scoped_ptr
<HttpStream
> send_rejected_stream(
646 NewTestStream("send_rejected.html"));
648 HttpRequestHeaders headers
;
649 HttpResponseInfo response
;
650 EXPECT_EQ(OK
, closed_stream
->SendRequest(headers
,
651 &response
, callback_
.callback()));
652 EXPECT_EQ(OK
, read_evicted_stream
->SendRequest(headers
, &response
,
653 callback_
.callback()));
654 EXPECT_EQ(OK
, read_rejected_stream
->SendRequest(headers
, &response
,
655 callback_
.callback()));
656 TestCompletionCallback send_closed_callback
;
657 EXPECT_EQ(ERR_IO_PENDING
,
658 send_closed_stream
->SendRequest(headers
, &response
,
659 send_closed_callback
.callback()));
660 TestCompletionCallback send_evicted_callback
;
661 EXPECT_EQ(ERR_IO_PENDING
,
662 send_evicted_stream
->SendRequest(headers
, &response
,
663 send_evicted_callback
.callback()));
665 TestCompletionCallback read_evicted_callback
;
666 EXPECT_EQ(ERR_IO_PENDING
,
667 read_evicted_stream
->ReadResponseHeaders(
668 read_evicted_callback
.callback()));
670 EXPECT_EQ(OK
, closed_stream
->ReadResponseHeaders(callback_
.callback()));
671 ExpectResponse("ok.html", closed_stream
, false);
672 closed_stream
->Close(true);
674 EXPECT_EQ(ERR_PIPELINE_EVICTION
, read_evicted_callback
.WaitForResult());
675 read_evicted_stream
->Close(true);
677 EXPECT_EQ(ERR_PIPELINE_EVICTION
,
678 read_rejected_stream
->ReadResponseHeaders(callback_
.callback()));
679 read_rejected_stream
->Close(true);
682 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED
, send_closed_callback
.WaitForResult());
683 send_closed_stream
->Close(true);
685 EXPECT_EQ(ERR_PIPELINE_EVICTION
, send_evicted_callback
.WaitForResult());
686 send_evicted_stream
->Close(true);
688 EXPECT_EQ(ERR_PIPELINE_EVICTION
,
689 send_rejected_stream
->SendRequest(headers
, &response
,
690 callback_
.callback()));
691 send_rejected_stream
->Close(true);
694 TEST_F(HttpPipelinedConnectionImplTest
, AbortWhileSending
) {
695 MockWrite writes
[] = {
696 MockWrite(ASYNC
, 0, "GET /aborts.html HTTP/1.1\r\n\r\n"),
698 Initialize(NULL
, 0, writes
, arraysize(writes
));
700 scoped_ptr
<HttpStream
> aborted_stream(NewTestStream("aborts.html"));
701 scoped_ptr
<HttpStream
> evicted_stream(NewTestStream("evicted.html"));
703 HttpRequestHeaders headers
;
704 HttpResponseInfo response
;
705 TestCompletionCallback aborted_callback
;
706 EXPECT_EQ(ERR_IO_PENDING
,
707 aborted_stream
->SendRequest(headers
, &response
,
708 aborted_callback
.callback()));
709 TestCompletionCallback evicted_callback
;
710 EXPECT_EQ(ERR_IO_PENDING
,
711 evicted_stream
->SendRequest(headers
, &response
,
712 evicted_callback
.callback()));
714 aborted_stream
->Close(true);
715 EXPECT_EQ(ERR_PIPELINE_EVICTION
, evicted_callback
.WaitForResult());
716 evicted_stream
->Close(true);
717 EXPECT_FALSE(aborted_callback
.have_result());
720 TEST_F(HttpPipelinedConnectionImplTest
, AbortWhileSendingSecondRequest
) {
721 MockWrite writes
[] = {
722 MockWrite(ASYNC
, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
723 MockWrite(ASYNC
, 1, "GET /aborts.html HTTP/1.1\r\n\r\n"),
725 Initialize(NULL
, 0, writes
, arraysize(writes
));
727 scoped_ptr
<HttpStream
> ok_stream(NewTestStream("ok.html"));
728 scoped_ptr
<HttpStream
> aborted_stream(NewTestStream("aborts.html"));
729 scoped_ptr
<HttpStream
> evicted_stream(NewTestStream("evicted.html"));
731 HttpRequestHeaders headers
;
732 HttpResponseInfo response
;
733 TestCompletionCallback ok_callback
;
734 EXPECT_EQ(ERR_IO_PENDING
, ok_stream
->SendRequest(headers
, &response
,
735 ok_callback
.callback()));
736 TestCompletionCallback aborted_callback
;
737 EXPECT_EQ(ERR_IO_PENDING
,
738 aborted_stream
->SendRequest(headers
, &response
,
739 aborted_callback
.callback()));
740 TestCompletionCallback evicted_callback
;
741 EXPECT_EQ(ERR_IO_PENDING
,
742 evicted_stream
->SendRequest(headers
, &response
,
743 evicted_callback
.callback()));
746 EXPECT_LE(OK
, ok_callback
.WaitForResult());
747 base::MessageLoop::current()->RunUntilIdle();
748 aborted_stream
->Close(true);
749 EXPECT_EQ(ERR_PIPELINE_EVICTION
, evicted_callback
.WaitForResult());
750 evicted_stream
->Close(true);
751 EXPECT_FALSE(aborted_callback
.have_result());
752 ok_stream
->Close(true);
755 TEST_F(HttpPipelinedConnectionImplTest
, AbortWhileReadingHeaders
) {
756 MockWrite writes
[] = {
757 MockWrite(SYNCHRONOUS
, 0, "GET /aborts.html HTTP/1.1\r\n\r\n"),
758 MockWrite(SYNCHRONOUS
, 1, "GET /evicted.html HTTP/1.1\r\n\r\n"),
761 MockRead(ASYNC
, ERR_FAILED
, 2),
763 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
765 scoped_ptr
<HttpStream
> aborted_stream(NewTestStream("aborts.html"));
766 scoped_ptr
<HttpStream
> evicted_stream(NewTestStream("evicted.html"));
767 scoped_ptr
<HttpStream
> rejected_stream(NewTestStream("rejected.html"));
769 HttpRequestHeaders headers
;
770 HttpResponseInfo response
;
772 aborted_stream
->SendRequest(headers
, &response
,
773 callback_
.callback()));
775 evicted_stream
->SendRequest(headers
, &response
,
776 callback_
.callback()));
778 EXPECT_EQ(ERR_IO_PENDING
,
779 aborted_stream
->ReadResponseHeaders(callback_
.callback()));
780 TestCompletionCallback evicted_callback
;
781 EXPECT_EQ(ERR_IO_PENDING
,
782 evicted_stream
->ReadResponseHeaders(evicted_callback
.callback()));
784 aborted_stream
->Close(true);
785 EXPECT_EQ(ERR_PIPELINE_EVICTION
, evicted_callback
.WaitForResult());
786 evicted_stream
->Close(true);
788 EXPECT_EQ(ERR_PIPELINE_EVICTION
,
789 rejected_stream
->SendRequest(headers
, &response
,
790 callback_
.callback()));
791 rejected_stream
->Close(true);
794 TEST_F(HttpPipelinedConnectionImplTest
, PendingResponseAbandoned
) {
795 MockWrite writes
[] = {
796 MockWrite(SYNCHRONOUS
, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
797 MockWrite(SYNCHRONOUS
, 1, "GET /abandoned.html HTTP/1.1\r\n\r\n"),
798 MockWrite(SYNCHRONOUS
, 2, "GET /evicted.html HTTP/1.1\r\n\r\n"),
801 MockRead(SYNCHRONOUS
, 3, "HTTP/1.1 200 OK\r\n"),
802 MockRead(SYNCHRONOUS
, 4, "Content-Length: 7\r\n\r\n"),
803 MockRead(SYNCHRONOUS
, 5, "ok.html"),
805 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
807 scoped_ptr
<HttpStream
> ok_stream(NewTestStream("ok.html"));
808 scoped_ptr
<HttpStream
> abandoned_stream(NewTestStream("abandoned.html"));
809 scoped_ptr
<HttpStream
> evicted_stream(NewTestStream("evicted.html"));
811 HttpRequestHeaders headers
;
812 HttpResponseInfo response
;
813 EXPECT_EQ(OK
, ok_stream
->SendRequest(headers
, &response
,
814 callback_
.callback()));
815 EXPECT_EQ(OK
, abandoned_stream
->SendRequest(headers
, &response
,
816 callback_
.callback()));
817 EXPECT_EQ(OK
, evicted_stream
->SendRequest(headers
, &response
,
818 callback_
.callback()));
820 EXPECT_EQ(OK
, ok_stream
->ReadResponseHeaders(callback_
.callback()));
821 TestCompletionCallback abandoned_callback
;
822 EXPECT_EQ(ERR_IO_PENDING
, abandoned_stream
->ReadResponseHeaders(
823 abandoned_callback
.callback()));
824 TestCompletionCallback evicted_callback
;
825 EXPECT_EQ(ERR_IO_PENDING
,
826 evicted_stream
->ReadResponseHeaders(evicted_callback
.callback()));
828 abandoned_stream
->Close(false);
830 ExpectResponse("ok.html", ok_stream
, false);
831 ok_stream
->Close(false);
833 EXPECT_EQ(ERR_PIPELINE_EVICTION
, evicted_callback
.WaitForResult());
834 evicted_stream
->Close(true);
835 EXPECT_FALSE(evicted_stream
->IsConnectionReusable());
838 TEST_F(HttpPipelinedConnectionImplTest
, DisconnectedAfterOneRequestRecovery
) {
839 MockWrite writes
[] = {
840 MockWrite(SYNCHRONOUS
, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
841 MockWrite(SYNCHRONOUS
, 1, "GET /rejected.html HTTP/1.1\r\n\r\n"),
842 MockWrite(ASYNC
, ERR_SOCKET_NOT_CONNECTED
, 5),
843 MockWrite(SYNCHRONOUS
, ERR_SOCKET_NOT_CONNECTED
, 7),
846 MockRead(SYNCHRONOUS
, 2, "HTTP/1.1 200 OK\r\n"),
847 MockRead(SYNCHRONOUS
, 3, "Content-Length: 7\r\n\r\n"),
848 MockRead(SYNCHRONOUS
, 4, "ok.html"),
849 MockRead(SYNCHRONOUS
, ERR_SOCKET_NOT_CONNECTED
, 6),
851 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
853 scoped_ptr
<HttpStream
> ok_stream(NewTestStream("ok.html"));
854 scoped_ptr
<HttpStream
> rejected_read_stream(NewTestStream("rejected.html"));
855 scoped_ptr
<HttpStream
> evicted_send_stream(NewTestStream("evicted.html"));
856 scoped_ptr
<HttpStream
> rejected_send_stream(NewTestStream("rejected.html"));
858 HttpRequestHeaders headers
;
859 HttpResponseInfo response
;
860 EXPECT_EQ(OK
, ok_stream
->SendRequest(headers
,
861 &response
, callback_
.callback()));
862 EXPECT_EQ(OK
, rejected_read_stream
->SendRequest(headers
, &response
,
863 callback_
.callback()));
865 EXPECT_EQ(OK
, ok_stream
->ReadResponseHeaders(callback_
.callback()));
866 ExpectResponse("ok.html", ok_stream
, false);
867 ok_stream
->Close(false);
869 TestCompletionCallback read_callback
;
870 EXPECT_EQ(ERR_IO_PENDING
,
871 evicted_send_stream
->SendRequest(headers
, &response
,
872 read_callback
.callback()));
874 EXPECT_EQ(ERR_PIPELINE_EVICTION
, read_callback
.WaitForResult());
876 EXPECT_EQ(ERR_PIPELINE_EVICTION
,
877 rejected_read_stream
->ReadResponseHeaders(callback_
.callback()));
878 EXPECT_EQ(ERR_PIPELINE_EVICTION
,
879 rejected_send_stream
->SendRequest(headers
, &response
,
880 callback_
.callback()));
882 rejected_read_stream
->Close(true);
883 rejected_send_stream
->Close(true);
886 TEST_F(HttpPipelinedConnectionImplTest
, DisconnectedPendingReadRecovery
) {
887 MockWrite writes
[] = {
888 MockWrite(SYNCHRONOUS
, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
889 MockWrite(SYNCHRONOUS
, 1, "GET /evicted.html HTTP/1.1\r\n\r\n"),
892 MockRead(SYNCHRONOUS
, 2, "HTTP/1.1 200 OK\r\n"),
893 MockRead(SYNCHRONOUS
, 3, "Content-Length: 7\r\n\r\n"),
894 MockRead(SYNCHRONOUS
, 4, "ok.html"),
895 MockRead(SYNCHRONOUS
, ERR_SOCKET_NOT_CONNECTED
, 5),
897 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
899 scoped_ptr
<HttpStream
> ok_stream(NewTestStream("ok.html"));
900 scoped_ptr
<HttpStream
> evicted_stream(NewTestStream("evicted.html"));
902 HttpRequestHeaders headers
;
903 HttpResponseInfo response
;
904 EXPECT_EQ(OK
, ok_stream
->SendRequest(headers
,
905 &response
, callback_
.callback()));
906 EXPECT_EQ(OK
, evicted_stream
->SendRequest(headers
, &response
,
907 callback_
.callback()));
909 EXPECT_EQ(OK
, ok_stream
->ReadResponseHeaders(callback_
.callback()));
910 ExpectResponse("ok.html", ok_stream
, false);
912 TestCompletionCallback evicted_callback
;
913 EXPECT_EQ(ERR_IO_PENDING
,
914 evicted_stream
->ReadResponseHeaders(evicted_callback
.callback()));
916 ok_stream
->Close(false);
918 EXPECT_EQ(ERR_PIPELINE_EVICTION
, evicted_callback
.WaitForResult());
919 evicted_stream
->Close(false);
922 TEST_F(HttpPipelinedConnectionImplTest
, CloseCalledBeforeNextReadLoop
) {
923 MockWrite writes
[] = {
924 MockWrite(SYNCHRONOUS
, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
925 MockWrite(SYNCHRONOUS
, 1, "GET /evicted.html HTTP/1.1\r\n\r\n"),
928 MockRead(SYNCHRONOUS
, 2, "HTTP/1.1 200 OK\r\n"),
929 MockRead(SYNCHRONOUS
, 3, "Content-Length: 7\r\n\r\n"),
930 MockRead(SYNCHRONOUS
, 4, "ok.html"),
931 MockRead(SYNCHRONOUS
, ERR_SOCKET_NOT_CONNECTED
, 5),
933 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
935 scoped_ptr
<HttpStream
> ok_stream(NewTestStream("ok.html"));
936 scoped_ptr
<HttpStream
> evicted_stream(NewTestStream("evicted.html"));
938 HttpRequestHeaders headers
;
939 HttpResponseInfo response
;
940 EXPECT_EQ(OK
, ok_stream
->SendRequest(headers
,
941 &response
, callback_
.callback()));
942 EXPECT_EQ(OK
, evicted_stream
->SendRequest(headers
, &response
,
943 callback_
.callback()));
945 EXPECT_EQ(OK
, ok_stream
->ReadResponseHeaders(callback_
.callback()));
946 ExpectResponse("ok.html", ok_stream
, false);
948 TestCompletionCallback evicted_callback
;
949 EXPECT_EQ(ERR_IO_PENDING
,
950 evicted_stream
->ReadResponseHeaders(evicted_callback
.callback()));
952 ok_stream
->Close(false);
953 evicted_stream
->Close(false);
956 TEST_F(HttpPipelinedConnectionImplTest
, CloseCalledBeforeReadCallback
) {
957 MockWrite writes
[] = {
958 MockWrite(SYNCHRONOUS
, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
959 MockWrite(SYNCHRONOUS
, 1, "GET /evicted.html HTTP/1.1\r\n\r\n"),
962 MockRead(SYNCHRONOUS
, 2, "HTTP/1.1 200 OK\r\n"),
963 MockRead(SYNCHRONOUS
, 3, "Content-Length: 7\r\n\r\n"),
964 MockRead(SYNCHRONOUS
, 4, "ok.html"),
965 MockRead(SYNCHRONOUS
, ERR_SOCKET_NOT_CONNECTED
, 5),
967 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
969 scoped_ptr
<HttpStream
> ok_stream(NewTestStream("ok.html"));
970 scoped_ptr
<HttpStream
> evicted_stream(NewTestStream("evicted.html"));
972 HttpRequestHeaders headers
;
973 HttpResponseInfo response
;
974 EXPECT_EQ(OK
, ok_stream
->SendRequest(headers
,
975 &response
, callback_
.callback()));
976 EXPECT_EQ(OK
, evicted_stream
->SendRequest(headers
, &response
,
977 callback_
.callback()));
979 EXPECT_EQ(OK
, ok_stream
->ReadResponseHeaders(callback_
.callback()));
980 ExpectResponse("ok.html", ok_stream
, false);
982 TestCompletionCallback evicted_callback
;
983 EXPECT_EQ(ERR_IO_PENDING
,
984 evicted_stream
->ReadResponseHeaders(evicted_callback
.callback()));
986 ok_stream
->Close(false);
988 // The posted tasks should be:
989 // 1. DoReadHeadersLoop, which will post:
990 // 2. InvokeUserCallback
991 SuddenCloseObserver
observer(evicted_stream
.get(), 2);
992 base::MessageLoop::current()->AddTaskObserver(&observer
);
993 base::MessageLoop::current()->RunUntilIdle();
994 EXPECT_FALSE(evicted_callback
.have_result());
997 class StreamDeleter
{
999 StreamDeleter(HttpStream
* stream
)
1001 callback_(base::Bind(&StreamDeleter::OnIOComplete
,
1002 base::Unretained(this))) {
1006 EXPECT_FALSE(stream_
);
1009 const CompletionCallback
& callback() { return callback_
; }
1012 void OnIOComplete(int result
) {
1013 stream_
->Close(true);
1017 scoped_ptr
<HttpStream
> stream_
;
1018 CompletionCallback callback_
;
1021 TEST_F(HttpPipelinedConnectionImplTest
, CloseCalledDuringSendCallback
) {
1022 MockWrite writes
[] = {
1023 MockWrite(ASYNC
, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
1025 Initialize(NULL
, 0, writes
, arraysize(writes
));
1027 HttpStream
* stream(NewTestStream("ok.html"));
1029 StreamDeleter
deleter(stream
);
1030 HttpRequestHeaders headers
;
1031 HttpResponseInfo response
;
1032 EXPECT_EQ(ERR_IO_PENDING
, stream
->SendRequest(headers
, &response
,
1033 deleter
.callback()));
1037 TEST_F(HttpPipelinedConnectionImplTest
, CloseCalledDuringReadCallback
) {
1038 MockWrite writes
[] = {
1039 MockWrite(SYNCHRONOUS
, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
1041 MockRead reads
[] = {
1042 MockRead(SYNCHRONOUS
, 1, "HTTP/1.1 200 OK\r\n"),
1043 MockRead(ASYNC
, 2, "Content-Length: 7\r\n\r\n"),
1045 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1047 HttpStream
* stream(NewTestStream("ok.html"));
1049 HttpRequestHeaders headers
;
1050 HttpResponseInfo response
;
1051 EXPECT_EQ(OK
, stream
->SendRequest(headers
,
1052 &response
, callback_
.callback()));
1054 StreamDeleter
deleter(stream
);
1055 EXPECT_EQ(ERR_IO_PENDING
, stream
->ReadResponseHeaders(deleter
.callback()));
1059 TEST_F(HttpPipelinedConnectionImplTest
,
1060 CloseCalledDuringReadCallbackWithPendingRead
) {
1061 MockWrite writes
[] = {
1062 MockWrite(SYNCHRONOUS
, 0, "GET /failed.html HTTP/1.1\r\n\r\n"),
1063 MockWrite(SYNCHRONOUS
, 1, "GET /evicted.html HTTP/1.1\r\n\r\n"),
1065 MockRead reads
[] = {
1066 MockRead(SYNCHRONOUS
, 2, "HTTP/1.1 200 OK\r\n"),
1067 MockRead(ASYNC
, 3, "Content-Length: 7\r\n\r\n"),
1069 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1071 HttpStream
* failed_stream(NewTestStream("failed.html"));
1072 HttpStream
* evicted_stream(NewTestStream("evicted.html"));
1074 HttpRequestHeaders headers
;
1075 HttpResponseInfo response
;
1076 EXPECT_EQ(OK
, failed_stream
->SendRequest(headers
, &response
,
1077 callback_
.callback()));
1078 EXPECT_EQ(OK
, evicted_stream
->SendRequest(headers
, &response
,
1079 callback_
.callback()));
1081 StreamDeleter
failed_deleter(failed_stream
);
1082 EXPECT_EQ(ERR_IO_PENDING
,
1083 failed_stream
->ReadResponseHeaders(failed_deleter
.callback()));
1084 StreamDeleter
evicted_deleter(evicted_stream
);
1085 EXPECT_EQ(ERR_IO_PENDING
,
1086 evicted_stream
->ReadResponseHeaders(evicted_deleter
.callback()));
1090 TEST_F(HttpPipelinedConnectionImplTest
, CloseOtherDuringReadCallback
) {
1091 MockWrite writes
[] = {
1092 MockWrite(SYNCHRONOUS
, 0, "GET /deleter.html HTTP/1.1\r\n\r\n"),
1093 MockWrite(SYNCHRONOUS
, 1, "GET /deleted.html HTTP/1.1\r\n\r\n"),
1095 MockRead reads
[] = {
1096 MockRead(SYNCHRONOUS
, 2, "HTTP/1.1 200 OK\r\n"),
1097 MockRead(ASYNC
, 3, "Content-Length: 7\r\n\r\n"),
1099 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1101 scoped_ptr
<HttpStream
> deleter_stream(NewTestStream("deleter.html"));
1102 HttpStream
* deleted_stream(NewTestStream("deleted.html"));
1104 HttpRequestHeaders headers
;
1105 HttpResponseInfo response
;
1106 EXPECT_EQ(OK
, deleter_stream
->SendRequest(headers
,
1107 &response
, callback_
.callback()));
1108 EXPECT_EQ(OK
, deleted_stream
->SendRequest(headers
,
1109 &response
, callback_
.callback()));
1111 StreamDeleter
deleter(deleted_stream
);
1112 EXPECT_EQ(ERR_IO_PENDING
,
1113 deleter_stream
->ReadResponseHeaders(deleter
.callback()));
1114 EXPECT_EQ(ERR_IO_PENDING
,
1115 deleted_stream
->ReadResponseHeaders(callback_
.callback()));
1119 TEST_F(HttpPipelinedConnectionImplTest
, CloseBeforeSendCallbackRuns
) {
1120 MockWrite writes
[] = {
1121 MockWrite(ASYNC
, 0, "GET /close.html HTTP/1.1\r\n\r\n"),
1122 MockWrite(ASYNC
, 1, "GET /dummy.html HTTP/1.1\r\n\r\n"),
1124 Initialize(NULL
, 0, writes
, arraysize(writes
));
1126 scoped_ptr
<HttpStream
> close_stream(NewTestStream("close.html"));
1127 scoped_ptr
<HttpStream
> dummy_stream(NewTestStream("dummy.html"));
1129 scoped_ptr
<TestCompletionCallback
> close_callback(
1130 new TestCompletionCallback
);
1131 HttpRequestHeaders headers
;
1132 HttpResponseInfo response
;
1133 EXPECT_EQ(ERR_IO_PENDING
,
1134 close_stream
->SendRequest(headers
,
1135 &response
, close_callback
->callback()));
1138 EXPECT_FALSE(close_callback
->have_result());
1140 close_stream
->Close(false);
1141 close_stream
.reset();
1142 close_callback
.reset();
1144 base::MessageLoop::current()->RunUntilIdle();
1147 TEST_F(HttpPipelinedConnectionImplTest
, CloseBeforeReadCallbackRuns
) {
1148 MockWrite writes
[] = {
1149 MockWrite(SYNCHRONOUS
, 0, "GET /close.html HTTP/1.1\r\n\r\n"),
1150 MockWrite(SYNCHRONOUS
, 3, "GET /dummy.html HTTP/1.1\r\n\r\n"),
1152 MockRead reads
[] = {
1153 MockRead(SYNCHRONOUS
, 1, "HTTP/1.1 200 OK\r\n"),
1154 MockRead(ASYNC
, 2, "Content-Length: 7\r\n\r\n"),
1156 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1158 scoped_ptr
<HttpStream
> close_stream(NewTestStream("close.html"));
1159 scoped_ptr
<HttpStream
> dummy_stream(NewTestStream("dummy.html"));
1161 HttpRequestHeaders headers
;
1162 HttpResponseInfo response
;
1163 EXPECT_EQ(OK
, close_stream
->SendRequest(headers
,
1164 &response
, callback_
.callback()));
1166 scoped_ptr
<TestCompletionCallback
> close_callback(
1167 new TestCompletionCallback
);
1168 EXPECT_EQ(ERR_IO_PENDING
,
1169 close_stream
->ReadResponseHeaders(close_callback
->callback()));
1172 EXPECT_FALSE(close_callback
->have_result());
1174 close_stream
->Close(false);
1175 close_stream
.reset();
1176 close_callback
.reset();
1178 base::MessageLoop::current()->RunUntilIdle();
1181 TEST_F(HttpPipelinedConnectionImplTest
, AbortWhileSendQueued
) {
1182 MockWrite writes
[] = {
1183 MockWrite(ASYNC
, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
1184 MockWrite(ASYNC
, 1, "GET /ko.html HTTP/1.1\r\n\r\n"),
1186 Initialize(NULL
, 0, writes
, arraysize(writes
));
1188 scoped_ptr
<HttpStream
> stream1(NewTestStream("ok.html"));
1189 scoped_ptr
<HttpStream
> stream2(NewTestStream("ko.html"));
1191 HttpRequestHeaders headers1
;
1192 HttpResponseInfo response1
;
1193 TestCompletionCallback callback1
;
1194 EXPECT_EQ(ERR_IO_PENDING
, stream1
->SendRequest(headers1
, &response1
,
1195 callback1
.callback()));
1197 HttpRequestHeaders headers2
;
1198 HttpResponseInfo response2
;
1199 TestCompletionCallback callback2
;
1200 EXPECT_EQ(ERR_IO_PENDING
, stream2
->SendRequest(headers2
, &response2
,
1201 callback2
.callback()));
1204 stream1
->Close(true);
1206 EXPECT_FALSE(callback2
.have_result());
1209 TEST_F(HttpPipelinedConnectionImplTest
, NoGapBetweenCloseAndEviction
) {
1210 MockWrite writes
[] = {
1211 MockWrite(SYNCHRONOUS
, 0, "GET /close.html HTTP/1.1\r\n\r\n"),
1212 MockWrite(SYNCHRONOUS
, 2, "GET /dummy.html HTTP/1.1\r\n\r\n"),
1214 MockRead reads
[] = {
1215 MockRead(SYNCHRONOUS
, 1, "HTTP/1.1 200 OK\r\n"),
1216 MockRead(ASYNC
, 3, "Content-Length: 7\r\n\r\n"),
1218 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1220 scoped_ptr
<HttpStream
> close_stream(NewTestStream("close.html"));
1221 scoped_ptr
<HttpStream
> dummy_stream(NewTestStream("dummy.html"));
1223 HttpRequestHeaders headers
;
1224 HttpResponseInfo response
;
1225 EXPECT_EQ(OK
, close_stream
->SendRequest(headers
, &response
,
1226 callback_
.callback()));
1228 TestCompletionCallback close_callback
;
1229 EXPECT_EQ(ERR_IO_PENDING
,
1230 close_stream
->ReadResponseHeaders(close_callback
.callback()));
1232 EXPECT_EQ(OK
, dummy_stream
->SendRequest(headers
, &response
,
1233 callback_
.callback()));
1235 TestCompletionCallback dummy_callback
;
1236 EXPECT_EQ(ERR_IO_PENDING
,
1237 dummy_stream
->ReadResponseHeaders(dummy_callback
.callback()));
1239 close_stream
->Close(true);
1240 close_stream
.reset();
1242 EXPECT_TRUE(dummy_callback
.have_result());
1243 EXPECT_EQ(ERR_PIPELINE_EVICTION
, dummy_callback
.WaitForResult());
1244 dummy_stream
->Close(true);
1245 dummy_stream
.reset();
1249 TEST_F(HttpPipelinedConnectionImplTest
, RecoverFromDrainOnRedirect
) {
1250 MockWrite writes
[] = {
1251 MockWrite(SYNCHRONOUS
, 0, "GET /redirect.html HTTP/1.1\r\n\r\n"),
1252 MockWrite(SYNCHRONOUS
, 1, "GET /ok.html HTTP/1.1\r\n\r\n"),
1254 MockRead reads
[] = {
1255 MockRead(SYNCHRONOUS
, 2,
1256 "HTTP/1.1 302 OK\r\n"
1257 "Content-Length: 8\r\n\r\n"
1259 MockRead(SYNCHRONOUS
, 3,
1260 "HTTP/1.1 200 OK\r\n"
1261 "Content-Length: 7\r\n\r\n"
1264 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1266 scoped_ptr
<HttpStream
> stream1(NewTestStream("redirect.html"));
1267 scoped_ptr
<HttpStream
> stream2(NewTestStream("ok.html"));
1269 HttpRequestHeaders headers1
;
1270 HttpResponseInfo response1
;
1271 EXPECT_EQ(OK
, stream1
->SendRequest(headers1
,
1272 &response1
, callback_
.callback()));
1273 HttpRequestHeaders headers2
;
1274 HttpResponseInfo response2
;
1275 EXPECT_EQ(OK
, stream2
->SendRequest(headers2
,
1276 &response2
, callback_
.callback()));
1278 EXPECT_EQ(OK
, stream1
->ReadResponseHeaders(callback_
.callback()));
1279 stream1
.release()->Drain(NULL
);
1281 EXPECT_EQ(OK
, stream2
->ReadResponseHeaders(callback_
.callback()));
1282 ExpectResponse("ok.html", stream2
, false);
1283 stream2
->Close(false);
1286 TEST_F(HttpPipelinedConnectionImplTest
, EvictAfterDrainOfUnknownSize
) {
1287 MockWrite writes
[] = {
1288 MockWrite(SYNCHRONOUS
, 0, "GET /redirect.html HTTP/1.1\r\n\r\n"),
1289 MockWrite(SYNCHRONOUS
, 1, "GET /ok.html HTTP/1.1\r\n\r\n"),
1291 MockRead reads
[] = {
1292 MockRead(SYNCHRONOUS
, 2,
1293 "HTTP/1.1 302 OK\r\n\r\n"
1296 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1298 scoped_ptr
<HttpStream
> stream1(NewTestStream("redirect.html"));
1299 scoped_ptr
<HttpStream
> stream2(NewTestStream("ok.html"));
1301 HttpRequestHeaders headers1
;
1302 HttpResponseInfo response1
;
1303 EXPECT_EQ(OK
, stream1
->SendRequest(headers1
,
1304 &response1
, callback_
.callback()));
1305 HttpRequestHeaders headers2
;
1306 HttpResponseInfo response2
;
1307 EXPECT_EQ(OK
, stream2
->SendRequest(headers2
,
1308 &response2
, callback_
.callback()));
1310 EXPECT_EQ(OK
, stream1
->ReadResponseHeaders(callback_
.callback()));
1311 stream1
.release()->Drain(NULL
);
1313 EXPECT_EQ(ERR_PIPELINE_EVICTION
,
1314 stream2
->ReadResponseHeaders(callback_
.callback()));
1315 stream2
->Close(false);
1318 TEST_F(HttpPipelinedConnectionImplTest
, EvictAfterFailedDrain
) {
1319 MockWrite writes
[] = {
1320 MockWrite(SYNCHRONOUS
, 0, "GET /redirect.html HTTP/1.1\r\n\r\n"),
1321 MockWrite(SYNCHRONOUS
, 1, "GET /ok.html HTTP/1.1\r\n\r\n"),
1323 MockRead reads
[] = {
1324 MockRead(SYNCHRONOUS
, 2,
1325 "HTTP/1.1 302 OK\r\n"
1326 "Content-Length: 8\r\n\r\n"),
1327 MockRead(SYNCHRONOUS
, ERR_SOCKET_NOT_CONNECTED
, 3),
1329 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1331 scoped_ptr
<HttpStream
> stream1(NewTestStream("redirect.html"));
1332 scoped_ptr
<HttpStream
> stream2(NewTestStream("ok.html"));
1334 HttpRequestHeaders headers1
;
1335 HttpResponseInfo response1
;
1336 EXPECT_EQ(OK
, stream1
->SendRequest(headers1
,
1337 &response1
, callback_
.callback()));
1338 HttpRequestHeaders headers2
;
1339 HttpResponseInfo response2
;
1340 EXPECT_EQ(OK
, stream2
->SendRequest(headers2
,
1341 &response2
, callback_
.callback()));
1344 EXPECT_EQ(OK
, stream1
->ReadResponseHeaders(callback_
.callback()));
1345 stream1
.release()->Drain(NULL
);
1347 EXPECT_EQ(ERR_PIPELINE_EVICTION
,
1348 stream2
->ReadResponseHeaders(callback_
.callback()));
1349 stream2
->Close(false);
1352 TEST_F(HttpPipelinedConnectionImplTest
, EvictIfDrainingChunkedEncoding
) {
1353 MockWrite writes
[] = {
1354 MockWrite(SYNCHRONOUS
, 0, "GET /redirect.html HTTP/1.1\r\n\r\n"),
1355 MockWrite(SYNCHRONOUS
, 1, "GET /ok.html HTTP/1.1\r\n\r\n"),
1357 MockRead reads
[] = {
1358 MockRead(SYNCHRONOUS
, 2,
1359 "HTTP/1.1 302 OK\r\n"
1360 "Transfer-Encoding: chunked\r\n\r\n"),
1361 MockRead(SYNCHRONOUS
, 3,
1364 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1366 scoped_ptr
<HttpStream
> stream1(NewTestStream("redirect.html"));
1367 scoped_ptr
<HttpStream
> stream2(NewTestStream("ok.html"));
1369 HttpRequestHeaders headers1
;
1370 HttpResponseInfo response1
;
1371 EXPECT_EQ(OK
, stream1
->SendRequest(headers1
,
1372 &response1
, callback_
.callback()));
1373 HttpRequestHeaders headers2
;
1374 HttpResponseInfo response2
;
1375 EXPECT_EQ(OK
, stream2
->SendRequest(headers2
,
1376 &response2
, callback_
.callback()));
1379 EXPECT_EQ(OK
, stream1
->ReadResponseHeaders(callback_
.callback()));
1380 stream1
.release()->Drain(NULL
);
1382 EXPECT_EQ(ERR_PIPELINE_EVICTION
,
1383 stream2
->ReadResponseHeaders(callback_
.callback()));
1384 stream2
->Close(false);
1387 TEST_F(HttpPipelinedConnectionImplTest
, EvictionDueToMissingContentLength
) {
1388 MockWrite writes
[] = {
1389 MockWrite(SYNCHRONOUS
, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
1390 MockWrite(SYNCHRONOUS
, 1, "GET /evicted.html HTTP/1.1\r\n\r\n"),
1391 MockWrite(SYNCHRONOUS
, 2, "GET /rejected.html HTTP/1.1\r\n\r\n"),
1393 MockRead reads
[] = {
1394 MockRead(ASYNC
, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1395 MockRead(SYNCHRONOUS
, 4, "ok.html"),
1396 MockRead(SYNCHRONOUS
, OK
, 5),
1398 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1400 scoped_ptr
<HttpStream
> ok_stream(NewTestStream("ok.html"));
1401 scoped_ptr
<HttpStream
> evicted_stream(NewTestStream("evicted.html"));
1402 scoped_ptr
<HttpStream
> rejected_stream(NewTestStream("rejected.html"));
1404 HttpRequestHeaders headers
;
1405 HttpResponseInfo response
;
1406 EXPECT_EQ(OK
, ok_stream
->SendRequest(headers
,
1407 &response
, callback_
.callback()));
1408 EXPECT_EQ(OK
, evicted_stream
->SendRequest(headers
,
1409 &response
, callback_
.callback()));
1410 EXPECT_EQ(OK
, rejected_stream
->SendRequest(headers
,
1411 &response
, callback_
.callback()));
1413 TestCompletionCallback ok_callback
;
1414 EXPECT_EQ(ERR_IO_PENDING
,
1415 ok_stream
->ReadResponseHeaders(ok_callback
.callback()));
1417 TestCompletionCallback evicted_callback
;
1418 EXPECT_EQ(ERR_IO_PENDING
,
1419 evicted_stream
->ReadResponseHeaders(evicted_callback
.callback()));
1422 EXPECT_LE(OK
, ok_callback
.WaitForResult());
1423 data_
->StopAfter(10);
1425 ExpectResponse("ok.html", ok_stream
, false);
1426 ok_stream
->Close(false);
1428 EXPECT_EQ(ERR_PIPELINE_EVICTION
,
1429 rejected_stream
->ReadResponseHeaders(callback_
.callback()));
1430 rejected_stream
->Close(true);
1431 EXPECT_EQ(ERR_PIPELINE_EVICTION
, evicted_callback
.WaitForResult());
1432 evicted_stream
->Close(true);
1435 TEST_F(HttpPipelinedConnectionImplTest
, FeedbackOnSocketError
) {
1436 MockWrite writes
[] = {
1437 MockWrite(SYNCHRONOUS
, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
1439 MockRead reads
[] = {
1440 MockRead(SYNCHRONOUS
, ERR_FAILED
, 1),
1442 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1444 EXPECT_CALL(delegate_
,
1447 HttpPipelinedConnection::PIPELINE_SOCKET_ERROR
))
1450 scoped_ptr
<HttpStream
> stream(NewTestStream("ok.html"));
1451 HttpRequestHeaders headers
;
1452 HttpResponseInfo response
;
1453 EXPECT_EQ(OK
, stream
->SendRequest(headers
,
1454 &response
, callback_
.callback()));
1455 EXPECT_EQ(ERR_FAILED
, stream
->ReadResponseHeaders(callback_
.callback()));
1458 TEST_F(HttpPipelinedConnectionImplTest
, FeedbackOnNoInternetConnection
) {
1459 MockWrite writes
[] = {
1460 MockWrite(SYNCHRONOUS
, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
1462 MockRead reads
[] = {
1463 MockRead(SYNCHRONOUS
, ERR_INTERNET_DISCONNECTED
, 1),
1465 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1467 EXPECT_CALL(delegate_
, OnPipelineFeedback(_
, _
))
1470 scoped_ptr
<HttpStream
> stream(NewTestStream("ok.html"));
1471 HttpRequestHeaders headers
;
1472 HttpResponseInfo response
;
1473 EXPECT_EQ(OK
, stream
->SendRequest(headers
,
1474 &response
, callback_
.callback()));
1475 EXPECT_EQ(ERR_INTERNET_DISCONNECTED
,
1476 stream
->ReadResponseHeaders(callback_
.callback()));
1479 TEST_F(HttpPipelinedConnectionImplTest
, FeedbackOnHttp10
) {
1480 MockWrite writes
[] = {
1481 MockWrite(SYNCHRONOUS
, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
1483 MockRead reads
[] = {
1484 MockRead(SYNCHRONOUS
, 1, "HTTP/1.0 200 OK\r\n"),
1485 MockRead(SYNCHRONOUS
, 2, "Content-Length: 7\r\n"),
1486 MockRead(SYNCHRONOUS
, 3, "Connection: keep-alive\r\n\r\n"),
1487 MockRead(SYNCHRONOUS
, 4, "ok.html"),
1489 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1491 EXPECT_CALL(delegate_
,
1492 OnPipelineFeedback(pipeline_
.get(),
1493 HttpPipelinedConnection::OLD_HTTP_VERSION
))
1496 scoped_ptr
<HttpStream
> stream(NewTestStream("ok.html"));
1497 TestSyncRequest(stream
, "ok.html");
1500 TEST_F(HttpPipelinedConnectionImplTest
, FeedbackOnMustClose
) {
1501 MockWrite writes
[] = {
1502 MockWrite(SYNCHRONOUS
, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
1504 MockRead reads
[] = {
1505 MockRead(SYNCHRONOUS
, 1, "HTTP/1.1 200 OK\r\n"),
1506 MockRead(SYNCHRONOUS
, 2, "Content-Length: 7\r\n"),
1507 MockRead(SYNCHRONOUS
, 3, "Connection: close\r\n\r\n"),
1508 MockRead(SYNCHRONOUS
, 4, "ok.html"),
1510 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1512 EXPECT_CALL(delegate_
,
1515 HttpPipelinedConnection::MUST_CLOSE_CONNECTION
))
1518 scoped_ptr
<HttpStream
> stream(NewTestStream("ok.html"));
1519 TestSyncRequest(stream
, "ok.html");
1522 TEST_F(HttpPipelinedConnectionImplTest
, FeedbackOnNoContentLength
) {
1523 MockWrite writes
[] = {
1524 MockWrite(SYNCHRONOUS
, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
1526 MockRead reads
[] = {
1527 MockRead(SYNCHRONOUS
, 1, "HTTP/1.1 200 OK\r\n\r\n"),
1528 MockRead(SYNCHRONOUS
, 2, "ok.html"),
1530 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1532 EXPECT_CALL(delegate_
,
1535 HttpPipelinedConnection::MUST_CLOSE_CONNECTION
))
1538 scoped_ptr
<HttpStream
> stream(NewTestStream("ok.html"));
1539 TestSyncRequest(stream
, "ok.html");
1542 TEST_F(HttpPipelinedConnectionImplTest
, FeedbackOnAuthenticationRequired
) {
1543 MockWrite writes
[] = {
1544 MockWrite(SYNCHRONOUS
, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
1546 MockRead reads
[] = {
1547 MockRead(SYNCHRONOUS
, 1, "HTTP/1.1 401 Unauthorized\r\n"),
1548 MockRead(SYNCHRONOUS
, 2, "WWW-Authenticate: NTLM\r\n"),
1549 MockRead(SYNCHRONOUS
, 3, "Content-Length: 7\r\n\r\n"),
1550 MockRead(SYNCHRONOUS
, 4, "ok.html"),
1552 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1554 EXPECT_CALL(delegate_
,
1557 HttpPipelinedConnection::AUTHENTICATION_REQUIRED
))
1560 scoped_ptr
<HttpStream
> stream(NewTestStream("ok.html"));
1561 TestSyncRequest(stream
, "ok.html");
1564 TEST_F(HttpPipelinedConnectionImplTest
, OnPipelineHasCapacity
) {
1565 MockWrite writes
[] = {
1566 MockWrite(SYNCHRONOUS
, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
1568 Initialize(NULL
, 0, writes
, arraysize(writes
));
1570 EXPECT_CALL(delegate_
, OnPipelineHasCapacity(pipeline_
.get())).Times(0);
1571 scoped_ptr
<HttpStream
> stream(NewTestStream("ok.html"));
1573 EXPECT_CALL(delegate_
, OnPipelineHasCapacity(pipeline_
.get())).Times(1);
1574 HttpRequestHeaders headers
;
1575 HttpResponseInfo response
;
1576 EXPECT_EQ(OK
, stream
->SendRequest(headers
,
1577 &response
, callback_
.callback()));
1579 EXPECT_CALL(delegate_
, OnPipelineHasCapacity(pipeline_
.get())).Times(0);
1580 base::MessageLoop::current()->RunUntilIdle();
1582 stream
->Close(false);
1583 EXPECT_CALL(delegate_
, OnPipelineHasCapacity(pipeline_
.get())).Times(1);
1587 TEST_F(HttpPipelinedConnectionImplTest
, OnPipelineHasCapacityWithoutSend
) {
1588 MockWrite writes
[] = {
1589 MockWrite(SYNCHRONOUS
, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
1591 Initialize(NULL
, 0, writes
, arraysize(writes
));
1593 EXPECT_CALL(delegate_
, OnPipelineHasCapacity(pipeline_
.get())).Times(0);
1594 scoped_ptr
<HttpStream
> stream(NewTestStream("ok.html"));
1596 EXPECT_CALL(delegate_
, OnPipelineHasCapacity(pipeline_
.get())).Times(1);
1597 base::MessageLoop::current()->RunUntilIdle();
1599 stream
->Close(false);
1600 EXPECT_CALL(delegate_
, OnPipelineHasCapacity(pipeline_
.get())).Times(1);
1604 } // anonymous namespace