- add sources.
[platform/framework/web/crosswalk.git] / src / net / http / http_pipelined_connection_impl_unittest.cc
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