1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/spdy/spdy_session.h"
7 #include "net/base/host_cache.h"
8 #include "net/base/ip_endpoint.h"
9 #include "net/base/net_log_unittest.h"
10 #include "net/spdy/spdy_io_buffer.h"
11 #include "net/spdy/spdy_session_pool.h"
12 #include "net/spdy/spdy_stream.h"
13 #include "net/spdy/spdy_test_util_spdy3.h"
14 #include "testing/platform_test.h"
16 using namespace net::test_spdy3
;
20 // TODO(cbentzel): Expose compression setter/getter in public SpdySession
21 // interface rather than going through all these contortions.
22 class SpdySessionSpdy3Test
: public PlatformTest
{
24 virtual void SetUp() {
25 SpdySession::set_default_protocol(kProtoSPDY3
);
29 SpdyTestStateHelper spdy_state_
;
32 class TestSpdyStreamDelegate
: public net::SpdyStream::Delegate
{
34 explicit TestSpdyStreamDelegate(const CompletionCallback
& callback
)
35 : callback_(callback
) {}
36 virtual ~TestSpdyStreamDelegate() {}
38 virtual bool OnSendHeadersComplete(int status
) { return true; }
40 virtual int OnSendBody() {
41 return ERR_UNEXPECTED
;
44 virtual int OnSendBodyComplete(int /*status*/, bool* /*eof*/) {
45 return ERR_UNEXPECTED
;
48 virtual int OnResponseReceived(const SpdyHeaderBlock
& response
,
49 base::Time response_time
,
54 virtual void OnDataReceived(const char* buffer
, int bytes
) {
57 virtual void OnDataSent(int length
) {
60 virtual void OnClose(int status
) {
61 CompletionCallback callback
= callback_
;
66 virtual void set_chunk_callback(net::ChunkCallback
*) {}
69 CompletionCallback callback_
;
72 // Test the SpdyIOBuffer class.
73 TEST_F(SpdySessionSpdy3Test
, SpdyIOBuffer
) {
74 std::priority_queue
<SpdyIOBuffer
> queue_
;
75 const size_t kQueueSize
= 100;
77 // Insert items with random priority and increasing buffer size
78 for (size_t index
= 0; index
< kQueueSize
; ++index
) {
79 queue_
.push(SpdyIOBuffer(
80 new IOBufferWithSize(index
+ 1),
82 static_cast<RequestPriority
>(rand() % NUM_PRIORITIES
),
86 EXPECT_EQ(kQueueSize
, queue_
.size());
88 // Verify items come out with decreasing priority or FIFO order.
89 RequestPriority last_priority
= NUM_PRIORITIES
;
91 for (size_t index
= 0; index
< kQueueSize
; ++index
) {
92 SpdyIOBuffer buffer
= queue_
.top();
93 EXPECT_LE(buffer
.priority(), last_priority
);
94 if (buffer
.priority() < last_priority
)
96 EXPECT_LT(last_size
, buffer
.size());
97 last_priority
= buffer
.priority();
98 last_size
= buffer
.size();
102 EXPECT_EQ(0u, queue_
.size());
105 TEST_F(SpdySessionSpdy3Test
, GoAway
) {
106 SpdySessionDependencies session_deps
;
107 session_deps
.host_resolver
->set_synchronous_mode(true);
109 MockConnect
connect_data(SYNCHRONOUS
, OK
);
110 scoped_ptr
<SpdyFrame
> goaway(ConstructSpdyGoAway());
112 CreateMockRead(*goaway
),
113 MockRead(SYNCHRONOUS
, 0, 0) // EOF
115 StaticSocketDataProvider
data(reads
, arraysize(reads
), NULL
, 0);
116 data
.set_connect_data(connect_data
);
117 session_deps
.socket_factory
->AddSocketDataProvider(&data
);
119 SSLSocketDataProvider
ssl(SYNCHRONOUS
, OK
);
120 ssl
.SetNextProto(kProtoSPDY3
);
121 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl
);
123 scoped_refptr
<HttpNetworkSession
> http_session(
124 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
126 const std::string
kTestHost("www.foo.com");
127 const int kTestPort
= 80;
128 HostPortPair
test_host_port_pair(kTestHost
, kTestPort
);
129 HostPortProxyPair
pair(test_host_port_pair
, ProxyServer::Direct());
131 SpdySessionPool
* spdy_session_pool(http_session
->spdy_session_pool());
132 EXPECT_FALSE(spdy_session_pool
->HasSession(pair
));
133 scoped_refptr
<SpdySession
> session
=
134 spdy_session_pool
->Get(pair
, BoundNetLog());
135 EXPECT_TRUE(spdy_session_pool
->HasSession(pair
));
137 scoped_refptr
<TransportSocketParams
> transport_params(
138 new TransportSocketParams(test_host_port_pair
,
142 scoped_ptr
<ClientSocketHandle
> connection(new ClientSocketHandle
);
143 EXPECT_EQ(OK
, connection
->Init(test_host_port_pair
.ToString(),
144 transport_params
, MEDIUM
, CompletionCallback(),
145 http_session
->GetTransportSocketPool(
146 HttpNetworkSession::NORMAL_SOCKET_POOL
),
148 EXPECT_EQ(OK
, session
->InitializeWithSocket(connection
.release(), false, OK
));
149 EXPECT_EQ(3, session
->GetProtocolVersion());
151 // Flush the SpdySession::OnReadComplete() task.
152 MessageLoop::current()->RunAllPending();
154 EXPECT_FALSE(spdy_session_pool
->HasSession(pair
));
156 scoped_refptr
<SpdySession
> session2
=
157 spdy_session_pool
->Get(pair
, BoundNetLog());
159 // Delete the first session.
162 // Delete the second session.
163 spdy_session_pool
->Remove(session2
);
167 TEST_F(SpdySessionSpdy3Test
, Ping
) {
168 SpdySessionDependencies session_deps
;
169 session_deps
.host_resolver
->set_synchronous_mode(true);
171 MockConnect
connect_data(SYNCHRONOUS
, OK
);
172 scoped_ptr
<SpdyFrame
> read_ping(ConstructSpdyPing());
174 CreateMockRead(*read_ping
),
175 CreateMockRead(*read_ping
),
176 MockRead(SYNCHRONOUS
, 0, 0) // EOF
178 scoped_ptr
<SpdyFrame
> write_ping(ConstructSpdyPing());
179 MockRead writes
[] = {
180 CreateMockRead(*write_ping
),
181 CreateMockRead(*write_ping
),
183 StaticSocketDataProvider
data(
184 reads
, arraysize(reads
), writes
, arraysize(writes
));
185 data
.set_connect_data(connect_data
);
186 session_deps
.socket_factory
->AddSocketDataProvider(&data
);
188 SSLSocketDataProvider
ssl(SYNCHRONOUS
, OK
);
189 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl
);
191 scoped_refptr
<HttpNetworkSession
> http_session(
192 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
194 static const char kStreamUrl
[] = "http://www.google.com/";
195 GURL
url(kStreamUrl
);
197 const std::string
kTestHost("www.google.com");
198 const int kTestPort
= 80;
199 HostPortPair
test_host_port_pair(kTestHost
, kTestPort
);
200 HostPortProxyPair
pair(test_host_port_pair
, ProxyServer::Direct());
202 SpdySessionPool
* spdy_session_pool(http_session
->spdy_session_pool());
203 EXPECT_FALSE(spdy_session_pool
->HasSession(pair
));
204 scoped_refptr
<SpdySession
> session
=
205 spdy_session_pool
->Get(pair
, BoundNetLog());
206 EXPECT_TRUE(spdy_session_pool
->HasSession(pair
));
209 scoped_refptr
<TransportSocketParams
> transport_params(
210 new TransportSocketParams(test_host_port_pair
,
214 scoped_ptr
<ClientSocketHandle
> connection(new ClientSocketHandle
);
215 EXPECT_EQ(OK
, connection
->Init(test_host_port_pair
.ToString(),
216 transport_params
, MEDIUM
, CompletionCallback(),
217 http_session
->GetTransportSocketPool(
218 HttpNetworkSession::NORMAL_SOCKET_POOL
),
220 EXPECT_EQ(OK
, session
->InitializeWithSocket(connection
.release(), false, OK
));
222 scoped_refptr
<SpdyStream
> spdy_stream1
;
223 TestCompletionCallback callback1
;
224 EXPECT_EQ(OK
, session
->CreateStream(url
,
228 callback1
.callback()));
229 scoped_ptr
<TestSpdyStreamDelegate
> delegate(
230 new TestSpdyStreamDelegate(callback1
.callback()));
231 spdy_stream1
->SetDelegate(delegate
.get());
233 base::TimeTicks before_ping_time
= base::TimeTicks::Now();
235 // Enable sending of PING.
236 SpdySession::set_enable_ping_based_connection_checking(true);
237 session
->set_connection_at_risk_of_loss_time(base::TimeDelta::FromSeconds(0));
238 session
->set_trailing_ping_delay_time(base::TimeDelta::FromSeconds(0));
239 session
->set_hung_interval(base::TimeDelta::FromMilliseconds(50));
241 session
->SendPrefacePingIfNoneInFlight();
243 EXPECT_EQ(OK
, callback1
.WaitForResult());
245 session
->CheckPingStatus(before_ping_time
);
247 EXPECT_EQ(0, session
->pings_in_flight());
248 EXPECT_GT(session
->next_ping_id(), static_cast<uint32
>(1));
249 EXPECT_FALSE(session
->trailing_ping_pending());
250 EXPECT_FALSE(session
->check_ping_status_pending());
251 EXPECT_GE(session
->received_data_time(), before_ping_time
);
253 EXPECT_FALSE(spdy_session_pool
->HasSession(pair
));
255 // Delete the first session.
259 TEST_F(SpdySessionSpdy3Test
, FailedPing
) {
260 SpdySessionDependencies session_deps
;
261 session_deps
.host_resolver
->set_synchronous_mode(true);
263 MockConnect
connect_data(SYNCHRONOUS
, OK
);
264 scoped_ptr
<SpdyFrame
> read_ping(ConstructSpdyPing());
266 CreateMockRead(*read_ping
),
267 MockRead(SYNCHRONOUS
, 0, 0) // EOF
269 scoped_ptr
<SpdyFrame
> write_ping(ConstructSpdyPing());
270 MockRead writes
[] = {
271 CreateMockRead(*write_ping
),
273 StaticSocketDataProvider
data(
274 reads
, arraysize(reads
), writes
, arraysize(writes
));
275 data
.set_connect_data(connect_data
);
276 session_deps
.socket_factory
->AddSocketDataProvider(&data
);
278 SSLSocketDataProvider
ssl(SYNCHRONOUS
, OK
);
279 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl
);
281 scoped_refptr
<HttpNetworkSession
> http_session(
282 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
284 static const char kStreamUrl
[] = "http://www.gmail.com/";
285 GURL
url(kStreamUrl
);
287 const std::string
kTestHost("www.gmail.com");
288 const int kTestPort
= 80;
289 HostPortPair
test_host_port_pair(kTestHost
, kTestPort
);
290 HostPortProxyPair
pair(test_host_port_pair
, ProxyServer::Direct());
292 SpdySessionPool
* spdy_session_pool(http_session
->spdy_session_pool());
293 EXPECT_FALSE(spdy_session_pool
->HasSession(pair
));
294 scoped_refptr
<SpdySession
> session
=
295 spdy_session_pool
->Get(pair
, BoundNetLog());
296 EXPECT_TRUE(spdy_session_pool
->HasSession(pair
));
298 scoped_refptr
<TransportSocketParams
> transport_params(
299 new TransportSocketParams(test_host_port_pair
,
303 scoped_ptr
<ClientSocketHandle
> connection(new ClientSocketHandle
);
304 EXPECT_EQ(OK
, connection
->Init(test_host_port_pair
.ToString(),
305 transport_params
, MEDIUM
, CompletionCallback(),
306 http_session
->GetTransportSocketPool(
307 HttpNetworkSession::NORMAL_SOCKET_POOL
),
309 EXPECT_EQ(OK
, session
->InitializeWithSocket(connection
.release(), false, OK
));
311 scoped_refptr
<SpdyStream
> spdy_stream1
;
312 TestCompletionCallback callback1
;
313 EXPECT_EQ(OK
, session
->CreateStream(url
,
317 callback1
.callback()));
318 scoped_ptr
<TestSpdyStreamDelegate
> delegate(
319 new TestSpdyStreamDelegate(callback1
.callback()));
320 spdy_stream1
->SetDelegate(delegate
.get());
322 // Enable sending of PING.
323 SpdySession::set_enable_ping_based_connection_checking(true);
324 session
->set_connection_at_risk_of_loss_time(base::TimeDelta::FromSeconds(0));
325 session
->set_trailing_ping_delay_time(base::TimeDelta::FromSeconds(0));
326 session
->set_hung_interval(base::TimeDelta::FromSeconds(0));
328 // Send a PING frame.
329 session
->WritePingFrame(1);
330 EXPECT_LT(0, session
->pings_in_flight());
331 EXPECT_GT(session
->next_ping_id(), static_cast<uint32
>(1));
332 EXPECT_TRUE(session
->check_ping_status_pending());
334 // Assert session is not closed.
335 EXPECT_FALSE(session
->IsClosed());
336 EXPECT_LT(0u, session
->num_active_streams());
337 EXPECT_TRUE(spdy_session_pool
->HasSession(pair
));
339 // We set last time we have received any data in 1 sec less than now.
340 // CheckPingStatus will trigger timeout because hung interval is zero.
341 base::TimeTicks now
= base::TimeTicks::Now();
342 session
->received_data_time_
= now
- base::TimeDelta::FromSeconds(1);
343 session
->CheckPingStatus(now
);
345 EXPECT_TRUE(session
->IsClosed());
346 EXPECT_EQ(0u, session
->num_active_streams());
347 EXPECT_EQ(0u, session
->num_unclaimed_pushed_streams());
348 EXPECT_FALSE(spdy_session_pool
->HasSession(pair
));
350 // Delete the first session.
354 class StreamReleaserCallback
: public TestCompletionCallbackBase
{
356 StreamReleaserCallback(SpdySession
* session
,
357 SpdyStream
* first_stream
)
359 first_stream_(first_stream
),
360 ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
361 base::Bind(&StreamReleaserCallback::OnComplete
,
362 base::Unretained(this)))) {
365 virtual ~StreamReleaserCallback() {}
367 scoped_refptr
<SpdyStream
>* stream() { return &stream_
; }
369 const CompletionCallback
& callback() const { return callback_
; }
372 void OnComplete(int result
) {
373 session_
->CloseSessionOnError(ERR_FAILED
, false, "On complete.");
375 first_stream_
->Cancel();
376 first_stream_
= NULL
;
382 scoped_refptr
<SpdySession
> session_
;
383 scoped_refptr
<SpdyStream
> first_stream_
;
384 scoped_refptr
<SpdyStream
> stream_
;
385 CompletionCallback callback_
;
388 // TODO(kristianm): Could also test with more sessions where some are idle,
389 // and more than one session to a HostPortPair.
390 TEST_F(SpdySessionSpdy3Test
, CloseIdleSessions
) {
391 SpdySessionDependencies session_deps
;
392 scoped_refptr
<HttpNetworkSession
> http_session(
393 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
394 SpdySessionPool
* spdy_session_pool(http_session
->spdy_session_pool());
397 const std::string
kTestHost1("http://www.a.com");
398 HostPortPair
test_host_port_pair1(kTestHost1
, 80);
399 HostPortProxyPair
pair1(test_host_port_pair1
, ProxyServer::Direct());
400 scoped_refptr
<SpdySession
> session1
=
401 spdy_session_pool
->Get(pair1
, BoundNetLog());
402 scoped_refptr
<SpdyStream
> spdy_stream1
;
403 TestCompletionCallback callback1
;
404 GURL
url1(kTestHost1
);
405 EXPECT_EQ(OK
, session1
->CreateStream(url1
,
406 MEDIUM
, /* priority, not important */
409 callback1
.callback()));
412 const std::string
kTestHost2("http://www.b.com");
413 HostPortPair
test_host_port_pair2(kTestHost2
, 80);
414 HostPortProxyPair
pair2(test_host_port_pair2
, ProxyServer::Direct());
415 scoped_refptr
<SpdySession
> session2
=
416 spdy_session_pool
->Get(pair2
, BoundNetLog());
417 scoped_refptr
<SpdyStream
> spdy_stream2
;
418 TestCompletionCallback callback2
;
419 GURL
url2(kTestHost2
);
420 EXPECT_EQ(OK
, session2
->CreateStream(
421 url2
, MEDIUM
, /* priority, not important */
422 &spdy_stream2
, BoundNetLog(), callback2
.callback()));
425 const std::string
kTestHost3("http://www.c.com");
426 HostPortPair
test_host_port_pair3(kTestHost3
, 80);
427 HostPortProxyPair
pair3(test_host_port_pair3
, ProxyServer::Direct());
428 scoped_refptr
<SpdySession
> session3
=
429 spdy_session_pool
->Get(pair3
, BoundNetLog());
430 scoped_refptr
<SpdyStream
> spdy_stream3
;
431 TestCompletionCallback callback3
;
432 GURL
url3(kTestHost3
);
433 EXPECT_EQ(OK
, session3
->CreateStream(
434 url3
, MEDIUM
, /* priority, not important */
435 &spdy_stream3
, BoundNetLog(), callback3
.callback()));
437 // All sessions are active and not closed
438 EXPECT_TRUE(session1
->is_active());
439 EXPECT_FALSE(session1
->IsClosed());
440 EXPECT_TRUE(session2
->is_active());
441 EXPECT_FALSE(session2
->IsClosed());
442 EXPECT_TRUE(session3
->is_active());
443 EXPECT_FALSE(session3
->IsClosed());
445 // Should not do anything, all are active
446 spdy_session_pool
->CloseIdleSessions();
447 EXPECT_TRUE(session1
->is_active());
448 EXPECT_FALSE(session1
->IsClosed());
449 EXPECT_TRUE(session2
->is_active());
450 EXPECT_FALSE(session2
->IsClosed());
451 EXPECT_TRUE(session3
->is_active());
452 EXPECT_FALSE(session3
->IsClosed());
454 // Make sessions 1 and 3 inactive, but keep them open.
455 // Session 2 still open and active
456 session1
->CloseStream(spdy_stream1
->stream_id(), OK
);
457 session3
->CloseStream(spdy_stream3
->stream_id(), OK
);
458 EXPECT_FALSE(session1
->is_active());
459 EXPECT_FALSE(session1
->IsClosed());
460 EXPECT_TRUE(session2
->is_active());
461 EXPECT_FALSE(session2
->IsClosed());
462 EXPECT_FALSE(session3
->is_active());
463 EXPECT_FALSE(session3
->IsClosed());
465 // Should close session 1 and 3, 2 should be left open
466 spdy_session_pool
->CloseIdleSessions();
467 EXPECT_FALSE(session1
->is_active());
468 EXPECT_TRUE(session1
->IsClosed());
469 EXPECT_TRUE(session2
->is_active());
470 EXPECT_FALSE(session2
->IsClosed());
471 EXPECT_FALSE(session3
->is_active());
472 EXPECT_TRUE(session3
->IsClosed());
474 // Should not do anything
475 spdy_session_pool
->CloseIdleSessions();
476 EXPECT_TRUE(session2
->is_active());
477 EXPECT_FALSE(session2
->IsClosed());
480 session2
->CloseStream(spdy_stream2
->stream_id(), OK
);
481 EXPECT_FALSE(session2
->is_active());
482 EXPECT_FALSE(session2
->IsClosed());
484 // This should close session 2
485 spdy_session_pool
->CloseIdleSessions();
486 EXPECT_FALSE(session2
->is_active());
487 EXPECT_TRUE(session2
->IsClosed());
490 // Start with max concurrent streams set to 1. Request two streams. Receive a
491 // settings frame setting max concurrent streams to 2. Have the callback
492 // release the stream, which releases its reference (the last) to the session.
493 // Make sure nothing blows up.
494 // http://crbug.com/57331
495 TEST_F(SpdySessionSpdy3Test
, OnSettings
) {
496 SpdySessionDependencies session_deps
;
497 session_deps
.host_resolver
->set_synchronous_mode(true);
499 SettingsMap new_settings
;
500 const SpdySettingsIds kSpdySettingsIds1
= SETTINGS_MAX_CONCURRENT_STREAMS
;
501 const size_t max_concurrent_streams
= 2;
502 new_settings
[kSpdySettingsIds1
] =
503 SettingsFlagsAndValue(SETTINGS_FLAG_NONE
, max_concurrent_streams
);
505 // Set up the socket so we read a SETTINGS frame that raises max concurrent
507 MockConnect
connect_data(SYNCHRONOUS
, OK
);
508 scoped_ptr
<SpdyFrame
> settings_frame(ConstructSpdySettings(new_settings
));
510 CreateMockRead(*settings_frame
),
511 MockRead(SYNCHRONOUS
, 0, 0) // EOF
514 StaticSocketDataProvider
data(reads
, arraysize(reads
), NULL
, 0);
515 data
.set_connect_data(connect_data
);
516 session_deps
.socket_factory
->AddSocketDataProvider(&data
);
518 SSLSocketDataProvider
ssl(SYNCHRONOUS
, OK
);
519 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl
);
521 scoped_refptr
<HttpNetworkSession
> http_session(
522 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
524 const std::string
kTestHost("www.foo.com");
525 const int kTestPort
= 80;
526 HostPortPair
test_host_port_pair(kTestHost
, kTestPort
);
527 HostPortProxyPair
pair(test_host_port_pair
, ProxyServer::Direct());
529 // Initialize the SpdySetting with 1 max concurrent streams.
530 SpdySessionPool
* spdy_session_pool(http_session
->spdy_session_pool());
531 spdy_session_pool
->http_server_properties()->SetSpdySetting(
534 SETTINGS_FLAG_PLEASE_PERSIST
,
538 EXPECT_FALSE(spdy_session_pool
->HasSession(pair
));
539 scoped_refptr
<SpdySession
> session
=
540 spdy_session_pool
->Get(pair
, BoundNetLog());
541 ASSERT_TRUE(spdy_session_pool
->HasSession(pair
));
543 scoped_refptr
<TransportSocketParams
> transport_params(
544 new TransportSocketParams(test_host_port_pair
,
548 scoped_ptr
<ClientSocketHandle
> connection(new ClientSocketHandle
);
549 EXPECT_EQ(OK
, connection
->Init(test_host_port_pair
.ToString(),
550 transport_params
, MEDIUM
, CompletionCallback(),
551 http_session
->GetTransportSocketPool(
552 HttpNetworkSession::NORMAL_SOCKET_POOL
),
554 EXPECT_EQ(OK
, session
->InitializeWithSocket(connection
.release(), false, OK
));
556 // Create 2 streams. First will succeed. Second will be pending.
557 scoped_refptr
<SpdyStream
> spdy_stream1
;
558 TestCompletionCallback callback1
;
559 GURL
url("http://www.google.com");
561 session
->CreateStream(url
,
562 MEDIUM
, /* priority, not important */
565 callback1
.callback()));
567 StreamReleaserCallback
stream_releaser(session
, spdy_stream1
);
569 ASSERT_EQ(ERR_IO_PENDING
,
570 session
->CreateStream(url
,
571 MEDIUM
, /* priority, not important */
572 stream_releaser
.stream(),
574 stream_releaser
.callback()));
576 // Make sure |stream_releaser| holds the last refs.
580 EXPECT_EQ(OK
, stream_releaser
.WaitForResult());
583 // Start with max concurrent streams set to 1. Request two streams. When the
584 // first completes, have the callback close itself, which should trigger the
585 // second stream creation. Then cancel that one immediately. Don't crash.
586 // http://crbug.com/63532
587 TEST_F(SpdySessionSpdy3Test
, CancelPendingCreateStream
) {
588 SpdySessionDependencies session_deps
;
589 session_deps
.host_resolver
->set_synchronous_mode(true);
592 MockRead(SYNCHRONOUS
, ERR_IO_PENDING
) // Stall forever.
595 StaticSocketDataProvider
data(reads
, arraysize(reads
), NULL
, 0);
596 MockConnect
connect_data(SYNCHRONOUS
, OK
);
598 data
.set_connect_data(connect_data
);
599 session_deps
.socket_factory
->AddSocketDataProvider(&data
);
601 SSLSocketDataProvider
ssl(SYNCHRONOUS
, OK
);
602 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl
);
604 scoped_refptr
<HttpNetworkSession
> http_session(
605 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
607 const std::string
kTestHost("www.foo.com");
608 const int kTestPort
= 80;
609 HostPortPair
test_host_port_pair(kTestHost
, kTestPort
);
610 HostPortProxyPair
pair(test_host_port_pair
, ProxyServer::Direct());
612 // Initialize the SpdySetting with 1 max concurrent streams.
613 SpdySessionPool
* spdy_session_pool(http_session
->spdy_session_pool());
614 spdy_session_pool
->http_server_properties()->SetSpdySetting(
616 SETTINGS_MAX_CONCURRENT_STREAMS
,
617 SETTINGS_FLAG_PLEASE_PERSIST
,
621 EXPECT_FALSE(spdy_session_pool
->HasSession(pair
));
622 scoped_refptr
<SpdySession
> session
=
623 spdy_session_pool
->Get(pair
, BoundNetLog());
624 ASSERT_TRUE(spdy_session_pool
->HasSession(pair
));
626 scoped_refptr
<TransportSocketParams
> transport_params(
627 new TransportSocketParams(test_host_port_pair
,
631 scoped_ptr
<ClientSocketHandle
> connection(new ClientSocketHandle
);
632 EXPECT_EQ(OK
, connection
->Init(test_host_port_pair
.ToString(),
633 transport_params
, MEDIUM
, CompletionCallback(),
634 http_session
->GetTransportSocketPool(
635 HttpNetworkSession::NORMAL_SOCKET_POOL
),
637 EXPECT_EQ(OK
, session
->InitializeWithSocket(connection
.release(), false, OK
));
639 // Use scoped_ptr to let us invalidate the memory when we want to, to trigger
640 // a valgrind error if the callback is invoked when it's not supposed to be.
641 scoped_ptr
<TestCompletionCallback
> callback(new TestCompletionCallback
);
643 // Create 2 streams. First will succeed. Second will be pending.
644 scoped_refptr
<SpdyStream
> spdy_stream1
;
645 GURL
url("http://www.google.com");
647 session
->CreateStream(url
,
648 MEDIUM
, /* priority, not important */
651 callback
->callback()));
653 scoped_refptr
<SpdyStream
> spdy_stream2
;
654 ASSERT_EQ(ERR_IO_PENDING
,
655 session
->CreateStream(url
,
656 MEDIUM
, /* priority, not important */
659 callback
->callback()));
661 // Release the first one, this will allow the second to be created.
662 spdy_stream1
->Cancel();
665 session
->CancelPendingCreateStreams(&spdy_stream2
);
668 // Should not crash when running the pending callback.
669 MessageLoop::current()->RunAllPending();
672 TEST_F(SpdySessionSpdy3Test
, SendSettingsOnNewSession
) {
673 SpdySessionDependencies session_deps
;
674 session_deps
.host_resolver
->set_synchronous_mode(true);
677 MockRead(SYNCHRONOUS
, ERR_IO_PENDING
) // Stall forever.
680 // Create the bogus setting that we want to verify is sent out.
681 // Note that it will be marked as SETTINGS_FLAG_PERSISTED when sent out. But
682 // to persist it into the HttpServerProperties, we need to mark as
683 // SETTINGS_FLAG_PLEASE_PERSIST.
684 SettingsMap settings
;
685 const SpdySettingsIds kSpdySettingsIds1
= SETTINGS_UPLOAD_BANDWIDTH
;
686 const uint32 kBogusSettingValue
= 0xCDCD;
687 settings
[kSpdySettingsIds1
] =
688 SettingsFlagsAndValue(SETTINGS_FLAG_PERSISTED
, kBogusSettingValue
);
689 MockConnect
connect_data(SYNCHRONOUS
, OK
);
690 scoped_ptr
<SpdyFrame
> settings_frame(ConstructSpdySettings(settings
));
691 MockWrite writes
[] = {
692 CreateMockWrite(*settings_frame
),
695 StaticSocketDataProvider
data(
696 reads
, arraysize(reads
), writes
, arraysize(writes
));
697 data
.set_connect_data(connect_data
);
698 session_deps
.socket_factory
->AddSocketDataProvider(&data
);
700 SSLSocketDataProvider
ssl(SYNCHRONOUS
, OK
);
701 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl
);
703 scoped_refptr
<HttpNetworkSession
> http_session(
704 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
706 const std::string
kTestHost("www.foo.com");
707 const int kTestPort
= 80;
708 HostPortPair
test_host_port_pair(kTestHost
, kTestPort
);
709 HostPortProxyPair
pair(test_host_port_pair
, ProxyServer::Direct());
711 SpdySessionPool
* spdy_session_pool(http_session
->spdy_session_pool());
712 spdy_session_pool
->http_server_properties()->SetSpdySetting(
715 SETTINGS_FLAG_PLEASE_PERSIST
,
718 EXPECT_FALSE(spdy_session_pool
->HasSession(pair
));
719 scoped_refptr
<SpdySession
> session
=
720 spdy_session_pool
->Get(pair
, BoundNetLog());
721 EXPECT_TRUE(spdy_session_pool
->HasSession(pair
));
723 scoped_refptr
<TransportSocketParams
> transport_params(
724 new TransportSocketParams(test_host_port_pair
,
728 scoped_ptr
<ClientSocketHandle
> connection(new ClientSocketHandle
);
729 EXPECT_EQ(OK
, connection
->Init(test_host_port_pair
.ToString(),
730 transport_params
, MEDIUM
, CompletionCallback(),
731 http_session
->GetTransportSocketPool(
732 HttpNetworkSession::NORMAL_SOCKET_POOL
),
734 EXPECT_EQ(OK
, session
->InitializeWithSocket(connection
.release(), false, OK
));
735 MessageLoop::current()->RunAllPending();
736 EXPECT_TRUE(data
.at_write_eof());
740 // This test has two variants, one for each style of closing the connection.
741 // If |clean_via_close_current_sessions| is false, the sessions are closed
742 // manually, calling SpdySessionPool::Remove() directly. If it is true,
743 // sessions are closed with SpdySessionPool::CloseCurrentSessions().
744 void IPPoolingTest(bool clean_via_close_current_sessions
) {
745 const int kTestPort
= 80;
749 HostPortProxyPair pair
;
750 AddressList addresses
;
752 { "www.foo.com", "192.0.2.33,192.168.0.1,192.168.0.5" },
753 { "images.foo.com", "192.168.0.2,192.168.0.3,192.168.0.5,192.0.2.33" },
754 { "js.foo.com", "192.168.0.4,192.168.0.3" },
757 SpdySessionDependencies session_deps
;
758 session_deps
.host_resolver
->set_synchronous_mode(true);
759 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(test_hosts
); i
++) {
760 session_deps
.host_resolver
->rules()->AddIPLiteralRule(test_hosts
[i
].name
,
761 test_hosts
[i
].iplist
, "");
763 // This test requires that the HostResolver cache be populated. Normal
764 // code would have done this already, but we do it manually.
765 HostResolver::RequestInfo
info(HostPortPair(test_hosts
[i
].name
, kTestPort
));
766 session_deps
.host_resolver
->Resolve(
767 info
, &test_hosts
[i
].addresses
, CompletionCallback(), NULL
,
770 // Setup a HostPortProxyPair
771 test_hosts
[i
].pair
= HostPortProxyPair(
772 HostPortPair(test_hosts
[i
].name
, kTestPort
), ProxyServer::Direct());
775 MockConnect
connect_data(SYNCHRONOUS
, OK
);
777 MockRead(SYNCHRONOUS
, ERR_IO_PENDING
) // Stall forever.
780 StaticSocketDataProvider
data(reads
, arraysize(reads
), NULL
, 0);
781 data
.set_connect_data(connect_data
);
782 session_deps
.socket_factory
->AddSocketDataProvider(&data
);
784 SSLSocketDataProvider
ssl(SYNCHRONOUS
, OK
);
785 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl
);
787 scoped_refptr
<HttpNetworkSession
> http_session(
788 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
790 // Setup the first session to the first host.
791 SpdySessionPool
* spdy_session_pool(http_session
->spdy_session_pool());
792 EXPECT_FALSE(spdy_session_pool
->HasSession(test_hosts
[0].pair
));
793 scoped_refptr
<SpdySession
> session
=
794 spdy_session_pool
->Get(test_hosts
[0].pair
, BoundNetLog());
795 EXPECT_TRUE(spdy_session_pool
->HasSession(test_hosts
[0].pair
));
797 HostPortPair
test_host_port_pair(test_hosts
[0].name
, kTestPort
);
798 scoped_refptr
<TransportSocketParams
> transport_params(
799 new TransportSocketParams(test_host_port_pair
,
803 scoped_ptr
<ClientSocketHandle
> connection(new ClientSocketHandle
);
804 EXPECT_EQ(OK
, connection
->Init(test_host_port_pair
.ToString(),
805 transport_params
, MEDIUM
, CompletionCallback(),
806 http_session
->GetTransportSocketPool(
807 HttpNetworkSession::NORMAL_SOCKET_POOL
),
809 EXPECT_EQ(OK
, session
->InitializeWithSocket(connection
.release(), false, OK
));
811 // TODO(rtenneti): MockClientSocket::GetPeerAddress return's 0 as the port
812 // number. Fix it to return port 80 and then use GetPeerAddress to AddAlias.
813 const addrinfo
* address
= test_hosts
[0].addresses
.head();
814 SpdySessionPoolPeer
pool_peer(spdy_session_pool
);
815 pool_peer
.AddAlias(address
, test_hosts
[0].pair
);
817 // Flush the SpdySession::OnReadComplete() task.
818 MessageLoop::current()->RunAllPending();
820 // The third host has no overlap with the first, so it can't pool IPs.
821 EXPECT_FALSE(spdy_session_pool
->HasSession(test_hosts
[2].pair
));
823 // The second host overlaps with the first, and should IP pool.
824 EXPECT_TRUE(spdy_session_pool
->HasSession(test_hosts
[1].pair
));
826 // Verify that the second host, through a proxy, won't share the IP.
827 HostPortProxyPair
proxy_pair(test_hosts
[1].pair
.first
,
828 ProxyServer::FromPacString("HTTP http://proxy.foo.com/"));
829 EXPECT_FALSE(spdy_session_pool
->HasSession(proxy_pair
));
831 // Overlap between 2 and 3 does is not transitive to 1.
832 EXPECT_FALSE(spdy_session_pool
->HasSession(test_hosts
[2].pair
));
834 // Create a new session to host 2.
835 scoped_refptr
<SpdySession
> session2
=
836 spdy_session_pool
->Get(test_hosts
[2].pair
, BoundNetLog());
838 // Verify that we have sessions for everything.
839 EXPECT_TRUE(spdy_session_pool
->HasSession(test_hosts
[0].pair
));
840 EXPECT_TRUE(spdy_session_pool
->HasSession(test_hosts
[1].pair
));
841 EXPECT_TRUE(spdy_session_pool
->HasSession(test_hosts
[2].pair
));
843 // Grab the session to host 1 and verify that it is the same session
844 // we got with host 0, and that is a different than host 2's session.
845 scoped_refptr
<SpdySession
> session1
=
846 spdy_session_pool
->Get(test_hosts
[1].pair
, BoundNetLog());
847 EXPECT_EQ(session
.get(), session1
.get());
848 EXPECT_NE(session2
.get(), session1
.get());
850 // Remove the aliases and observe that we still have a session for host1.
851 pool_peer
.RemoveAliases(test_hosts
[0].pair
);
852 pool_peer
.RemoveAliases(test_hosts
[1].pair
);
853 EXPECT_TRUE(spdy_session_pool
->HasSession(test_hosts
[1].pair
));
855 // Expire the host cache
856 session_deps
.host_resolver
->GetHostCache()->clear();
857 EXPECT_TRUE(spdy_session_pool
->HasSession(test_hosts
[1].pair
));
859 // Cleanup the sessions.
860 if (!clean_via_close_current_sessions
) {
861 spdy_session_pool
->Remove(session
);
863 spdy_session_pool
->Remove(session2
);
866 spdy_session_pool
->CloseCurrentSessions();
869 // Verify that the map is all cleaned up.
870 EXPECT_FALSE(spdy_session_pool
->HasSession(test_hosts
[0].pair
));
871 EXPECT_FALSE(spdy_session_pool
->HasSession(test_hosts
[1].pair
));
872 EXPECT_FALSE(spdy_session_pool
->HasSession(test_hosts
[2].pair
));
877 TEST_F(SpdySessionSpdy3Test
, IPPooling
) {
878 IPPoolingTest(false);
881 TEST_F(SpdySessionSpdy3Test
, IPPoolingCloseCurrentSessions
) {
885 TEST_F(SpdySessionSpdy3Test
, ClearSettingsStorageOnIPAddressChanged
) {
886 const std::string
kTestHost("www.foo.com");
887 const int kTestPort
= 80;
888 HostPortPair
test_host_port_pair(kTestHost
, kTestPort
);
890 SpdySessionDependencies session_deps
;
891 scoped_refptr
<HttpNetworkSession
> http_session(
892 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
893 SpdySessionPool
* spdy_session_pool(http_session
->spdy_session_pool());
895 HttpServerProperties
* test_http_server_properties
=
896 spdy_session_pool
->http_server_properties();
897 SettingsFlagsAndValue
flags_and_value1(SETTINGS_FLAG_PLEASE_PERSIST
, 2);
898 test_http_server_properties
->SetSpdySetting(
900 SETTINGS_MAX_CONCURRENT_STREAMS
,
901 SETTINGS_FLAG_PLEASE_PERSIST
,
903 EXPECT_NE(0u, test_http_server_properties
->GetSpdySettings(
904 test_host_port_pair
).size());
905 spdy_session_pool
->OnIPAddressChanged();
906 EXPECT_EQ(0u, test_http_server_properties
->GetSpdySettings(
907 test_host_port_pair
).size());
910 TEST_F(SpdySessionSpdy3Test
, NeedsCredentials
) {
911 SpdySessionDependencies session_deps
;
913 MockConnect
connect_data(SYNCHRONOUS
, OK
);
915 MockRead(SYNCHRONOUS
, ERR_IO_PENDING
) // Stall forever.
917 StaticSocketDataProvider
data(reads
, arraysize(reads
), NULL
, 0);
918 data
.set_connect_data(connect_data
);
919 session_deps
.socket_factory
->AddSocketDataProvider(&data
);
921 SSLSocketDataProvider
ssl(SYNCHRONOUS
, OK
);
922 ssl
.domain_bound_cert_type
= CLIENT_CERT_ECDSA_SIGN
;
923 ssl
.protocol_negotiated
= kProtoSPDY3
;
924 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl
);
926 scoped_refptr
<HttpNetworkSession
> http_session(
927 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
929 const GURL
url("https:/www.foo.com");
930 HostPortPair
test_host_port_pair(url
.host(), 443);
931 HostPortProxyPair
pair(test_host_port_pair
, ProxyServer::Direct());
933 SpdySessionPool
* spdy_session_pool(http_session
->spdy_session_pool());
934 EXPECT_FALSE(spdy_session_pool
->HasSession(pair
));
935 scoped_refptr
<SpdySession
> session
=
936 spdy_session_pool
->Get(pair
, BoundNetLog());
937 EXPECT_TRUE(spdy_session_pool
->HasSession(pair
));
939 SSLConfig ssl_config
;
940 scoped_refptr
<TransportSocketParams
> transport_params(
941 new TransportSocketParams(test_host_port_pair
,
945 scoped_refptr
<SOCKSSocketParams
> socks_params
;
946 scoped_refptr
<HttpProxySocketParams
> http_proxy_params
;
947 scoped_refptr
<SSLSocketParams
> ssl_params(
948 new SSLSocketParams(transport_params
,
951 ProxyServer::SCHEME_DIRECT
,
957 scoped_ptr
<ClientSocketHandle
> connection(new ClientSocketHandle
);
958 EXPECT_EQ(OK
, connection
->Init(test_host_port_pair
.ToString(),
959 ssl_params
, MEDIUM
, CompletionCallback(),
960 http_session
->GetSSLSocketPool(
961 HttpNetworkSession::NORMAL_SOCKET_POOL
),
964 EXPECT_EQ(OK
, session
->InitializeWithSocket(connection
.release(), true, OK
));
966 EXPECT_TRUE(session
->NeedsCredentials());
968 // Flush the SpdySession::OnReadComplete() task.
969 MessageLoop::current()->RunAllPending();
971 spdy_session_pool
->Remove(session
);
974 TEST_F(SpdySessionSpdy3Test
, SendCredentials
) {
975 SpdySessionDependencies session_deps
;
977 MockConnect
connect_data(SYNCHRONOUS
, OK
);
979 MockRead(SYNCHRONOUS
, ERR_IO_PENDING
) // Stall forever.
981 SettingsMap settings
;
982 scoped_ptr
<SpdyFrame
> settings_frame(ConstructSpdySettings(settings
));
983 MockWrite writes
[] = {
984 CreateMockWrite(*settings_frame
),
986 StaticSocketDataProvider
data(reads
, arraysize(reads
),
987 writes
, arraysize(writes
));
988 data
.set_connect_data(connect_data
);
989 session_deps
.socket_factory
->AddSocketDataProvider(&data
);
991 SSLSocketDataProvider
ssl(SYNCHRONOUS
, OK
);
992 ssl
.domain_bound_cert_type
= CLIENT_CERT_ECDSA_SIGN
;
993 ssl
.protocol_negotiated
= kProtoSPDY3
;
994 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl
);
996 scoped_refptr
<HttpNetworkSession
> http_session(
997 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
999 const GURL
kTestUrl("https://www.foo.com");
1000 HostPortPair
test_host_port_pair(kTestUrl
.host(), 443);
1001 HostPortProxyPair
pair(test_host_port_pair
, ProxyServer::Direct());
1003 SpdySessionPool
* spdy_session_pool(http_session
->spdy_session_pool());
1004 EXPECT_FALSE(spdy_session_pool
->HasSession(pair
));
1005 scoped_refptr
<SpdySession
> session
=
1006 spdy_session_pool
->Get(pair
, BoundNetLog());
1007 EXPECT_TRUE(spdy_session_pool
->HasSession(pair
));
1009 SSLConfig ssl_config
;
1010 scoped_refptr
<TransportSocketParams
> transport_params(
1011 new TransportSocketParams(test_host_port_pair
,
1015 scoped_refptr
<SOCKSSocketParams
> socks_params
;
1016 scoped_refptr
<HttpProxySocketParams
> http_proxy_params
;
1017 scoped_refptr
<SSLSocketParams
> ssl_params(
1018 new SSLSocketParams(transport_params
,
1021 ProxyServer::SCHEME_DIRECT
,
1022 test_host_port_pair
,
1027 scoped_ptr
<ClientSocketHandle
> connection(new ClientSocketHandle
);
1028 EXPECT_EQ(OK
, connection
->Init(test_host_port_pair
.ToString(),
1029 ssl_params
, MEDIUM
, CompletionCallback(),
1030 http_session
->GetSSLSocketPool(
1031 HttpNetworkSession::NORMAL_SOCKET_POOL
),
1034 EXPECT_EQ(OK
, session
->InitializeWithSocket(connection
.release(), true, OK
));
1035 EXPECT_TRUE(session
->NeedsCredentials());
1037 // Flush the SpdySession::OnReadComplete() task.
1038 MessageLoop::current()->RunAllPending();
1040 spdy_session_pool
->Remove(session
);
1041 EXPECT_FALSE(spdy_session_pool
->HasSession(pair
));
1044 TEST_F(SpdySessionSpdy3Test
, CloseSessionOnError
) {
1045 SpdySessionDependencies session_deps
;
1046 session_deps
.host_resolver
->set_synchronous_mode(true);
1048 MockConnect
connect_data(SYNCHRONOUS
, OK
);
1049 scoped_ptr
<SpdyFrame
> goaway(ConstructSpdyGoAway());
1050 MockRead reads
[] = {
1051 CreateMockRead(*goaway
),
1052 MockRead(SYNCHRONOUS
, 0, 0) // EOF
1055 net::CapturingBoundNetLog
log(net::CapturingNetLog::kUnbounded
);
1057 StaticSocketDataProvider
data(reads
, arraysize(reads
), NULL
, 0);
1058 data
.set_connect_data(connect_data
);
1059 session_deps
.socket_factory
->AddSocketDataProvider(&data
);
1061 SSLSocketDataProvider
ssl(SYNCHRONOUS
, OK
);
1062 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl
);
1064 scoped_refptr
<HttpNetworkSession
> http_session(
1065 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1067 const std::string
kTestHost("www.foo.com");
1068 const int kTestPort
= 80;
1069 HostPortPair
test_host_port_pair(kTestHost
, kTestPort
);
1070 HostPortProxyPair
pair(test_host_port_pair
, ProxyServer::Direct());
1072 SpdySessionPool
* spdy_session_pool(http_session
->spdy_session_pool());
1073 EXPECT_FALSE(spdy_session_pool
->HasSession(pair
));
1074 scoped_refptr
<SpdySession
> session
=
1075 spdy_session_pool
->Get(pair
, log
.bound());
1076 EXPECT_TRUE(spdy_session_pool
->HasSession(pair
));
1078 scoped_refptr
<TransportSocketParams
> transport_params(
1079 new TransportSocketParams(test_host_port_pair
,
1083 scoped_ptr
<ClientSocketHandle
> connection(new ClientSocketHandle
);
1084 EXPECT_EQ(OK
, connection
->Init(test_host_port_pair
.ToString(),
1085 transport_params
, MEDIUM
, CompletionCallback(),
1086 http_session
->GetTransportSocketPool(
1087 HttpNetworkSession::NORMAL_SOCKET_POOL
),
1089 EXPECT_EQ(OK
, session
->InitializeWithSocket(connection
.release(), false, OK
));
1091 // Flush the SpdySession::OnReadComplete() task.
1092 MessageLoop::current()->RunAllPending();
1094 EXPECT_FALSE(spdy_session_pool
->HasSession(pair
));
1096 // Check that the NetLog was filled reasonably.
1097 net::CapturingNetLog::EntryList entries
;
1098 log
.GetEntries(&entries
);
1099 EXPECT_LT(0u, entries
.size());
1101 // Check that we logged SPDY_SESSION_CLOSE correctly.
1102 int pos
= net::ExpectLogContainsSomewhere(
1104 net::NetLog::TYPE_SPDY_SESSION_CLOSE
,
1105 net::NetLog::PHASE_NONE
);
1107 CapturingNetLog::Entry entry
= entries
[pos
];
1108 NetLogSpdySessionCloseParameter
* request_params
=
1109 static_cast<NetLogSpdySessionCloseParameter
*>(
1110 entry
.extra_parameters
.get());
1111 EXPECT_EQ(ERR_CONNECTION_CLOSED
, request_params
->status());
1114 TEST_F(SpdySessionSpdy3Test
, UpdateStreamsSendWindowSize
) {
1115 // Set SETTINGS_INITIAL_WINDOW_SIZE to a small number so that WINDOW_UPDATE
1117 SettingsMap new_settings
;
1118 int32 window_size
= 1;
1119 new_settings
[SETTINGS_INITIAL_WINDOW_SIZE
] =
1120 SettingsFlagsAndValue(SETTINGS_FLAG_NONE
, window_size
);
1122 // Set up the socket so we read a SETTINGS frame that sets
1123 // INITIAL_WINDOW_SIZE.
1124 MockConnect
connect_data(SYNCHRONOUS
, OK
);
1125 scoped_ptr
<SpdyFrame
> settings_frame(ConstructSpdySettings(new_settings
));
1126 MockRead reads
[] = {
1127 CreateMockRead(*settings_frame
),
1128 MockRead(SYNCHRONOUS
, 0, 0) // EOF
1131 SpdySessionDependencies session_deps
;
1132 session_deps
.host_resolver
->set_synchronous_mode(true);
1134 StaticSocketDataProvider
data(reads
, arraysize(reads
), NULL
, 0);
1135 data
.set_connect_data(connect_data
);
1136 session_deps
.socket_factory
->AddSocketDataProvider(&data
);
1138 SSLSocketDataProvider
ssl(SYNCHRONOUS
, OK
);
1139 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl
);
1141 scoped_refptr
<HttpNetworkSession
> http_session(
1142 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1144 const std::string
kTestHost("www.foo.com");
1145 const int kTestPort
= 80;
1146 HostPortPair
test_host_port_pair(kTestHost
, kTestPort
);
1147 HostPortProxyPair
pair(test_host_port_pair
, ProxyServer::Direct());
1149 SpdySessionPool
* spdy_session_pool(http_session
->spdy_session_pool());
1151 // Create a session.
1152 EXPECT_FALSE(spdy_session_pool
->HasSession(pair
));
1153 scoped_refptr
<SpdySession
> session
=
1154 spdy_session_pool
->Get(pair
, BoundNetLog());
1155 ASSERT_TRUE(spdy_session_pool
->HasSession(pair
));
1157 scoped_refptr
<TransportSocketParams
> transport_params(
1158 new TransportSocketParams(test_host_port_pair
,
1162 scoped_ptr
<ClientSocketHandle
> connection(new ClientSocketHandle
);
1163 EXPECT_EQ(OK
, connection
->Init(test_host_port_pair
.ToString(),
1164 transport_params
, MEDIUM
, CompletionCallback(),
1165 http_session
->GetTransportSocketPool(
1166 HttpNetworkSession::NORMAL_SOCKET_POOL
),
1168 EXPECT_EQ(OK
, session
->InitializeWithSocket(connection
.release(), false, OK
));
1170 scoped_refptr
<SpdyStream
> spdy_stream1
;
1171 TestCompletionCallback callback1
;
1172 GURL
url("http://www.google.com");
1174 session
->CreateStream(url
,
1175 MEDIUM
, /* priority, not important */
1178 callback1
.callback()));
1179 EXPECT_NE(spdy_stream1
->send_window_size(), window_size
);
1181 MessageLoop::current()->RunAllPending();
1182 EXPECT_EQ(session
->initial_send_window_size(), window_size
);
1183 EXPECT_EQ(spdy_stream1
->send_window_size(), window_size
);
1185 // Release the first one, this will allow the second to be created.
1186 spdy_stream1
->Cancel();
1187 spdy_stream1
= NULL
;
1189 scoped_refptr
<SpdyStream
> spdy_stream2
;
1191 session
->CreateStream(url
,
1192 MEDIUM
, /* priority, not important */
1195 callback1
.callback()));
1197 EXPECT_EQ(spdy_stream2
->send_window_size(), window_size
);
1198 spdy_stream2
->Cancel();
1199 spdy_stream2
= NULL
;