• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/spdy/spdy_session.h"
6 
7 #include "base/bind.h"
8 #include "base/callback.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/run_loop.h"
11 #include "net/base/io_buffer.h"
12 #include "net/base/ip_endpoint.h"
13 #include "net/base/net_log_unittest.h"
14 #include "net/base/request_priority.h"
15 #include "net/base/test_data_directory.h"
16 #include "net/base/test_data_stream.h"
17 #include "net/socket/client_socket_pool_manager.h"
18 #include "net/socket/next_proto.h"
19 #include "net/socket/socket_test_util.h"
20 #include "net/spdy/spdy_http_utils.h"
21 #include "net/spdy/spdy_session_pool.h"
22 #include "net/spdy/spdy_session_test_util.h"
23 #include "net/spdy/spdy_stream.h"
24 #include "net/spdy/spdy_stream_test_util.h"
25 #include "net/spdy/spdy_test_util_common.h"
26 #include "net/spdy/spdy_test_utils.h"
27 #include "net/test/cert_test_util.h"
28 #include "testing/platform_test.h"
29 
30 namespace net {
31 
32 namespace {
33 
34 static const char kTestUrl[] = "http://www.example.org/";
35 static const char kTestHost[] = "www.example.org";
36 static const int kTestPort = 80;
37 
38 const char kBodyData[] = "Body data";
39 const size_t kBodyDataSize = arraysize(kBodyData);
40 const base::StringPiece kBodyDataStringPiece(kBodyData, kBodyDataSize);
41 
42 static base::TimeDelta g_time_delta;
TheNearFuture()43 base::TimeTicks TheNearFuture() {
44   return base::TimeTicks::Now() + g_time_delta;
45 }
46 
47 }  // namespace
48 
49 class SpdySessionTest : public PlatformTest,
50                         public ::testing::WithParamInterface<NextProto> {
51  public:
52   // Functions used with RunResumeAfterUnstallTest().
53 
StallSessionOnly(SpdySession * session,SpdyStream * stream)54   void StallSessionOnly(SpdySession* session, SpdyStream* stream) {
55     StallSessionSend(session);
56   }
57 
StallStreamOnly(SpdySession * session,SpdyStream * stream)58   void StallStreamOnly(SpdySession* session, SpdyStream* stream) {
59     StallStreamSend(stream);
60   }
61 
StallSessionStream(SpdySession * session,SpdyStream * stream)62   void StallSessionStream(SpdySession* session, SpdyStream* stream) {
63     StallSessionSend(session);
64     StallStreamSend(stream);
65   }
66 
StallStreamSession(SpdySession * session,SpdyStream * stream)67   void StallStreamSession(SpdySession* session, SpdyStream* stream) {
68     StallStreamSend(stream);
69     StallSessionSend(session);
70   }
71 
UnstallSessionOnly(SpdySession * session,SpdyStream * stream,int32 delta_window_size)72   void UnstallSessionOnly(SpdySession* session,
73                           SpdyStream* stream,
74                           int32 delta_window_size) {
75     UnstallSessionSend(session, delta_window_size);
76   }
77 
UnstallStreamOnly(SpdySession * session,SpdyStream * stream,int32 delta_window_size)78   void UnstallStreamOnly(SpdySession* session,
79                          SpdyStream* stream,
80                          int32 delta_window_size) {
81     UnstallStreamSend(stream, delta_window_size);
82   }
83 
UnstallSessionStream(SpdySession * session,SpdyStream * stream,int32 delta_window_size)84   void UnstallSessionStream(SpdySession* session,
85                             SpdyStream* stream,
86                             int32 delta_window_size) {
87     UnstallSessionSend(session, delta_window_size);
88     UnstallStreamSend(stream, delta_window_size);
89   }
90 
UnstallStreamSession(SpdySession * session,SpdyStream * stream,int32 delta_window_size)91   void UnstallStreamSession(SpdySession* session,
92                             SpdyStream* stream,
93                             int32 delta_window_size) {
94     UnstallStreamSend(stream, delta_window_size);
95     UnstallSessionSend(session, delta_window_size);
96   }
97 
98  protected:
SpdySessionTest()99   SpdySessionTest()
100       : old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
101             HttpNetworkSession::NORMAL_SOCKET_POOL)),
102         old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
103             HttpNetworkSession::NORMAL_SOCKET_POOL)),
104         spdy_util_(GetParam()),
105         session_deps_(GetParam()),
106         spdy_session_pool_(NULL),
107         test_url_(kTestUrl),
108         test_host_port_pair_(kTestHost, kTestPort),
109         key_(test_host_port_pair_, ProxyServer::Direct(),
110              kPrivacyModeDisabled) {
111   }
112 
~SpdySessionTest()113   virtual ~SpdySessionTest() {
114     // Important to restore the per-pool limit first, since the pool limit must
115     // always be greater than group limit, and the tests reduce both limits.
116     ClientSocketPoolManager::set_max_sockets_per_pool(
117         HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
118     ClientSocketPoolManager::set_max_sockets_per_group(
119         HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
120   }
121 
SetUp()122   virtual void SetUp() OVERRIDE {
123     g_time_delta = base::TimeDelta();
124   }
125 
CreateDeterministicNetworkSession()126   void CreateDeterministicNetworkSession() {
127     http_session_ =
128         SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_);
129     spdy_session_pool_ = http_session_->spdy_session_pool();
130   }
131 
CreateNetworkSession()132   void CreateNetworkSession() {
133     http_session_ =
134         SpdySessionDependencies::SpdyCreateSession(&session_deps_);
135     spdy_session_pool_ = http_session_->spdy_session_pool();
136   }
137 
StallSessionSend(SpdySession * session)138   void StallSessionSend(SpdySession* session) {
139     // Reduce the send window size to 0 to stall.
140     while (session->session_send_window_size_ > 0) {
141       session->DecreaseSendWindowSize(
142           std::min(kMaxSpdyFrameChunkSize, session->session_send_window_size_));
143     }
144   }
145 
UnstallSessionSend(SpdySession * session,int32 delta_window_size)146   void UnstallSessionSend(SpdySession* session, int32 delta_window_size) {
147     session->IncreaseSendWindowSize(delta_window_size);
148   }
149 
StallStreamSend(SpdyStream * stream)150   void StallStreamSend(SpdyStream* stream) {
151     // Reduce the send window size to 0 to stall.
152     while (stream->send_window_size() > 0) {
153       stream->DecreaseSendWindowSize(
154           std::min(kMaxSpdyFrameChunkSize, stream->send_window_size()));
155     }
156   }
157 
UnstallStreamSend(SpdyStream * stream,int32 delta_window_size)158   void UnstallStreamSend(SpdyStream* stream, int32 delta_window_size) {
159     stream->IncreaseSendWindowSize(delta_window_size);
160   }
161 
162   void RunResumeAfterUnstallTest(
163       const base::Callback<void(SpdySession*, SpdyStream*)>& stall_function,
164       const base::Callback<void(SpdySession*, SpdyStream*, int32)>&
165           unstall_function);
166 
167   // Original socket limits.  Some tests set these.  Safest to always restore
168   // them once each test has been run.
169   int old_max_group_sockets_;
170   int old_max_pool_sockets_;
171 
172   SpdyTestUtil spdy_util_;
173   SpdySessionDependencies session_deps_;
174   scoped_refptr<HttpNetworkSession> http_session_;
175   SpdySessionPool* spdy_session_pool_;
176   GURL test_url_;
177   HostPortPair test_host_port_pair_;
178   SpdySessionKey key_;
179 };
180 
181 INSTANTIATE_TEST_CASE_P(
182     NextProto,
183     SpdySessionTest,
184     testing::Values(kProtoDeprecatedSPDY2,
185                     kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2,
186                     kProtoHTTP2Draft04));
187 
188 // Try to create a SPDY session that will fail during
189 // initialization. Nothing should blow up.
TEST_P(SpdySessionTest,InitialReadError)190 TEST_P(SpdySessionTest, InitialReadError) {
191   CreateDeterministicNetworkSession();
192 
193   TryCreateFakeSpdySessionExpectingFailure(
194       spdy_session_pool_, key_, ERR_FAILED);
195 }
196 
197 namespace {
198 
199 // A helper class that vends a callback that, when fired, destroys a
200 // given SpdyStreamRequest.
201 class StreamRequestDestroyingCallback : public TestCompletionCallbackBase {
202  public:
StreamRequestDestroyingCallback()203   StreamRequestDestroyingCallback() {}
204 
~StreamRequestDestroyingCallback()205   virtual ~StreamRequestDestroyingCallback() {}
206 
SetRequestToDestroy(scoped_ptr<SpdyStreamRequest> request)207   void SetRequestToDestroy(scoped_ptr<SpdyStreamRequest> request) {
208     request_ = request.Pass();
209   }
210 
MakeCallback()211   CompletionCallback MakeCallback() {
212     return base::Bind(&StreamRequestDestroyingCallback::OnComplete,
213                       base::Unretained(this));
214   }
215 
216  private:
OnComplete(int result)217   void OnComplete(int result) {
218     request_.reset();
219     SetResult(result);
220   }
221 
222   scoped_ptr<SpdyStreamRequest> request_;
223 };
224 
225 }  // namespace
226 
227 // Request kInitialMaxConcurrentStreams streams.  Request two more
228 // streams, but have the callback for one destroy the second stream
229 // request. Close the session. Nothing should blow up. This is a
230 // regression test for http://crbug.com/250841 .
TEST_P(SpdySessionTest,PendingStreamCancellingAnother)231 TEST_P(SpdySessionTest, PendingStreamCancellingAnother) {
232   session_deps_.host_resolver->set_synchronous_mode(true);
233 
234   MockRead reads[] = {MockRead(ASYNC, 0, 0), };
235 
236   DeterministicSocketData data(reads, arraysize(reads), NULL, 0);
237   MockConnect connect_data(SYNCHRONOUS, OK);
238   data.set_connect_data(connect_data);
239   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
240 
241   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
242   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
243 
244   CreateDeterministicNetworkSession();
245 
246   base::WeakPtr<SpdySession> session =
247       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
248 
249   // Create the maximum number of concurrent streams.
250   for (size_t i = 0; i < kInitialMaxConcurrentStreams; ++i) {
251     base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously(
252         SPDY_BIDIRECTIONAL_STREAM, session, test_url_, MEDIUM, BoundNetLog());
253     ASSERT_TRUE(spdy_stream != NULL);
254   }
255 
256   SpdyStreamRequest request1;
257   scoped_ptr<SpdyStreamRequest> request2(new SpdyStreamRequest);
258 
259   StreamRequestDestroyingCallback callback1;
260   ASSERT_EQ(ERR_IO_PENDING,
261             request1.StartRequest(SPDY_BIDIRECTIONAL_STREAM,
262                                   session,
263                                   test_url_,
264                                   MEDIUM,
265                                   BoundNetLog(),
266                                   callback1.MakeCallback()));
267 
268   // |callback2| is never called.
269   TestCompletionCallback callback2;
270   ASSERT_EQ(ERR_IO_PENDING,
271             request2->StartRequest(SPDY_BIDIRECTIONAL_STREAM,
272                                    session,
273                                    test_url_,
274                                    MEDIUM,
275                                    BoundNetLog(),
276                                    callback2.callback()));
277 
278   callback1.SetRequestToDestroy(request2.Pass());
279 
280   session->CloseSessionOnError(ERR_ABORTED, "Aborting session");
281 
282   EXPECT_EQ(ERR_ABORTED, callback1.WaitForResult());
283 
284   data.RunFor(1);
285 }
286 
287 // A session receiving a GOAWAY frame with no active streams should
288 // immediately close.
TEST_P(SpdySessionTest,GoAwayWithNoActiveStreams)289 TEST_P(SpdySessionTest, GoAwayWithNoActiveStreams) {
290   session_deps_.host_resolver->set_synchronous_mode(true);
291 
292   MockConnect connect_data(SYNCHRONOUS, OK);
293   scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
294   MockRead reads[] = {
295     CreateMockRead(*goaway, 0),
296   };
297   DeterministicSocketData data(reads, arraysize(reads), NULL, 0);
298   data.set_connect_data(connect_data);
299   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
300 
301   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
302   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
303 
304   CreateDeterministicNetworkSession();
305 
306   base::WeakPtr<SpdySession> session =
307       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
308 
309   EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion());
310 
311   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
312 
313   // Read and process the GOAWAY frame.
314   data.RunFor(1);
315 
316   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
317 
318   EXPECT_TRUE(session == NULL);
319 }
320 
321 // A session receiving a GOAWAY frame immediately with no active
322 // streams should then close.
TEST_P(SpdySessionTest,GoAwayImmediatelyWithNoActiveStreams)323 TEST_P(SpdySessionTest, GoAwayImmediatelyWithNoActiveStreams) {
324   session_deps_.host_resolver->set_synchronous_mode(true);
325 
326   MockConnect connect_data(SYNCHRONOUS, OK);
327   scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
328   MockRead reads[] = {
329     CreateMockRead(*goaway, 0, SYNCHRONOUS),
330   };
331   DeterministicSocketData data(reads, arraysize(reads), NULL, 0);
332   data.set_connect_data(connect_data);
333   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
334 
335   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
336   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
337 
338   CreateDeterministicNetworkSession();
339 
340   data.StopAfter(1);
341 
342   TryCreateInsecureSpdySessionExpectingFailure(
343       http_session_, key_, ERR_CONNECTION_CLOSED, BoundNetLog());
344 
345   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
346 }
347 
348 // A session receiving a GOAWAY frame with active streams should close
349 // when the last active stream is closed.
TEST_P(SpdySessionTest,GoAwayWithActiveStreams)350 TEST_P(SpdySessionTest, GoAwayWithActiveStreams) {
351   session_deps_.host_resolver->set_synchronous_mode(true);
352 
353   MockConnect connect_data(SYNCHRONOUS, OK);
354   scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
355   MockRead reads[] = {
356     CreateMockRead(*goaway, 2),
357     MockRead(ASYNC, 0, 3)  // EOF
358   };
359   scoped_ptr<SpdyFrame> req1(
360       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
361   scoped_ptr<SpdyFrame> req2(
362       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, MEDIUM, true));
363   MockWrite writes[] = {
364     CreateMockWrite(*req1, 0),
365     CreateMockWrite(*req2, 1),
366   };
367   DeterministicSocketData data(reads, arraysize(reads),
368                                writes, arraysize(writes));
369   data.set_connect_data(connect_data);
370   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
371 
372   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
373   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
374 
375   CreateDeterministicNetworkSession();
376 
377   base::WeakPtr<SpdySession> session =
378       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
379 
380   EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion());
381 
382   GURL url("http://www.google.com");
383   base::WeakPtr<SpdyStream> spdy_stream1 =
384       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
385                                 session, url, MEDIUM, BoundNetLog());
386   test::StreamDelegateDoNothing delegate1(spdy_stream1);
387   spdy_stream1->SetDelegate(&delegate1);
388 
389   base::WeakPtr<SpdyStream> spdy_stream2 =
390       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
391                                 session, url, MEDIUM, BoundNetLog());
392   test::StreamDelegateDoNothing delegate2(spdy_stream2);
393   spdy_stream2->SetDelegate(&delegate2);
394 
395   scoped_ptr<SpdyHeaderBlock> headers(
396       spdy_util_.ConstructGetHeaderBlock(url.spec()));
397   scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock(*headers));
398 
399   spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
400   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
401   spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
402   EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders());
403 
404   data.RunFor(2);
405 
406   EXPECT_EQ(1u, spdy_stream1->stream_id());
407   EXPECT_EQ(3u, spdy_stream2->stream_id());
408 
409   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
410 
411   // Read and process the GOAWAY frame.
412   data.RunFor(1);
413 
414   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
415 
416   EXPECT_FALSE(session->IsStreamActive(3));
417   EXPECT_EQ(NULL, spdy_stream2.get());
418   EXPECT_TRUE(session->IsStreamActive(1));
419 
420   EXPECT_FALSE(session->IsClosed());
421 
422   // Should close the session.
423   spdy_stream1->Close();
424   EXPECT_EQ(NULL, spdy_stream1.get());
425 
426   EXPECT_TRUE(session == NULL);
427 }
428 
429 // Have a session receive two GOAWAY frames, with the last one causing
430 // the last active stream to be closed. The session should then be
431 // closed after the second GOAWAY frame.
TEST_P(SpdySessionTest,GoAwayTwice)432 TEST_P(SpdySessionTest, GoAwayTwice) {
433   session_deps_.host_resolver->set_synchronous_mode(true);
434 
435   MockConnect connect_data(SYNCHRONOUS, OK);
436   scoped_ptr<SpdyFrame> goaway1(spdy_util_.ConstructSpdyGoAway(1));
437   scoped_ptr<SpdyFrame> goaway2(spdy_util_.ConstructSpdyGoAway(0));
438   MockRead reads[] = {
439     CreateMockRead(*goaway1, 2),
440     CreateMockRead(*goaway2, 3),
441     MockRead(ASYNC, 0, 4)  // EOF
442   };
443   scoped_ptr<SpdyFrame> req1(
444       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
445   scoped_ptr<SpdyFrame> req2(
446       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, MEDIUM, true));
447   MockWrite writes[] = {
448     CreateMockWrite(*req1, 0),
449     CreateMockWrite(*req2, 1),
450   };
451   DeterministicSocketData data(reads, arraysize(reads),
452                                writes, arraysize(writes));
453   data.set_connect_data(connect_data);
454   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
455 
456   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
457   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
458 
459   CreateDeterministicNetworkSession();
460 
461   base::WeakPtr<SpdySession> session =
462       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
463 
464   EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion());
465 
466   GURL url("http://www.google.com");
467   base::WeakPtr<SpdyStream> spdy_stream1 =
468       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
469                                 session, url, MEDIUM, BoundNetLog());
470   test::StreamDelegateDoNothing delegate1(spdy_stream1);
471   spdy_stream1->SetDelegate(&delegate1);
472 
473   base::WeakPtr<SpdyStream> spdy_stream2 =
474       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
475                                 session, url, MEDIUM, BoundNetLog());
476   test::StreamDelegateDoNothing delegate2(spdy_stream2);
477   spdy_stream2->SetDelegate(&delegate2);
478 
479   scoped_ptr<SpdyHeaderBlock> headers(
480       spdy_util_.ConstructGetHeaderBlock(url.spec()));
481   scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock(*headers));
482 
483   spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
484   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
485   spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
486   EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders());
487 
488   data.RunFor(2);
489 
490   EXPECT_EQ(1u, spdy_stream1->stream_id());
491   EXPECT_EQ(3u, spdy_stream2->stream_id());
492 
493   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
494 
495   // Read and process the first GOAWAY frame.
496   data.RunFor(1);
497 
498   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
499 
500   EXPECT_FALSE(session->IsStreamActive(3));
501   EXPECT_EQ(NULL, spdy_stream2.get());
502   EXPECT_TRUE(session->IsStreamActive(1));
503 
504   EXPECT_FALSE(session->IsClosed());
505 
506   // Read and process the second GOAWAY frame, which should close the
507   // session.
508   data.RunFor(1);
509 
510   EXPECT_TRUE(session == NULL);
511 }
512 
513 // Have a session with active streams receive a GOAWAY frame and then
514 // close it. It should handle the close properly (i.e., not try to
515 // make itself unavailable in its pool twice).
TEST_P(SpdySessionTest,GoAwayWithActiveStreamsThenClose)516 TEST_P(SpdySessionTest, GoAwayWithActiveStreamsThenClose) {
517   session_deps_.host_resolver->set_synchronous_mode(true);
518 
519   MockConnect connect_data(SYNCHRONOUS, OK);
520   scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
521   MockRead reads[] = {
522     CreateMockRead(*goaway, 2),
523     MockRead(ASYNC, 0, 3)  // EOF
524   };
525   scoped_ptr<SpdyFrame> req1(
526       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
527   scoped_ptr<SpdyFrame> req2(
528       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, MEDIUM, true));
529   MockWrite writes[] = {
530     CreateMockWrite(*req1, 0),
531     CreateMockWrite(*req2, 1),
532   };
533   DeterministicSocketData data(reads, arraysize(reads),
534                                writes, arraysize(writes));
535   data.set_connect_data(connect_data);
536   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
537 
538   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
539   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
540 
541   CreateDeterministicNetworkSession();
542 
543   base::WeakPtr<SpdySession> session =
544       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
545 
546   EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion());
547 
548   GURL url("http://www.google.com");
549   base::WeakPtr<SpdyStream> spdy_stream1 =
550       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
551                                 session, url, MEDIUM, BoundNetLog());
552   test::StreamDelegateDoNothing delegate1(spdy_stream1);
553   spdy_stream1->SetDelegate(&delegate1);
554 
555   base::WeakPtr<SpdyStream> spdy_stream2 =
556       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
557                                 session, url, MEDIUM, BoundNetLog());
558   test::StreamDelegateDoNothing delegate2(spdy_stream2);
559   spdy_stream2->SetDelegate(&delegate2);
560 
561   scoped_ptr<SpdyHeaderBlock> headers(
562       spdy_util_.ConstructGetHeaderBlock(url.spec()));
563   scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock(*headers));
564 
565   spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
566   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
567   spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
568   EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders());
569 
570   data.RunFor(2);
571 
572   EXPECT_EQ(1u, spdy_stream1->stream_id());
573   EXPECT_EQ(3u, spdy_stream2->stream_id());
574 
575   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
576 
577   // Read and process the GOAWAY frame.
578   data.RunFor(1);
579 
580   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
581 
582   EXPECT_FALSE(session->IsStreamActive(3));
583   EXPECT_EQ(NULL, spdy_stream2.get());
584   EXPECT_TRUE(session->IsStreamActive(1));
585 
586   EXPECT_FALSE(session->IsClosed());
587 
588   session->CloseSessionOnError(ERR_ABORTED, "Aborting session");
589 
590   EXPECT_EQ(NULL, spdy_stream1.get());
591   EXPECT_TRUE(session == NULL);
592 }
593 
594 // Try to create a stream after receiving a GOAWAY frame. It should
595 // fail.
TEST_P(SpdySessionTest,CreateStreamAfterGoAway)596 TEST_P(SpdySessionTest, CreateStreamAfterGoAway) {
597   const char kStreamUrl[] = "http://www.google.com";
598   session_deps_.host_resolver->set_synchronous_mode(true);
599 
600   MockConnect connect_data(SYNCHRONOUS, OK);
601   scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
602   MockRead reads[] = {
603     CreateMockRead(*goaway, 1),
604     MockRead(ASYNC, 0, 2)  // EOF
605   };
606   scoped_ptr<SpdyFrame> req(
607       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
608   MockWrite writes[] = {
609     CreateMockWrite(*req, 0),
610   };
611   DeterministicSocketData data(reads, arraysize(reads),
612                                writes, arraysize(writes));
613   data.set_connect_data(connect_data);
614   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
615 
616   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
617   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
618 
619   CreateDeterministicNetworkSession();
620 
621   base::WeakPtr<SpdySession> session =
622       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
623 
624   EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion());
625 
626   GURL url(kStreamUrl);
627   base::WeakPtr<SpdyStream> spdy_stream =
628       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
629                                 session, url, MEDIUM, BoundNetLog());
630   test::StreamDelegateDoNothing delegate(spdy_stream);
631   spdy_stream->SetDelegate(&delegate);
632 
633   scoped_ptr<SpdyHeaderBlock> headers(
634       spdy_util_.ConstructGetHeaderBlock(url.spec()));
635   spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
636   EXPECT_TRUE(spdy_stream->HasUrlFromHeaders());
637 
638   data.RunFor(1);
639 
640   EXPECT_EQ(1u, spdy_stream->stream_id());
641 
642   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
643 
644   // Read and process the GOAWAY frame.
645   data.RunFor(1);
646 
647   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
648   EXPECT_TRUE(session->IsStreamActive(1));
649 
650   SpdyStreamRequest stream_request;
651   int rv = stream_request.StartRequest(
652       SPDY_REQUEST_RESPONSE_STREAM, session, url, MEDIUM, BoundNetLog(),
653       CompletionCallback());
654   EXPECT_EQ(ERR_FAILED, rv);
655 
656   // Read and process EOF.
657   data.RunFor(1);
658 
659   EXPECT_TRUE(session == NULL);
660 }
661 
662 // Receiving a SYN_STREAM frame after a GOAWAY frame should result in
663 // the stream being refused.
TEST_P(SpdySessionTest,SynStreamAfterGoAway)664 TEST_P(SpdySessionTest, SynStreamAfterGoAway) {
665   const char kStreamUrl[] = "http://www.google.com";
666   session_deps_.host_resolver->set_synchronous_mode(true);
667 
668   MockConnect connect_data(SYNCHRONOUS, OK);
669   scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
670   scoped_ptr<SpdyFrame>
671       push(spdy_util_.ConstructSpdyPush(NULL, 0, 2, 1, kStreamUrl));
672   MockRead reads[] = {
673     CreateMockRead(*goaway, 1),
674     CreateMockRead(*push, 2),
675     MockRead(ASYNC, 0, 4)  // EOF
676   };
677   scoped_ptr<SpdyFrame> req(
678       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
679   scoped_ptr<SpdyFrame> rst(
680       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
681   MockWrite writes[] = {
682     CreateMockWrite(*req, 0),
683     CreateMockWrite(*rst, 3)
684   };
685   DeterministicSocketData data(reads, arraysize(reads),
686                                writes, arraysize(writes));
687   data.set_connect_data(connect_data);
688   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
689 
690   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
691   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
692 
693   CreateDeterministicNetworkSession();
694 
695   base::WeakPtr<SpdySession> session =
696       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
697 
698   EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion());
699 
700   GURL url(kStreamUrl);
701   base::WeakPtr<SpdyStream> spdy_stream =
702       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
703                                 session, url, MEDIUM, BoundNetLog());
704   test::StreamDelegateDoNothing delegate(spdy_stream);
705   spdy_stream->SetDelegate(&delegate);
706 
707   scoped_ptr<SpdyHeaderBlock> headers(
708       spdy_util_.ConstructGetHeaderBlock(url.spec()));
709   spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
710   EXPECT_TRUE(spdy_stream->HasUrlFromHeaders());
711 
712   data.RunFor(1);
713 
714   EXPECT_EQ(1u, spdy_stream->stream_id());
715 
716   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
717 
718   // Read and process the GOAWAY frame.
719   data.RunFor(1);
720 
721   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
722   EXPECT_TRUE(session->IsStreamActive(1));
723 
724   // Read and process the SYN_STREAM frame, the subsequent RST_STREAM,
725   // and EOF.
726   data.RunFor(3);
727 
728   EXPECT_TRUE(session == NULL);
729 }
730 
TEST_P(SpdySessionTest,ClientPing)731 TEST_P(SpdySessionTest, ClientPing) {
732   session_deps_.enable_ping = true;
733   session_deps_.host_resolver->set_synchronous_mode(true);
734 
735   MockConnect connect_data(SYNCHRONOUS, OK);
736   scoped_ptr<SpdyFrame> read_ping(spdy_util_.ConstructSpdyPing(1));
737   MockRead reads[] = {
738     CreateMockRead(*read_ping, 1),
739     MockRead(ASYNC, 0, 0, 2)  // EOF
740   };
741   scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1));
742   MockWrite writes[] = {
743     CreateMockWrite(*write_ping, 0),
744   };
745   DeterministicSocketData data(
746       reads, arraysize(reads), writes, arraysize(writes));
747   data.set_connect_data(connect_data);
748   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
749 
750   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
751   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
752 
753   CreateDeterministicNetworkSession();
754 
755   base::WeakPtr<SpdySession> session =
756       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
757 
758   base::WeakPtr<SpdyStream> spdy_stream1 =
759       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
760                                 session, test_url_, MEDIUM, BoundNetLog());
761   ASSERT_TRUE(spdy_stream1.get() != NULL);
762   test::StreamDelegateSendImmediate delegate(spdy_stream1, NULL);
763   spdy_stream1->SetDelegate(&delegate);
764 
765   base::TimeTicks before_ping_time = base::TimeTicks::Now();
766 
767   session->set_connection_at_risk_of_loss_time(
768       base::TimeDelta::FromSeconds(-1));
769   session->set_hung_interval(base::TimeDelta::FromMilliseconds(50));
770 
771   session->SendPrefacePingIfNoneInFlight();
772 
773   data.RunFor(2);
774 
775   session->CheckPingStatus(before_ping_time);
776 
777   EXPECT_EQ(0, session->pings_in_flight());
778   EXPECT_GE(session->next_ping_id(), static_cast<uint32>(1));
779   EXPECT_FALSE(session->check_ping_status_pending());
780   EXPECT_GE(session->last_activity_time(), before_ping_time);
781 
782   data.RunFor(1);
783 
784   EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose());
785 
786   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
787   EXPECT_TRUE(session == NULL);
788 }
789 
TEST_P(SpdySessionTest,ServerPing)790 TEST_P(SpdySessionTest, ServerPing) {
791   session_deps_.host_resolver->set_synchronous_mode(true);
792 
793   MockConnect connect_data(SYNCHRONOUS, OK);
794   scoped_ptr<SpdyFrame> read_ping(spdy_util_.ConstructSpdyPing(2));
795   MockRead reads[] = {
796     CreateMockRead(*read_ping),
797     MockRead(SYNCHRONOUS, 0, 0)  // EOF
798   };
799   scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(2));
800   MockWrite writes[] = {
801     CreateMockWrite(*write_ping),
802   };
803   StaticSocketDataProvider data(
804       reads, arraysize(reads), writes, arraysize(writes));
805   data.set_connect_data(connect_data);
806   session_deps_.socket_factory->AddSocketDataProvider(&data);
807 
808   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
809   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
810 
811   CreateNetworkSession();
812 
813   base::WeakPtr<SpdySession> session =
814       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
815 
816   base::WeakPtr<SpdyStream> spdy_stream1 =
817       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
818                                 session, test_url_, MEDIUM, BoundNetLog());
819   ASSERT_TRUE(spdy_stream1.get() != NULL);
820   test::StreamDelegateSendImmediate delegate(spdy_stream1, NULL);
821   spdy_stream1->SetDelegate(&delegate);
822 
823   // Flush the read completion task.
824   base::MessageLoop::current()->RunUntilIdle();
825 
826   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
827 
828   EXPECT_TRUE(session == NULL);
829   EXPECT_EQ(NULL, spdy_stream1.get());
830 }
831 
832 // Cause a ping to be sent out while producing a write. The write loop
833 // should handle this properly, i.e. another DoWriteLoop task should
834 // not be posted. This is a regression test for
835 // http://crbug.com/261043 .
TEST_P(SpdySessionTest,PingAndWriteLoop)836 TEST_P(SpdySessionTest, PingAndWriteLoop) {
837   session_deps_.enable_ping = true;
838   session_deps_.time_func = TheNearFuture;
839 
840   MockConnect connect_data(SYNCHRONOUS, OK);
841   scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1));
842   scoped_ptr<SpdyFrame> req(
843       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
844   MockWrite writes[] = {
845     CreateMockWrite(*req, 0),
846     CreateMockWrite(*write_ping, 1),
847   };
848 
849   MockRead reads[] = {
850     MockRead(ASYNC, 0, 2)  // EOF
851   };
852 
853   session_deps_.host_resolver->set_synchronous_mode(true);
854 
855   DeterministicSocketData data(reads, arraysize(reads),
856                                writes, arraysize(writes));
857   data.set_connect_data(connect_data);
858   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
859 
860   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
861   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
862 
863   CreateDeterministicNetworkSession();
864 
865   base::WeakPtr<SpdySession> session =
866       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
867 
868   GURL url("http://www.google.com");
869   base::WeakPtr<SpdyStream> spdy_stream =
870       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
871                                 session, url, LOWEST, BoundNetLog());
872   test::StreamDelegateDoNothing delegate(spdy_stream);
873   spdy_stream->SetDelegate(&delegate);
874 
875   scoped_ptr<SpdyHeaderBlock> headers(
876       spdy_util_.ConstructGetHeaderBlock(url.spec()));
877   spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
878 
879   // Shift time so that a ping will be sent out.
880   g_time_delta = base::TimeDelta::FromSeconds(11);
881 
882   data.RunFor(2);
883 
884   session->CloseSessionOnError(ERR_ABORTED, "Aborting");
885 }
886 
TEST_P(SpdySessionTest,DeleteExpiredPushStreams)887 TEST_P(SpdySessionTest, DeleteExpiredPushStreams) {
888   session_deps_.host_resolver->set_synchronous_mode(true);
889 
890   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
891   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
892   session_deps_.time_func = TheNearFuture;
893 
894   CreateNetworkSession();
895 
896   base::WeakPtr<SpdySession> session =
897       CreateFakeSpdySession(spdy_session_pool_, key_);
898 
899   session->buffered_spdy_framer_.reset(
900       new BufferedSpdyFramer(spdy_util_.spdy_version(), false));
901 
902   // Create the associated stream and add to active streams.
903   scoped_ptr<SpdyHeaderBlock> request_headers(
904       spdy_util_.ConstructGetHeaderBlock("http://www.google.com/"));
905 
906   scoped_ptr<SpdyStream> stream(new SpdyStream(SPDY_REQUEST_RESPONSE_STREAM,
907                                                session,
908                                                GURL(),
909                                                DEFAULT_PRIORITY,
910                                                kSpdyStreamInitialWindowSize,
911                                                kSpdyStreamInitialWindowSize,
912                                                session->net_log_));
913   stream->SendRequestHeaders(request_headers.Pass(), NO_MORE_DATA_TO_SEND);
914   SpdyStream* stream_ptr = stream.get();
915   session->InsertCreatedStream(stream.Pass());
916   stream = session->ActivateCreatedStream(stream_ptr);
917   session->InsertActivatedStream(stream.Pass());
918 
919   SpdyHeaderBlock headers;
920   spdy_util_.AddUrlToHeaderBlock("http://www.google.com/a.dat", &headers);
921 
922   // OnSynStream() expects |in_io_loop_| to be true.
923   session->in_io_loop_ = true;
924   session->OnSynStream(2, 1, 0, 0, true, false, headers);
925   session->in_io_loop_ = false;
926 
927   // Verify that there is one unclaimed push stream.
928   EXPECT_EQ(1u, session->num_unclaimed_pushed_streams());
929   SpdySession::PushedStreamMap::iterator iter =
930       session->unclaimed_pushed_streams_.find(
931           GURL("http://www.google.com/a.dat"));
932   EXPECT_TRUE(session->unclaimed_pushed_streams_.end() != iter);
933 
934   // Shift time to expire the push stream.
935   g_time_delta = base::TimeDelta::FromSeconds(301);
936 
937   spdy_util_.AddUrlToHeaderBlock("http://www.google.com/b.dat", &headers);
938   session->in_io_loop_ = true;
939   session->OnSynStream(4, 1, 0, 0, true, false, headers);
940   session->in_io_loop_ = false;
941 
942   // Verify that the second pushed stream evicted the first pushed stream.
943   EXPECT_EQ(1u, session->num_unclaimed_pushed_streams());
944   iter = session->unclaimed_pushed_streams_.find(
945       GURL("http://www.google.com/b.dat"));
946   EXPECT_TRUE(session->unclaimed_pushed_streams_.end() != iter);
947 }
948 
TEST_P(SpdySessionTest,FailedPing)949 TEST_P(SpdySessionTest, FailedPing) {
950   session_deps_.host_resolver->set_synchronous_mode(true);
951 
952   MockConnect connect_data(SYNCHRONOUS, OK);
953   MockRead reads[] = {
954     MockRead(ASYNC, 0, 0, 0)  // EOF
955   };
956   scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1));
957   DeterministicSocketData data(reads, arraysize(reads), NULL, 0);
958   data.set_connect_data(connect_data);
959   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
960 
961   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
962   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
963 
964   CreateDeterministicNetworkSession();
965 
966   base::WeakPtr<SpdySession> session =
967       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
968 
969   base::WeakPtr<SpdyStream> spdy_stream1 =
970       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
971                                 session, test_url_, MEDIUM, BoundNetLog());
972   ASSERT_TRUE(spdy_stream1.get() != NULL);
973   test::StreamDelegateSendImmediate delegate(spdy_stream1, NULL);
974   spdy_stream1->SetDelegate(&delegate);
975 
976   session->set_connection_at_risk_of_loss_time(base::TimeDelta::FromSeconds(0));
977   session->set_hung_interval(base::TimeDelta::FromSeconds(0));
978 
979   // Send a PING frame.
980   session->WritePingFrame(1);
981   EXPECT_LT(0, session->pings_in_flight());
982   EXPECT_GE(session->next_ping_id(), static_cast<uint32>(1));
983   EXPECT_TRUE(session->check_ping_status_pending());
984 
985   // Assert session is not closed.
986   EXPECT_FALSE(session->IsClosed());
987   EXPECT_LT(0u, session->num_active_streams() + session->num_created_streams());
988   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
989 
990   // We set last time we have received any data in 1 sec less than now.
991   // CheckPingStatus will trigger timeout because hung interval is zero.
992   base::TimeTicks now = base::TimeTicks::Now();
993   session->last_activity_time_ = now - base::TimeDelta::FromSeconds(1);
994   session->CheckPingStatus(now);
995 
996   EXPECT_TRUE(session == NULL);
997   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
998 
999   data.RunFor(1);
1000   EXPECT_EQ(NULL, spdy_stream1.get());
1001 }
1002 
1003 // Request kInitialMaxConcurrentStreams + 1 streams.  Receive a
1004 // settings frame increasing the max concurrent streams by 1.  Make
1005 // sure nothing blows up. This is a regression test for
1006 // http://crbug.com/57331 .
TEST_P(SpdySessionTest,OnSettings)1007 TEST_P(SpdySessionTest, OnSettings) {
1008   session_deps_.host_resolver->set_synchronous_mode(true);
1009 
1010   const SpdySettingsIds kSpdySettingsIds = SETTINGS_MAX_CONCURRENT_STREAMS;
1011 
1012   SettingsMap new_settings;
1013   const uint32 max_concurrent_streams = kInitialMaxConcurrentStreams + 1;
1014   new_settings[kSpdySettingsIds] =
1015       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
1016   scoped_ptr<SpdyFrame> settings_frame(
1017       spdy_util_.ConstructSpdySettings(new_settings));
1018   MockRead reads[] = {
1019     CreateMockRead(*settings_frame, 0),
1020     MockRead(ASYNC, 0, 1),
1021   };
1022 
1023   DeterministicSocketData data(reads, arraysize(reads), NULL, 0);
1024   MockConnect connect_data(SYNCHRONOUS, OK);
1025   data.set_connect_data(connect_data);
1026   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
1027 
1028   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
1029   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
1030 
1031   CreateDeterministicNetworkSession();
1032 
1033   base::WeakPtr<SpdySession> session =
1034       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
1035 
1036   // Create the maximum number of concurrent streams.
1037   for (size_t i = 0; i < kInitialMaxConcurrentStreams; ++i) {
1038     base::WeakPtr<SpdyStream> spdy_stream =
1039         CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
1040                                   session, test_url_, MEDIUM, BoundNetLog());
1041     ASSERT_TRUE(spdy_stream != NULL);
1042   }
1043 
1044   StreamReleaserCallback stream_releaser;
1045   SpdyStreamRequest request;
1046   ASSERT_EQ(ERR_IO_PENDING,
1047             request.StartRequest(
1048                 SPDY_BIDIRECTIONAL_STREAM, session, test_url_, MEDIUM,
1049                 BoundNetLog(),
1050                 stream_releaser.MakeCallback(&request)));
1051 
1052   data.RunFor(1);
1053 
1054   EXPECT_EQ(OK, stream_releaser.WaitForResult());
1055 
1056   data.RunFor(1);
1057   EXPECT_TRUE(session == NULL);
1058 }
1059 
1060 // Start with a persisted value for max concurrent streams. Receive a
1061 // settings frame increasing the max concurrent streams by 1 and which
1062 // also clears the persisted data. Verify that persisted data is
1063 // correct.
TEST_P(SpdySessionTest,ClearSettings)1064 TEST_P(SpdySessionTest, ClearSettings) {
1065   session_deps_.host_resolver->set_synchronous_mode(true);
1066 
1067   SettingsMap new_settings;
1068   const uint32 max_concurrent_streams = kInitialMaxConcurrentStreams + 1;
1069   new_settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
1070       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
1071   scoped_ptr<SpdyFrame> settings_frame(
1072       spdy_util_.ConstructSpdySettings(new_settings));
1073   uint8 flags = SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS;
1074   test::SetFrameFlags(settings_frame.get(), flags, spdy_util_.spdy_version());
1075   MockRead reads[] = {
1076     CreateMockRead(*settings_frame, 0),
1077     MockRead(ASYNC, 0, 1),
1078   };
1079 
1080   DeterministicSocketData data(reads, arraysize(reads), NULL, 0);
1081   MockConnect connect_data(SYNCHRONOUS, OK);
1082   data.set_connect_data(connect_data);
1083   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
1084 
1085   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
1086   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
1087 
1088   CreateDeterministicNetworkSession();
1089 
1090   // Initialize the SpdySetting with the default.
1091   spdy_session_pool_->http_server_properties()->SetSpdySetting(
1092       test_host_port_pair_,
1093       SETTINGS_MAX_CONCURRENT_STREAMS,
1094       SETTINGS_FLAG_PLEASE_PERSIST,
1095       kInitialMaxConcurrentStreams);
1096 
1097   EXPECT_FALSE(
1098       spdy_session_pool_->http_server_properties()->GetSpdySettings(
1099           test_host_port_pair_).empty());
1100 
1101   base::WeakPtr<SpdySession> session =
1102       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
1103 
1104   // Create the maximum number of concurrent streams.
1105   for (size_t i = 0; i < kInitialMaxConcurrentStreams; ++i) {
1106     base::WeakPtr<SpdyStream> spdy_stream =
1107         CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
1108                                   session, test_url_, MEDIUM, BoundNetLog());
1109     ASSERT_TRUE(spdy_stream != NULL);
1110   }
1111 
1112   StreamReleaserCallback stream_releaser;
1113 
1114   SpdyStreamRequest request;
1115   ASSERT_EQ(ERR_IO_PENDING,
1116             request.StartRequest(
1117                 SPDY_BIDIRECTIONAL_STREAM, session, test_url_, MEDIUM,
1118                 BoundNetLog(),
1119                 stream_releaser.MakeCallback(&request)));
1120 
1121   data.RunFor(1);
1122 
1123   EXPECT_EQ(OK, stream_releaser.WaitForResult());
1124 
1125   // Make sure that persisted data is cleared.
1126   EXPECT_TRUE(
1127       spdy_session_pool_->http_server_properties()->GetSpdySettings(
1128           test_host_port_pair_).empty());
1129 
1130   // Make sure session's max_concurrent_streams is correct.
1131   EXPECT_EQ(kInitialMaxConcurrentStreams + 1,
1132             session->max_concurrent_streams());
1133 
1134   data.RunFor(1);
1135   EXPECT_TRUE(session == NULL);
1136 }
1137 
1138 // Start with max concurrent streams set to 1.  Request two streams.
1139 // When the first completes, have the callback close its stream, which
1140 // should trigger the second stream creation.  Then cancel that one
1141 // immediately.  Don't crash.  This is a regression test for
1142 // http://crbug.com/63532 .
TEST_P(SpdySessionTest,CancelPendingCreateStream)1143 TEST_P(SpdySessionTest, CancelPendingCreateStream) {
1144   session_deps_.host_resolver->set_synchronous_mode(true);
1145 
1146   MockRead reads[] = {
1147     MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
1148   };
1149 
1150   StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
1151   MockConnect connect_data(SYNCHRONOUS, OK);
1152 
1153   data.set_connect_data(connect_data);
1154   session_deps_.socket_factory->AddSocketDataProvider(&data);
1155 
1156   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
1157   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
1158 
1159   CreateNetworkSession();
1160 
1161   // Initialize the SpdySetting with 1 max concurrent streams.
1162   spdy_session_pool_->http_server_properties()->SetSpdySetting(
1163       test_host_port_pair_,
1164       SETTINGS_MAX_CONCURRENT_STREAMS,
1165       SETTINGS_FLAG_PLEASE_PERSIST,
1166       1);
1167 
1168   base::WeakPtr<SpdySession> session =
1169       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
1170 
1171   // Leave room for only one more stream to be created.
1172   for (size_t i = 0; i < kInitialMaxConcurrentStreams - 1; ++i) {
1173     base::WeakPtr<SpdyStream> spdy_stream =
1174         CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
1175                                   session, test_url_, MEDIUM, BoundNetLog());
1176     ASSERT_TRUE(spdy_stream != NULL);
1177   }
1178 
1179   // Create 2 more streams.  First will succeed.  Second will be pending.
1180   base::WeakPtr<SpdyStream> spdy_stream1 =
1181       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
1182                                 session, test_url_, MEDIUM, BoundNetLog());
1183   ASSERT_TRUE(spdy_stream1.get() != NULL);
1184 
1185   // Use scoped_ptr to let us invalidate the memory when we want to, to trigger
1186   // a valgrind error if the callback is invoked when it's not supposed to be.
1187   scoped_ptr<TestCompletionCallback> callback(new TestCompletionCallback);
1188 
1189   SpdyStreamRequest request;
1190   ASSERT_EQ(ERR_IO_PENDING,
1191             request.StartRequest(
1192                 SPDY_BIDIRECTIONAL_STREAM, session, test_url_, MEDIUM,
1193                 BoundNetLog(),
1194                 callback->callback()));
1195 
1196   // Release the first one, this will allow the second to be created.
1197   spdy_stream1->Cancel();
1198   EXPECT_EQ(NULL, spdy_stream1.get());
1199 
1200   request.CancelRequest();
1201   callback.reset();
1202 
1203   // Should not crash when running the pending callback.
1204   base::MessageLoop::current()->RunUntilIdle();
1205 }
1206 
TEST_P(SpdySessionTest,SendInitialDataOnNewSession)1207 TEST_P(SpdySessionTest, SendInitialDataOnNewSession) {
1208   session_deps_.host_resolver->set_synchronous_mode(true);
1209 
1210   MockRead reads[] = {
1211     MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
1212   };
1213 
1214   SettingsMap settings;
1215   const SpdySettingsIds kSpdySettingsIds1 = SETTINGS_MAX_CONCURRENT_STREAMS;
1216   const SpdySettingsIds kSpdySettingsIds2 = SETTINGS_INITIAL_WINDOW_SIZE;
1217   const uint32 kInitialRecvWindowSize = 10 * 1024 * 1024;
1218   settings[kSpdySettingsIds1] =
1219       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kMaxConcurrentPushedStreams);
1220   if (spdy_util_.spdy_version() >= SPDY3) {
1221     settings[kSpdySettingsIds2] =
1222         SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kInitialRecvWindowSize);
1223   }
1224   MockConnect connect_data(SYNCHRONOUS, OK);
1225   scoped_ptr<SpdyFrame> settings_frame(
1226       spdy_util_.ConstructSpdySettings(settings));
1227   scoped_ptr<SpdyFrame> initial_window_update(
1228       spdy_util_.ConstructSpdyWindowUpdate(
1229           kSessionFlowControlStreamId,
1230           kDefaultInitialRecvWindowSize - kSpdySessionInitialWindowSize));
1231   std::vector<MockWrite> writes;
1232   if (GetParam() == kProtoHTTP2Draft04) {
1233     writes.push_back(
1234         MockWrite(ASYNC,
1235                   kHttp2ConnectionHeaderPrefix,
1236                   kHttp2ConnectionHeaderPrefixSize));
1237   }
1238   writes.push_back(CreateMockWrite(*settings_frame));
1239   if (GetParam() >= kProtoSPDY31) {
1240     writes.push_back(CreateMockWrite(*initial_window_update));
1241   };
1242 
1243   SettingsMap server_settings;
1244   const uint32 initial_max_concurrent_streams = 1;
1245   server_settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
1246       SettingsFlagsAndValue(SETTINGS_FLAG_PERSISTED,
1247                             initial_max_concurrent_streams);
1248   scoped_ptr<SpdyFrame> server_settings_frame(
1249       spdy_util_.ConstructSpdySettings(server_settings));
1250   writes.push_back(CreateMockWrite(*server_settings_frame));
1251 
1252   session_deps_.stream_initial_recv_window_size = kInitialRecvWindowSize;
1253 
1254   StaticSocketDataProvider data(reads, arraysize(reads),
1255                                 vector_as_array(&writes), writes.size());
1256   data.set_connect_data(connect_data);
1257   session_deps_.socket_factory->AddSocketDataProvider(&data);
1258 
1259   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
1260   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
1261 
1262   CreateNetworkSession();
1263 
1264   spdy_session_pool_->http_server_properties()->SetSpdySetting(
1265       test_host_port_pair_,
1266       SETTINGS_MAX_CONCURRENT_STREAMS,
1267       SETTINGS_FLAG_PLEASE_PERSIST,
1268       initial_max_concurrent_streams);
1269 
1270   SpdySessionPoolPeer pool_peer(spdy_session_pool_);
1271   pool_peer.SetEnableSendingInitialData(true);
1272 
1273   base::WeakPtr<SpdySession> session =
1274       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
1275 
1276   base::MessageLoop::current()->RunUntilIdle();
1277   EXPECT_TRUE(data.at_write_eof());
1278 }
1279 
TEST_P(SpdySessionTest,ClearSettingsStorageOnIPAddressChanged)1280 TEST_P(SpdySessionTest, ClearSettingsStorageOnIPAddressChanged) {
1281   CreateNetworkSession();
1282 
1283   base::WeakPtr<HttpServerProperties> test_http_server_properties =
1284       spdy_session_pool_->http_server_properties();
1285   SettingsFlagsAndValue flags_and_value1(SETTINGS_FLAG_PLEASE_PERSIST, 2);
1286   test_http_server_properties->SetSpdySetting(
1287       test_host_port_pair_,
1288       SETTINGS_MAX_CONCURRENT_STREAMS,
1289       SETTINGS_FLAG_PLEASE_PERSIST,
1290       2);
1291   EXPECT_NE(0u, test_http_server_properties->GetSpdySettings(
1292       test_host_port_pair_).size());
1293   spdy_session_pool_->OnIPAddressChanged();
1294   EXPECT_EQ(0u, test_http_server_properties->GetSpdySettings(
1295       test_host_port_pair_).size());
1296 }
1297 
TEST_P(SpdySessionTest,Initialize)1298 TEST_P(SpdySessionTest, Initialize) {
1299   CapturingBoundNetLog log;
1300   session_deps_.net_log = log.bound().net_log();
1301   session_deps_.host_resolver->set_synchronous_mode(true);
1302 
1303   MockConnect connect_data(SYNCHRONOUS, OK);
1304   MockRead reads[] = {
1305     MockRead(ASYNC, 0, 0)  // EOF
1306   };
1307 
1308   StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
1309   data.set_connect_data(connect_data);
1310   session_deps_.socket_factory->AddSocketDataProvider(&data);
1311 
1312   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
1313   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
1314 
1315   CreateNetworkSession();
1316 
1317   base::WeakPtr<SpdySession> session =
1318       CreateInsecureSpdySession(http_session_, key_, log.bound());
1319   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
1320 
1321   // Flush the read completion task.
1322   base::MessageLoop::current()->RunUntilIdle();
1323 
1324   net::CapturingNetLog::CapturedEntryList entries;
1325   log.GetEntries(&entries);
1326   EXPECT_LT(0u, entries.size());
1327 
1328   // Check that we logged TYPE_SPDY_SESSION_INITIALIZED correctly.
1329   int pos = net::ExpectLogContainsSomewhere(
1330       entries, 0,
1331       net::NetLog::TYPE_SPDY_SESSION_INITIALIZED,
1332       net::NetLog::PHASE_NONE);
1333   EXPECT_LT(0, pos);
1334 
1335   CapturingNetLog::CapturedEntry entry = entries[pos];
1336   NetLog::Source socket_source;
1337   EXPECT_TRUE(NetLog::Source::FromEventParameters(entry.params.get(),
1338                                                   &socket_source));
1339   EXPECT_TRUE(socket_source.IsValid());
1340   EXPECT_NE(log.bound().source().id, socket_source.id);
1341 }
1342 
TEST_P(SpdySessionTest,CloseSessionOnError)1343 TEST_P(SpdySessionTest, CloseSessionOnError) {
1344   session_deps_.host_resolver->set_synchronous_mode(true);
1345 
1346   MockConnect connect_data(SYNCHRONOUS, OK);
1347   scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway());
1348   MockRead reads[] = {
1349     CreateMockRead(*goaway),
1350     MockRead(SYNCHRONOUS, 0, 0)  // EOF
1351   };
1352 
1353   StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
1354   data.set_connect_data(connect_data);
1355   session_deps_.socket_factory->AddSocketDataProvider(&data);
1356 
1357   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
1358   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
1359 
1360   CreateNetworkSession();
1361 
1362   CapturingBoundNetLog log;
1363   base::WeakPtr<SpdySession> session =
1364       CreateInsecureSpdySession(http_session_, key_, log.bound());
1365   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
1366 
1367   // Flush the read completion task.
1368   base::MessageLoop::current()->RunUntilIdle();
1369 
1370   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
1371   EXPECT_TRUE(session == NULL);
1372 
1373   // Check that the NetLog was filled reasonably.
1374   net::CapturingNetLog::CapturedEntryList entries;
1375   log.GetEntries(&entries);
1376   EXPECT_LT(0u, entries.size());
1377 
1378   // Check that we logged SPDY_SESSION_CLOSE correctly.
1379   int pos = net::ExpectLogContainsSomewhere(
1380       entries, 0,
1381       net::NetLog::TYPE_SPDY_SESSION_CLOSE,
1382       net::NetLog::PHASE_NONE);
1383 
1384   if (pos < static_cast<int>(entries.size())) {
1385     CapturingNetLog::CapturedEntry entry = entries[pos];
1386     int error_code = 0;
1387     ASSERT_TRUE(entry.GetNetErrorCode(&error_code));
1388     EXPECT_EQ(ERR_CONNECTION_CLOSED, error_code);
1389   } else {
1390     ADD_FAILURE();
1391   }
1392 }
1393 
1394 // Queue up a low-priority SYN_STREAM followed by a high-priority
1395 // one. The high priority one should still send first and receive
1396 // first.
TEST_P(SpdySessionTest,OutOfOrderSynStreams)1397 TEST_P(SpdySessionTest, OutOfOrderSynStreams) {
1398   // Construct the request.
1399   MockConnect connect_data(SYNCHRONOUS, OK);
1400   scoped_ptr<SpdyFrame> req_highest(
1401       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, HIGHEST, true));
1402   scoped_ptr<SpdyFrame> req_lowest(
1403       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
1404   MockWrite writes[] = {
1405     CreateMockWrite(*req_highest, 0),
1406     CreateMockWrite(*req_lowest, 1),
1407   };
1408 
1409   scoped_ptr<SpdyFrame> resp_highest(
1410       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
1411   scoped_ptr<SpdyFrame> body_highest(
1412       spdy_util_.ConstructSpdyBodyFrame(1, true));
1413   scoped_ptr<SpdyFrame> resp_lowest(
1414       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
1415   scoped_ptr<SpdyFrame> body_lowest(
1416       spdy_util_.ConstructSpdyBodyFrame(3, true));
1417   MockRead reads[] = {
1418     CreateMockRead(*resp_highest, 2),
1419     CreateMockRead(*body_highest, 3),
1420     CreateMockRead(*resp_lowest, 4),
1421     CreateMockRead(*body_lowest, 5),
1422     MockRead(ASYNC, 0, 6)  // EOF
1423   };
1424 
1425   session_deps_.host_resolver->set_synchronous_mode(true);
1426 
1427   DeterministicSocketData data(reads, arraysize(reads),
1428                                writes, arraysize(writes));
1429   data.set_connect_data(connect_data);
1430   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
1431 
1432   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
1433   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
1434 
1435   CreateDeterministicNetworkSession();
1436 
1437   base::WeakPtr<SpdySession> session =
1438       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
1439 
1440   GURL url("http://www.google.com");
1441 
1442   base::WeakPtr<SpdyStream> spdy_stream_lowest =
1443       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
1444                                 session, url, LOWEST, BoundNetLog());
1445   ASSERT_TRUE(spdy_stream_lowest);
1446   EXPECT_EQ(0u, spdy_stream_lowest->stream_id());
1447   test::StreamDelegateDoNothing delegate_lowest(spdy_stream_lowest);
1448   spdy_stream_lowest->SetDelegate(&delegate_lowest);
1449 
1450   base::WeakPtr<SpdyStream> spdy_stream_highest =
1451       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
1452                                 session, url, HIGHEST, BoundNetLog());
1453   ASSERT_TRUE(spdy_stream_highest);
1454   EXPECT_EQ(0u, spdy_stream_highest->stream_id());
1455   test::StreamDelegateDoNothing delegate_highest(spdy_stream_highest);
1456   spdy_stream_highest->SetDelegate(&delegate_highest);
1457 
1458   // Queue the lower priority one first.
1459 
1460   scoped_ptr<SpdyHeaderBlock> headers_lowest(
1461       spdy_util_.ConstructGetHeaderBlock(url.spec()));
1462   spdy_stream_lowest->SendRequestHeaders(
1463       headers_lowest.Pass(), NO_MORE_DATA_TO_SEND);
1464   EXPECT_TRUE(spdy_stream_lowest->HasUrlFromHeaders());
1465 
1466   scoped_ptr<SpdyHeaderBlock> headers_highest(
1467       spdy_util_.ConstructGetHeaderBlock(url.spec()));
1468   spdy_stream_highest->SendRequestHeaders(
1469       headers_highest.Pass(), NO_MORE_DATA_TO_SEND);
1470   EXPECT_TRUE(spdy_stream_highest->HasUrlFromHeaders());
1471 
1472   data.RunFor(7);
1473 
1474   EXPECT_FALSE(spdy_stream_lowest);
1475   EXPECT_FALSE(spdy_stream_highest);
1476   EXPECT_EQ(3u, delegate_lowest.stream_id());
1477   EXPECT_EQ(1u, delegate_highest.stream_id());
1478 }
1479 
TEST_P(SpdySessionTest,CancelStream)1480 TEST_P(SpdySessionTest, CancelStream) {
1481   MockConnect connect_data(SYNCHRONOUS, OK);
1482   // Request 1, at HIGHEST priority, will be cancelled before it writes data.
1483   // Request 2, at LOWEST priority, will be a full request and will be id 1.
1484   scoped_ptr<SpdyFrame> req2(
1485       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
1486   MockWrite writes[] = {
1487     CreateMockWrite(*req2, 0),
1488   };
1489 
1490   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
1491   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
1492   MockRead reads[] = {
1493     CreateMockRead(*resp2, 1),
1494     CreateMockRead(*body2, 2),
1495     MockRead(ASYNC, 0, 3)  // EOF
1496   };
1497 
1498   session_deps_.host_resolver->set_synchronous_mode(true);
1499 
1500   DeterministicSocketData data(reads, arraysize(reads),
1501                                writes, arraysize(writes));
1502   data.set_connect_data(connect_data);
1503   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
1504 
1505   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
1506   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
1507 
1508   CreateDeterministicNetworkSession();
1509 
1510   base::WeakPtr<SpdySession> session =
1511       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
1512 
1513   GURL url1("http://www.google.com");
1514   base::WeakPtr<SpdyStream> spdy_stream1 =
1515       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
1516                                 session, url1, HIGHEST, BoundNetLog());
1517   ASSERT_TRUE(spdy_stream1.get() != NULL);
1518   EXPECT_EQ(0u, spdy_stream1->stream_id());
1519   test::StreamDelegateDoNothing delegate1(spdy_stream1);
1520   spdy_stream1->SetDelegate(&delegate1);
1521 
1522   GURL url2("http://www.google.com");
1523   base::WeakPtr<SpdyStream> spdy_stream2 =
1524       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
1525                                 session, url2, LOWEST, BoundNetLog());
1526   ASSERT_TRUE(spdy_stream2.get() != NULL);
1527   EXPECT_EQ(0u, spdy_stream2->stream_id());
1528   test::StreamDelegateDoNothing delegate2(spdy_stream2);
1529   spdy_stream2->SetDelegate(&delegate2);
1530 
1531   scoped_ptr<SpdyHeaderBlock> headers(
1532       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
1533   spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
1534   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
1535 
1536   scoped_ptr<SpdyHeaderBlock> headers2(
1537       spdy_util_.ConstructGetHeaderBlock(url2.spec()));
1538   spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
1539   EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders());
1540 
1541   EXPECT_EQ(0u, spdy_stream1->stream_id());
1542 
1543   spdy_stream1->Cancel();
1544   EXPECT_EQ(NULL, spdy_stream1.get());
1545 
1546   EXPECT_EQ(0u, delegate1.stream_id());
1547 
1548   data.RunFor(1);
1549 
1550   EXPECT_EQ(0u, delegate1.stream_id());
1551   EXPECT_EQ(1u, delegate2.stream_id());
1552 
1553   spdy_stream2->Cancel();
1554   EXPECT_EQ(NULL, spdy_stream2.get());
1555 }
1556 
1557 // Create two streams that are set to re-close themselves on close,
1558 // and then close the session. Nothing should blow up. Also a
1559 // regression test for http://crbug.com/139518 .
TEST_P(SpdySessionTest,CloseSessionWithTwoCreatedSelfClosingStreams)1560 TEST_P(SpdySessionTest, CloseSessionWithTwoCreatedSelfClosingStreams) {
1561   session_deps_.host_resolver->set_synchronous_mode(true);
1562 
1563   MockConnect connect_data(SYNCHRONOUS, OK);
1564 
1565   // No actual data will be sent.
1566   MockWrite writes[] = {
1567     MockWrite(ASYNC, 0, 1)  // EOF
1568   };
1569 
1570   MockRead reads[] = {
1571     MockRead(ASYNC, 0, 0)  // EOF
1572   };
1573   DeterministicSocketData data(reads, arraysize(reads),
1574                                writes, arraysize(writes));
1575   data.set_connect_data(connect_data);
1576   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
1577 
1578   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
1579   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
1580 
1581   CreateDeterministicNetworkSession();
1582 
1583   base::WeakPtr<SpdySession> session =
1584       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
1585 
1586   GURL url1("http://www.google.com");
1587   base::WeakPtr<SpdyStream> spdy_stream1 =
1588       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
1589                                 session, url1, HIGHEST, BoundNetLog());
1590   ASSERT_TRUE(spdy_stream1.get() != NULL);
1591   EXPECT_EQ(0u, spdy_stream1->stream_id());
1592 
1593   GURL url2("http://www.google.com");
1594   base::WeakPtr<SpdyStream> spdy_stream2 =
1595       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
1596                                 session, url2, LOWEST, BoundNetLog());
1597   ASSERT_TRUE(spdy_stream2.get() != NULL);
1598   EXPECT_EQ(0u, spdy_stream2->stream_id());
1599 
1600   test::ClosingDelegate delegate1(spdy_stream1);
1601   spdy_stream1->SetDelegate(&delegate1);
1602 
1603   test::ClosingDelegate delegate2(spdy_stream2);
1604   spdy_stream2->SetDelegate(&delegate2);
1605 
1606   scoped_ptr<SpdyHeaderBlock> headers(
1607       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
1608   spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
1609   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
1610 
1611   scoped_ptr<SpdyHeaderBlock> headers2(
1612       spdy_util_.ConstructGetHeaderBlock(url2.spec()));
1613   spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
1614   EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders());
1615 
1616   // Ensure that the streams have not yet been activated and assigned an id.
1617   EXPECT_EQ(0u, spdy_stream1->stream_id());
1618   EXPECT_EQ(0u, spdy_stream2->stream_id());
1619 
1620   // Ensure we don't crash while closing the session.
1621   session->CloseSessionOnError(ERR_ABORTED, std::string());
1622 
1623   EXPECT_EQ(NULL, spdy_stream1.get());
1624   EXPECT_EQ(NULL, spdy_stream2.get());
1625 
1626   EXPECT_TRUE(delegate1.StreamIsClosed());
1627   EXPECT_TRUE(delegate2.StreamIsClosed());
1628 
1629   EXPECT_TRUE(session == NULL);
1630 }
1631 
1632 // Create two streams that are set to close each other on close, and
1633 // then close the session. Nothing should blow up.
TEST_P(SpdySessionTest,CloseSessionWithTwoCreatedMutuallyClosingStreams)1634 TEST_P(SpdySessionTest, CloseSessionWithTwoCreatedMutuallyClosingStreams) {
1635   session_deps_.host_resolver->set_synchronous_mode(true);
1636 
1637   MockConnect connect_data(SYNCHRONOUS, OK);
1638 
1639   // No actual data will be sent.
1640   MockWrite writes[] = {
1641     MockWrite(ASYNC, 0, 1)  // EOF
1642   };
1643 
1644   MockRead reads[] = {
1645     MockRead(ASYNC, 0, 0)  // EOF
1646   };
1647   DeterministicSocketData data(reads, arraysize(reads),
1648                                writes, arraysize(writes));
1649   data.set_connect_data(connect_data);
1650   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
1651 
1652   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
1653   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
1654 
1655   CreateDeterministicNetworkSession();
1656 
1657   base::WeakPtr<SpdySession> session =
1658       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
1659 
1660   GURL url1("http://www.google.com");
1661   base::WeakPtr<SpdyStream> spdy_stream1 =
1662       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
1663                                 session, url1, HIGHEST, BoundNetLog());
1664   ASSERT_TRUE(spdy_stream1.get() != NULL);
1665   EXPECT_EQ(0u, spdy_stream1->stream_id());
1666 
1667   GURL url2("http://www.google.com");
1668   base::WeakPtr<SpdyStream> spdy_stream2 =
1669       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
1670                                 session, url2, LOWEST, BoundNetLog());
1671   ASSERT_TRUE(spdy_stream2.get() != NULL);
1672   EXPECT_EQ(0u, spdy_stream2->stream_id());
1673 
1674   // Make |spdy_stream1| close |spdy_stream2|.
1675   test::ClosingDelegate delegate1(spdy_stream2);
1676   spdy_stream1->SetDelegate(&delegate1);
1677 
1678   // Make |spdy_stream2| close |spdy_stream1|.
1679   test::ClosingDelegate delegate2(spdy_stream1);
1680   spdy_stream2->SetDelegate(&delegate2);
1681 
1682   scoped_ptr<SpdyHeaderBlock> headers(
1683       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
1684   spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
1685   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
1686 
1687   scoped_ptr<SpdyHeaderBlock> headers2(
1688       spdy_util_.ConstructGetHeaderBlock(url2.spec()));
1689   spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
1690   EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders());
1691 
1692   // Ensure that the streams have not yet been activated and assigned an id.
1693   EXPECT_EQ(0u, spdy_stream1->stream_id());
1694   EXPECT_EQ(0u, spdy_stream2->stream_id());
1695 
1696   // Ensure we don't crash while closing the session.
1697   session->CloseSessionOnError(ERR_ABORTED, std::string());
1698 
1699   EXPECT_EQ(NULL, spdy_stream1.get());
1700   EXPECT_EQ(NULL, spdy_stream2.get());
1701 
1702   EXPECT_TRUE(delegate1.StreamIsClosed());
1703   EXPECT_TRUE(delegate2.StreamIsClosed());
1704 
1705   EXPECT_TRUE(session == NULL);
1706 }
1707 
1708 // Create two streams that are set to re-close themselves on close,
1709 // activate them, and then close the session. Nothing should blow up.
TEST_P(SpdySessionTest,CloseSessionWithTwoActivatedSelfClosingStreams)1710 TEST_P(SpdySessionTest, CloseSessionWithTwoActivatedSelfClosingStreams) {
1711   session_deps_.host_resolver->set_synchronous_mode(true);
1712 
1713   MockConnect connect_data(SYNCHRONOUS, OK);
1714 
1715   scoped_ptr<SpdyFrame> req1(
1716       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
1717   scoped_ptr<SpdyFrame> req2(
1718       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, MEDIUM, true));
1719   MockWrite writes[] = {
1720     CreateMockWrite(*req1, 0),
1721     CreateMockWrite(*req2, 1),
1722   };
1723 
1724   MockRead reads[] = {
1725     MockRead(ASYNC, 0, 2)  // EOF
1726   };
1727 
1728   DeterministicSocketData data(reads, arraysize(reads),
1729                                writes, arraysize(writes));
1730   data.set_connect_data(connect_data);
1731   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
1732 
1733   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
1734   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
1735 
1736   CreateDeterministicNetworkSession();
1737 
1738   base::WeakPtr<SpdySession> session =
1739       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
1740 
1741   GURL url1("http://www.google.com");
1742   base::WeakPtr<SpdyStream> spdy_stream1 =
1743       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
1744                                 session, url1, MEDIUM, BoundNetLog());
1745   ASSERT_TRUE(spdy_stream1.get() != NULL);
1746   EXPECT_EQ(0u, spdy_stream1->stream_id());
1747 
1748   GURL url2("http://www.google.com");
1749   base::WeakPtr<SpdyStream> spdy_stream2 =
1750       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
1751                                 session, url2, MEDIUM, BoundNetLog());
1752   ASSERT_TRUE(spdy_stream2.get() != NULL);
1753   EXPECT_EQ(0u, spdy_stream2->stream_id());
1754 
1755   test::ClosingDelegate delegate1(spdy_stream1);
1756   spdy_stream1->SetDelegate(&delegate1);
1757 
1758   test::ClosingDelegate delegate2(spdy_stream2);
1759   spdy_stream2->SetDelegate(&delegate2);
1760 
1761   scoped_ptr<SpdyHeaderBlock> headers(
1762       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
1763   spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
1764   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
1765 
1766   scoped_ptr<SpdyHeaderBlock> headers2(
1767       spdy_util_.ConstructGetHeaderBlock(url2.spec()));
1768   spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
1769   EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders());
1770 
1771   // Ensure that the streams have not yet been activated and assigned an id.
1772   EXPECT_EQ(0u, spdy_stream1->stream_id());
1773   EXPECT_EQ(0u, spdy_stream2->stream_id());
1774 
1775   data.RunFor(2);
1776 
1777   EXPECT_EQ(1u, spdy_stream1->stream_id());
1778   EXPECT_EQ(3u, spdy_stream2->stream_id());
1779 
1780   // Ensure we don't crash while closing the session.
1781   session->CloseSessionOnError(ERR_ABORTED, std::string());
1782 
1783   EXPECT_EQ(NULL, spdy_stream1.get());
1784   EXPECT_EQ(NULL, spdy_stream2.get());
1785 
1786   EXPECT_TRUE(delegate1.StreamIsClosed());
1787   EXPECT_TRUE(delegate2.StreamIsClosed());
1788 
1789   EXPECT_TRUE(session == NULL);
1790 }
1791 
1792 // Create two streams that are set to close each other on close,
1793 // activate them, and then close the session. Nothing should blow up.
TEST_P(SpdySessionTest,CloseSessionWithTwoActivatedMutuallyClosingStreams)1794 TEST_P(SpdySessionTest, CloseSessionWithTwoActivatedMutuallyClosingStreams) {
1795   session_deps_.host_resolver->set_synchronous_mode(true);
1796 
1797   MockConnect connect_data(SYNCHRONOUS, OK);
1798 
1799   scoped_ptr<SpdyFrame> req1(
1800       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
1801   scoped_ptr<SpdyFrame> req2(
1802       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, MEDIUM, true));
1803   MockWrite writes[] = {
1804     CreateMockWrite(*req1, 0),
1805     CreateMockWrite(*req2, 1),
1806   };
1807 
1808   MockRead reads[] = {
1809     MockRead(ASYNC, 0, 2)  // EOF
1810   };
1811 
1812   DeterministicSocketData data(reads, arraysize(reads),
1813                                writes, arraysize(writes));
1814   data.set_connect_data(connect_data);
1815   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
1816 
1817   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
1818   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
1819 
1820   CreateDeterministicNetworkSession();
1821 
1822   base::WeakPtr<SpdySession> session =
1823       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
1824 
1825   GURL url1("http://www.google.com");
1826   base::WeakPtr<SpdyStream> spdy_stream1 =
1827       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
1828                                 session, url1, MEDIUM, BoundNetLog());
1829   ASSERT_TRUE(spdy_stream1.get() != NULL);
1830   EXPECT_EQ(0u, spdy_stream1->stream_id());
1831 
1832   GURL url2("http://www.google.com");
1833   base::WeakPtr<SpdyStream> spdy_stream2 =
1834       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
1835                                 session, url2, MEDIUM, BoundNetLog());
1836   ASSERT_TRUE(spdy_stream2.get() != NULL);
1837   EXPECT_EQ(0u, spdy_stream2->stream_id());
1838 
1839   // Make |spdy_stream1| close |spdy_stream2|.
1840   test::ClosingDelegate delegate1(spdy_stream2);
1841   spdy_stream1->SetDelegate(&delegate1);
1842 
1843   // Make |spdy_stream2| close |spdy_stream1|.
1844   test::ClosingDelegate delegate2(spdy_stream1);
1845   spdy_stream2->SetDelegate(&delegate2);
1846 
1847   scoped_ptr<SpdyHeaderBlock> headers(
1848       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
1849   spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
1850   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
1851 
1852   scoped_ptr<SpdyHeaderBlock> headers2(
1853       spdy_util_.ConstructGetHeaderBlock(url2.spec()));
1854   spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
1855   EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders());
1856 
1857   // Ensure that the streams have not yet been activated and assigned an id.
1858   EXPECT_EQ(0u, spdy_stream1->stream_id());
1859   EXPECT_EQ(0u, spdy_stream2->stream_id());
1860 
1861   data.RunFor(2);
1862 
1863   EXPECT_EQ(1u, spdy_stream1->stream_id());
1864   EXPECT_EQ(3u, spdy_stream2->stream_id());
1865 
1866   // Ensure we don't crash while closing the session.
1867   session->CloseSessionOnError(ERR_ABORTED, std::string());
1868 
1869   EXPECT_EQ(NULL, spdy_stream1.get());
1870   EXPECT_EQ(NULL, spdy_stream2.get());
1871 
1872   EXPECT_TRUE(delegate1.StreamIsClosed());
1873   EXPECT_TRUE(delegate2.StreamIsClosed());
1874 
1875   EXPECT_TRUE(session == NULL);
1876 }
1877 
1878 // Delegate that closes a given session when the stream is closed.
1879 class SessionClosingDelegate : public test::StreamDelegateDoNothing {
1880  public:
SessionClosingDelegate(const base::WeakPtr<SpdyStream> & stream,const base::WeakPtr<SpdySession> & session_to_close)1881   SessionClosingDelegate(const base::WeakPtr<SpdyStream>& stream,
1882                          const base::WeakPtr<SpdySession>& session_to_close)
1883       : StreamDelegateDoNothing(stream),
1884         session_to_close_(session_to_close) {}
1885 
~SessionClosingDelegate()1886   virtual ~SessionClosingDelegate() {}
1887 
OnClose(int status)1888   virtual void OnClose(int status) OVERRIDE {
1889     session_to_close_->CloseSessionOnError(ERR_ABORTED, "Aborted");
1890   }
1891 
1892  private:
1893   base::WeakPtr<SpdySession> session_to_close_;
1894 };
1895 
1896 // Close an activated stream that closes its session. Nothing should
1897 // blow up. This is a regression test for http://crbug.com/263691 .
TEST_P(SpdySessionTest,CloseActivatedStreamThatClosesSession)1898 TEST_P(SpdySessionTest, CloseActivatedStreamThatClosesSession) {
1899   session_deps_.host_resolver->set_synchronous_mode(true);
1900 
1901   MockConnect connect_data(SYNCHRONOUS, OK);
1902 
1903   scoped_ptr<SpdyFrame> req(
1904       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
1905   MockWrite writes[] = {
1906     CreateMockWrite(*req, 0),
1907   };
1908 
1909   MockRead reads[] = {
1910     MockRead(ASYNC, 0, 1)  // EOF
1911   };
1912   DeterministicSocketData data(reads, arraysize(reads),
1913                                writes, arraysize(writes));
1914   data.set_connect_data(connect_data);
1915   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
1916 
1917   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
1918   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
1919 
1920   CreateDeterministicNetworkSession();
1921 
1922   base::WeakPtr<SpdySession> session =
1923       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
1924 
1925   GURL url("http://www.google.com");
1926   base::WeakPtr<SpdyStream> spdy_stream =
1927       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
1928                                 session, url, MEDIUM, BoundNetLog());
1929   ASSERT_TRUE(spdy_stream.get() != NULL);
1930   EXPECT_EQ(0u, spdy_stream->stream_id());
1931 
1932   SessionClosingDelegate delegate(spdy_stream, session);
1933   spdy_stream->SetDelegate(&delegate);
1934 
1935   scoped_ptr<SpdyHeaderBlock> headers(
1936       spdy_util_.ConstructGetHeaderBlock(url.spec()));
1937   spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
1938   EXPECT_TRUE(spdy_stream->HasUrlFromHeaders());
1939 
1940   EXPECT_EQ(0u, spdy_stream->stream_id());
1941 
1942   data.RunFor(1);
1943 
1944   EXPECT_EQ(1u, spdy_stream->stream_id());
1945 
1946   // Ensure we don't crash while closing the stream (which closes the
1947   // session).
1948   spdy_stream->Cancel();
1949 
1950   EXPECT_EQ(NULL, spdy_stream.get());
1951   EXPECT_TRUE(delegate.StreamIsClosed());
1952   EXPECT_TRUE(session == NULL);
1953 }
1954 
TEST_P(SpdySessionTest,VerifyDomainAuthentication)1955 TEST_P(SpdySessionTest, VerifyDomainAuthentication) {
1956   session_deps_.host_resolver->set_synchronous_mode(true);
1957 
1958   MockConnect connect_data(SYNCHRONOUS, OK);
1959 
1960   // No actual data will be sent.
1961   MockWrite writes[] = {
1962     MockWrite(ASYNC, 0, 1)  // EOF
1963   };
1964 
1965   MockRead reads[] = {
1966     MockRead(ASYNC, 0, 0)  // EOF
1967   };
1968   DeterministicSocketData data(reads, arraysize(reads),
1969                                writes, arraysize(writes));
1970   data.set_connect_data(connect_data);
1971   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
1972 
1973   // Load a cert that is valid for:
1974   //   www.example.org
1975   //   mail.example.org
1976   //   www.example.com
1977   base::FilePath certs_dir = GetTestCertsDirectory();
1978   scoped_refptr<X509Certificate> test_cert(
1979       ImportCertFromFile(certs_dir, "spdy_pooling.pem"));
1980   ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert);
1981 
1982   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
1983   ssl.cert = test_cert;
1984   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
1985 
1986   CreateDeterministicNetworkSession();
1987 
1988   base::WeakPtr<SpdySession> session =
1989       CreateSecureSpdySession(http_session_, key_, BoundNetLog());
1990 
1991   EXPECT_TRUE(session->VerifyDomainAuthentication("www.example.org"));
1992   EXPECT_TRUE(session->VerifyDomainAuthentication("mail.example.org"));
1993   EXPECT_TRUE(session->VerifyDomainAuthentication("mail.example.com"));
1994   EXPECT_FALSE(session->VerifyDomainAuthentication("mail.google.com"));
1995 }
1996 
TEST_P(SpdySessionTest,ConnectionPooledWithTlsChannelId)1997 TEST_P(SpdySessionTest, ConnectionPooledWithTlsChannelId) {
1998   session_deps_.host_resolver->set_synchronous_mode(true);
1999 
2000   MockConnect connect_data(SYNCHRONOUS, OK);
2001 
2002   // No actual data will be sent.
2003   MockWrite writes[] = {
2004     MockWrite(ASYNC, 0, 1)  // EOF
2005   };
2006 
2007   MockRead reads[] = {
2008     MockRead(ASYNC, 0, 0)  // EOF
2009   };
2010   DeterministicSocketData data(reads, arraysize(reads),
2011                                writes, arraysize(writes));
2012   data.set_connect_data(connect_data);
2013   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
2014 
2015   // Load a cert that is valid for:
2016   //   www.example.org
2017   //   mail.example.org
2018   //   www.example.com
2019   base::FilePath certs_dir = GetTestCertsDirectory();
2020   scoped_refptr<X509Certificate> test_cert(
2021       ImportCertFromFile(certs_dir, "spdy_pooling.pem"));
2022   ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert);
2023 
2024   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
2025   ssl.channel_id_sent = true;
2026   ssl.cert = test_cert;
2027   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
2028 
2029   CreateDeterministicNetworkSession();
2030 
2031   base::WeakPtr<SpdySession> session =
2032       CreateSecureSpdySession(http_session_, key_, BoundNetLog());
2033 
2034   EXPECT_TRUE(session->VerifyDomainAuthentication("www.example.org"));
2035   EXPECT_TRUE(session->VerifyDomainAuthentication("mail.example.org"));
2036   EXPECT_FALSE(session->VerifyDomainAuthentication("mail.example.com"));
2037   EXPECT_FALSE(session->VerifyDomainAuthentication("mail.google.com"));
2038 }
2039 
TEST_P(SpdySessionTest,CloseTwoStalledCreateStream)2040 TEST_P(SpdySessionTest, CloseTwoStalledCreateStream) {
2041   // TODO(rtenneti): Define a helper class/methods and move the common code in
2042   // this file.
2043   MockConnect connect_data(SYNCHRONOUS, OK);
2044 
2045   SettingsMap new_settings;
2046   const SpdySettingsIds kSpdySettingsIds1 = SETTINGS_MAX_CONCURRENT_STREAMS;
2047   const uint32 max_concurrent_streams = 1;
2048   new_settings[kSpdySettingsIds1] =
2049       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
2050 
2051   scoped_ptr<SpdyFrame> req1(
2052       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2053   scoped_ptr<SpdyFrame> req2(
2054       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
2055   scoped_ptr<SpdyFrame> req3(
2056       spdy_util_.ConstructSpdyGet(NULL, 0, false, 5, LOWEST, true));
2057   MockWrite writes[] = {
2058     CreateMockWrite(*req1, 1),
2059     CreateMockWrite(*req2, 4),
2060     CreateMockWrite(*req3, 7),
2061   };
2062 
2063   // Set up the socket so we read a SETTINGS frame that sets max concurrent
2064   // streams to 1.
2065   scoped_ptr<SpdyFrame> settings_frame(
2066       spdy_util_.ConstructSpdySettings(new_settings));
2067 
2068   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2069   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
2070 
2071   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
2072   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
2073 
2074   scoped_ptr<SpdyFrame> resp3(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 5));
2075   scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(5, true));
2076 
2077   MockRead reads[] = {
2078     CreateMockRead(*settings_frame),
2079     CreateMockRead(*resp1, 2),
2080     CreateMockRead(*body1, 3),
2081     CreateMockRead(*resp2, 5),
2082     CreateMockRead(*body2, 6),
2083     CreateMockRead(*resp3, 8),
2084     CreateMockRead(*body3, 9),
2085     MockRead(ASYNC, 0, 10)  // EOF
2086   };
2087 
2088   DeterministicSocketData data(reads, arraysize(reads),
2089                                writes, arraysize(writes));
2090   data.set_connect_data(connect_data);
2091   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
2092 
2093   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
2094   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
2095 
2096   CreateDeterministicNetworkSession();
2097 
2098   base::WeakPtr<SpdySession> session =
2099       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
2100 
2101   // Read the settings frame.
2102   data.RunFor(1);
2103 
2104   GURL url1("http://www.google.com");
2105   base::WeakPtr<SpdyStream> spdy_stream1 =
2106       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
2107                                 session, url1, LOWEST, BoundNetLog());
2108   ASSERT_TRUE(spdy_stream1.get() != NULL);
2109   EXPECT_EQ(0u, spdy_stream1->stream_id());
2110   test::StreamDelegateDoNothing delegate1(spdy_stream1);
2111   spdy_stream1->SetDelegate(&delegate1);
2112 
2113   TestCompletionCallback callback2;
2114   GURL url2("http://www.google.com");
2115   SpdyStreamRequest request2;
2116   ASSERT_EQ(ERR_IO_PENDING,
2117             request2.StartRequest(
2118                 SPDY_REQUEST_RESPONSE_STREAM,
2119                 session, url2, LOWEST, BoundNetLog(), callback2.callback()));
2120 
2121   TestCompletionCallback callback3;
2122   GURL url3("http://www.google.com");
2123   SpdyStreamRequest request3;
2124   ASSERT_EQ(ERR_IO_PENDING,
2125             request3.StartRequest(
2126                 SPDY_REQUEST_RESPONSE_STREAM,
2127                 session, url3, LOWEST, BoundNetLog(), callback3.callback()));
2128 
2129   EXPECT_EQ(0u, session->num_active_streams());
2130   EXPECT_EQ(1u, session->num_created_streams());
2131   EXPECT_EQ(2u, session->pending_create_stream_queue_size(LOWEST));
2132 
2133   scoped_ptr<SpdyHeaderBlock> headers(
2134       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
2135   spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
2136   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
2137 
2138   // Run until 1st stream is activated and then closed.
2139   EXPECT_EQ(0u, delegate1.stream_id());
2140   data.RunFor(3);
2141   EXPECT_EQ(NULL, spdy_stream1.get());
2142   EXPECT_EQ(1u, delegate1.stream_id());
2143 
2144   EXPECT_EQ(0u, session->num_active_streams());
2145   EXPECT_EQ(0u, session->num_created_streams());
2146   EXPECT_EQ(1u, session->pending_create_stream_queue_size(LOWEST));
2147 
2148   // Pump loop for SpdySession::ProcessPendingStreamRequests() to
2149   // create the 2nd stream.
2150   base::MessageLoop::current()->RunUntilIdle();
2151 
2152   EXPECT_EQ(0u, session->num_active_streams());
2153   EXPECT_EQ(1u, session->num_created_streams());
2154   EXPECT_EQ(1u, session->pending_create_stream_queue_size(LOWEST));
2155 
2156   base::WeakPtr<SpdyStream> stream2 = request2.ReleaseStream();
2157   test::StreamDelegateDoNothing delegate2(stream2);
2158   stream2->SetDelegate(&delegate2);
2159   scoped_ptr<SpdyHeaderBlock> headers2(
2160       spdy_util_.ConstructGetHeaderBlock(url2.spec()));
2161   stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
2162   EXPECT_TRUE(stream2->HasUrlFromHeaders());
2163 
2164   // Run until 2nd stream is activated and then closed.
2165   EXPECT_EQ(0u, delegate2.stream_id());
2166   data.RunFor(3);
2167   EXPECT_EQ(NULL, stream2.get());
2168   EXPECT_EQ(3u, delegate2.stream_id());
2169 
2170   EXPECT_EQ(0u, session->num_active_streams());
2171   EXPECT_EQ(0u, session->num_created_streams());
2172   EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST));
2173 
2174   // Pump loop for SpdySession::ProcessPendingStreamRequests() to
2175   // create the 3rd stream.
2176   base::MessageLoop::current()->RunUntilIdle();
2177 
2178   EXPECT_EQ(0u, session->num_active_streams());
2179   EXPECT_EQ(1u, session->num_created_streams());
2180   EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST));
2181 
2182   base::WeakPtr<SpdyStream> stream3 = request3.ReleaseStream();
2183   test::StreamDelegateDoNothing delegate3(stream3);
2184   stream3->SetDelegate(&delegate3);
2185   scoped_ptr<SpdyHeaderBlock> headers3(
2186       spdy_util_.ConstructGetHeaderBlock(url3.spec()));
2187   stream3->SendRequestHeaders(headers3.Pass(), NO_MORE_DATA_TO_SEND);
2188   EXPECT_TRUE(stream3->HasUrlFromHeaders());
2189 
2190   // Run until 2nd stream is activated and then closed.
2191   EXPECT_EQ(0u, delegate3.stream_id());
2192   data.RunFor(3);
2193   EXPECT_EQ(NULL, stream3.get());
2194   EXPECT_EQ(5u, delegate3.stream_id());
2195 
2196   EXPECT_EQ(0u, session->num_active_streams());
2197   EXPECT_EQ(0u, session->num_created_streams());
2198   EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST));
2199 
2200   data.RunFor(1);
2201 }
2202 
TEST_P(SpdySessionTest,CancelTwoStalledCreateStream)2203 TEST_P(SpdySessionTest, CancelTwoStalledCreateStream) {
2204   session_deps_.host_resolver->set_synchronous_mode(true);
2205 
2206   MockRead reads[] = {
2207     MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
2208   };
2209 
2210   StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
2211   MockConnect connect_data(SYNCHRONOUS, OK);
2212 
2213   data.set_connect_data(connect_data);
2214   session_deps_.socket_factory->AddSocketDataProvider(&data);
2215 
2216   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
2217   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2218 
2219   CreateNetworkSession();
2220 
2221   base::WeakPtr<SpdySession> session =
2222       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
2223 
2224   // Leave room for only one more stream to be created.
2225   for (size_t i = 0; i < kInitialMaxConcurrentStreams - 1; ++i) {
2226     base::WeakPtr<SpdyStream> spdy_stream =
2227         CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
2228                                   session, test_url_, MEDIUM, BoundNetLog());
2229     ASSERT_TRUE(spdy_stream != NULL);
2230   }
2231 
2232   GURL url1("http://www.google.com");
2233   base::WeakPtr<SpdyStream> spdy_stream1 =
2234       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
2235                                 session, url1, LOWEST, BoundNetLog());
2236   ASSERT_TRUE(spdy_stream1.get() != NULL);
2237   EXPECT_EQ(0u, spdy_stream1->stream_id());
2238 
2239   TestCompletionCallback callback2;
2240   GURL url2("http://www.google.com");
2241   SpdyStreamRequest request2;
2242   ASSERT_EQ(ERR_IO_PENDING,
2243             request2.StartRequest(
2244                 SPDY_BIDIRECTIONAL_STREAM, session, url2, LOWEST, BoundNetLog(),
2245                 callback2.callback()));
2246 
2247   TestCompletionCallback callback3;
2248   GURL url3("http://www.google.com");
2249   SpdyStreamRequest request3;
2250   ASSERT_EQ(ERR_IO_PENDING,
2251             request3.StartRequest(
2252                 SPDY_BIDIRECTIONAL_STREAM, session, url3, LOWEST, BoundNetLog(),
2253                 callback3.callback()));
2254 
2255   EXPECT_EQ(0u, session->num_active_streams());
2256   EXPECT_EQ(kInitialMaxConcurrentStreams, session->num_created_streams());
2257   EXPECT_EQ(2u, session->pending_create_stream_queue_size(LOWEST));
2258 
2259   // Cancel the first stream; this will allow the second stream to be created.
2260   EXPECT_TRUE(spdy_stream1.get() != NULL);
2261   spdy_stream1->Cancel();
2262   EXPECT_EQ(NULL, spdy_stream1.get());
2263 
2264   EXPECT_EQ(OK, callback2.WaitForResult());
2265   EXPECT_EQ(0u, session->num_active_streams());
2266   EXPECT_EQ(kInitialMaxConcurrentStreams, session->num_created_streams());
2267   EXPECT_EQ(1u, session->pending_create_stream_queue_size(LOWEST));
2268 
2269   // Cancel the second stream; this will allow the third stream to be created.
2270   base::WeakPtr<SpdyStream> spdy_stream2 = request2.ReleaseStream();
2271   spdy_stream2->Cancel();
2272   EXPECT_EQ(NULL, spdy_stream2.get());
2273 
2274   EXPECT_EQ(OK, callback3.WaitForResult());
2275   EXPECT_EQ(0u, session->num_active_streams());
2276   EXPECT_EQ(kInitialMaxConcurrentStreams, session->num_created_streams());
2277   EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST));
2278 
2279   // Cancel the third stream.
2280   base::WeakPtr<SpdyStream> spdy_stream3 = request3.ReleaseStream();
2281   spdy_stream3->Cancel();
2282   EXPECT_EQ(NULL, spdy_stream3.get());
2283   EXPECT_EQ(0u, session->num_active_streams());
2284   EXPECT_EQ(kInitialMaxConcurrentStreams - 1, session->num_created_streams());
2285   EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST));
2286 }
2287 
2288 // Test that SpdySession::DoReadLoop reads data from the socket
2289 // without yielding.  This test makes 32k - 1 bytes of data available
2290 // on the socket for reading. It then verifies that it has read all
2291 // the available data without yielding.
TEST_P(SpdySessionTest,ReadDataWithoutYielding)2292 TEST_P(SpdySessionTest, ReadDataWithoutYielding) {
2293   MockConnect connect_data(SYNCHRONOUS, OK);
2294   BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
2295 
2296   scoped_ptr<SpdyFrame> req1(
2297       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
2298   MockWrite writes[] = {
2299     CreateMockWrite(*req1, 0),
2300   };
2301 
2302   // Build buffer of size kMaxReadBytesWithoutYielding / 4
2303   // (-spdy_data_frame_size).
2304   ASSERT_EQ(32 * 1024, kMaxReadBytesWithoutYielding);
2305   const int kPayloadSize =
2306       kMaxReadBytesWithoutYielding / 4 - framer.GetControlFrameHeaderSize();
2307   TestDataStream test_stream;
2308   scoped_refptr<net::IOBuffer> payload(new net::IOBuffer(kPayloadSize));
2309   char* payload_data = payload->data();
2310   test_stream.GetBytes(payload_data, kPayloadSize);
2311 
2312   scoped_ptr<SpdyFrame> partial_data_frame(
2313       framer.CreateDataFrame(1, payload_data, kPayloadSize, DATA_FLAG_NONE));
2314   scoped_ptr<SpdyFrame> finish_data_frame(
2315       framer.CreateDataFrame(1, payload_data, kPayloadSize - 1, DATA_FLAG_FIN));
2316 
2317   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2318 
2319   // Write 1 byte less than kMaxReadBytes to check that DoRead reads up to 32k
2320   // bytes.
2321   MockRead reads[] = {
2322     CreateMockRead(*resp1, 1),
2323     CreateMockRead(*partial_data_frame, 2),
2324     CreateMockRead(*partial_data_frame, 3, SYNCHRONOUS),
2325     CreateMockRead(*partial_data_frame, 4, SYNCHRONOUS),
2326     CreateMockRead(*finish_data_frame, 5, SYNCHRONOUS),
2327     MockRead(ASYNC, 0, 6)  // EOF
2328   };
2329 
2330   // Create SpdySession and SpdyStream and send the request.
2331   DeterministicSocketData data(reads, arraysize(reads),
2332                                writes, arraysize(writes));
2333   data.set_connect_data(connect_data);
2334   session_deps_.host_resolver->set_synchronous_mode(true);
2335   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
2336 
2337   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
2338   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
2339 
2340   CreateDeterministicNetworkSession();
2341 
2342   base::WeakPtr<SpdySession> session =
2343       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
2344 
2345   GURL url1("http://www.google.com");
2346   base::WeakPtr<SpdyStream> spdy_stream1 =
2347       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
2348                                 session, url1, MEDIUM, BoundNetLog());
2349   ASSERT_TRUE(spdy_stream1.get() != NULL);
2350   EXPECT_EQ(0u, spdy_stream1->stream_id());
2351   test::StreamDelegateDoNothing delegate1(spdy_stream1);
2352   spdy_stream1->SetDelegate(&delegate1);
2353 
2354   scoped_ptr<SpdyHeaderBlock> headers1(
2355       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
2356   spdy_stream1->SendRequestHeaders(headers1.Pass(), NO_MORE_DATA_TO_SEND);
2357   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
2358 
2359   // Set up the TaskObserver to verify SpdySession::DoReadLoop doesn't
2360   // post a task.
2361   SpdySessionTestTaskObserver observer("spdy_session.cc", "DoReadLoop");
2362 
2363   // Run until 1st read.
2364   EXPECT_EQ(0u, delegate1.stream_id());
2365   data.RunFor(2);
2366   EXPECT_EQ(1u, delegate1.stream_id());
2367   EXPECT_EQ(0u, observer.executed_count());
2368 
2369   // Read all the data and verify SpdySession::DoReadLoop has not
2370   // posted a task.
2371   data.RunFor(4);
2372   EXPECT_EQ(NULL, spdy_stream1.get());
2373 
2374   // Verify task observer's executed_count is zero, which indicates DoRead read
2375   // all the available data.
2376   EXPECT_EQ(0u, observer.executed_count());
2377   EXPECT_TRUE(data.at_write_eof());
2378   EXPECT_TRUE(data.at_read_eof());
2379 }
2380 
2381 // Test that SpdySession::DoReadLoop yields while reading the
2382 // data. This test makes 32k + 1 bytes of data available on the socket
2383 // for reading. It then verifies that DoRead has yielded even though
2384 // there is data available for it to read (i.e, socket()->Read didn't
2385 // return ERR_IO_PENDING during socket reads).
TEST_P(SpdySessionTest,TestYieldingDuringReadData)2386 TEST_P(SpdySessionTest, TestYieldingDuringReadData) {
2387   MockConnect connect_data(SYNCHRONOUS, OK);
2388   BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
2389 
2390   scoped_ptr<SpdyFrame> req1(
2391       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
2392   MockWrite writes[] = {
2393     CreateMockWrite(*req1, 0),
2394   };
2395 
2396   // Build buffer of size kMaxReadBytesWithoutYielding / 4
2397   // (-spdy_data_frame_size).
2398   ASSERT_EQ(32 * 1024, kMaxReadBytesWithoutYielding);
2399   const int kPayloadSize =
2400       kMaxReadBytesWithoutYielding / 4 - framer.GetControlFrameHeaderSize();
2401   TestDataStream test_stream;
2402   scoped_refptr<net::IOBuffer> payload(new net::IOBuffer(kPayloadSize));
2403   char* payload_data = payload->data();
2404   test_stream.GetBytes(payload_data, kPayloadSize);
2405 
2406   scoped_ptr<SpdyFrame> partial_data_frame(
2407       framer.CreateDataFrame(1, payload_data, kPayloadSize, DATA_FLAG_NONE));
2408   scoped_ptr<SpdyFrame> finish_data_frame(
2409       framer.CreateDataFrame(1, "h", 1, DATA_FLAG_FIN));
2410 
2411   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2412 
2413   // Write 1 byte more than kMaxReadBytes to check that DoRead yields.
2414   MockRead reads[] = {
2415     CreateMockRead(*resp1, 1),
2416     CreateMockRead(*partial_data_frame, 2),
2417     CreateMockRead(*partial_data_frame, 3, SYNCHRONOUS),
2418     CreateMockRead(*partial_data_frame, 4, SYNCHRONOUS),
2419     CreateMockRead(*partial_data_frame, 5, SYNCHRONOUS),
2420     CreateMockRead(*finish_data_frame, 6, SYNCHRONOUS),
2421     MockRead(ASYNC, 0, 7)  // EOF
2422   };
2423 
2424   // Create SpdySession and SpdyStream and send the request.
2425   DeterministicSocketData data(reads, arraysize(reads),
2426                                writes, arraysize(writes));
2427   data.set_connect_data(connect_data);
2428   session_deps_.host_resolver->set_synchronous_mode(true);
2429   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
2430 
2431   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
2432   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
2433 
2434   CreateDeterministicNetworkSession();
2435 
2436   base::WeakPtr<SpdySession> session =
2437       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
2438 
2439   GURL url1("http://www.google.com");
2440   base::WeakPtr<SpdyStream> spdy_stream1 =
2441       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
2442                                 session, url1, MEDIUM, BoundNetLog());
2443   ASSERT_TRUE(spdy_stream1.get() != NULL);
2444   EXPECT_EQ(0u, spdy_stream1->stream_id());
2445   test::StreamDelegateDoNothing delegate1(spdy_stream1);
2446   spdy_stream1->SetDelegate(&delegate1);
2447 
2448   scoped_ptr<SpdyHeaderBlock> headers1(
2449       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
2450   spdy_stream1->SendRequestHeaders(headers1.Pass(), NO_MORE_DATA_TO_SEND);
2451   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
2452 
2453   // Set up the TaskObserver to verify SpdySession::DoReadLoop posts a
2454   // task.
2455   SpdySessionTestTaskObserver observer("spdy_session.cc", "DoReadLoop");
2456 
2457   // Run until 1st read.
2458   EXPECT_EQ(0u, delegate1.stream_id());
2459   data.RunFor(2);
2460   EXPECT_EQ(1u, delegate1.stream_id());
2461   EXPECT_EQ(0u, observer.executed_count());
2462 
2463   // Read all the data and verify SpdySession::DoReadLoop has posted a
2464   // task.
2465   data.RunFor(6);
2466   EXPECT_EQ(NULL, spdy_stream1.get());
2467 
2468   // Verify task observer's executed_count is 1, which indicates DoRead has
2469   // posted only one task and thus yielded though there is data available for it
2470   // to read.
2471   EXPECT_EQ(1u, observer.executed_count());
2472   EXPECT_TRUE(data.at_write_eof());
2473   EXPECT_TRUE(data.at_read_eof());
2474 }
2475 
2476 // Test that SpdySession::DoReadLoop() tests interactions of yielding
2477 // + async, by doing the following MockReads.
2478 //
2479 // MockRead of SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 2K
2480 // ASYNC 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 2K.
2481 //
2482 // The above reads 26K synchronously. Since that is less that 32K, we
2483 // will attempt to read again. However, that DoRead() will return
2484 // ERR_IO_PENDING (because of async read), so DoReadLoop() will
2485 // yield. When we come back, DoRead() will read the results from the
2486 // async read, and rest of the data synchronously.
TEST_P(SpdySessionTest,TestYieldingDuringAsyncReadData)2487 TEST_P(SpdySessionTest, TestYieldingDuringAsyncReadData) {
2488   MockConnect connect_data(SYNCHRONOUS, OK);
2489   BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
2490 
2491   scoped_ptr<SpdyFrame> req1(
2492       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
2493   MockWrite writes[] = {
2494     CreateMockWrite(*req1, 0),
2495   };
2496 
2497   // Build buffer of size kMaxReadBytesWithoutYielding / 4
2498   // (-spdy_data_frame_size).
2499   ASSERT_EQ(32 * 1024, kMaxReadBytesWithoutYielding);
2500   TestDataStream test_stream;
2501   const int kEightKPayloadSize =
2502       kMaxReadBytesWithoutYielding / 4 - framer.GetControlFrameHeaderSize();
2503   scoped_refptr<net::IOBuffer> eightk_payload(
2504       new net::IOBuffer(kEightKPayloadSize));
2505   char* eightk_payload_data = eightk_payload->data();
2506   test_stream.GetBytes(eightk_payload_data, kEightKPayloadSize);
2507 
2508   // Build buffer of 2k size.
2509   TestDataStream test_stream2;
2510   const int kTwoKPayloadSize = kEightKPayloadSize - 6 * 1024;
2511   scoped_refptr<net::IOBuffer> twok_payload(
2512       new net::IOBuffer(kTwoKPayloadSize));
2513   char* twok_payload_data = twok_payload->data();
2514   test_stream2.GetBytes(twok_payload_data, kTwoKPayloadSize);
2515 
2516   scoped_ptr<SpdyFrame> eightk_data_frame(framer.CreateDataFrame(
2517       1, eightk_payload_data, kEightKPayloadSize, DATA_FLAG_NONE));
2518   scoped_ptr<SpdyFrame> twok_data_frame(framer.CreateDataFrame(
2519       1, twok_payload_data, kTwoKPayloadSize, DATA_FLAG_NONE));
2520   scoped_ptr<SpdyFrame> finish_data_frame(framer.CreateDataFrame(
2521       1, "h", 1, DATA_FLAG_FIN));
2522 
2523   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2524 
2525   MockRead reads[] = {
2526     CreateMockRead(*resp1, 1),
2527     CreateMockRead(*eightk_data_frame, 2),
2528     CreateMockRead(*eightk_data_frame, 3, SYNCHRONOUS),
2529     CreateMockRead(*eightk_data_frame, 4, SYNCHRONOUS),
2530     CreateMockRead(*twok_data_frame, 5, SYNCHRONOUS),
2531     CreateMockRead(*eightk_data_frame, 6, ASYNC),
2532     CreateMockRead(*eightk_data_frame, 7, SYNCHRONOUS),
2533     CreateMockRead(*eightk_data_frame, 8, SYNCHRONOUS),
2534     CreateMockRead(*eightk_data_frame, 9, SYNCHRONOUS),
2535     CreateMockRead(*twok_data_frame, 10, SYNCHRONOUS),
2536     CreateMockRead(*finish_data_frame, 11, SYNCHRONOUS),
2537     MockRead(ASYNC, 0, 12)  // EOF
2538   };
2539 
2540   // Create SpdySession and SpdyStream and send the request.
2541   DeterministicSocketData data(reads, arraysize(reads),
2542                                writes, arraysize(writes));
2543   data.set_connect_data(connect_data);
2544   session_deps_.host_resolver->set_synchronous_mode(true);
2545   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
2546 
2547   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
2548   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
2549 
2550   CreateDeterministicNetworkSession();
2551 
2552   base::WeakPtr<SpdySession> session =
2553       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
2554 
2555   GURL url1("http://www.google.com");
2556   base::WeakPtr<SpdyStream> spdy_stream1 =
2557       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
2558                                 session, url1, MEDIUM, BoundNetLog());
2559   ASSERT_TRUE(spdy_stream1.get() != NULL);
2560   EXPECT_EQ(0u, spdy_stream1->stream_id());
2561   test::StreamDelegateDoNothing delegate1(spdy_stream1);
2562   spdy_stream1->SetDelegate(&delegate1);
2563 
2564   scoped_ptr<SpdyHeaderBlock> headers1(
2565       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
2566   spdy_stream1->SendRequestHeaders(headers1.Pass(), NO_MORE_DATA_TO_SEND);
2567   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
2568 
2569   // Set up the TaskObserver to monitor SpdySession::DoReadLoop
2570   // posting of tasks.
2571   SpdySessionTestTaskObserver observer("spdy_session.cc", "DoReadLoop");
2572 
2573   // Run until 1st read.
2574   EXPECT_EQ(0u, delegate1.stream_id());
2575   data.RunFor(2);
2576   EXPECT_EQ(1u, delegate1.stream_id());
2577   EXPECT_EQ(0u, observer.executed_count());
2578 
2579   // Read all the data and verify SpdySession::DoReadLoop has posted a
2580   // task.
2581   data.RunFor(12);
2582   EXPECT_EQ(NULL, spdy_stream1.get());
2583 
2584   // Verify task observer's executed_count is 1, which indicates DoRead has
2585   // posted only one task and thus yielded though there is data available for
2586   // it to read.
2587   EXPECT_EQ(1u, observer.executed_count());
2588   EXPECT_TRUE(data.at_write_eof());
2589   EXPECT_TRUE(data.at_read_eof());
2590 }
2591 
2592 // Send a GoAway frame when SpdySession is in DoReadLoop. Make sure
2593 // nothing blows up.
TEST_P(SpdySessionTest,GoAwayWhileInDoReadLoop)2594 TEST_P(SpdySessionTest, GoAwayWhileInDoReadLoop) {
2595   MockConnect connect_data(SYNCHRONOUS, OK);
2596   BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
2597 
2598   scoped_ptr<SpdyFrame> req1(
2599       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
2600   MockWrite writes[] = {
2601     CreateMockWrite(*req1, 0),
2602   };
2603 
2604   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2605   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
2606   scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway());
2607 
2608   MockRead reads[] = {
2609     CreateMockRead(*resp1, 1),
2610     CreateMockRead(*body1, 2),
2611     CreateMockRead(*goaway, 3),
2612   };
2613 
2614   // Create SpdySession and SpdyStream and send the request.
2615   DeterministicSocketData data(reads, arraysize(reads),
2616                                writes, arraysize(writes));
2617   data.set_connect_data(connect_data);
2618   session_deps_.host_resolver->set_synchronous_mode(true);
2619   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
2620 
2621   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
2622   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
2623 
2624   CreateDeterministicNetworkSession();
2625 
2626   base::WeakPtr<SpdySession> session =
2627       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
2628 
2629   GURL url1("http://www.google.com");
2630   base::WeakPtr<SpdyStream> spdy_stream1 =
2631       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
2632                                 session, url1, MEDIUM, BoundNetLog());
2633   test::StreamDelegateDoNothing delegate1(spdy_stream1);
2634   spdy_stream1->SetDelegate(&delegate1);
2635   ASSERT_TRUE(spdy_stream1.get() != NULL);
2636   EXPECT_EQ(0u, spdy_stream1->stream_id());
2637 
2638   scoped_ptr<SpdyHeaderBlock> headers1(
2639       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
2640   spdy_stream1->SendRequestHeaders(headers1.Pass(), NO_MORE_DATA_TO_SEND);
2641   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
2642 
2643   // Run until 1st read.
2644   EXPECT_EQ(0u, spdy_stream1->stream_id());
2645   data.RunFor(1);
2646   EXPECT_EQ(1u, spdy_stream1->stream_id());
2647 
2648   // Run until GoAway.
2649   data.RunFor(3);
2650   EXPECT_EQ(NULL, spdy_stream1.get());
2651   EXPECT_TRUE(data.at_write_eof());
2652   EXPECT_TRUE(data.at_read_eof());
2653   EXPECT_TRUE(session == NULL);
2654 }
2655 
2656 // Within this framework, a SpdySession should be initialized with
2657 // flow control disabled for protocol version 2, with flow control
2658 // enabled only for streams for protocol version 3, and with flow
2659 // control enabled for streams and sessions for higher versions.
TEST_P(SpdySessionTest,ProtocolNegotiation)2660 TEST_P(SpdySessionTest, ProtocolNegotiation) {
2661   session_deps_.host_resolver->set_synchronous_mode(true);
2662 
2663   MockConnect connect_data(SYNCHRONOUS, OK);
2664   MockRead reads[] = {
2665     MockRead(SYNCHRONOUS, 0, 0)  // EOF
2666   };
2667   StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
2668   data.set_connect_data(connect_data);
2669   session_deps_.socket_factory->AddSocketDataProvider(&data);
2670 
2671   CreateNetworkSession();
2672   base::WeakPtr<SpdySession> session =
2673       CreateFakeSpdySession(spdy_session_pool_, key_);
2674 
2675   EXPECT_EQ(spdy_util_.spdy_version(),
2676             session->buffered_spdy_framer_->protocol_version());
2677   if (GetParam() == kProtoDeprecatedSPDY2) {
2678     EXPECT_EQ(SpdySession::FLOW_CONTROL_NONE, session->flow_control_state());
2679     EXPECT_EQ(0, session->session_send_window_size_);
2680     EXPECT_EQ(0, session->session_recv_window_size_);
2681   } else if (GetParam() == kProtoSPDY3) {
2682     EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM, session->flow_control_state());
2683     EXPECT_EQ(0, session->session_send_window_size_);
2684     EXPECT_EQ(0, session->session_recv_window_size_);
2685   } else {
2686     EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
2687               session->flow_control_state());
2688     EXPECT_EQ(kSpdySessionInitialWindowSize,
2689               session->session_send_window_size_);
2690     EXPECT_EQ(kSpdySessionInitialWindowSize,
2691               session->session_recv_window_size_);
2692   }
2693   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
2694 }
2695 
2696 // Tests the case of a non-SPDY request closing an idle SPDY session when no
2697 // pointers to the idle session are currently held.
TEST_P(SpdySessionTest,CloseOneIdleConnection)2698 TEST_P(SpdySessionTest, CloseOneIdleConnection) {
2699   ClientSocketPoolManager::set_max_sockets_per_group(
2700       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
2701   ClientSocketPoolManager::set_max_sockets_per_pool(
2702       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
2703 
2704   MockConnect connect_data(SYNCHRONOUS, OK);
2705   MockRead reads[] = {
2706     MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
2707   };
2708   StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
2709   data.set_connect_data(connect_data);
2710   session_deps_.socket_factory->AddSocketDataProvider(&data);
2711   session_deps_.socket_factory->AddSocketDataProvider(&data);
2712 
2713   CreateNetworkSession();
2714 
2715   TransportClientSocketPool* pool =
2716       http_session_->GetTransportSocketPool(
2717           HttpNetworkSession::NORMAL_SOCKET_POOL);
2718 
2719   // Create an idle SPDY session.
2720   SpdySessionKey key1(HostPortPair("1.com", 80), ProxyServer::Direct(),
2721                       kPrivacyModeDisabled);
2722   base::WeakPtr<SpdySession> session1 =
2723       CreateInsecureSpdySession(http_session_, key1, BoundNetLog());
2724   EXPECT_FALSE(pool->IsStalled());
2725 
2726   // Trying to create a new connection should cause the pool to be stalled, and
2727   // post a task asynchronously to try and close the session.
2728   TestCompletionCallback callback2;
2729   HostPortPair host_port2("2.com", 80);
2730   scoped_refptr<TransportSocketParams> params2(
2731       new TransportSocketParams(host_port2, false, false,
2732                                 OnHostResolutionCallback()));
2733   scoped_ptr<ClientSocketHandle> connection2(new ClientSocketHandle);
2734   EXPECT_EQ(ERR_IO_PENDING,
2735             connection2->Init(host_port2.ToString(), params2, DEFAULT_PRIORITY,
2736                               callback2.callback(), pool, BoundNetLog()));
2737   EXPECT_TRUE(pool->IsStalled());
2738 
2739   // The socket pool should close the connection asynchronously and establish a
2740   // new connection.
2741   EXPECT_EQ(OK, callback2.WaitForResult());
2742   EXPECT_FALSE(pool->IsStalled());
2743   EXPECT_TRUE(session1 == NULL);
2744 }
2745 
2746 // Tests the case of a non-SPDY request closing an idle SPDY session when no
2747 // pointers to the idle session are currently held, in the case the SPDY session
2748 // has an alias.
TEST_P(SpdySessionTest,CloseOneIdleConnectionWithAlias)2749 TEST_P(SpdySessionTest, CloseOneIdleConnectionWithAlias) {
2750   ClientSocketPoolManager::set_max_sockets_per_group(
2751       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
2752   ClientSocketPoolManager::set_max_sockets_per_pool(
2753       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
2754 
2755   MockConnect connect_data(SYNCHRONOUS, OK);
2756   MockRead reads[] = {
2757     MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
2758   };
2759   StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
2760   data.set_connect_data(connect_data);
2761   session_deps_.socket_factory->AddSocketDataProvider(&data);
2762   session_deps_.socket_factory->AddSocketDataProvider(&data);
2763 
2764   session_deps_.host_resolver->set_synchronous_mode(true);
2765   session_deps_.host_resolver->rules()->AddIPLiteralRule(
2766       "1.com", "192.168.0.2", std::string());
2767   session_deps_.host_resolver->rules()->AddIPLiteralRule(
2768       "2.com", "192.168.0.2", std::string());
2769   // Not strictly needed.
2770   session_deps_.host_resolver->rules()->AddIPLiteralRule(
2771       "3.com", "192.168.0.3", std::string());
2772 
2773   CreateNetworkSession();
2774 
2775   TransportClientSocketPool* pool =
2776       http_session_->GetTransportSocketPool(
2777           HttpNetworkSession::NORMAL_SOCKET_POOL);
2778 
2779   // Create an idle SPDY session.
2780   SpdySessionKey key1(HostPortPair("1.com", 80), ProxyServer::Direct(),
2781                       kPrivacyModeDisabled);
2782   base::WeakPtr<SpdySession> session1 =
2783       CreateInsecureSpdySession(http_session_, key1, BoundNetLog());
2784   EXPECT_FALSE(pool->IsStalled());
2785 
2786   // Set up an alias for the idle SPDY session, increasing its ref count to 2.
2787   SpdySessionKey key2(HostPortPair("2.com", 80), ProxyServer::Direct(),
2788                       kPrivacyModeDisabled);
2789   HostResolver::RequestInfo info(key2.host_port_pair());
2790   AddressList addresses;
2791   // Pre-populate the DNS cache, since a synchronous resolution is required in
2792   // order to create the alias.
2793   session_deps_.host_resolver->Resolve(info,
2794                                        DEFAULT_PRIORITY,
2795                                        &addresses,
2796                                        CompletionCallback(),
2797                                        NULL,
2798                                        BoundNetLog());
2799   // Get a session for |key2|, which should return the session created earlier.
2800   base::WeakPtr<SpdySession> session2 =
2801       spdy_session_pool_->FindAvailableSession(key2, BoundNetLog());
2802   ASSERT_EQ(session1.get(), session2.get());
2803   EXPECT_FALSE(pool->IsStalled());
2804 
2805   // Trying to create a new connection should cause the pool to be stalled, and
2806   // post a task asynchronously to try and close the session.
2807   TestCompletionCallback callback3;
2808   HostPortPair host_port3("3.com", 80);
2809   scoped_refptr<TransportSocketParams> params3(
2810       new TransportSocketParams(host_port3, false, false,
2811                                 OnHostResolutionCallback()));
2812   scoped_ptr<ClientSocketHandle> connection3(new ClientSocketHandle);
2813   EXPECT_EQ(ERR_IO_PENDING,
2814             connection3->Init(host_port3.ToString(), params3, DEFAULT_PRIORITY,
2815                               callback3.callback(), pool, BoundNetLog()));
2816   EXPECT_TRUE(pool->IsStalled());
2817 
2818   // The socket pool should close the connection asynchronously and establish a
2819   // new connection.
2820   EXPECT_EQ(OK, callback3.WaitForResult());
2821   EXPECT_FALSE(pool->IsStalled());
2822   EXPECT_TRUE(session1 == NULL);
2823   EXPECT_TRUE(session2 == NULL);
2824 }
2825 
2826 // Tests that when a SPDY session becomes idle, it closes itself if there is
2827 // a lower layer pool stalled on the per-pool socket limit.
TEST_P(SpdySessionTest,CloseSessionOnIdleWhenPoolStalled)2828 TEST_P(SpdySessionTest, CloseSessionOnIdleWhenPoolStalled) {
2829   ClientSocketPoolManager::set_max_sockets_per_group(
2830       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
2831   ClientSocketPoolManager::set_max_sockets_per_pool(
2832       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
2833 
2834   MockConnect connect_data(SYNCHRONOUS, OK);
2835   MockRead reads[] = {
2836     MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
2837   };
2838   scoped_ptr<SpdyFrame> req1(
2839       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2840   scoped_ptr<SpdyFrame> cancel1(
2841       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
2842   MockWrite writes[] = {
2843     CreateMockWrite(*req1, 1),
2844     CreateMockWrite(*cancel1, 1),
2845   };
2846   StaticSocketDataProvider data(reads, arraysize(reads),
2847                                 writes, arraysize(writes));
2848   data.set_connect_data(connect_data);
2849   session_deps_.socket_factory->AddSocketDataProvider(&data);
2850 
2851   MockRead http_reads[] = {
2852     MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
2853   };
2854   StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
2855                                      NULL, 0);
2856   http_data.set_connect_data(connect_data);
2857   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
2858 
2859 
2860   CreateNetworkSession();
2861 
2862   TransportClientSocketPool* pool =
2863       http_session_->GetTransportSocketPool(
2864           HttpNetworkSession::NORMAL_SOCKET_POOL);
2865 
2866   // Create a SPDY session.
2867   GURL url1("http://www.google.com");
2868   SpdySessionKey key1(HostPortPair(url1.host(), 80),
2869                       ProxyServer::Direct(), kPrivacyModeDisabled);
2870   base::WeakPtr<SpdySession> session1 =
2871       CreateInsecureSpdySession(http_session_, key1, BoundNetLog());
2872   EXPECT_FALSE(pool->IsStalled());
2873 
2874   // Create a stream using the session, and send a request.
2875 
2876   TestCompletionCallback callback1;
2877   base::WeakPtr<SpdyStream> spdy_stream1 =
2878       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
2879                                 session1, url1, DEFAULT_PRIORITY,
2880                                 BoundNetLog());
2881   ASSERT_TRUE(spdy_stream1.get());
2882   test::StreamDelegateDoNothing delegate1(spdy_stream1);
2883   spdy_stream1->SetDelegate(&delegate1);
2884 
2885   scoped_ptr<SpdyHeaderBlock> headers1(
2886       spdy_util_.ConstructGetHeaderBlock(url1.spec()));
2887   EXPECT_EQ(ERR_IO_PENDING,
2888             spdy_stream1->SendRequestHeaders(
2889                 headers1.Pass(), NO_MORE_DATA_TO_SEND));
2890   EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
2891 
2892   base::MessageLoop::current()->RunUntilIdle();
2893 
2894   // Trying to create a new connection should cause the pool to be stalled, and
2895   // post a task asynchronously to try and close the session.
2896   TestCompletionCallback callback2;
2897   HostPortPair host_port2("2.com", 80);
2898   scoped_refptr<TransportSocketParams> params2(
2899       new TransportSocketParams(host_port2, false, false,
2900                                 OnHostResolutionCallback()));
2901   scoped_ptr<ClientSocketHandle> connection2(new ClientSocketHandle);
2902   EXPECT_EQ(ERR_IO_PENDING,
2903             connection2->Init(host_port2.ToString(), params2, DEFAULT_PRIORITY,
2904                               callback2.callback(), pool, BoundNetLog()));
2905   EXPECT_TRUE(pool->IsStalled());
2906 
2907   // Running the message loop should cause the socket pool to ask the SPDY
2908   // session to close an idle socket, but since the socket is in use, nothing
2909   // happens.
2910   base::RunLoop().RunUntilIdle();
2911   EXPECT_TRUE(pool->IsStalled());
2912   EXPECT_FALSE(callback2.have_result());
2913 
2914   // Cancelling the request should result in the session's socket being
2915   // closed, since the pool is stalled.
2916   ASSERT_TRUE(spdy_stream1.get());
2917   spdy_stream1->Cancel();
2918   base::RunLoop().RunUntilIdle();
2919   ASSERT_FALSE(pool->IsStalled());
2920   EXPECT_EQ(OK, callback2.WaitForResult());
2921 }
2922 
2923 // Verify that SpdySessionKey and therefore SpdySession is different when
2924 // privacy mode is enabled or disabled.
TEST_P(SpdySessionTest,SpdySessionKeyPrivacyMode)2925 TEST_P(SpdySessionTest, SpdySessionKeyPrivacyMode) {
2926   CreateDeterministicNetworkSession();
2927 
2928   HostPortPair host_port_pair("www.google.com", 443);
2929   SpdySessionKey key_privacy_enabled(host_port_pair, ProxyServer::Direct(),
2930                                      kPrivacyModeEnabled);
2931   SpdySessionKey key_privacy_disabled(host_port_pair, ProxyServer::Direct(),
2932                                      kPrivacyModeDisabled);
2933 
2934   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_enabled));
2935   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_disabled));
2936 
2937   // Add SpdySession with PrivacyMode Enabled to the pool.
2938   base::WeakPtr<SpdySession> session_privacy_enabled =
2939       CreateFakeSpdySession(spdy_session_pool_, key_privacy_enabled);
2940 
2941   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_privacy_enabled));
2942   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_disabled));
2943 
2944   // Add SpdySession with PrivacyMode Disabled to the pool.
2945   base::WeakPtr<SpdySession> session_privacy_disabled =
2946       CreateFakeSpdySession(spdy_session_pool_, key_privacy_disabled);
2947 
2948   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_privacy_enabled));
2949   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_privacy_disabled));
2950 
2951   session_privacy_enabled->CloseSessionOnError(ERR_ABORTED, std::string());
2952   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_enabled));
2953   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_privacy_disabled));
2954 
2955   session_privacy_disabled->CloseSessionOnError(ERR_ABORTED, std::string());
2956   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_enabled));
2957   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_disabled));
2958 }
2959 
2960 // Delegate that creates another stream when its stream is closed.
2961 class StreamCreatingDelegate : public test::StreamDelegateDoNothing {
2962  public:
StreamCreatingDelegate(const base::WeakPtr<SpdyStream> & stream,const base::WeakPtr<SpdySession> & session)2963   StreamCreatingDelegate(const base::WeakPtr<SpdyStream>& stream,
2964                          const base::WeakPtr<SpdySession>& session)
2965       : StreamDelegateDoNothing(stream),
2966         session_(session) {}
2967 
~StreamCreatingDelegate()2968   virtual ~StreamCreatingDelegate() {}
2969 
OnClose(int status)2970   virtual void OnClose(int status) OVERRIDE {
2971     GURL url("http://www.google.com");
2972     ignore_result(
2973         CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
2974                                   session_, url, MEDIUM, BoundNetLog()));
2975   }
2976 
2977  private:
2978   const base::WeakPtr<SpdySession> session_;
2979 };
2980 
2981 // Create another stream in response to a stream being reset. Nothing
2982 // should blow up. This is a regression test for
2983 // http://crbug.com/263690 .
TEST_P(SpdySessionTest,CreateStreamOnStreamReset)2984 TEST_P(SpdySessionTest, CreateStreamOnStreamReset) {
2985   session_deps_.host_resolver->set_synchronous_mode(true);
2986 
2987   MockConnect connect_data(SYNCHRONOUS, OK);
2988 
2989   scoped_ptr<SpdyFrame> req(
2990       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
2991   MockWrite writes[] = {
2992     CreateMockWrite(*req, 0),
2993   };
2994 
2995   scoped_ptr<SpdyFrame> rst(
2996       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_REFUSED_STREAM));
2997   MockRead reads[] = {
2998     CreateMockRead(*rst, 1),
2999     MockRead(ASYNC, 0, 2)  // EOF
3000   };
3001   DeterministicSocketData data(reads, arraysize(reads),
3002                                writes, arraysize(writes));
3003   data.set_connect_data(connect_data);
3004   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
3005 
3006   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
3007   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
3008 
3009   CreateDeterministicNetworkSession();
3010 
3011   base::WeakPtr<SpdySession> session =
3012       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
3013 
3014   GURL url("http://www.google.com");
3015   base::WeakPtr<SpdyStream> spdy_stream =
3016       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
3017                                 session, url, MEDIUM, BoundNetLog());
3018   ASSERT_TRUE(spdy_stream.get() != NULL);
3019   EXPECT_EQ(0u, spdy_stream->stream_id());
3020 
3021   StreamCreatingDelegate delegate(spdy_stream, session);
3022   spdy_stream->SetDelegate(&delegate);
3023 
3024   scoped_ptr<SpdyHeaderBlock> headers(
3025       spdy_util_.ConstructGetHeaderBlock(url.spec()));
3026   spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
3027   EXPECT_TRUE(spdy_stream->HasUrlFromHeaders());
3028 
3029   EXPECT_EQ(0u, spdy_stream->stream_id());
3030 
3031   data.RunFor(1);
3032 
3033   EXPECT_EQ(1u, spdy_stream->stream_id());
3034 
3035   // Cause the stream to be reset, which should cause another stream
3036   // to be created.
3037   data.RunFor(1);
3038 
3039   EXPECT_EQ(NULL, spdy_stream.get());
3040   EXPECT_TRUE(delegate.StreamIsClosed());
3041   EXPECT_EQ(0u, session->num_active_streams());
3042   EXPECT_EQ(1u, session->num_created_streams());
3043 }
3044 
3045 // The tests below are only for SPDY/3 and above.
3046 
TEST_P(SpdySessionTest,UpdateStreamsSendWindowSize)3047 TEST_P(SpdySessionTest, UpdateStreamsSendWindowSize) {
3048   if (GetParam() < kProtoSPDY3)
3049     return;
3050 
3051   // Set SETTINGS_INITIAL_WINDOW_SIZE to a small number so that WINDOW_UPDATE
3052   // gets sent.
3053   SettingsMap new_settings;
3054   int32 window_size = 1;
3055   new_settings[SETTINGS_INITIAL_WINDOW_SIZE] =
3056       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, window_size);
3057 
3058   // Set up the socket so we read a SETTINGS frame that sets
3059   // INITIAL_WINDOW_SIZE.
3060   MockConnect connect_data(SYNCHRONOUS, OK);
3061   scoped_ptr<SpdyFrame> settings_frame(
3062       spdy_util_.ConstructSpdySettings(new_settings));
3063   MockRead reads[] = {
3064     CreateMockRead(*settings_frame, 0),
3065     MockRead(ASYNC, 0, 1)  // EOF
3066   };
3067 
3068   session_deps_.host_resolver->set_synchronous_mode(true);
3069 
3070   scoped_ptr<DeterministicSocketData> data(
3071       new DeterministicSocketData(reads, arraysize(reads), NULL, 0));
3072   data->set_connect_data(connect_data);
3073   session_deps_.deterministic_socket_factory->AddSocketDataProvider(data.get());
3074 
3075   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
3076   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3077 
3078   CreateDeterministicNetworkSession();
3079 
3080   base::WeakPtr<SpdySession> session =
3081       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
3082   base::WeakPtr<SpdyStream> spdy_stream1 =
3083       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
3084                                 session, test_url_, MEDIUM, BoundNetLog());
3085   ASSERT_TRUE(spdy_stream1.get() != NULL);
3086   TestCompletionCallback callback1;
3087   EXPECT_NE(spdy_stream1->send_window_size(), window_size);
3088 
3089   data->RunFor(1);  // Process the SETTINGS frame, but not the EOF
3090   base::MessageLoop::current()->RunUntilIdle();
3091   EXPECT_EQ(session->stream_initial_send_window_size(), window_size);
3092   EXPECT_EQ(spdy_stream1->send_window_size(), window_size);
3093 
3094   // Release the first one, this will allow the second to be created.
3095   spdy_stream1->Cancel();
3096   EXPECT_EQ(NULL, spdy_stream1.get());
3097 
3098   base::WeakPtr<SpdyStream> spdy_stream2 =
3099       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
3100                                 session, test_url_, MEDIUM, BoundNetLog());
3101   ASSERT_TRUE(spdy_stream2.get() != NULL);
3102   EXPECT_EQ(spdy_stream2->send_window_size(), window_size);
3103   spdy_stream2->Cancel();
3104   EXPECT_EQ(NULL, spdy_stream2.get());
3105 }
3106 
3107 // The tests below are only for SPDY/3.1 and above.
3108 
3109 // SpdySession::{Increase,Decrease}RecvWindowSize should properly
3110 // adjust the session receive window size for SPDY 3.1 and higher. In
3111 // addition, SpdySession::IncreaseRecvWindowSize should trigger
3112 // sending a WINDOW_UPDATE frame for a large enough delta.
TEST_P(SpdySessionTest,AdjustRecvWindowSize)3113 TEST_P(SpdySessionTest, AdjustRecvWindowSize) {
3114   if (GetParam() < kProtoSPDY31)
3115     return;
3116 
3117   session_deps_.host_resolver->set_synchronous_mode(true);
3118 
3119   const int32 delta_window_size = 100;
3120 
3121   MockConnect connect_data(SYNCHRONOUS, OK);
3122   MockRead reads[] = {
3123     MockRead(ASYNC, 0, 1)  // EOF
3124   };
3125   scoped_ptr<SpdyFrame> window_update(
3126       spdy_util_.ConstructSpdyWindowUpdate(
3127           kSessionFlowControlStreamId,
3128           kSpdySessionInitialWindowSize + delta_window_size));
3129   MockWrite writes[] = {
3130     CreateMockWrite(*window_update, 0),
3131   };
3132   DeterministicSocketData data(reads, arraysize(reads),
3133                                writes, arraysize(writes));
3134   data.set_connect_data(connect_data);
3135   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
3136 
3137   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
3138   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
3139 
3140   CreateDeterministicNetworkSession();
3141   base::WeakPtr<SpdySession> session =
3142       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
3143   EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
3144             session->flow_control_state());
3145 
3146   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
3147   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
3148 
3149   session->IncreaseRecvWindowSize(delta_window_size);
3150   EXPECT_EQ(kSpdySessionInitialWindowSize + delta_window_size,
3151             session->session_recv_window_size_);
3152   EXPECT_EQ(delta_window_size, session->session_unacked_recv_window_bytes_);
3153 
3154   // Should trigger sending a WINDOW_UPDATE frame.
3155   session->IncreaseRecvWindowSize(kSpdySessionInitialWindowSize);
3156   EXPECT_EQ(kSpdySessionInitialWindowSize + delta_window_size +
3157             kSpdySessionInitialWindowSize,
3158             session->session_recv_window_size_);
3159   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
3160 
3161   data.RunFor(1);
3162 
3163   // DecreaseRecvWindowSize() expects |in_io_loop_| to be true.
3164   session->in_io_loop_ = true;
3165   session->DecreaseRecvWindowSize(
3166       kSpdySessionInitialWindowSize + delta_window_size +
3167       kSpdySessionInitialWindowSize);
3168   session->in_io_loop_ = false;
3169   EXPECT_EQ(0, session->session_recv_window_size_);
3170   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
3171 }
3172 
3173 // SpdySession::{Increase,Decrease}SendWindowSize should properly
3174 // adjust the session send window size when the "enable_spdy_31" flag
3175 // is set.
TEST_P(SpdySessionTest,AdjustSendWindowSize)3176 TEST_P(SpdySessionTest, AdjustSendWindowSize) {
3177   if (GetParam() < kProtoSPDY31)
3178     return;
3179 
3180   session_deps_.host_resolver->set_synchronous_mode(true);
3181 
3182   MockConnect connect_data(SYNCHRONOUS, OK);
3183   MockRead reads[] = {
3184     MockRead(SYNCHRONOUS, 0, 0)  // EOF
3185   };
3186   StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
3187   data.set_connect_data(connect_data);
3188   session_deps_.socket_factory->AddSocketDataProvider(&data);
3189 
3190   CreateNetworkSession();
3191   base::WeakPtr<SpdySession> session =
3192       CreateFakeSpdySession(spdy_session_pool_, key_);
3193   EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
3194             session->flow_control_state());
3195 
3196   const int32 delta_window_size = 100;
3197 
3198   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_);
3199 
3200   session->IncreaseSendWindowSize(delta_window_size);
3201   EXPECT_EQ(kSpdySessionInitialWindowSize + delta_window_size,
3202             session->session_send_window_size_);
3203 
3204   session->DecreaseSendWindowSize(delta_window_size);
3205   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_);
3206 }
3207 
3208 // Incoming data for an inactive stream should not cause the session
3209 // receive window size to decrease, but it should cause the unacked
3210 // bytes to increase.
TEST_P(SpdySessionTest,SessionFlowControlInactiveStream)3211 TEST_P(SpdySessionTest, SessionFlowControlInactiveStream) {
3212   if (GetParam() < kProtoSPDY31)
3213     return;
3214 
3215   session_deps_.host_resolver->set_synchronous_mode(true);
3216 
3217   MockConnect connect_data(SYNCHRONOUS, OK);
3218   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyBodyFrame(1, false));
3219   MockRead reads[] = {
3220     CreateMockRead(*resp, 0),
3221     MockRead(ASYNC, 0, 1)  // EOF
3222   };
3223   DeterministicSocketData data(reads, arraysize(reads), NULL, 0);
3224   data.set_connect_data(connect_data);
3225   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
3226 
3227   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
3228   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
3229 
3230   CreateDeterministicNetworkSession();
3231   base::WeakPtr<SpdySession> session =
3232       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
3233   EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
3234             session->flow_control_state());
3235 
3236   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
3237   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
3238 
3239   data.RunFor(1);
3240 
3241   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
3242   EXPECT_EQ(kUploadDataSize, session->session_unacked_recv_window_bytes_);
3243 
3244   data.RunFor(1);
3245 }
3246 
3247 // A delegate that drops any received data.
3248 class DropReceivedDataDelegate : public test::StreamDelegateSendImmediate {
3249  public:
DropReceivedDataDelegate(const base::WeakPtr<SpdyStream> & stream,base::StringPiece data)3250   DropReceivedDataDelegate(const base::WeakPtr<SpdyStream>& stream,
3251                            base::StringPiece data)
3252       : StreamDelegateSendImmediate(stream, data) {}
3253 
~DropReceivedDataDelegate()3254   virtual ~DropReceivedDataDelegate() {}
3255 
3256   // Drop any received data.
OnDataReceived(scoped_ptr<SpdyBuffer> buffer)3257   virtual void OnDataReceived(scoped_ptr<SpdyBuffer> buffer) OVERRIDE {}
3258 };
3259 
3260 // Send data back and forth but use a delegate that drops its received
3261 // data. The receive window should still increase to its original
3262 // value, i.e. we shouldn't "leak" receive window bytes.
TEST_P(SpdySessionTest,SessionFlowControlNoReceiveLeaks)3263 TEST_P(SpdySessionTest, SessionFlowControlNoReceiveLeaks) {
3264   if (GetParam() < kProtoSPDY31)
3265     return;
3266 
3267   const char kStreamUrl[] = "http://www.google.com/";
3268 
3269   const int32 msg_data_size = 100;
3270   const std::string msg_data(msg_data_size, 'a');
3271 
3272   MockConnect connect_data(SYNCHRONOUS, OK);
3273 
3274   scoped_ptr<SpdyFrame> req(
3275       spdy_util_.ConstructSpdyPost(
3276           kStreamUrl, 1, msg_data_size, MEDIUM, NULL, 0));
3277   scoped_ptr<SpdyFrame> msg(
3278       spdy_util_.ConstructSpdyBodyFrame(
3279           1, msg_data.data(), msg_data_size, false));
3280   MockWrite writes[] = {
3281     CreateMockWrite(*req, 0),
3282     CreateMockWrite(*msg, 2),
3283   };
3284 
3285   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3286   scoped_ptr<SpdyFrame> echo(
3287       spdy_util_.ConstructSpdyBodyFrame(
3288           1, msg_data.data(), msg_data_size, false));
3289   scoped_ptr<SpdyFrame> window_update(
3290       spdy_util_.ConstructSpdyWindowUpdate(
3291           kSessionFlowControlStreamId, msg_data_size));
3292   MockRead reads[] = {
3293     CreateMockRead(*resp, 1),
3294     CreateMockRead(*echo, 3),
3295     MockRead(ASYNC, 0, 4)  // EOF
3296   };
3297 
3298   // Create SpdySession and SpdyStream and send the request.
3299   DeterministicSocketData data(reads, arraysize(reads),
3300                                writes, arraysize(writes));
3301   data.set_connect_data(connect_data);
3302   session_deps_.host_resolver->set_synchronous_mode(true);
3303   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
3304 
3305   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
3306   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
3307 
3308   CreateDeterministicNetworkSession();
3309 
3310   base::WeakPtr<SpdySession> session =
3311       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
3312 
3313   GURL url(kStreamUrl);
3314   base::WeakPtr<SpdyStream> stream =
3315       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
3316                                 session, url, MEDIUM, BoundNetLog());
3317   ASSERT_TRUE(stream.get() != NULL);
3318   EXPECT_EQ(0u, stream->stream_id());
3319 
3320   DropReceivedDataDelegate delegate(stream, msg_data);
3321   stream->SetDelegate(&delegate);
3322 
3323   scoped_ptr<SpdyHeaderBlock> headers(
3324       spdy_util_.ConstructPostHeaderBlock(url.spec(), msg_data_size));
3325   EXPECT_EQ(ERR_IO_PENDING,
3326             stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND));
3327   EXPECT_TRUE(stream->HasUrlFromHeaders());
3328 
3329   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
3330   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
3331 
3332   data.RunFor(4);
3333 
3334   EXPECT_TRUE(data.at_write_eof());
3335   EXPECT_TRUE(data.at_read_eof());
3336 
3337   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
3338   EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_);
3339 
3340   stream->Close();
3341   EXPECT_EQ(NULL, stream.get());
3342 
3343   EXPECT_EQ(OK, delegate.WaitForClose());
3344 
3345   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
3346   EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_);
3347 }
3348 
3349 // Send data back and forth but close the stream before its data frame
3350 // can be written to the socket. The send window should then increase
3351 // to its original value, i.e. we shouldn't "leak" send window bytes.
TEST_P(SpdySessionTest,SessionFlowControlNoSendLeaks)3352 TEST_P(SpdySessionTest, SessionFlowControlNoSendLeaks) {
3353   if (GetParam() < kProtoSPDY31)
3354     return;
3355 
3356   const char kStreamUrl[] = "http://www.google.com/";
3357 
3358   const int32 msg_data_size = 100;
3359   const std::string msg_data(msg_data_size, 'a');
3360 
3361   MockConnect connect_data(SYNCHRONOUS, OK);
3362 
3363   scoped_ptr<SpdyFrame> req(
3364       spdy_util_.ConstructSpdyPost(
3365           kStreamUrl, 1, msg_data_size, MEDIUM, NULL, 0));
3366   MockWrite writes[] = {
3367     CreateMockWrite(*req, 0),
3368   };
3369 
3370   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3371   MockRead reads[] = {
3372     CreateMockRead(*resp, 1),
3373     MockRead(ASYNC, 0, 2)  // EOF
3374   };
3375 
3376   // Create SpdySession and SpdyStream and send the request.
3377   DeterministicSocketData data(reads, arraysize(reads),
3378                                writes, arraysize(writes));
3379   data.set_connect_data(connect_data);
3380   session_deps_.host_resolver->set_synchronous_mode(true);
3381   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
3382 
3383   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
3384   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
3385 
3386   CreateDeterministicNetworkSession();
3387 
3388   base::WeakPtr<SpdySession> session =
3389       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
3390 
3391   GURL url(kStreamUrl);
3392   base::WeakPtr<SpdyStream> stream =
3393       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
3394                                 session, url, MEDIUM, BoundNetLog());
3395   ASSERT_TRUE(stream.get() != NULL);
3396   EXPECT_EQ(0u, stream->stream_id());
3397 
3398   test::StreamDelegateSendImmediate delegate(stream, msg_data);
3399   stream->SetDelegate(&delegate);
3400 
3401   scoped_ptr<SpdyHeaderBlock> headers(
3402       spdy_util_.ConstructPostHeaderBlock(url.spec(), msg_data_size));
3403   EXPECT_EQ(ERR_IO_PENDING,
3404             stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND));
3405   EXPECT_TRUE(stream->HasUrlFromHeaders());
3406 
3407   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_);
3408 
3409   data.RunFor(1);
3410 
3411   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_);
3412 
3413   data.RunFor(1);
3414 
3415   EXPECT_TRUE(data.at_write_eof());
3416   EXPECT_TRUE(data.at_read_eof());
3417 
3418   EXPECT_EQ(kSpdySessionInitialWindowSize - msg_data_size,
3419             session->session_send_window_size_);
3420 
3421   // Closing the stream should increase the session's send window.
3422   stream->Close();
3423   EXPECT_EQ(NULL, stream.get());
3424 
3425   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_);
3426 
3427   EXPECT_EQ(OK, delegate.WaitForClose());
3428 }
3429 
3430 // Send data back and forth; the send and receive windows should
3431 // change appropriately.
TEST_P(SpdySessionTest,SessionFlowControlEndToEnd)3432 TEST_P(SpdySessionTest, SessionFlowControlEndToEnd) {
3433   if (GetParam() < kProtoSPDY31)
3434     return;
3435 
3436   const char kStreamUrl[] = "http://www.google.com/";
3437 
3438   const int32 msg_data_size = 100;
3439   const std::string msg_data(msg_data_size, 'a');
3440 
3441   MockConnect connect_data(SYNCHRONOUS, OK);
3442 
3443   scoped_ptr<SpdyFrame> req(
3444       spdy_util_.ConstructSpdyPost(
3445           kStreamUrl, 1, msg_data_size, MEDIUM, NULL, 0));
3446   scoped_ptr<SpdyFrame> msg(
3447       spdy_util_.ConstructSpdyBodyFrame(
3448           1, msg_data.data(), msg_data_size, false));
3449   MockWrite writes[] = {
3450     CreateMockWrite(*req, 0),
3451     CreateMockWrite(*msg, 2),
3452   };
3453 
3454   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3455   scoped_ptr<SpdyFrame> echo(
3456       spdy_util_.ConstructSpdyBodyFrame(
3457           1, msg_data.data(), msg_data_size, false));
3458   scoped_ptr<SpdyFrame> window_update(
3459       spdy_util_.ConstructSpdyWindowUpdate(
3460           kSessionFlowControlStreamId, msg_data_size));
3461   MockRead reads[] = {
3462     CreateMockRead(*resp, 1),
3463     CreateMockRead(*echo, 3),
3464     CreateMockRead(*window_update, 4),
3465     MockRead(ASYNC, 0, 5)  // EOF
3466   };
3467 
3468   // Create SpdySession and SpdyStream and send the request.
3469   DeterministicSocketData data(reads, arraysize(reads),
3470                                writes, arraysize(writes));
3471   data.set_connect_data(connect_data);
3472   session_deps_.host_resolver->set_synchronous_mode(true);
3473   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
3474 
3475   SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
3476   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
3477 
3478   CreateDeterministicNetworkSession();
3479 
3480   base::WeakPtr<SpdySession> session =
3481       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
3482 
3483   GURL url(kStreamUrl);
3484   base::WeakPtr<SpdyStream> stream =
3485       CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
3486                                 session, url, MEDIUM, BoundNetLog());
3487   ASSERT_TRUE(stream.get() != NULL);
3488   EXPECT_EQ(0u, stream->stream_id());
3489 
3490   test::StreamDelegateSendImmediate delegate(stream, msg_data);
3491   stream->SetDelegate(&delegate);
3492 
3493   scoped_ptr<SpdyHeaderBlock> headers(
3494       spdy_util_.ConstructPostHeaderBlock(url.spec(), msg_data_size));
3495   EXPECT_EQ(ERR_IO_PENDING,
3496             stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND));
3497   EXPECT_TRUE(stream->HasUrlFromHeaders());
3498 
3499   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_);
3500   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
3501   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
3502 
3503   data.RunFor(1);
3504 
3505   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_);
3506   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
3507   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
3508 
3509   data.RunFor(1);
3510 
3511   EXPECT_EQ(kSpdySessionInitialWindowSize - msg_data_size,
3512             session->session_send_window_size_);
3513   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
3514   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
3515 
3516   data.RunFor(1);
3517 
3518   EXPECT_EQ(kSpdySessionInitialWindowSize - msg_data_size,
3519             session->session_send_window_size_);
3520   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
3521   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
3522 
3523   data.RunFor(1);
3524 
3525   EXPECT_EQ(kSpdySessionInitialWindowSize - msg_data_size,
3526             session->session_send_window_size_);
3527   EXPECT_EQ(kSpdySessionInitialWindowSize - msg_data_size,
3528             session->session_recv_window_size_);
3529   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
3530 
3531   data.RunFor(1);
3532 
3533   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_);
3534   EXPECT_EQ(kSpdySessionInitialWindowSize - msg_data_size,
3535             session->session_recv_window_size_);
3536   EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
3537 
3538   EXPECT_TRUE(data.at_write_eof());
3539   EXPECT_TRUE(data.at_read_eof());
3540 
3541   EXPECT_EQ(msg_data, delegate.TakeReceivedData());
3542 
3543   // Draining the delegate's read queue should increase the session's
3544   // receive window.
3545   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_);
3546   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
3547   EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_);
3548 
3549   stream->Close();
3550   EXPECT_EQ(NULL, stream.get());
3551 
3552   EXPECT_EQ(OK, delegate.WaitForClose());
3553 
3554   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_);
3555   EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
3556   EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_);
3557 }
3558 
3559 // Given a stall function and an unstall function, runs a test to make
3560 // sure that a stream resumes after unstall.
RunResumeAfterUnstallTest(const base::Callback<void (SpdySession *,SpdyStream *)> & stall_function,const base::Callback<void (SpdySession *,SpdyStream *,int32)> & unstall_function)3561 void SpdySessionTest::RunResumeAfterUnstallTest(
3562     const base::Callback<void(SpdySession*, SpdyStream*)>& stall_function,
3563     const base::Callback<void(SpdySession*, SpdyStream*, int32)>&
3564         unstall_function) {
3565   const char kStreamUrl[] = "http://www.google.com/";
3566   GURL url(kStreamUrl);
3567 
3568   session_deps_.host_resolver->set_synchronous_mode(true);
3569 
3570   scoped_ptr<SpdyFrame> req(
3571       spdy_util_.ConstructSpdyPost(
3572           kStreamUrl, 1, kBodyDataSize, LOWEST, NULL, 0));
3573   scoped_ptr<SpdyFrame> body(
3574       spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, true));
3575   MockWrite writes[] = {
3576     CreateMockWrite(*req, 0),
3577     CreateMockWrite(*body, 1),
3578   };
3579 
3580   scoped_ptr<SpdyFrame> resp(
3581       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3582   scoped_ptr<SpdyFrame> echo(
3583       spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, false));
3584   MockRead reads[] = {
3585     CreateMockRead(*resp, 2),
3586     MockRead(ASYNC, 0, 0, 3), // EOF
3587   };
3588 
3589   DeterministicSocketData data(reads, arraysize(reads),
3590                                writes, arraysize(writes));
3591   MockConnect connect_data(SYNCHRONOUS, OK);
3592   data.set_connect_data(connect_data);
3593 
3594   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
3595 
3596   CreateDeterministicNetworkSession();
3597   base::WeakPtr<SpdySession> session =
3598       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
3599   EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
3600             session->flow_control_state());
3601 
3602   base::WeakPtr<SpdyStream> stream =
3603       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
3604                                 session, url, LOWEST, BoundNetLog());
3605   ASSERT_TRUE(stream.get() != NULL);
3606 
3607   test::StreamDelegateWithBody delegate(stream, kBodyDataStringPiece);
3608   stream->SetDelegate(&delegate);
3609 
3610   EXPECT_FALSE(stream->HasUrlFromHeaders());
3611   EXPECT_FALSE(stream->send_stalled_by_flow_control());
3612 
3613   scoped_ptr<SpdyHeaderBlock> headers(
3614       spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
3615   EXPECT_EQ(ERR_IO_PENDING,
3616             stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND));
3617   EXPECT_TRUE(stream->HasUrlFromHeaders());
3618   EXPECT_EQ(kStreamUrl, stream->GetUrlFromHeaders().spec());
3619 
3620   stall_function.Run(session.get(), stream.get());
3621 
3622   data.RunFor(1);
3623 
3624   EXPECT_TRUE(stream->send_stalled_by_flow_control());
3625 
3626   unstall_function.Run(session.get(), stream.get(), kBodyDataSize);
3627 
3628   EXPECT_FALSE(stream->send_stalled_by_flow_control());
3629 
3630   data.RunFor(3);
3631 
3632   EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose());
3633 
3634   EXPECT_TRUE(delegate.send_headers_completed());
3635   EXPECT_EQ("200", delegate.GetResponseHeaderValue(":status"));
3636   EXPECT_EQ("HTTP/1.1", delegate.GetResponseHeaderValue(":version"));
3637   EXPECT_EQ(std::string(), delegate.TakeReceivedData());
3638   EXPECT_TRUE(data.at_write_eof());
3639 }
3640 
3641 // Run the resume-after-unstall test with all possible stall and
3642 // unstall sequences.
3643 
TEST_P(SpdySessionTest,ResumeAfterUnstallSession)3644 TEST_P(SpdySessionTest, ResumeAfterUnstallSession) {
3645   if (GetParam() < kProtoSPDY31)
3646     return;
3647 
3648   RunResumeAfterUnstallTest(
3649       base::Bind(&SpdySessionTest::StallSessionOnly,
3650                  base::Unretained(this)),
3651       base::Bind(&SpdySessionTest::UnstallSessionOnly,
3652                  base::Unretained(this)));
3653 }
3654 
3655 // Equivalent to
3656 // SpdyStreamTest.ResumeAfterSendWindowSizeIncrease.
TEST_P(SpdySessionTest,ResumeAfterUnstallStream)3657 TEST_P(SpdySessionTest, ResumeAfterUnstallStream) {
3658   if (GetParam() < kProtoSPDY31)
3659     return;
3660 
3661   RunResumeAfterUnstallTest(
3662       base::Bind(&SpdySessionTest::StallStreamOnly,
3663                  base::Unretained(this)),
3664       base::Bind(&SpdySessionTest::UnstallStreamOnly,
3665                  base::Unretained(this)));
3666 }
3667 
TEST_P(SpdySessionTest,StallSessionStreamResumeAfterUnstallSessionStream)3668 TEST_P(SpdySessionTest, StallSessionStreamResumeAfterUnstallSessionStream) {
3669   if (GetParam() < kProtoSPDY31)
3670     return;
3671 
3672   RunResumeAfterUnstallTest(
3673       base::Bind(&SpdySessionTest::StallSessionStream,
3674                  base::Unretained(this)),
3675       base::Bind(&SpdySessionTest::UnstallSessionStream,
3676                  base::Unretained(this)));
3677 }
3678 
TEST_P(SpdySessionTest,StallStreamSessionResumeAfterUnstallSessionStream)3679 TEST_P(SpdySessionTest, StallStreamSessionResumeAfterUnstallSessionStream) {
3680   if (GetParam() < kProtoSPDY31)
3681     return;
3682 
3683   RunResumeAfterUnstallTest(
3684       base::Bind(&SpdySessionTest::StallStreamSession,
3685                  base::Unretained(this)),
3686       base::Bind(&SpdySessionTest::UnstallSessionStream,
3687                  base::Unretained(this)));
3688 }
3689 
TEST_P(SpdySessionTest,StallStreamSessionResumeAfterUnstallStreamSession)3690 TEST_P(SpdySessionTest, StallStreamSessionResumeAfterUnstallStreamSession) {
3691   if (GetParam() < kProtoSPDY31)
3692     return;
3693 
3694   RunResumeAfterUnstallTest(
3695       base::Bind(&SpdySessionTest::StallStreamSession,
3696                  base::Unretained(this)),
3697       base::Bind(&SpdySessionTest::UnstallStreamSession,
3698                  base::Unretained(this)));
3699 }
3700 
TEST_P(SpdySessionTest,StallSessionStreamResumeAfterUnstallStreamSession)3701 TEST_P(SpdySessionTest, StallSessionStreamResumeAfterUnstallStreamSession) {
3702   if (GetParam() < kProtoSPDY31)
3703     return;
3704 
3705   RunResumeAfterUnstallTest(
3706       base::Bind(&SpdySessionTest::StallSessionStream,
3707                  base::Unretained(this)),
3708       base::Bind(&SpdySessionTest::UnstallStreamSession,
3709                  base::Unretained(this)));
3710 }
3711 
3712 // Cause a stall by reducing the flow control send window to 0. The
3713 // streams should resume in priority order when that window is then
3714 // increased.
TEST_P(SpdySessionTest,ResumeByPriorityAfterSendWindowSizeIncrease)3715 TEST_P(SpdySessionTest, ResumeByPriorityAfterSendWindowSizeIncrease) {
3716   if (GetParam() < kProtoSPDY31)
3717     return;
3718 
3719   const char kStreamUrl[] = "http://www.google.com/";
3720   GURL url(kStreamUrl);
3721 
3722   session_deps_.host_resolver->set_synchronous_mode(true);
3723 
3724   scoped_ptr<SpdyFrame> req1(
3725       spdy_util_.ConstructSpdyPost(
3726           kStreamUrl, 1, kBodyDataSize, LOWEST, NULL, 0));
3727   scoped_ptr<SpdyFrame> req2(
3728       spdy_util_.ConstructSpdyPost(
3729           kStreamUrl, 3, kBodyDataSize, MEDIUM, NULL, 0));
3730   scoped_ptr<SpdyFrame> body1(
3731       spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, true));
3732   scoped_ptr<SpdyFrame> body2(
3733       spdy_util_.ConstructSpdyBodyFrame(3, kBodyData, kBodyDataSize, true));
3734   MockWrite writes[] = {
3735     CreateMockWrite(*req1, 0),
3736     CreateMockWrite(*req2, 1),
3737     CreateMockWrite(*body2, 2),
3738     CreateMockWrite(*body1, 3),
3739   };
3740 
3741   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3742   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3743   MockRead reads[] = {
3744     CreateMockRead(*resp1, 4),
3745     CreateMockRead(*resp2, 5),
3746     MockRead(ASYNC, 0, 0, 6), // EOF
3747   };
3748 
3749   DeterministicSocketData data(reads, arraysize(reads),
3750                                writes, arraysize(writes));
3751   MockConnect connect_data(SYNCHRONOUS, OK);
3752   data.set_connect_data(connect_data);
3753 
3754   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
3755 
3756   CreateDeterministicNetworkSession();
3757   base::WeakPtr<SpdySession> session =
3758       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
3759   EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
3760             session->flow_control_state());
3761 
3762   base::WeakPtr<SpdyStream> stream1 =
3763       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
3764                                 session, url, LOWEST, BoundNetLog());
3765   ASSERT_TRUE(stream1.get() != NULL);
3766 
3767   test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece);
3768   stream1->SetDelegate(&delegate1);
3769 
3770   EXPECT_FALSE(stream1->HasUrlFromHeaders());
3771 
3772   base::WeakPtr<SpdyStream> stream2 =
3773       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
3774                                 session, url, MEDIUM, BoundNetLog());
3775   ASSERT_TRUE(stream2.get() != NULL);
3776 
3777   test::StreamDelegateWithBody delegate2(stream2, kBodyDataStringPiece);
3778   stream2->SetDelegate(&delegate2);
3779 
3780   EXPECT_FALSE(stream2->HasUrlFromHeaders());
3781 
3782   EXPECT_FALSE(stream1->send_stalled_by_flow_control());
3783   EXPECT_FALSE(stream2->send_stalled_by_flow_control());
3784 
3785   StallSessionSend(session.get());
3786 
3787   scoped_ptr<SpdyHeaderBlock> headers1(
3788       spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
3789   EXPECT_EQ(ERR_IO_PENDING,
3790             stream1->SendRequestHeaders(headers1.Pass(), MORE_DATA_TO_SEND));
3791   EXPECT_TRUE(stream1->HasUrlFromHeaders());
3792   EXPECT_EQ(kStreamUrl, stream1->GetUrlFromHeaders().spec());
3793 
3794   data.RunFor(1);
3795   EXPECT_EQ(1u, stream1->stream_id());
3796   EXPECT_TRUE(stream1->send_stalled_by_flow_control());
3797 
3798   scoped_ptr<SpdyHeaderBlock> headers2(
3799       spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
3800   EXPECT_EQ(ERR_IO_PENDING,
3801             stream2->SendRequestHeaders(headers2.Pass(), MORE_DATA_TO_SEND));
3802   EXPECT_TRUE(stream2->HasUrlFromHeaders());
3803   EXPECT_EQ(kStreamUrl, stream2->GetUrlFromHeaders().spec());
3804 
3805   data.RunFor(1);
3806   EXPECT_EQ(3u, stream2->stream_id());
3807   EXPECT_TRUE(stream2->send_stalled_by_flow_control());
3808 
3809   // This should unstall only stream2.
3810   UnstallSessionSend(session.get(), kBodyDataSize);
3811 
3812   EXPECT_TRUE(stream1->send_stalled_by_flow_control());
3813   EXPECT_FALSE(stream2->send_stalled_by_flow_control());
3814 
3815   data.RunFor(1);
3816 
3817   EXPECT_TRUE(stream1->send_stalled_by_flow_control());
3818   EXPECT_FALSE(stream2->send_stalled_by_flow_control());
3819 
3820   // This should then unstall stream1.
3821   UnstallSessionSend(session.get(), kBodyDataSize);
3822 
3823   EXPECT_FALSE(stream1->send_stalled_by_flow_control());
3824   EXPECT_FALSE(stream2->send_stalled_by_flow_control());
3825 
3826   data.RunFor(4);
3827 
3828   EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose());
3829   EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose());
3830 
3831   EXPECT_TRUE(delegate1.send_headers_completed());
3832   EXPECT_EQ("200", delegate1.GetResponseHeaderValue(":status"));
3833   EXPECT_EQ("HTTP/1.1", delegate1.GetResponseHeaderValue(":version"));
3834   EXPECT_EQ(std::string(), delegate1.TakeReceivedData());
3835 
3836   EXPECT_TRUE(delegate2.send_headers_completed());
3837   EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status"));
3838   EXPECT_EQ("HTTP/1.1", delegate2.GetResponseHeaderValue(":version"));
3839   EXPECT_EQ(std::string(), delegate2.TakeReceivedData());
3840 
3841   EXPECT_TRUE(data.at_write_eof());
3842 }
3843 
3844 // Delegate that closes a given stream after sending its body.
3845 class StreamClosingDelegate : public test::StreamDelegateWithBody {
3846  public:
StreamClosingDelegate(const base::WeakPtr<SpdyStream> & stream,base::StringPiece data)3847   StreamClosingDelegate(const base::WeakPtr<SpdyStream>& stream,
3848                         base::StringPiece data)
3849       : StreamDelegateWithBody(stream, data) {}
3850 
~StreamClosingDelegate()3851   virtual ~StreamClosingDelegate() {}
3852 
set_stream_to_close(const base::WeakPtr<SpdyStream> & stream_to_close)3853   void set_stream_to_close(const base::WeakPtr<SpdyStream>& stream_to_close) {
3854     stream_to_close_ = stream_to_close;
3855   }
3856 
OnDataSent()3857   virtual void OnDataSent() OVERRIDE {
3858     test::StreamDelegateWithBody::OnDataSent();
3859     if (stream_to_close_.get()) {
3860       stream_to_close_->Close();
3861       EXPECT_EQ(NULL, stream_to_close_.get());
3862     }
3863   }
3864 
3865  private:
3866   base::WeakPtr<SpdyStream> stream_to_close_;
3867 };
3868 
3869 // Cause a stall by reducing the flow control send window to
3870 // 0. Unstalling the session should properly handle deleted streams.
TEST_P(SpdySessionTest,SendWindowSizeIncreaseWithDeletedStreams)3871 TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedStreams) {
3872   if (GetParam() < kProtoSPDY31)
3873     return;
3874 
3875   const char kStreamUrl[] = "http://www.google.com/";
3876   GURL url(kStreamUrl);
3877 
3878   session_deps_.host_resolver->set_synchronous_mode(true);
3879 
3880   scoped_ptr<SpdyFrame> req1(
3881       spdy_util_.ConstructSpdyPost(
3882           kStreamUrl, 1, kBodyDataSize, LOWEST, NULL, 0));
3883   scoped_ptr<SpdyFrame> req2(
3884       spdy_util_.ConstructSpdyPost(
3885           kStreamUrl, 3, kBodyDataSize, LOWEST, NULL, 0));
3886   scoped_ptr<SpdyFrame> req3(
3887       spdy_util_.ConstructSpdyPost(
3888           kStreamUrl, 5, kBodyDataSize, LOWEST, NULL, 0));
3889   scoped_ptr<SpdyFrame> body2(
3890       spdy_util_.ConstructSpdyBodyFrame(3, kBodyData, kBodyDataSize, true));
3891   MockWrite writes[] = {
3892     CreateMockWrite(*req1, 0),
3893     CreateMockWrite(*req2, 1),
3894     CreateMockWrite(*req3, 2),
3895     CreateMockWrite(*body2, 3),
3896   };
3897 
3898   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3899   MockRead reads[] = {
3900     CreateMockRead(*resp2, 4),
3901     MockRead(ASYNC, 0, 0, 5), // EOF
3902   };
3903 
3904   DeterministicSocketData data(reads, arraysize(reads),
3905                                writes, arraysize(writes));
3906   MockConnect connect_data(SYNCHRONOUS, OK);
3907   data.set_connect_data(connect_data);
3908 
3909   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
3910 
3911   CreateDeterministicNetworkSession();
3912   base::WeakPtr<SpdySession> session =
3913       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
3914   EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
3915             session->flow_control_state());
3916 
3917   base::WeakPtr<SpdyStream> stream1 =
3918       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
3919                                 session, url, LOWEST, BoundNetLog());
3920   ASSERT_TRUE(stream1.get() != NULL);
3921 
3922   test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece);
3923   stream1->SetDelegate(&delegate1);
3924 
3925   EXPECT_FALSE(stream1->HasUrlFromHeaders());
3926 
3927   base::WeakPtr<SpdyStream> stream2 =
3928       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
3929                                 session, url, LOWEST, BoundNetLog());
3930   ASSERT_TRUE(stream2.get() != NULL);
3931 
3932   StreamClosingDelegate delegate2(stream2, kBodyDataStringPiece);
3933   stream2->SetDelegate(&delegate2);
3934 
3935   EXPECT_FALSE(stream2->HasUrlFromHeaders());
3936 
3937   base::WeakPtr<SpdyStream> stream3 =
3938       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
3939                                 session, url, LOWEST, BoundNetLog());
3940   ASSERT_TRUE(stream3.get() != NULL);
3941 
3942   test::StreamDelegateWithBody delegate3(stream3, kBodyDataStringPiece);
3943   stream3->SetDelegate(&delegate3);
3944 
3945   EXPECT_FALSE(stream3->HasUrlFromHeaders());
3946 
3947   EXPECT_FALSE(stream1->send_stalled_by_flow_control());
3948   EXPECT_FALSE(stream2->send_stalled_by_flow_control());
3949   EXPECT_FALSE(stream3->send_stalled_by_flow_control());
3950 
3951   StallSessionSend(session.get());
3952 
3953   scoped_ptr<SpdyHeaderBlock> headers1(
3954       spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
3955   EXPECT_EQ(ERR_IO_PENDING,
3956             stream1->SendRequestHeaders(headers1.Pass(), MORE_DATA_TO_SEND));
3957   EXPECT_TRUE(stream1->HasUrlFromHeaders());
3958   EXPECT_EQ(kStreamUrl, stream1->GetUrlFromHeaders().spec());
3959 
3960   data.RunFor(1);
3961   EXPECT_EQ(1u, stream1->stream_id());
3962   EXPECT_TRUE(stream1->send_stalled_by_flow_control());
3963 
3964   scoped_ptr<SpdyHeaderBlock> headers2(
3965       spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
3966   EXPECT_EQ(ERR_IO_PENDING,
3967             stream2->SendRequestHeaders(headers2.Pass(), MORE_DATA_TO_SEND));
3968   EXPECT_TRUE(stream2->HasUrlFromHeaders());
3969   EXPECT_EQ(kStreamUrl, stream2->GetUrlFromHeaders().spec());
3970 
3971   data.RunFor(1);
3972   EXPECT_EQ(3u, stream2->stream_id());
3973   EXPECT_TRUE(stream2->send_stalled_by_flow_control());
3974 
3975   scoped_ptr<SpdyHeaderBlock> headers3(
3976       spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
3977   EXPECT_EQ(ERR_IO_PENDING,
3978             stream3->SendRequestHeaders(headers3.Pass(), MORE_DATA_TO_SEND));
3979   EXPECT_TRUE(stream3->HasUrlFromHeaders());
3980   EXPECT_EQ(kStreamUrl, stream3->GetUrlFromHeaders().spec());
3981 
3982   data.RunFor(1);
3983   EXPECT_EQ(5u, stream3->stream_id());
3984   EXPECT_TRUE(stream3->send_stalled_by_flow_control());
3985 
3986   SpdyStreamId stream_id1 = stream1->stream_id();
3987   SpdyStreamId stream_id2 = stream2->stream_id();
3988   SpdyStreamId stream_id3 = stream3->stream_id();
3989 
3990   // Close stream1 preemptively.
3991   session->CloseActiveStream(stream_id1, ERR_CONNECTION_CLOSED);
3992   EXPECT_EQ(NULL, stream1.get());
3993 
3994   EXPECT_FALSE(session->IsStreamActive(stream_id1));
3995   EXPECT_TRUE(session->IsStreamActive(stream_id2));
3996   EXPECT_TRUE(session->IsStreamActive(stream_id3));
3997 
3998   // Unstall stream2, which should then close stream3.
3999   delegate2.set_stream_to_close(stream3);
4000   UnstallSessionSend(session.get(), kBodyDataSize);
4001 
4002   data.RunFor(1);
4003   EXPECT_EQ(NULL, stream3.get());
4004 
4005   EXPECT_FALSE(stream2->send_stalled_by_flow_control());
4006   EXPECT_FALSE(session->IsStreamActive(stream_id1));
4007   EXPECT_TRUE(session->IsStreamActive(stream_id2));
4008   EXPECT_FALSE(session->IsStreamActive(stream_id3));
4009 
4010   data.RunFor(2);
4011   EXPECT_EQ(NULL, stream2.get());
4012 
4013   EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose());
4014   EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose());
4015   EXPECT_EQ(OK, delegate3.WaitForClose());
4016 
4017   EXPECT_TRUE(delegate1.send_headers_completed());
4018   EXPECT_EQ(std::string(), delegate1.TakeReceivedData());
4019 
4020   EXPECT_TRUE(delegate2.send_headers_completed());
4021   EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status"));
4022   EXPECT_EQ("HTTP/1.1", delegate2.GetResponseHeaderValue(":version"));
4023   EXPECT_EQ(std::string(), delegate2.TakeReceivedData());
4024 
4025   EXPECT_TRUE(delegate3.send_headers_completed());
4026   EXPECT_EQ(std::string(), delegate3.TakeReceivedData());
4027 
4028   EXPECT_TRUE(data.at_write_eof());
4029 }
4030 
4031 // Cause a stall by reducing the flow control send window to
4032 // 0. Unstalling the session should properly handle the session itself
4033 // being closed.
TEST_P(SpdySessionTest,SendWindowSizeIncreaseWithDeletedSession)4034 TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedSession) {
4035   if (GetParam() < kProtoSPDY31)
4036     return;
4037 
4038   const char kStreamUrl[] = "http://www.google.com/";
4039   GURL url(kStreamUrl);
4040 
4041   session_deps_.host_resolver->set_synchronous_mode(true);
4042 
4043   scoped_ptr<SpdyFrame> req1(
4044       spdy_util_.ConstructSpdyPost(
4045           kStreamUrl, 1, kBodyDataSize, LOWEST, NULL, 0));
4046   scoped_ptr<SpdyFrame> req2(
4047       spdy_util_.ConstructSpdyPost(
4048           kStreamUrl, 3, kBodyDataSize, LOWEST, NULL, 0));
4049   scoped_ptr<SpdyFrame> body1(
4050       spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, false));
4051   MockWrite writes[] = {
4052     CreateMockWrite(*req1, 0),
4053     CreateMockWrite(*req2, 1),
4054   };
4055 
4056   MockRead reads[] = {
4057     MockRead(ASYNC, 0, 0, 2), // EOF
4058   };
4059 
4060   DeterministicSocketData data(reads, arraysize(reads),
4061                                writes, arraysize(writes));
4062   MockConnect connect_data(SYNCHRONOUS, OK);
4063   data.set_connect_data(connect_data);
4064 
4065   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
4066 
4067   CreateDeterministicNetworkSession();
4068   base::WeakPtr<SpdySession> session =
4069       CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
4070   EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
4071             session->flow_control_state());
4072 
4073   base::WeakPtr<SpdyStream> stream1 =
4074       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
4075                                 session, url, LOWEST, BoundNetLog());
4076   ASSERT_TRUE(stream1.get() != NULL);
4077 
4078   test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece);
4079   stream1->SetDelegate(&delegate1);
4080 
4081   EXPECT_FALSE(stream1->HasUrlFromHeaders());
4082 
4083   base::WeakPtr<SpdyStream> stream2 =
4084       CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
4085                                 session, url, LOWEST, BoundNetLog());
4086   ASSERT_TRUE(stream2.get() != NULL);
4087 
4088   test::StreamDelegateWithBody delegate2(stream2, kBodyDataStringPiece);
4089   stream2->SetDelegate(&delegate2);
4090 
4091   EXPECT_FALSE(stream2->HasUrlFromHeaders());
4092 
4093   EXPECT_FALSE(stream1->send_stalled_by_flow_control());
4094   EXPECT_FALSE(stream2->send_stalled_by_flow_control());
4095 
4096   StallSessionSend(session.get());
4097 
4098   scoped_ptr<SpdyHeaderBlock> headers1(
4099       spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
4100   EXPECT_EQ(ERR_IO_PENDING,
4101             stream1->SendRequestHeaders(headers1.Pass(), MORE_DATA_TO_SEND));
4102   EXPECT_TRUE(stream1->HasUrlFromHeaders());
4103   EXPECT_EQ(kStreamUrl, stream1->GetUrlFromHeaders().spec());
4104 
4105   data.RunFor(1);
4106   EXPECT_EQ(1u, stream1->stream_id());
4107   EXPECT_TRUE(stream1->send_stalled_by_flow_control());
4108 
4109   scoped_ptr<SpdyHeaderBlock> headers2(
4110       spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
4111   EXPECT_EQ(ERR_IO_PENDING,
4112             stream2->SendRequestHeaders(headers2.Pass(), MORE_DATA_TO_SEND));
4113   EXPECT_TRUE(stream2->HasUrlFromHeaders());
4114   EXPECT_EQ(kStreamUrl, stream2->GetUrlFromHeaders().spec());
4115 
4116   data.RunFor(1);
4117   EXPECT_EQ(3u, stream2->stream_id());
4118   EXPECT_TRUE(stream2->send_stalled_by_flow_control());
4119 
4120   EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
4121 
4122   // Unstall stream1.
4123   UnstallSessionSend(session.get(), kBodyDataSize);
4124 
4125   // Close the session (since we can't do it from within the delegate
4126   // method, since it's in the stream's loop).
4127   session->CloseSessionOnError(ERR_CONNECTION_CLOSED, "Closing session");
4128   EXPECT_TRUE(session == NULL);
4129 
4130   EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
4131 
4132   EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose());
4133   EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose());
4134 
4135   EXPECT_TRUE(delegate1.send_headers_completed());
4136   EXPECT_EQ(std::string(), delegate1.TakeReceivedData());
4137 
4138   EXPECT_TRUE(delegate2.send_headers_completed());
4139   EXPECT_EQ(std::string(), delegate2.TakeReceivedData());
4140 
4141   EXPECT_TRUE(data.at_write_eof());
4142 }
4143 
4144 }  // namespace net
4145