Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(558)

Side by Side Diff: net/http/http_pipelined_connection_impl_unittest.cc

Issue 275953002: Remove HTTP pipelining support. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merge Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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.
4
5 #include "net/http/http_pipelined_connection_impl.h"
6
7 #include <string>
8
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"
24
25 using testing::_;
26 using testing::NiceMock;
27 using testing::StrEq;
28
29 namespace net {
30
31 namespace {
32
33 // Tests the load timing of a stream that's connected and is not the first
34 // request sent on a connection.
35 void TestLoadTimingReused(const HttpStream& stream) {
36 LoadTimingInfo load_timing_info;
37 EXPECT_TRUE(stream.GetLoadTimingInfo(&load_timing_info));
38
39 EXPECT_TRUE(load_timing_info.socket_reused);
40 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
41
42 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
43 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
44 }
45
46 // Tests the load timing of a stream that's connected and using a fresh
47 // connection.
48 void TestLoadTimingNotReused(const HttpStream& stream) {
49 LoadTimingInfo load_timing_info;
50 EXPECT_TRUE(stream.GetLoadTimingInfo(&load_timing_info));
51
52 EXPECT_FALSE(load_timing_info.socket_reused);
53 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
54
55 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
56 CONNECT_TIMING_HAS_DNS_TIMES);
57 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
58 }
59
60 class MockPipelineDelegate : public HttpPipelinedConnection::Delegate {
61 public:
62 MOCK_METHOD1(OnPipelineHasCapacity, void(HttpPipelinedConnection* pipeline));
63 MOCK_METHOD2(OnPipelineFeedback, void(
64 HttpPipelinedConnection* pipeline,
65 HttpPipelinedConnection::Feedback feedback));
66 };
67
68 class SuddenCloseObserver : public base::MessageLoop::TaskObserver {
69 public:
70 SuddenCloseObserver(HttpStream* stream, int close_before_task)
71 : stream_(stream),
72 close_before_task_(close_before_task),
73 current_task_(0) { }
74
75 virtual void WillProcessTask(const base::PendingTask& pending_task) OVERRIDE {
76 ++current_task_;
77 if (current_task_ == close_before_task_) {
78 stream_->Close(false);
79 base::MessageLoop::current()->RemoveTaskObserver(this);
80 }
81 }
82
83 virtual void DidProcessTask(const base::PendingTask& pending_task) OVERRIDE {}
84
85 private:
86 HttpStream* stream_;
87 int close_before_task_;
88 int current_task_;
89 };
90
91 class HttpPipelinedConnectionImplTest : public testing::Test {
92 public:
93 HttpPipelinedConnectionImplTest()
94 : histograms_("a"),
95 pool_(1, 1, &histograms_, &factory_),
96 origin_("host", 123) {
97 }
98
99 void TearDown() {
100 base::MessageLoop::current()->RunUntilIdle();
101 }
102
103 void Initialize(MockRead* reads, size_t reads_count,
104 MockWrite* writes, size_t writes_count) {
105 data_.reset(new DeterministicSocketData(reads, reads_count,
106 writes, writes_count));
107 data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
108 if (reads_count || writes_count) {
109 data_->StopAfter(reads_count + writes_count);
110 }
111 factory_.AddSocketDataProvider(data_.get());
112 scoped_refptr<MockTransportSocketParams> params;
113 ClientSocketHandle* connection = new ClientSocketHandle;
114 // Only give the connection a real NetLog to make sure that LoadTiming uses
115 // the connection's ID, rather than the pipeline's. Since pipelines are
116 // destroyed when they've responded to all requests, but the connection
117 // lives on, this is an important behavior.
118 connection->Init("a", params, MEDIUM, CompletionCallback(), &pool_,
119 net_log_.bound());
120 pipeline_.reset(new HttpPipelinedConnectionImpl(
121 connection, &delegate_, origin_, ssl_config_, proxy_info_,
122 BoundNetLog(), false, kProtoUnknown));
123 }
124
125 HttpRequestInfo* GetRequestInfo(const std::string& filename) {
126 HttpRequestInfo* request_info = new HttpRequestInfo;
127 request_info->url = GURL("http://localhost/" + filename);
128 request_info->method = "GET";
129 request_info_vector_.push_back(request_info);
130 return request_info;
131 }
132
133 HttpStream* NewTestStream(const std::string& filename) {
134 HttpStream* stream = pipeline_->CreateNewStream();
135 HttpRequestInfo* request_info = GetRequestInfo(filename);
136 int rv = stream->InitializeStream(
137 request_info, DEFAULT_PRIORITY, BoundNetLog(), CompletionCallback());
138 DCHECK_EQ(OK, rv);
139 return stream;
140 }
141
142 void ExpectResponse(const std::string& expected,
143 scoped_ptr<HttpStream>& stream, bool async) {
144 scoped_refptr<IOBuffer> buffer(new IOBuffer(expected.size()));
145
146 if (async) {
147 EXPECT_EQ(ERR_IO_PENDING,
148 stream->ReadResponseBody(buffer.get(), expected.size(),
149 callback_.callback()));
150 data_->RunFor(1);
151 EXPECT_EQ(static_cast<int>(expected.size()), callback_.WaitForResult());
152 } else {
153 EXPECT_EQ(static_cast<int>(expected.size()),
154 stream->ReadResponseBody(buffer.get(), expected.size(),
155 callback_.callback()));
156 }
157 std::string actual(buffer->data(), expected.size());
158 EXPECT_THAT(actual, StrEq(expected));
159 }
160
161 void TestSyncRequest(scoped_ptr<HttpStream>& stream,
162 const std::string& filename) {
163 HttpRequestHeaders headers;
164 HttpResponseInfo response;
165 EXPECT_EQ(OK, stream->SendRequest(headers, &response,
166 callback_.callback()));
167 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
168 ExpectResponse(filename, stream, false);
169
170 stream->Close(false);
171 }
172
173 CapturingBoundNetLog net_log_;
174 DeterministicMockClientSocketFactory factory_;
175 ClientSocketPoolHistograms histograms_;
176 MockTransportClientSocketPool pool_;
177 scoped_ptr<DeterministicSocketData> data_;
178
179 HostPortPair origin_;
180 SSLConfig ssl_config_;
181 ProxyInfo proxy_info_;
182 NiceMock<MockPipelineDelegate> delegate_;
183 TestCompletionCallback callback_;
184 scoped_ptr<HttpPipelinedConnectionImpl> pipeline_;
185 ScopedVector<HttpRequestInfo> request_info_vector_;
186 };
187
188 TEST_F(HttpPipelinedConnectionImplTest, PipelineNotUsed) {
189 Initialize(NULL, 0, NULL, 0);
190 }
191
192 TEST_F(HttpPipelinedConnectionImplTest, StreamNotUsed) {
193 Initialize(NULL, 0, NULL, 0);
194
195 scoped_ptr<HttpStream> stream(pipeline_->CreateNewStream());
196
197 stream->Close(false);
198 }
199
200 TEST_F(HttpPipelinedConnectionImplTest, StreamBoundButNotUsed) {
201 Initialize(NULL, 0, NULL, 0);
202
203 scoped_ptr<HttpStream> stream(NewTestStream("ok.html"));
204
205 TestLoadTimingNotReused(*stream);
206 stream->Close(false);
207 TestLoadTimingNotReused(*stream);
208 }
209
210 TEST_F(HttpPipelinedConnectionImplTest, SyncSingleRequest) {
211 MockWrite writes[] = {
212 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
213 };
214 MockRead reads[] = {
215 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
216 MockRead(SYNCHRONOUS, 2, "Content-Length: 7\r\n\r\n"),
217 MockRead(SYNCHRONOUS, 3, "ok.html"),
218 };
219 Initialize(reads, arraysize(reads), writes, arraysize(writes));
220
221 scoped_ptr<HttpStream> stream(NewTestStream("ok.html"));
222 TestLoadTimingNotReused(*stream);
223 TestSyncRequest(stream, "ok.html");
224 TestLoadTimingNotReused(*stream);
225 }
226
227 TEST_F(HttpPipelinedConnectionImplTest, AsyncSingleRequest) {
228 MockWrite writes[] = {
229 MockWrite(ASYNC, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
230 };
231 MockRead reads[] = {
232 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n"),
233 MockRead(ASYNC, 2, "Content-Length: 7\r\n\r\n"),
234 MockRead(ASYNC, 3, "ok.html"),
235 };
236 Initialize(reads, arraysize(reads), writes, arraysize(writes));
237
238 scoped_ptr<HttpStream> stream(NewTestStream("ok.html"));
239
240 HttpRequestHeaders headers;
241 HttpResponseInfo response;
242 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequest(headers, &response,
243 callback_.callback()));
244 data_->RunFor(1);
245 EXPECT_LE(OK, callback_.WaitForResult());
246 TestLoadTimingNotReused(*stream);
247
248 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
249 data_->RunFor(2);
250 EXPECT_LE(OK, callback_.WaitForResult());
251 TestLoadTimingNotReused(*stream);
252
253 ExpectResponse("ok.html", stream, true);
254 TestLoadTimingNotReused(*stream);
255
256 stream->Close(false);
257 }
258
259 TEST_F(HttpPipelinedConnectionImplTest, LockStepAsyncRequests) {
260 MockWrite writes[] = {
261 MockWrite(ASYNC, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
262 MockWrite(ASYNC, 1, "GET /ko.html HTTP/1.1\r\n\r\n"),
263 };
264 MockRead reads[] = {
265 MockRead(ASYNC, 2, "HTTP/1.1 200 OK\r\n"),
266 MockRead(ASYNC, 3, "Content-Length: 7\r\n\r\n"),
267 MockRead(ASYNC, 4, "ok.html"),
268 MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\n"),
269 MockRead(ASYNC, 6, "Content-Length: 7\r\n\r\n"),
270 MockRead(ASYNC, 7, "ko.html"),
271 };
272 Initialize(reads, arraysize(reads), writes, arraysize(writes));
273
274 scoped_ptr<HttpStream> stream1(NewTestStream("ok.html"));
275 scoped_ptr<HttpStream> stream2(NewTestStream("ko.html"));
276
277 HttpRequestHeaders headers1;
278 HttpResponseInfo response1;
279 EXPECT_EQ(ERR_IO_PENDING, stream1->SendRequest(headers1, &response1,
280 callback_.callback()));
281 TestLoadTimingNotReused(*stream1);
282
283 HttpRequestHeaders headers2;
284 HttpResponseInfo response2;
285 EXPECT_EQ(ERR_IO_PENDING, stream2->SendRequest(headers2, &response2,
286 callback_.callback()));
287 TestLoadTimingReused(*stream2);
288
289 data_->RunFor(1);
290 EXPECT_LE(OK, callback_.WaitForResult());
291 data_->RunFor(1);
292 EXPECT_LE(OK, callback_.WaitForResult());
293
294 EXPECT_EQ(ERR_IO_PENDING, stream1->ReadResponseHeaders(callback_.callback()));
295 EXPECT_EQ(ERR_IO_PENDING, stream2->ReadResponseHeaders(callback_.callback()));
296
297 data_->RunFor(2);
298 EXPECT_LE(OK, callback_.WaitForResult());
299
300 ExpectResponse("ok.html", stream1, true);
301
302 TestLoadTimingNotReused(*stream1);
303 LoadTimingInfo load_timing_info1;
304 EXPECT_TRUE(stream1->GetLoadTimingInfo(&load_timing_info1));
305 stream1->Close(false);
306
307 data_->RunFor(2);
308 EXPECT_LE(OK, callback_.WaitForResult());
309
310 ExpectResponse("ko.html", stream2, true);
311
312 TestLoadTimingReused(*stream2);
313 LoadTimingInfo load_timing_info2;
314 EXPECT_TRUE(stream2->GetLoadTimingInfo(&load_timing_info2));
315 EXPECT_EQ(load_timing_info1.socket_log_id,
316 load_timing_info2.socket_log_id);
317 stream2->Close(false);
318 }
319
320 TEST_F(HttpPipelinedConnectionImplTest, TwoResponsesInOnePacket) {
321 MockWrite writes[] = {
322 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
323 MockWrite(SYNCHRONOUS, 1, "GET /ko.html HTTP/1.1\r\n\r\n"),
324 };
325 MockRead reads[] = {
326 MockRead(SYNCHRONOUS, 2,
327 "HTTP/1.1 200 OK\r\n"
328 "Content-Length: 7\r\n\r\n"
329 "ok.html"
330 "HTTP/1.1 200 OK\r\n"
331 "Content-Length: 7\r\n\r\n"
332 "ko.html"),
333 };
334 Initialize(reads, arraysize(reads), writes, arraysize(writes));
335
336 scoped_ptr<HttpStream> stream1(NewTestStream("ok.html"));
337 scoped_ptr<HttpStream> stream2(NewTestStream("ko.html"));
338
339 HttpRequestHeaders headers1;
340 HttpResponseInfo response1;
341 EXPECT_EQ(OK, stream1->SendRequest(headers1,
342 &response1, callback_.callback()));
343 HttpRequestHeaders headers2;
344 HttpResponseInfo response2;
345 EXPECT_EQ(OK, stream2->SendRequest(headers2,
346 &response2, callback_.callback()));
347
348 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
349 ExpectResponse("ok.html", stream1, false);
350 stream1->Close(false);
351
352 EXPECT_EQ(OK, stream2->ReadResponseHeaders(callback_.callback()));
353 ExpectResponse("ko.html", stream2, false);
354 stream2->Close(false);
355 }
356
357 TEST_F(HttpPipelinedConnectionImplTest, SendOrderSwapped) {
358 MockWrite writes[] = {
359 MockWrite(SYNCHRONOUS, 0, "GET /ko.html HTTP/1.1\r\n\r\n"),
360 MockWrite(SYNCHRONOUS, 4, "GET /ok.html HTTP/1.1\r\n\r\n"),
361 };
362 MockRead reads[] = {
363 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
364 MockRead(SYNCHRONOUS, 2, "Content-Length: 7\r\n\r\n"),
365 MockRead(SYNCHRONOUS, 3, "ko.html"),
366 MockRead(SYNCHRONOUS, 5, "HTTP/1.1 200 OK\r\n"),
367 MockRead(SYNCHRONOUS, 6, "Content-Length: 7\r\n\r\n"),
368 MockRead(SYNCHRONOUS, 7, "ok.html"),
369 };
370 Initialize(reads, arraysize(reads), writes, arraysize(writes));
371
372 scoped_ptr<HttpStream> stream1(NewTestStream("ok.html"));
373 scoped_ptr<HttpStream> stream2(NewTestStream("ko.html"));
374
375 TestSyncRequest(stream2, "ko.html");
376 TestSyncRequest(stream1, "ok.html");
377 TestLoadTimingNotReused(*stream1);
378 TestLoadTimingReused(*stream2);
379 }
380
381 TEST_F(HttpPipelinedConnectionImplTest, ReadOrderSwapped) {
382 MockWrite writes[] = {
383 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
384 MockWrite(SYNCHRONOUS, 1, "GET /ko.html HTTP/1.1\r\n\r\n"),
385 };
386 MockRead reads[] = {
387 MockRead(SYNCHRONOUS, 2, "HTTP/1.1 200 OK\r\n"),
388 MockRead(SYNCHRONOUS, 3, "Content-Length: 7\r\n\r\n"),
389 MockRead(SYNCHRONOUS, 4, "ok.html"),
390 MockRead(SYNCHRONOUS, 5, "HTTP/1.1 200 OK\r\n"),
391 MockRead(SYNCHRONOUS, 6, "Content-Length: 7\r\n\r\n"),
392 MockRead(SYNCHRONOUS, 7, "ko.html"),
393 };
394 Initialize(reads, arraysize(reads), writes, arraysize(writes));
395
396 scoped_ptr<HttpStream> stream1(NewTestStream("ok.html"));
397 scoped_ptr<HttpStream> stream2(NewTestStream("ko.html"));
398
399 HttpRequestHeaders headers1;
400 HttpResponseInfo response1;
401 EXPECT_EQ(OK, stream1->SendRequest(headers1,
402 &response1, callback_.callback()));
403
404 HttpRequestHeaders headers2;
405 HttpResponseInfo response2;
406 EXPECT_EQ(OK, stream2->SendRequest(headers2,
407 &response2, callback_.callback()));
408
409 EXPECT_EQ(ERR_IO_PENDING, stream2->ReadResponseHeaders(callback_.callback()));
410
411 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
412 ExpectResponse("ok.html", stream1, false);
413
414 stream1->Close(false);
415
416 EXPECT_LE(OK, callback_.WaitForResult());
417 ExpectResponse("ko.html", stream2, false);
418
419 stream2->Close(false);
420 }
421
422 TEST_F(HttpPipelinedConnectionImplTest, SendWhileReading) {
423 MockWrite writes[] = {
424 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
425 MockWrite(SYNCHRONOUS, 3, "GET /ko.html HTTP/1.1\r\n\r\n"),
426 };
427 MockRead reads[] = {
428 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
429 MockRead(SYNCHRONOUS, 2, "Content-Length: 7\r\n\r\n"),
430 MockRead(SYNCHRONOUS, 4, "ok.html"),
431 MockRead(SYNCHRONOUS, 5, "HTTP/1.1 200 OK\r\n"),
432 MockRead(SYNCHRONOUS, 6, "Content-Length: 7\r\n\r\n"),
433 MockRead(SYNCHRONOUS, 7, "ko.html"),
434 };
435 Initialize(reads, arraysize(reads), writes, arraysize(writes));
436
437 scoped_ptr<HttpStream> stream1(NewTestStream("ok.html"));
438 scoped_ptr<HttpStream> stream2(NewTestStream("ko.html"));
439
440 HttpRequestHeaders headers1;
441 HttpResponseInfo response1;
442 EXPECT_EQ(OK, stream1->SendRequest(headers1,
443 &response1, callback_.callback()));
444 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
445
446 HttpRequestHeaders headers2;
447 HttpResponseInfo response2;
448 EXPECT_EQ(OK, stream2->SendRequest(headers2,
449 &response2, callback_.callback()));
450
451 ExpectResponse("ok.html", stream1, false);
452 stream1->Close(false);
453
454 EXPECT_EQ(OK, stream2->ReadResponseHeaders(callback_.callback()));
455 ExpectResponse("ko.html", stream2, false);
456 stream2->Close(false);
457 }
458
459 TEST_F(HttpPipelinedConnectionImplTest, AsyncSendWhileAsyncReadBlocked) {
460 MockWrite writes[] = {
461 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
462 MockWrite(ASYNC, 3, "GET /ko.html HTTP/1.1\r\n\r\n"),
463 };
464 MockRead reads[] = {
465 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
466 MockRead(SYNCHRONOUS, 2, "Content-Length: 7\r\n\r\n"),
467 MockRead(ASYNC, 4, "ok.html"),
468 MockRead(SYNCHRONOUS, 5, "HTTP/1.1 200 OK\r\n"),
469 MockRead(SYNCHRONOUS, 6, "Content-Length: 7\r\n\r\n"),
470 MockRead(SYNCHRONOUS, 7, "ko.html"),
471 };
472 Initialize(reads, arraysize(reads), writes, arraysize(writes));
473
474 scoped_ptr<HttpStream> stream1(NewTestStream("ok.html"));
475 scoped_ptr<HttpStream> stream2(NewTestStream("ko.html"));
476
477 HttpRequestHeaders headers1;
478 HttpResponseInfo response1;
479 EXPECT_EQ(OK, stream1->SendRequest(headers1,
480 &response1, callback_.callback()));
481 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
482 TestCompletionCallback callback1;
483 std::string expected = "ok.html";
484 scoped_refptr<IOBuffer> buffer(new IOBuffer(expected.size()));
485 EXPECT_EQ(ERR_IO_PENDING,
486 stream1->ReadResponseBody(buffer.get(), expected.size(),
487 callback1.callback()));
488
489 HttpRequestHeaders headers2;
490 HttpResponseInfo response2;
491 TestCompletionCallback callback2;
492 EXPECT_EQ(ERR_IO_PENDING, stream2->SendRequest(headers2, &response2,
493 callback2.callback()));
494
495 data_->RunFor(1);
496 EXPECT_LE(OK, callback2.WaitForResult());
497 EXPECT_EQ(ERR_IO_PENDING, stream2->ReadResponseHeaders(callback2.callback()));
498
499 data_->RunFor(1);
500 EXPECT_EQ(static_cast<int>(expected.size()), callback1.WaitForResult());
501 std::string actual(buffer->data(), expected.size());
502 EXPECT_THAT(actual, StrEq(expected));
503 stream1->Close(false);
504
505 data_->StopAfter(8);
506 EXPECT_LE(OK, callback2.WaitForResult());
507 ExpectResponse("ko.html", stream2, false);
508 stream2->Close(false);
509 }
510
511 TEST_F(HttpPipelinedConnectionImplTest, UnusedStreamAllowsLaterUse) {
512 MockWrite writes[] = {
513 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
514 };
515 MockRead reads[] = {
516 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
517 MockRead(SYNCHRONOUS, 2, "Content-Length: 7\r\n\r\n"),
518 MockRead(SYNCHRONOUS, 3, "ok.html"),
519 };
520 Initialize(reads, arraysize(reads), writes, arraysize(writes));
521
522 scoped_ptr<HttpStream> unused_stream(NewTestStream("unused.html"));
523 unused_stream->Close(false);
524
525 scoped_ptr<HttpStream> later_stream(NewTestStream("ok.html"));
526 TestSyncRequest(later_stream, "ok.html");
527 }
528
529 TEST_F(HttpPipelinedConnectionImplTest, UnsentStreamAllowsLaterUse) {
530 MockWrite writes[] = {
531 MockWrite(ASYNC, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
532 MockWrite(SYNCHRONOUS, 4, "GET /ko.html HTTP/1.1\r\n\r\n"),
533 };
534 MockRead reads[] = {
535 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n"),
536 MockRead(ASYNC, 2, "Content-Length: 7\r\n\r\n"),
537 MockRead(ASYNC, 3, "ok.html"),
538 MockRead(SYNCHRONOUS, 5, "HTTP/1.1 200 OK\r\n"),
539 MockRead(SYNCHRONOUS, 6, "Content-Length: 7\r\n\r\n"),
540 MockRead(SYNCHRONOUS, 7, "ko.html"),
541 };
542 Initialize(reads, arraysize(reads), writes, arraysize(writes));
543
544 scoped_ptr<HttpStream> stream(NewTestStream("ok.html"));
545
546 HttpRequestHeaders headers;
547 HttpResponseInfo response;
548 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequest(headers, &response,
549 callback_.callback()));
550
551 scoped_ptr<HttpStream> unsent_stream(NewTestStream("unsent.html"));
552 HttpRequestHeaders unsent_headers;
553 HttpResponseInfo unsent_response;
554 EXPECT_EQ(ERR_IO_PENDING, unsent_stream->SendRequest(unsent_headers,
555 &unsent_response,
556 callback_.callback()));
557 unsent_stream->Close(false);
558
559 data_->RunFor(1);
560 EXPECT_LE(OK, callback_.WaitForResult());
561
562 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
563 data_->RunFor(2);
564 EXPECT_LE(OK, callback_.WaitForResult());
565
566 ExpectResponse("ok.html", stream, true);
567
568 stream->Close(false);
569
570 data_->StopAfter(8);
571 scoped_ptr<HttpStream> later_stream(NewTestStream("ko.html"));
572 TestSyncRequest(later_stream, "ko.html");
573 }
574
575 TEST_F(HttpPipelinedConnectionImplTest, FailedSend) {
576 MockWrite writes[] = {
577 MockWrite(ASYNC, ERR_FAILED),
578 };
579 Initialize(NULL, 0, writes, arraysize(writes));
580
581 scoped_ptr<HttpStream> failed_stream(NewTestStream("ok.html"));
582 scoped_ptr<HttpStream> evicted_stream(NewTestStream("evicted.html"));
583 scoped_ptr<HttpStream> closed_stream(NewTestStream("closed.html"));
584 scoped_ptr<HttpStream> rejected_stream(NewTestStream("rejected.html"));
585
586 HttpRequestHeaders headers;
587 HttpResponseInfo response;
588 TestCompletionCallback failed_callback;
589 EXPECT_EQ(ERR_IO_PENDING,
590 failed_stream->SendRequest(headers, &response,
591 failed_callback.callback()));
592 TestCompletionCallback evicted_callback;
593 EXPECT_EQ(ERR_IO_PENDING,
594 evicted_stream->SendRequest(headers, &response,
595 evicted_callback.callback()));
596 EXPECT_EQ(ERR_IO_PENDING, closed_stream->SendRequest(headers, &response,
597 callback_.callback()));
598 closed_stream->Close(false);
599
600 data_->RunFor(1);
601 EXPECT_EQ(ERR_FAILED, failed_callback.WaitForResult());
602 EXPECT_EQ(ERR_PIPELINE_EVICTION, evicted_callback.WaitForResult());
603 EXPECT_EQ(ERR_PIPELINE_EVICTION,
604 rejected_stream->SendRequest(headers, &response,
605 callback_.callback()));
606
607 failed_stream->Close(true);
608 evicted_stream->Close(true);
609 rejected_stream->Close(true);
610 }
611
612 TEST_F(HttpPipelinedConnectionImplTest, ConnectionSuddenlyClosedAfterResponse) {
613 MockWrite writes[] = {
614 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
615 MockWrite(SYNCHRONOUS, 1, "GET /read_evicted.html HTTP/1.1\r\n\r\n"),
616 MockWrite(SYNCHRONOUS, 2, "GET /read_rejected.html HTTP/1.1\r\n\r\n"),
617 MockWrite(ASYNC, ERR_SOCKET_NOT_CONNECTED, 5),
618 };
619 MockRead reads[] = {
620 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n\r\n"),
621 MockRead(SYNCHRONOUS, 4, "ok.html"),
622 MockRead(ASYNC, OK, 6), // Connection closed message. Not read before the
623 // ERR_SOCKET_NOT_CONNECTED.
624 };
625 Initialize(reads, arraysize(reads), writes, arraysize(writes));
626
627 scoped_ptr<HttpStream> closed_stream(NewTestStream("ok.html"));
628 scoped_ptr<HttpStream> read_evicted_stream(
629 NewTestStream("read_evicted.html"));
630 scoped_ptr<HttpStream> read_rejected_stream(
631 NewTestStream("read_rejected.html"));
632 scoped_ptr<HttpStream> send_closed_stream(
633 NewTestStream("send_closed.html"));
634 scoped_ptr<HttpStream> send_evicted_stream(
635 NewTestStream("send_evicted.html"));
636 scoped_ptr<HttpStream> send_rejected_stream(
637 NewTestStream("send_rejected.html"));
638
639 HttpRequestHeaders headers;
640 HttpResponseInfo response;
641 EXPECT_EQ(OK, closed_stream->SendRequest(headers,
642 &response, callback_.callback()));
643 EXPECT_EQ(OK, read_evicted_stream->SendRequest(headers, &response,
644 callback_.callback()));
645 EXPECT_EQ(OK, read_rejected_stream->SendRequest(headers, &response,
646 callback_.callback()));
647 TestCompletionCallback send_closed_callback;
648 EXPECT_EQ(ERR_IO_PENDING,
649 send_closed_stream->SendRequest(headers, &response,
650 send_closed_callback.callback()));
651 TestCompletionCallback send_evicted_callback;
652 EXPECT_EQ(ERR_IO_PENDING,
653 send_evicted_stream->SendRequest(headers, &response,
654 send_evicted_callback.callback()));
655
656 TestCompletionCallback read_evicted_callback;
657 EXPECT_EQ(ERR_IO_PENDING,
658 read_evicted_stream->ReadResponseHeaders(
659 read_evicted_callback.callback()));
660
661 EXPECT_EQ(OK, closed_stream->ReadResponseHeaders(callback_.callback()));
662 ExpectResponse("ok.html", closed_stream, false);
663 closed_stream->Close(true);
664
665 EXPECT_EQ(ERR_PIPELINE_EVICTION, read_evicted_callback.WaitForResult());
666 read_evicted_stream->Close(true);
667
668 EXPECT_EQ(ERR_PIPELINE_EVICTION,
669 read_rejected_stream->ReadResponseHeaders(callback_.callback()));
670 read_rejected_stream->Close(true);
671
672 data_->RunFor(1);
673 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, send_closed_callback.WaitForResult());
674 send_closed_stream->Close(true);
675
676 EXPECT_EQ(ERR_PIPELINE_EVICTION, send_evicted_callback.WaitForResult());
677 send_evicted_stream->Close(true);
678
679 EXPECT_EQ(ERR_PIPELINE_EVICTION,
680 send_rejected_stream->SendRequest(headers, &response,
681 callback_.callback()));
682 send_rejected_stream->Close(true);
683 }
684
685 TEST_F(HttpPipelinedConnectionImplTest, AbortWhileSending) {
686 MockWrite writes[] = {
687 MockWrite(ASYNC, 0, "GET /aborts.html HTTP/1.1\r\n\r\n"),
688 };
689 Initialize(NULL, 0, writes, arraysize(writes));
690
691 scoped_ptr<HttpStream> aborted_stream(NewTestStream("aborts.html"));
692 scoped_ptr<HttpStream> evicted_stream(NewTestStream("evicted.html"));
693
694 HttpRequestHeaders headers;
695 HttpResponseInfo response;
696 TestCompletionCallback aborted_callback;
697 EXPECT_EQ(ERR_IO_PENDING,
698 aborted_stream->SendRequest(headers, &response,
699 aborted_callback.callback()));
700 TestCompletionCallback evicted_callback;
701 EXPECT_EQ(ERR_IO_PENDING,
702 evicted_stream->SendRequest(headers, &response,
703 evicted_callback.callback()));
704
705 aborted_stream->Close(true);
706 EXPECT_EQ(ERR_PIPELINE_EVICTION, evicted_callback.WaitForResult());
707 evicted_stream->Close(true);
708 EXPECT_FALSE(aborted_callback.have_result());
709 }
710
711 TEST_F(HttpPipelinedConnectionImplTest, AbortWhileSendingSecondRequest) {
712 MockWrite writes[] = {
713 MockWrite(ASYNC, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
714 MockWrite(ASYNC, 1, "GET /aborts.html HTTP/1.1\r\n\r\n"),
715 };
716 Initialize(NULL, 0, writes, arraysize(writes));
717
718 scoped_ptr<HttpStream> ok_stream(NewTestStream("ok.html"));
719 scoped_ptr<HttpStream> aborted_stream(NewTestStream("aborts.html"));
720 scoped_ptr<HttpStream> evicted_stream(NewTestStream("evicted.html"));
721
722 HttpRequestHeaders headers;
723 HttpResponseInfo response;
724 TestCompletionCallback ok_callback;
725 EXPECT_EQ(ERR_IO_PENDING, ok_stream->SendRequest(headers, &response,
726 ok_callback.callback()));
727 TestCompletionCallback aborted_callback;
728 EXPECT_EQ(ERR_IO_PENDING,
729 aborted_stream->SendRequest(headers, &response,
730 aborted_callback.callback()));
731 TestCompletionCallback evicted_callback;
732 EXPECT_EQ(ERR_IO_PENDING,
733 evicted_stream->SendRequest(headers, &response,
734 evicted_callback.callback()));
735
736 data_->RunFor(1);
737 EXPECT_LE(OK, ok_callback.WaitForResult());
738 base::MessageLoop::current()->RunUntilIdle();
739 aborted_stream->Close(true);
740 EXPECT_EQ(ERR_PIPELINE_EVICTION, evicted_callback.WaitForResult());
741 evicted_stream->Close(true);
742 EXPECT_FALSE(aborted_callback.have_result());
743 ok_stream->Close(true);
744 }
745
746 TEST_F(HttpPipelinedConnectionImplTest, AbortWhileReadingHeaders) {
747 MockWrite writes[] = {
748 MockWrite(SYNCHRONOUS, 0, "GET /aborts.html HTTP/1.1\r\n\r\n"),
749 MockWrite(SYNCHRONOUS, 1, "GET /evicted.html HTTP/1.1\r\n\r\n"),
750 };
751 MockRead reads[] = {
752 MockRead(ASYNC, ERR_FAILED, 2),
753 };
754 Initialize(reads, arraysize(reads), writes, arraysize(writes));
755
756 scoped_ptr<HttpStream> aborted_stream(NewTestStream("aborts.html"));
757 scoped_ptr<HttpStream> evicted_stream(NewTestStream("evicted.html"));
758 scoped_ptr<HttpStream> rejected_stream(NewTestStream("rejected.html"));
759
760 HttpRequestHeaders headers;
761 HttpResponseInfo response;
762 EXPECT_EQ(OK,
763 aborted_stream->SendRequest(headers, &response,
764 callback_.callback()));
765 EXPECT_EQ(OK,
766 evicted_stream->SendRequest(headers, &response,
767 callback_.callback()));
768
769 EXPECT_EQ(ERR_IO_PENDING,
770 aborted_stream->ReadResponseHeaders(callback_.callback()));
771 TestCompletionCallback evicted_callback;
772 EXPECT_EQ(ERR_IO_PENDING,
773 evicted_stream->ReadResponseHeaders(evicted_callback.callback()));
774
775 aborted_stream->Close(true);
776 EXPECT_EQ(ERR_PIPELINE_EVICTION, evicted_callback.WaitForResult());
777 evicted_stream->Close(true);
778
779 EXPECT_EQ(ERR_PIPELINE_EVICTION,
780 rejected_stream->SendRequest(headers, &response,
781 callback_.callback()));
782 rejected_stream->Close(true);
783 }
784
785 TEST_F(HttpPipelinedConnectionImplTest, PendingResponseAbandoned) {
786 MockWrite writes[] = {
787 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
788 MockWrite(SYNCHRONOUS, 1, "GET /abandoned.html HTTP/1.1\r\n\r\n"),
789 MockWrite(SYNCHRONOUS, 2, "GET /evicted.html HTTP/1.1\r\n\r\n"),
790 };
791 MockRead reads[] = {
792 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
793 MockRead(SYNCHRONOUS, 4, "Content-Length: 7\r\n\r\n"),
794 MockRead(SYNCHRONOUS, 5, "ok.html"),
795 };
796 Initialize(reads, arraysize(reads), writes, arraysize(writes));
797
798 scoped_ptr<HttpStream> ok_stream(NewTestStream("ok.html"));
799 scoped_ptr<HttpStream> abandoned_stream(NewTestStream("abandoned.html"));
800 scoped_ptr<HttpStream> evicted_stream(NewTestStream("evicted.html"));
801
802 HttpRequestHeaders headers;
803 HttpResponseInfo response;
804 EXPECT_EQ(OK, ok_stream->SendRequest(headers, &response,
805 callback_.callback()));
806 EXPECT_EQ(OK, abandoned_stream->SendRequest(headers, &response,
807 callback_.callback()));
808 EXPECT_EQ(OK, evicted_stream->SendRequest(headers, &response,
809 callback_.callback()));
810
811 EXPECT_EQ(OK, ok_stream->ReadResponseHeaders(callback_.callback()));
812 TestCompletionCallback abandoned_callback;
813 EXPECT_EQ(ERR_IO_PENDING, abandoned_stream->ReadResponseHeaders(
814 abandoned_callback.callback()));
815 TestCompletionCallback evicted_callback;
816 EXPECT_EQ(ERR_IO_PENDING,
817 evicted_stream->ReadResponseHeaders(evicted_callback.callback()));
818
819 abandoned_stream->Close(false);
820
821 ExpectResponse("ok.html", ok_stream, false);
822 ok_stream->Close(false);
823
824 EXPECT_EQ(ERR_PIPELINE_EVICTION, evicted_callback.WaitForResult());
825 evicted_stream->Close(true);
826 EXPECT_FALSE(evicted_stream->IsConnectionReusable());
827 }
828
829 TEST_F(HttpPipelinedConnectionImplTest, DisconnectedAfterOneRequestRecovery) {
830 MockWrite writes[] = {
831 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
832 MockWrite(SYNCHRONOUS, 1, "GET /rejected.html HTTP/1.1\r\n\r\n"),
833 MockWrite(ASYNC, ERR_SOCKET_NOT_CONNECTED, 5),
834 MockWrite(SYNCHRONOUS, ERR_SOCKET_NOT_CONNECTED, 7),
835 };
836 MockRead reads[] = {
837 MockRead(SYNCHRONOUS, 2, "HTTP/1.1 200 OK\r\n"),
838 MockRead(SYNCHRONOUS, 3, "Content-Length: 7\r\n\r\n"),
839 MockRead(SYNCHRONOUS, 4, "ok.html"),
840 MockRead(SYNCHRONOUS, ERR_SOCKET_NOT_CONNECTED, 6),
841 };
842 Initialize(reads, arraysize(reads), writes, arraysize(writes));
843
844 scoped_ptr<HttpStream> ok_stream(NewTestStream("ok.html"));
845 scoped_ptr<HttpStream> rejected_read_stream(NewTestStream("rejected.html"));
846 scoped_ptr<HttpStream> evicted_send_stream(NewTestStream("evicted.html"));
847 scoped_ptr<HttpStream> rejected_send_stream(NewTestStream("rejected.html"));
848
849 HttpRequestHeaders headers;
850 HttpResponseInfo response;
851 EXPECT_EQ(OK, ok_stream->SendRequest(headers,
852 &response, callback_.callback()));
853 EXPECT_EQ(OK, rejected_read_stream->SendRequest(headers, &response,
854 callback_.callback()));
855
856 EXPECT_EQ(OK, ok_stream->ReadResponseHeaders(callback_.callback()));
857 ExpectResponse("ok.html", ok_stream, false);
858 ok_stream->Close(false);
859
860 TestCompletionCallback read_callback;
861 EXPECT_EQ(ERR_IO_PENDING,
862 evicted_send_stream->SendRequest(headers, &response,
863 read_callback.callback()));
864 data_->RunFor(1);
865 EXPECT_EQ(ERR_PIPELINE_EVICTION, read_callback.WaitForResult());
866
867 EXPECT_EQ(ERR_PIPELINE_EVICTION,
868 rejected_read_stream->ReadResponseHeaders(callback_.callback()));
869 EXPECT_EQ(ERR_PIPELINE_EVICTION,
870 rejected_send_stream->SendRequest(headers, &response,
871 callback_.callback()));
872
873 rejected_read_stream->Close(true);
874 rejected_send_stream->Close(true);
875 }
876
877 TEST_F(HttpPipelinedConnectionImplTest, DisconnectedPendingReadRecovery) {
878 MockWrite writes[] = {
879 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
880 MockWrite(SYNCHRONOUS, 1, "GET /evicted.html HTTP/1.1\r\n\r\n"),
881 };
882 MockRead reads[] = {
883 MockRead(SYNCHRONOUS, 2, "HTTP/1.1 200 OK\r\n"),
884 MockRead(SYNCHRONOUS, 3, "Content-Length: 7\r\n\r\n"),
885 MockRead(SYNCHRONOUS, 4, "ok.html"),
886 MockRead(SYNCHRONOUS, ERR_SOCKET_NOT_CONNECTED, 5),
887 };
888 Initialize(reads, arraysize(reads), writes, arraysize(writes));
889
890 scoped_ptr<HttpStream> ok_stream(NewTestStream("ok.html"));
891 scoped_ptr<HttpStream> evicted_stream(NewTestStream("evicted.html"));
892
893 HttpRequestHeaders headers;
894 HttpResponseInfo response;
895 EXPECT_EQ(OK, ok_stream->SendRequest(headers,
896 &response, callback_.callback()));
897 EXPECT_EQ(OK, evicted_stream->SendRequest(headers, &response,
898 callback_.callback()));
899
900 EXPECT_EQ(OK, ok_stream->ReadResponseHeaders(callback_.callback()));
901 ExpectResponse("ok.html", ok_stream, false);
902
903 TestCompletionCallback evicted_callback;
904 EXPECT_EQ(ERR_IO_PENDING,
905 evicted_stream->ReadResponseHeaders(evicted_callback.callback()));
906
907 ok_stream->Close(false);
908
909 EXPECT_EQ(ERR_PIPELINE_EVICTION, evicted_callback.WaitForResult());
910 evicted_stream->Close(false);
911 }
912
913 TEST_F(HttpPipelinedConnectionImplTest, CloseCalledBeforeNextReadLoop) {
914 MockWrite writes[] = {
915 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
916 MockWrite(SYNCHRONOUS, 1, "GET /evicted.html HTTP/1.1\r\n\r\n"),
917 };
918 MockRead reads[] = {
919 MockRead(SYNCHRONOUS, 2, "HTTP/1.1 200 OK\r\n"),
920 MockRead(SYNCHRONOUS, 3, "Content-Length: 7\r\n\r\n"),
921 MockRead(SYNCHRONOUS, 4, "ok.html"),
922 MockRead(SYNCHRONOUS, ERR_SOCKET_NOT_CONNECTED, 5),
923 };
924 Initialize(reads, arraysize(reads), writes, arraysize(writes));
925
926 scoped_ptr<HttpStream> ok_stream(NewTestStream("ok.html"));
927 scoped_ptr<HttpStream> evicted_stream(NewTestStream("evicted.html"));
928
929 HttpRequestHeaders headers;
930 HttpResponseInfo response;
931 EXPECT_EQ(OK, ok_stream->SendRequest(headers,
932 &response, callback_.callback()));
933 EXPECT_EQ(OK, evicted_stream->SendRequest(headers, &response,
934 callback_.callback()));
935
936 EXPECT_EQ(OK, ok_stream->ReadResponseHeaders(callback_.callback()));
937 ExpectResponse("ok.html", ok_stream, false);
938
939 TestCompletionCallback evicted_callback;
940 EXPECT_EQ(ERR_IO_PENDING,
941 evicted_stream->ReadResponseHeaders(evicted_callback.callback()));
942
943 ok_stream->Close(false);
944 evicted_stream->Close(false);
945 }
946
947 TEST_F(HttpPipelinedConnectionImplTest, CloseCalledBeforeReadCallback) {
948 MockWrite writes[] = {
949 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
950 MockWrite(SYNCHRONOUS, 1, "GET /evicted.html HTTP/1.1\r\n\r\n"),
951 };
952 MockRead reads[] = {
953 MockRead(SYNCHRONOUS, 2, "HTTP/1.1 200 OK\r\n"),
954 MockRead(SYNCHRONOUS, 3, "Content-Length: 7\r\n\r\n"),
955 MockRead(SYNCHRONOUS, 4, "ok.html"),
956 MockRead(SYNCHRONOUS, ERR_SOCKET_NOT_CONNECTED, 5),
957 };
958 Initialize(reads, arraysize(reads), writes, arraysize(writes));
959
960 scoped_ptr<HttpStream> ok_stream(NewTestStream("ok.html"));
961 scoped_ptr<HttpStream> evicted_stream(NewTestStream("evicted.html"));
962
963 HttpRequestHeaders headers;
964 HttpResponseInfo response;
965 EXPECT_EQ(OK, ok_stream->SendRequest(headers,
966 &response, callback_.callback()));
967 EXPECT_EQ(OK, evicted_stream->SendRequest(headers, &response,
968 callback_.callback()));
969
970 EXPECT_EQ(OK, ok_stream->ReadResponseHeaders(callback_.callback()));
971 ExpectResponse("ok.html", ok_stream, false);
972
973 TestCompletionCallback evicted_callback;
974 EXPECT_EQ(ERR_IO_PENDING,
975 evicted_stream->ReadResponseHeaders(evicted_callback.callback()));
976
977 ok_stream->Close(false);
978
979 // The posted tasks should be:
980 // 1. DoReadHeadersLoop, which will post:
981 // 2. InvokeUserCallback
982 SuddenCloseObserver observer(evicted_stream.get(), 2);
983 base::MessageLoop::current()->AddTaskObserver(&observer);
984 base::MessageLoop::current()->RunUntilIdle();
985 EXPECT_FALSE(evicted_callback.have_result());
986 }
987
988 class StreamDeleter {
989 public:
990 StreamDeleter(HttpStream* stream)
991 : stream_(stream),
992 callback_(base::Bind(&StreamDeleter::OnIOComplete,
993 base::Unretained(this))) {
994 }
995
996 ~StreamDeleter() {
997 EXPECT_FALSE(stream_);
998 }
999
1000 const CompletionCallback& callback() { return callback_; }
1001
1002 private:
1003 void OnIOComplete(int result) {
1004 stream_->Close(true);
1005 stream_.reset();
1006 }
1007
1008 scoped_ptr<HttpStream> stream_;
1009 CompletionCallback callback_;
1010 };
1011
1012 TEST_F(HttpPipelinedConnectionImplTest, CloseCalledDuringSendCallback) {
1013 MockWrite writes[] = {
1014 MockWrite(ASYNC, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
1015 };
1016 Initialize(NULL, 0, writes, arraysize(writes));
1017
1018 HttpStream* stream(NewTestStream("ok.html"));
1019
1020 StreamDeleter deleter(stream);
1021 HttpRequestHeaders headers;
1022 HttpResponseInfo response;
1023 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequest(headers, &response,
1024 deleter.callback()));
1025 data_->RunFor(1);
1026 }
1027
1028 TEST_F(HttpPipelinedConnectionImplTest, CloseCalledDuringReadCallback) {
1029 MockWrite writes[] = {
1030 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
1031 };
1032 MockRead reads[] = {
1033 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
1034 MockRead(ASYNC, 2, "Content-Length: 7\r\n\r\n"),
1035 };
1036 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1037
1038 HttpStream* stream(NewTestStream("ok.html"));
1039
1040 HttpRequestHeaders headers;
1041 HttpResponseInfo response;
1042 EXPECT_EQ(OK, stream->SendRequest(headers,
1043 &response, callback_.callback()));
1044
1045 StreamDeleter deleter(stream);
1046 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(deleter.callback()));
1047 data_->RunFor(1);
1048 }
1049
1050 TEST_F(HttpPipelinedConnectionImplTest,
1051 CloseCalledDuringReadCallbackWithPendingRead) {
1052 MockWrite writes[] = {
1053 MockWrite(SYNCHRONOUS, 0, "GET /failed.html HTTP/1.1\r\n\r\n"),
1054 MockWrite(SYNCHRONOUS, 1, "GET /evicted.html HTTP/1.1\r\n\r\n"),
1055 };
1056 MockRead reads[] = {
1057 MockRead(SYNCHRONOUS, 2, "HTTP/1.1 200 OK\r\n"),
1058 MockRead(ASYNC, 3, "Content-Length: 7\r\n\r\n"),
1059 };
1060 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1061
1062 HttpStream* failed_stream(NewTestStream("failed.html"));
1063 HttpStream* evicted_stream(NewTestStream("evicted.html"));
1064
1065 HttpRequestHeaders headers;
1066 HttpResponseInfo response;
1067 EXPECT_EQ(OK, failed_stream->SendRequest(headers, &response,
1068 callback_.callback()));
1069 EXPECT_EQ(OK, evicted_stream->SendRequest(headers, &response,
1070 callback_.callback()));
1071
1072 StreamDeleter failed_deleter(failed_stream);
1073 EXPECT_EQ(ERR_IO_PENDING,
1074 failed_stream->ReadResponseHeaders(failed_deleter.callback()));
1075 StreamDeleter evicted_deleter(evicted_stream);
1076 EXPECT_EQ(ERR_IO_PENDING,
1077 evicted_stream->ReadResponseHeaders(evicted_deleter.callback()));
1078 data_->RunFor(1);
1079 }
1080
1081 TEST_F(HttpPipelinedConnectionImplTest, CloseOtherDuringReadCallback) {
1082 MockWrite writes[] = {
1083 MockWrite(SYNCHRONOUS, 0, "GET /deleter.html HTTP/1.1\r\n\r\n"),
1084 MockWrite(SYNCHRONOUS, 1, "GET /deleted.html HTTP/1.1\r\n\r\n"),
1085 };
1086 MockRead reads[] = {
1087 MockRead(SYNCHRONOUS, 2, "HTTP/1.1 200 OK\r\n"),
1088 MockRead(ASYNC, 3, "Content-Length: 7\r\n\r\n"),
1089 };
1090 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1091
1092 scoped_ptr<HttpStream> deleter_stream(NewTestStream("deleter.html"));
1093 HttpStream* deleted_stream(NewTestStream("deleted.html"));
1094
1095 HttpRequestHeaders headers;
1096 HttpResponseInfo response;
1097 EXPECT_EQ(OK, deleter_stream->SendRequest(headers,
1098 &response, callback_.callback()));
1099 EXPECT_EQ(OK, deleted_stream->SendRequest(headers,
1100 &response, callback_.callback()));
1101
1102 StreamDeleter deleter(deleted_stream);
1103 EXPECT_EQ(ERR_IO_PENDING,
1104 deleter_stream->ReadResponseHeaders(deleter.callback()));
1105 EXPECT_EQ(ERR_IO_PENDING,
1106 deleted_stream->ReadResponseHeaders(callback_.callback()));
1107 data_->RunFor(1);
1108 }
1109
1110 TEST_F(HttpPipelinedConnectionImplTest, CloseBeforeSendCallbackRuns) {
1111 MockWrite writes[] = {
1112 MockWrite(ASYNC, 0, "GET /close.html HTTP/1.1\r\n\r\n"),
1113 MockWrite(ASYNC, 1, "GET /dummy.html HTTP/1.1\r\n\r\n"),
1114 };
1115 Initialize(NULL, 0, writes, arraysize(writes));
1116
1117 scoped_ptr<HttpStream> close_stream(NewTestStream("close.html"));
1118 scoped_ptr<HttpStream> dummy_stream(NewTestStream("dummy.html"));
1119
1120 scoped_ptr<TestCompletionCallback> close_callback(
1121 new TestCompletionCallback);
1122 HttpRequestHeaders headers;
1123 HttpResponseInfo response;
1124 EXPECT_EQ(ERR_IO_PENDING,
1125 close_stream->SendRequest(headers,
1126 &response, close_callback->callback()));
1127
1128 data_->RunFor(1);
1129 EXPECT_FALSE(close_callback->have_result());
1130
1131 close_stream->Close(false);
1132 close_stream.reset();
1133 close_callback.reset();
1134
1135 base::MessageLoop::current()->RunUntilIdle();
1136 }
1137
1138 TEST_F(HttpPipelinedConnectionImplTest, CloseBeforeReadCallbackRuns) {
1139 MockWrite writes[] = {
1140 MockWrite(SYNCHRONOUS, 0, "GET /close.html HTTP/1.1\r\n\r\n"),
1141 MockWrite(SYNCHRONOUS, 3, "GET /dummy.html HTTP/1.1\r\n\r\n"),
1142 };
1143 MockRead reads[] = {
1144 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
1145 MockRead(ASYNC, 2, "Content-Length: 7\r\n\r\n"),
1146 };
1147 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1148
1149 scoped_ptr<HttpStream> close_stream(NewTestStream("close.html"));
1150 scoped_ptr<HttpStream> dummy_stream(NewTestStream("dummy.html"));
1151
1152 HttpRequestHeaders headers;
1153 HttpResponseInfo response;
1154 EXPECT_EQ(OK, close_stream->SendRequest(headers,
1155 &response, callback_.callback()));
1156
1157 scoped_ptr<TestCompletionCallback> close_callback(
1158 new TestCompletionCallback);
1159 EXPECT_EQ(ERR_IO_PENDING,
1160 close_stream->ReadResponseHeaders(close_callback->callback()));
1161
1162 data_->RunFor(1);
1163 EXPECT_FALSE(close_callback->have_result());
1164
1165 close_stream->Close(false);
1166 close_stream.reset();
1167 close_callback.reset();
1168
1169 base::MessageLoop::current()->RunUntilIdle();
1170 }
1171
1172 TEST_F(HttpPipelinedConnectionImplTest, AbortWhileSendQueued) {
1173 MockWrite writes[] = {
1174 MockWrite(ASYNC, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
1175 MockWrite(ASYNC, 1, "GET /ko.html HTTP/1.1\r\n\r\n"),
1176 };
1177 Initialize(NULL, 0, writes, arraysize(writes));
1178
1179 scoped_ptr<HttpStream> stream1(NewTestStream("ok.html"));
1180 scoped_ptr<HttpStream> stream2(NewTestStream("ko.html"));
1181
1182 HttpRequestHeaders headers1;
1183 HttpResponseInfo response1;
1184 TestCompletionCallback callback1;
1185 EXPECT_EQ(ERR_IO_PENDING, stream1->SendRequest(headers1, &response1,
1186 callback1.callback()));
1187
1188 HttpRequestHeaders headers2;
1189 HttpResponseInfo response2;
1190 TestCompletionCallback callback2;
1191 EXPECT_EQ(ERR_IO_PENDING, stream2->SendRequest(headers2, &response2,
1192 callback2.callback()));
1193
1194 stream2.reset();
1195 stream1->Close(true);
1196
1197 EXPECT_FALSE(callback2.have_result());
1198 }
1199
1200 TEST_F(HttpPipelinedConnectionImplTest, NoGapBetweenCloseAndEviction) {
1201 MockWrite writes[] = {
1202 MockWrite(SYNCHRONOUS, 0, "GET /close.html HTTP/1.1\r\n\r\n"),
1203 MockWrite(SYNCHRONOUS, 2, "GET /dummy.html HTTP/1.1\r\n\r\n"),
1204 };
1205 MockRead reads[] = {
1206 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
1207 MockRead(ASYNC, 3, "Content-Length: 7\r\n\r\n"),
1208 };
1209 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1210
1211 scoped_ptr<HttpStream> close_stream(NewTestStream("close.html"));
1212 scoped_ptr<HttpStream> dummy_stream(NewTestStream("dummy.html"));
1213
1214 HttpRequestHeaders headers;
1215 HttpResponseInfo response;
1216 EXPECT_EQ(OK, close_stream->SendRequest(headers, &response,
1217 callback_.callback()));
1218
1219 TestCompletionCallback close_callback;
1220 EXPECT_EQ(ERR_IO_PENDING,
1221 close_stream->ReadResponseHeaders(close_callback.callback()));
1222
1223 EXPECT_EQ(OK, dummy_stream->SendRequest(headers, &response,
1224 callback_.callback()));
1225
1226 TestCompletionCallback dummy_callback;
1227 EXPECT_EQ(ERR_IO_PENDING,
1228 dummy_stream->ReadResponseHeaders(dummy_callback.callback()));
1229
1230 close_stream->Close(true);
1231 close_stream.reset();
1232
1233 EXPECT_TRUE(dummy_callback.have_result());
1234 EXPECT_EQ(ERR_PIPELINE_EVICTION, dummy_callback.WaitForResult());
1235 dummy_stream->Close(true);
1236 dummy_stream.reset();
1237 pipeline_.reset();
1238 }
1239
1240 TEST_F(HttpPipelinedConnectionImplTest, RecoverFromDrainOnRedirect) {
1241 MockWrite writes[] = {
1242 MockWrite(SYNCHRONOUS, 0, "GET /redirect.html HTTP/1.1\r\n\r\n"),
1243 MockWrite(SYNCHRONOUS, 1, "GET /ok.html HTTP/1.1\r\n\r\n"),
1244 };
1245 MockRead reads[] = {
1246 MockRead(SYNCHRONOUS, 2,
1247 "HTTP/1.1 302 OK\r\n"
1248 "Content-Length: 8\r\n\r\n"
1249 "redirect"),
1250 MockRead(SYNCHRONOUS, 3,
1251 "HTTP/1.1 200 OK\r\n"
1252 "Content-Length: 7\r\n\r\n"
1253 "ok.html"),
1254 };
1255 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1256
1257 scoped_ptr<HttpStream> stream1(NewTestStream("redirect.html"));
1258 scoped_ptr<HttpStream> stream2(NewTestStream("ok.html"));
1259
1260 HttpRequestHeaders headers1;
1261 HttpResponseInfo response1;
1262 EXPECT_EQ(OK, stream1->SendRequest(headers1,
1263 &response1, callback_.callback()));
1264 HttpRequestHeaders headers2;
1265 HttpResponseInfo response2;
1266 EXPECT_EQ(OK, stream2->SendRequest(headers2,
1267 &response2, callback_.callback()));
1268
1269 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
1270 stream1.release()->Drain(NULL);
1271
1272 EXPECT_EQ(OK, stream2->ReadResponseHeaders(callback_.callback()));
1273 ExpectResponse("ok.html", stream2, false);
1274 stream2->Close(false);
1275 }
1276
1277 TEST_F(HttpPipelinedConnectionImplTest, EvictAfterDrainOfUnknownSize) {
1278 MockWrite writes[] = {
1279 MockWrite(SYNCHRONOUS, 0, "GET /redirect.html HTTP/1.1\r\n\r\n"),
1280 MockWrite(SYNCHRONOUS, 1, "GET /ok.html HTTP/1.1\r\n\r\n"),
1281 };
1282 MockRead reads[] = {
1283 MockRead(SYNCHRONOUS, 2,
1284 "HTTP/1.1 302 OK\r\n\r\n"
1285 "redirect"),
1286 };
1287 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1288
1289 scoped_ptr<HttpStream> stream1(NewTestStream("redirect.html"));
1290 scoped_ptr<HttpStream> stream2(NewTestStream("ok.html"));
1291
1292 HttpRequestHeaders headers1;
1293 HttpResponseInfo response1;
1294 EXPECT_EQ(OK, stream1->SendRequest(headers1,
1295 &response1, callback_.callback()));
1296 HttpRequestHeaders headers2;
1297 HttpResponseInfo response2;
1298 EXPECT_EQ(OK, stream2->SendRequest(headers2,
1299 &response2, callback_.callback()));
1300
1301 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
1302 stream1.release()->Drain(NULL);
1303
1304 EXPECT_EQ(ERR_PIPELINE_EVICTION,
1305 stream2->ReadResponseHeaders(callback_.callback()));
1306 stream2->Close(false);
1307 }
1308
1309 TEST_F(HttpPipelinedConnectionImplTest, EvictAfterFailedDrain) {
1310 MockWrite writes[] = {
1311 MockWrite(SYNCHRONOUS, 0, "GET /redirect.html HTTP/1.1\r\n\r\n"),
1312 MockWrite(SYNCHRONOUS, 1, "GET /ok.html HTTP/1.1\r\n\r\n"),
1313 };
1314 MockRead reads[] = {
1315 MockRead(SYNCHRONOUS, 2,
1316 "HTTP/1.1 302 OK\r\n"
1317 "Content-Length: 8\r\n\r\n"),
1318 MockRead(SYNCHRONOUS, ERR_SOCKET_NOT_CONNECTED, 3),
1319 };
1320 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1321
1322 scoped_ptr<HttpStream> stream1(NewTestStream("redirect.html"));
1323 scoped_ptr<HttpStream> stream2(NewTestStream("ok.html"));
1324
1325 HttpRequestHeaders headers1;
1326 HttpResponseInfo response1;
1327 EXPECT_EQ(OK, stream1->SendRequest(headers1,
1328 &response1, callback_.callback()));
1329 HttpRequestHeaders headers2;
1330 HttpResponseInfo response2;
1331 EXPECT_EQ(OK, stream2->SendRequest(headers2,
1332 &response2, callback_.callback()));
1333
1334
1335 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
1336 stream1.release()->Drain(NULL);
1337
1338 EXPECT_EQ(ERR_PIPELINE_EVICTION,
1339 stream2->ReadResponseHeaders(callback_.callback()));
1340 stream2->Close(false);
1341 }
1342
1343 TEST_F(HttpPipelinedConnectionImplTest, EvictIfDrainingChunkedEncoding) {
1344 MockWrite writes[] = {
1345 MockWrite(SYNCHRONOUS, 0, "GET /redirect.html HTTP/1.1\r\n\r\n"),
1346 MockWrite(SYNCHRONOUS, 1, "GET /ok.html HTTP/1.1\r\n\r\n"),
1347 };
1348 MockRead reads[] = {
1349 MockRead(SYNCHRONOUS, 2,
1350 "HTTP/1.1 302 OK\r\n"
1351 "Transfer-Encoding: chunked\r\n\r\n"),
1352 MockRead(SYNCHRONOUS, 3,
1353 "jibberish"),
1354 };
1355 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1356
1357 scoped_ptr<HttpStream> stream1(NewTestStream("redirect.html"));
1358 scoped_ptr<HttpStream> stream2(NewTestStream("ok.html"));
1359
1360 HttpRequestHeaders headers1;
1361 HttpResponseInfo response1;
1362 EXPECT_EQ(OK, stream1->SendRequest(headers1,
1363 &response1, callback_.callback()));
1364 HttpRequestHeaders headers2;
1365 HttpResponseInfo response2;
1366 EXPECT_EQ(OK, stream2->SendRequest(headers2,
1367 &response2, callback_.callback()));
1368
1369
1370 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
1371 stream1.release()->Drain(NULL);
1372
1373 EXPECT_EQ(ERR_PIPELINE_EVICTION,
1374 stream2->ReadResponseHeaders(callback_.callback()));
1375 stream2->Close(false);
1376 }
1377
1378 TEST_F(HttpPipelinedConnectionImplTest, EvictionDueToMissingContentLength) {
1379 MockWrite writes[] = {
1380 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
1381 MockWrite(SYNCHRONOUS, 1, "GET /evicted.html HTTP/1.1\r\n\r\n"),
1382 MockWrite(SYNCHRONOUS, 2, "GET /rejected.html HTTP/1.1\r\n\r\n"),
1383 };
1384 MockRead reads[] = {
1385 MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1386 MockRead(SYNCHRONOUS, 4, "ok.html"),
1387 MockRead(SYNCHRONOUS, OK, 5),
1388 };
1389 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1390
1391 scoped_ptr<HttpStream> ok_stream(NewTestStream("ok.html"));
1392 scoped_ptr<HttpStream> evicted_stream(NewTestStream("evicted.html"));
1393 scoped_ptr<HttpStream> rejected_stream(NewTestStream("rejected.html"));
1394
1395 HttpRequestHeaders headers;
1396 HttpResponseInfo response;
1397 EXPECT_EQ(OK, ok_stream->SendRequest(headers,
1398 &response, callback_.callback()));
1399 EXPECT_EQ(OK, evicted_stream->SendRequest(headers,
1400 &response, callback_.callback()));
1401 EXPECT_EQ(OK, rejected_stream->SendRequest(headers,
1402 &response, callback_.callback()));
1403
1404 TestCompletionCallback ok_callback;
1405 EXPECT_EQ(ERR_IO_PENDING,
1406 ok_stream->ReadResponseHeaders(ok_callback.callback()));
1407
1408 TestCompletionCallback evicted_callback;
1409 EXPECT_EQ(ERR_IO_PENDING,
1410 evicted_stream->ReadResponseHeaders(evicted_callback.callback()));
1411
1412 data_->RunFor(1);
1413 EXPECT_LE(OK, ok_callback.WaitForResult());
1414 data_->StopAfter(10);
1415
1416 ExpectResponse("ok.html", ok_stream, false);
1417 ok_stream->Close(false);
1418
1419 EXPECT_EQ(ERR_PIPELINE_EVICTION,
1420 rejected_stream->ReadResponseHeaders(callback_.callback()));
1421 rejected_stream->Close(true);
1422 EXPECT_EQ(ERR_PIPELINE_EVICTION, evicted_callback.WaitForResult());
1423 evicted_stream->Close(true);
1424 }
1425
1426 TEST_F(HttpPipelinedConnectionImplTest, FeedbackOnSocketError) {
1427 MockWrite writes[] = {
1428 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
1429 };
1430 MockRead reads[] = {
1431 MockRead(SYNCHRONOUS, ERR_FAILED, 1),
1432 };
1433 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1434
1435 EXPECT_CALL(delegate_,
1436 OnPipelineFeedback(
1437 pipeline_.get(),
1438 HttpPipelinedConnection::PIPELINE_SOCKET_ERROR))
1439 .Times(1);
1440
1441 scoped_ptr<HttpStream> stream(NewTestStream("ok.html"));
1442 HttpRequestHeaders headers;
1443 HttpResponseInfo response;
1444 EXPECT_EQ(OK, stream->SendRequest(headers,
1445 &response, callback_.callback()));
1446 EXPECT_EQ(ERR_FAILED, stream->ReadResponseHeaders(callback_.callback()));
1447 }
1448
1449 TEST_F(HttpPipelinedConnectionImplTest, FeedbackOnNoInternetConnection) {
1450 MockWrite writes[] = {
1451 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
1452 };
1453 MockRead reads[] = {
1454 MockRead(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED, 1),
1455 };
1456 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1457
1458 EXPECT_CALL(delegate_, OnPipelineFeedback(_, _))
1459 .Times(0);
1460
1461 scoped_ptr<HttpStream> stream(NewTestStream("ok.html"));
1462 HttpRequestHeaders headers;
1463 HttpResponseInfo response;
1464 EXPECT_EQ(OK, stream->SendRequest(headers,
1465 &response, callback_.callback()));
1466 EXPECT_EQ(ERR_INTERNET_DISCONNECTED,
1467 stream->ReadResponseHeaders(callback_.callback()));
1468 }
1469
1470 TEST_F(HttpPipelinedConnectionImplTest, FeedbackOnHttp10) {
1471 MockWrite writes[] = {
1472 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
1473 };
1474 MockRead reads[] = {
1475 MockRead(SYNCHRONOUS, 1, "HTTP/1.0 200 OK\r\n"),
1476 MockRead(SYNCHRONOUS, 2, "Content-Length: 7\r\n"),
1477 MockRead(SYNCHRONOUS, 3, "Connection: keep-alive\r\n\r\n"),
1478 MockRead(SYNCHRONOUS, 4, "ok.html"),
1479 };
1480 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1481
1482 EXPECT_CALL(delegate_,
1483 OnPipelineFeedback(pipeline_.get(),
1484 HttpPipelinedConnection::OLD_HTTP_VERSION))
1485 .Times(1);
1486
1487 scoped_ptr<HttpStream> stream(NewTestStream("ok.html"));
1488 TestSyncRequest(stream, "ok.html");
1489 }
1490
1491 TEST_F(HttpPipelinedConnectionImplTest, FeedbackOnMustClose) {
1492 MockWrite writes[] = {
1493 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
1494 };
1495 MockRead reads[] = {
1496 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
1497 MockRead(SYNCHRONOUS, 2, "Content-Length: 7\r\n"),
1498 MockRead(SYNCHRONOUS, 3, "Connection: close\r\n\r\n"),
1499 MockRead(SYNCHRONOUS, 4, "ok.html"),
1500 };
1501 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1502
1503 EXPECT_CALL(delegate_,
1504 OnPipelineFeedback(
1505 pipeline_.get(),
1506 HttpPipelinedConnection::MUST_CLOSE_CONNECTION))
1507 .Times(1);
1508
1509 scoped_ptr<HttpStream> stream(NewTestStream("ok.html"));
1510 TestSyncRequest(stream, "ok.html");
1511 }
1512
1513 TEST_F(HttpPipelinedConnectionImplTest, FeedbackOnNoContentLength) {
1514 MockWrite writes[] = {
1515 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
1516 };
1517 MockRead reads[] = {
1518 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n\r\n"),
1519 MockRead(SYNCHRONOUS, 2, "ok.html"),
1520 };
1521 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1522
1523 EXPECT_CALL(delegate_,
1524 OnPipelineFeedback(
1525 pipeline_.get(),
1526 HttpPipelinedConnection::MUST_CLOSE_CONNECTION))
1527 .Times(1);
1528
1529 scoped_ptr<HttpStream> stream(NewTestStream("ok.html"));
1530 TestSyncRequest(stream, "ok.html");
1531 }
1532
1533 TEST_F(HttpPipelinedConnectionImplTest, FeedbackOnAuthenticationRequired) {
1534 MockWrite writes[] = {
1535 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
1536 };
1537 MockRead reads[] = {
1538 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 401 Unauthorized\r\n"),
1539 MockRead(SYNCHRONOUS, 2, "WWW-Authenticate: NTLM\r\n"),
1540 MockRead(SYNCHRONOUS, 3, "Content-Length: 7\r\n\r\n"),
1541 MockRead(SYNCHRONOUS, 4, "ok.html"),
1542 };
1543 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1544
1545 EXPECT_CALL(delegate_,
1546 OnPipelineFeedback(
1547 pipeline_.get(),
1548 HttpPipelinedConnection::AUTHENTICATION_REQUIRED))
1549 .Times(1);
1550
1551 scoped_ptr<HttpStream> stream(NewTestStream("ok.html"));
1552 TestSyncRequest(stream, "ok.html");
1553 }
1554
1555 TEST_F(HttpPipelinedConnectionImplTest, OnPipelineHasCapacity) {
1556 MockWrite writes[] = {
1557 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
1558 };
1559 Initialize(NULL, 0, writes, arraysize(writes));
1560
1561 EXPECT_CALL(delegate_, OnPipelineHasCapacity(pipeline_.get())).Times(0);
1562 scoped_ptr<HttpStream> stream(NewTestStream("ok.html"));
1563
1564 EXPECT_CALL(delegate_, OnPipelineHasCapacity(pipeline_.get())).Times(1);
1565 HttpRequestHeaders headers;
1566 HttpResponseInfo response;
1567 EXPECT_EQ(OK, stream->SendRequest(headers,
1568 &response, callback_.callback()));
1569
1570 EXPECT_CALL(delegate_, OnPipelineHasCapacity(pipeline_.get())).Times(0);
1571 base::MessageLoop::current()->RunUntilIdle();
1572
1573 stream->Close(false);
1574 EXPECT_CALL(delegate_, OnPipelineHasCapacity(pipeline_.get())).Times(1);
1575 stream.reset(NULL);
1576 }
1577
1578 TEST_F(HttpPipelinedConnectionImplTest, OnPipelineHasCapacityWithoutSend) {
1579 MockWrite writes[] = {
1580 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
1581 };
1582 Initialize(NULL, 0, writes, arraysize(writes));
1583
1584 EXPECT_CALL(delegate_, OnPipelineHasCapacity(pipeline_.get())).Times(0);
1585 scoped_ptr<HttpStream> stream(NewTestStream("ok.html"));
1586
1587 EXPECT_CALL(delegate_, OnPipelineHasCapacity(pipeline_.get())).Times(1);
1588 base::MessageLoop::current()->RunUntilIdle();
1589
1590 stream->Close(false);
1591 EXPECT_CALL(delegate_, OnPipelineHasCapacity(pipeline_.get())).Times(1);
1592 stream.reset(NULL);
1593 }
1594
1595 } // anonymous namespace
1596
1597 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698