Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/spdy/spdy_session.h" | 5 #include "net/spdy/spdy_session.h" |
| 6 | 6 |
| 7 #include "net/base/cert_test_util.h" | 7 #include "net/base/cert_test_util.h" |
| 8 #include "net/base/host_cache.h" | 8 #include "net/base/host_cache.h" |
| 9 #include "net/base/ip_endpoint.h" | 9 #include "net/base/ip_endpoint.h" |
| 10 #include "net/base/net_log_unittest.h" | 10 #include "net/base/net_log_unittest.h" |
| 11 #include "net/base/test_data_directory.h" | 11 #include "net/base/test_data_directory.h" |
| 12 #include "net/spdy/spdy_io_buffer.h" | 12 #include "net/spdy/spdy_io_buffer.h" |
| 13 #include "net/spdy/spdy_session_pool.h" | 13 #include "net/spdy/spdy_session_pool.h" |
| 14 #include "net/spdy/spdy_stream.h" | 14 #include "net/spdy/spdy_stream.h" |
| 15 #include "net/spdy/spdy_test_util_spdy3.h" | 15 #include "net/spdy/spdy_test_util_spdy3.h" |
| 16 #include "testing/platform_test.h" | 16 #include "testing/platform_test.h" |
| 17 | 17 |
| 18 using namespace net::test_spdy3; | 18 using namespace net::test_spdy3; |
| 19 | 19 |
| 20 namespace net { | 20 namespace net { |
| 21 | 21 |
| 22 namespace { | 22 namespace { |
| 23 | 23 |
| 24 static int g_delta_seconds = 0; | |
| 24 base::TimeTicks the_near_future() { | 25 base::TimeTicks the_near_future() { |
| 25 return base::TimeTicks::Now() + | 26 return base::TimeTicks::Now() + base::TimeDelta::FromSeconds(g_delta_seconds); |
| 26 base::TimeDelta::FromSeconds(301); | |
| 27 } | 27 } |
| 28 | 28 |
| 29 class ClosingDelegate : public SpdyStream::Delegate { | 29 class ClosingDelegate : public SpdyStream::Delegate { |
| 30 public: | 30 public: |
| 31 ClosingDelegate(SpdyStream* stream) : stream_(stream) {} | 31 ClosingDelegate(SpdyStream* stream) : stream_(stream) {} |
| 32 | 32 |
| 33 // SpdyStream::Delegate implementation: | 33 // SpdyStream::Delegate implementation: |
| 34 virtual bool OnSendHeadersComplete(int status) OVERRIDE { | 34 virtual bool OnSendHeadersComplete(int status) OVERRIDE { |
| 35 return true; | 35 return true; |
| 36 } | 36 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 92 callback_.Reset(); | 92 callback_.Reset(); |
| 93 callback.Run(OK); | 93 callback.Run(OK); |
| 94 } | 94 } |
| 95 | 95 |
| 96 private: | 96 private: |
| 97 CompletionCallback callback_; | 97 CompletionCallback callback_; |
| 98 }; | 98 }; |
| 99 | 99 |
| 100 } // namespace | 100 } // namespace |
| 101 | 101 |
| 102 // TODO(cbentzel): Expose compression setter/getter in public SpdySession | |
| 103 // interface rather than going through all these contortions. | |
| 104 class SpdySessionSpdy3Test : public PlatformTest { | 102 class SpdySessionSpdy3Test : public PlatformTest { |
| 105 protected: | 103 }; |
| 106 virtual void SetUp() { | |
| 107 SpdySession::set_default_protocol(kProtoSPDY3); | |
| 108 } | |
| 109 | 104 |
| 110 private: | |
| 111 SpdyTestStateHelper spdy_state_; | |
| 112 }; | |
| 113 // Test the SpdyIOBuffer class. | 105 // Test the SpdyIOBuffer class. |
| 114 TEST_F(SpdySessionSpdy3Test, SpdyIOBuffer) { | 106 TEST_F(SpdySessionSpdy3Test, SpdyIOBuffer) { |
| 115 std::priority_queue<SpdyIOBuffer> queue_; | 107 std::priority_queue<SpdyIOBuffer> queue_; |
| 116 const size_t kQueueSize = 100; | 108 const size_t kQueueSize = 100; |
| 117 | 109 |
| 118 // Insert items with random priority and increasing buffer size | 110 // Insert items with random priority and increasing buffer size |
| 119 for (size_t index = 0; index < kQueueSize; ++index) { | 111 for (size_t index = 0; index < kQueueSize; ++index) { |
| 120 queue_.push(SpdyIOBuffer( | 112 queue_.push(SpdyIOBuffer( |
| 121 new IOBufferWithSize(index + 1), | 113 new IOBufferWithSize(index + 1), |
| 122 index + 1, | 114 index + 1, |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 201 // Delete the first session. | 193 // Delete the first session. |
| 202 session = NULL; | 194 session = NULL; |
| 203 | 195 |
| 204 // Delete the second session. | 196 // Delete the second session. |
| 205 spdy_session_pool->Remove(session2); | 197 spdy_session_pool->Remove(session2); |
| 206 session2 = NULL; | 198 session2 = NULL; |
| 207 } | 199 } |
| 208 | 200 |
| 209 TEST_F(SpdySessionSpdy3Test, ClientPing) { | 201 TEST_F(SpdySessionSpdy3Test, ClientPing) { |
| 210 SpdySessionDependencies session_deps; | 202 SpdySessionDependencies session_deps; |
| 203 session_deps.enable_ping = true; | |
| 211 session_deps.host_resolver->set_synchronous_mode(true); | 204 session_deps.host_resolver->set_synchronous_mode(true); |
| 212 | 205 |
| 213 MockConnect connect_data(SYNCHRONOUS, OK); | 206 MockConnect connect_data(SYNCHRONOUS, OK); |
| 214 scoped_ptr<SpdyFrame> read_ping(ConstructSpdyPing(1)); | 207 scoped_ptr<SpdyFrame> read_ping(ConstructSpdyPing(1)); |
| 215 MockRead reads[] = { | 208 MockRead reads[] = { |
| 216 CreateMockRead(*read_ping), | 209 CreateMockRead(*read_ping), |
| 217 MockRead(SYNCHRONOUS, 0, 0) // EOF | 210 MockRead(SYNCHRONOUS, 0, 0) // EOF |
| 218 }; | 211 }; |
| 219 scoped_ptr<SpdyFrame> write_ping(ConstructSpdyPing(1)); | 212 scoped_ptr<SpdyFrame> write_ping(ConstructSpdyPing(1)); |
| 220 MockWrite writes[] = { | 213 MockWrite writes[] = { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 265 MEDIUM, | 258 MEDIUM, |
| 266 &spdy_stream1, | 259 &spdy_stream1, |
| 267 BoundNetLog(), | 260 BoundNetLog(), |
| 268 callback1.callback())); | 261 callback1.callback())); |
| 269 scoped_ptr<TestSpdyStreamDelegate> delegate( | 262 scoped_ptr<TestSpdyStreamDelegate> delegate( |
| 270 new TestSpdyStreamDelegate(callback1.callback())); | 263 new TestSpdyStreamDelegate(callback1.callback())); |
| 271 spdy_stream1->SetDelegate(delegate.get()); | 264 spdy_stream1->SetDelegate(delegate.get()); |
| 272 | 265 |
| 273 base::TimeTicks before_ping_time = base::TimeTicks::Now(); | 266 base::TimeTicks before_ping_time = base::TimeTicks::Now(); |
| 274 | 267 |
| 275 // Enable sending of PING. | |
| 276 SpdySession::set_enable_ping_based_connection_checking(true); | |
| 277 session->set_connection_at_risk_of_loss_time(base::TimeDelta::FromSeconds(0)); | 268 session->set_connection_at_risk_of_loss_time(base::TimeDelta::FromSeconds(0)); |
| 278 session->set_hung_interval(base::TimeDelta::FromMilliseconds(50)); | 269 session->set_hung_interval(base::TimeDelta::FromMilliseconds(50)); |
| 279 | 270 |
| 280 session->SendPrefacePingIfNoneInFlight(); | 271 session->SendPrefacePingIfNoneInFlight(); |
| 281 | 272 |
| 282 EXPECT_EQ(OK, callback1.WaitForResult()); | 273 EXPECT_EQ(OK, callback1.WaitForResult()); |
| 283 | 274 |
| 284 session->CheckPingStatus(before_ping_time); | 275 session->CheckPingStatus(before_ping_time); |
| 285 | 276 |
| 286 EXPECT_EQ(0, session->pings_in_flight()); | 277 EXPECT_EQ(0, session->pings_in_flight()); |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 366 // Delete the session. | 357 // Delete the session. |
| 367 session = NULL; | 358 session = NULL; |
| 368 } | 359 } |
| 369 | 360 |
| 370 TEST_F(SpdySessionSpdy3Test, DeleteExpiredPushStreams) { | 361 TEST_F(SpdySessionSpdy3Test, DeleteExpiredPushStreams) { |
| 371 SpdySessionDependencies session_deps; | 362 SpdySessionDependencies session_deps; |
| 372 session_deps.host_resolver->set_synchronous_mode(true); | 363 session_deps.host_resolver->set_synchronous_mode(true); |
| 373 | 364 |
| 374 SSLSocketDataProvider ssl(SYNCHRONOUS, OK); | 365 SSLSocketDataProvider ssl(SYNCHRONOUS, OK); |
| 375 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl); | 366 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl); |
| 367 session_deps.time_func = the_near_future; | |
|
willchan no longer on Chromium
2012/12/01 20:49:13
Should probably still be CamelCased. Mind changing
Ryan Hamilton
2012/12/01 23:02:25
Done.
| |
| 376 | 368 |
| 377 scoped_refptr<HttpNetworkSession> http_session( | 369 scoped_refptr<HttpNetworkSession> http_session( |
| 378 SpdySessionDependencies::SpdyCreateSession(&session_deps)); | 370 SpdySessionDependencies::SpdyCreateSession(&session_deps)); |
| 379 | 371 |
| 380 const std::string kTestHost("www.google.com"); | 372 const std::string kTestHost("www.google.com"); |
| 381 const int kTestPort = 80; | 373 const int kTestPort = 80; |
| 382 HostPortPair test_host_port_pair(kTestHost, kTestPort); | 374 HostPortPair test_host_port_pair(kTestHost, kTestPort); |
| 383 HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct()); | 375 HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct()); |
| 384 | 376 |
| 385 SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool()); | 377 SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool()); |
| 386 EXPECT_FALSE(spdy_session_pool->HasSession(pair)); | 378 EXPECT_FALSE(spdy_session_pool->HasSession(pair)); |
| 387 scoped_refptr<SpdySession> session = | 379 scoped_refptr<SpdySession> session = |
| 388 spdy_session_pool->Get(pair, BoundNetLog()); | 380 spdy_session_pool->Get(pair, BoundNetLog()); |
| 389 EXPECT_TRUE(spdy_session_pool->HasSession(pair)); | 381 EXPECT_TRUE(spdy_session_pool->HasSession(pair)); |
| 390 | 382 |
| 391 // Give the session a SPDY3 framer. | 383 // Give the session a SPDY3 framer. |
| 392 session->buffered_spdy_framer_.reset(new BufferedSpdyFramer(3)); | 384 session->buffered_spdy_framer_.reset(new BufferedSpdyFramer(3, false)); |
| 393 | 385 |
| 394 // Create the associated stream and add to active streams. | 386 // Create the associated stream and add to active streams. |
| 395 scoped_ptr<SpdyHeaderBlock> request_headers(new SpdyHeaderBlock); | 387 scoped_ptr<SpdyHeaderBlock> request_headers(new SpdyHeaderBlock); |
| 396 (*request_headers)[":scheme"] = "http"; | 388 (*request_headers)[":scheme"] = "http"; |
| 397 (*request_headers)[":host"] = "www.google.com"; | 389 (*request_headers)[":host"] = "www.google.com"; |
| 398 (*request_headers)[":path"] = "/"; | 390 (*request_headers)[":path"] = "/"; |
| 399 | 391 |
| 400 scoped_refptr<SpdyStream> stream( | 392 scoped_refptr<SpdyStream> stream( |
| 401 new SpdyStream(session, false, session->net_log_)); | 393 new SpdyStream(session, false, session->net_log_)); |
| 402 stream->set_spdy_headers(request_headers.Pass()); | 394 stream->set_spdy_headers(request_headers.Pass()); |
| 403 session->ActivateStream(stream); | 395 session->ActivateStream(stream); |
| 404 | 396 |
| 405 SpdyHeaderBlock headers; | 397 SpdyHeaderBlock headers; |
| 406 headers[":scheme"] = "http"; | 398 headers[":scheme"] = "http"; |
| 407 headers[":host"] = "www.google.com"; | 399 headers[":host"] = "www.google.com"; |
| 408 headers[":path"] = "/a.dat"; | 400 headers[":path"] = "/a.dat"; |
| 409 session->OnSynStream(2, 1, 0, 0, true, false, headers); | 401 session->OnSynStream(2, 1, 0, 0, true, false, headers); |
| 410 | 402 |
| 411 // Verify that there is one unclaimed push stream. | 403 // Verify that there is one unclaimed push stream. |
| 412 EXPECT_EQ(1u, session->num_unclaimed_pushed_streams()); | 404 EXPECT_EQ(1u, session->num_unclaimed_pushed_streams()); |
| 413 SpdySession::PushedStreamMap::iterator iter = | 405 SpdySession::PushedStreamMap::iterator iter = |
| 414 session->unclaimed_pushed_streams_.find("http://www.google.com/a.dat"); | 406 session->unclaimed_pushed_streams_.find("http://www.google.com/a.dat"); |
| 415 EXPECT_TRUE(session->unclaimed_pushed_streams_.end() != iter); | 407 EXPECT_TRUE(session->unclaimed_pushed_streams_.end() != iter); |
| 416 | 408 |
| 417 // Shift time. | 409 // Shift time. |
| 418 SpdySession::set_time_func(the_near_future); | 410 g_delta_seconds = 301; |
|
willchan no longer on Chromium
2012/12/01 20:49:13
Strange that we're setting a global here in a sing
Ryan Hamilton
2012/12/01 23:02:25
I agree that it's weird :< Happy to refactor it,
willchan no longer on Chromium
2012/12/01 23:05:53
Can we just hardcode it to 301? IIUC, we only ever
| |
| 419 | 411 |
| 420 headers[":scheme"] = "http"; | 412 headers[":scheme"] = "http"; |
| 421 headers[":host"] = "www.google.com"; | 413 headers[":host"] = "www.google.com"; |
| 422 headers[":path"] = "/b.dat"; | 414 headers[":path"] = "/b.dat"; |
| 423 session->OnSynStream(4, 1, 0, 0, true, false, headers); | 415 session->OnSynStream(4, 1, 0, 0, true, false, headers); |
| 424 | 416 |
| 425 // Verify that the second pushed stream evicted the first pushed stream. | 417 // Verify that the second pushed stream evicted the first pushed stream. |
| 426 EXPECT_EQ(1u, session->num_unclaimed_pushed_streams()); | 418 EXPECT_EQ(1u, session->num_unclaimed_pushed_streams()); |
| 427 iter = session->unclaimed_pushed_streams_.find("http://www.google.com/b.dat"); | 419 iter = session->unclaimed_pushed_streams_.find("http://www.google.com/b.dat"); |
| 428 EXPECT_TRUE(session->unclaimed_pushed_streams_.end() != iter); | 420 EXPECT_TRUE(session->unclaimed_pushed_streams_.end() != iter); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 488 TestCompletionCallback callback1; | 480 TestCompletionCallback callback1; |
| 489 EXPECT_EQ(OK, session->CreateStream(url, | 481 EXPECT_EQ(OK, session->CreateStream(url, |
| 490 MEDIUM, | 482 MEDIUM, |
| 491 &spdy_stream1, | 483 &spdy_stream1, |
| 492 BoundNetLog(), | 484 BoundNetLog(), |
| 493 callback1.callback())); | 485 callback1.callback())); |
| 494 scoped_ptr<TestSpdyStreamDelegate> delegate( | 486 scoped_ptr<TestSpdyStreamDelegate> delegate( |
| 495 new TestSpdyStreamDelegate(callback1.callback())); | 487 new TestSpdyStreamDelegate(callback1.callback())); |
| 496 spdy_stream1->SetDelegate(delegate.get()); | 488 spdy_stream1->SetDelegate(delegate.get()); |
| 497 | 489 |
| 498 // Enable sending of PING. | |
| 499 SpdySession::set_enable_ping_based_connection_checking(true); | |
| 500 session->set_connection_at_risk_of_loss_time(base::TimeDelta::FromSeconds(0)); | 490 session->set_connection_at_risk_of_loss_time(base::TimeDelta::FromSeconds(0)); |
| 501 session->set_hung_interval(base::TimeDelta::FromSeconds(0)); | 491 session->set_hung_interval(base::TimeDelta::FromSeconds(0)); |
| 502 | 492 |
| 503 // Send a PING frame. | 493 // Send a PING frame. |
| 504 session->WritePingFrame(1); | 494 session->WritePingFrame(1); |
| 505 EXPECT_LT(0, session->pings_in_flight()); | 495 EXPECT_LT(0, session->pings_in_flight()); |
| 506 EXPECT_GE(session->next_ping_id(), static_cast<uint32>(1)); | 496 EXPECT_GE(session->next_ping_id(), static_cast<uint32>(1)); |
| 507 EXPECT_TRUE(session->check_ping_status_pending()); | 497 EXPECT_TRUE(session->check_ping_status_pending()); |
| 508 | 498 |
| 509 // Assert session is not closed. | 499 // Assert session is not closed. |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 860 const uint32 kInitialRecvWindowSize = 10 * 1024 * 1024; | 850 const uint32 kInitialRecvWindowSize = 10 * 1024 * 1024; |
| 861 settings[kSpdySettingsIds1] = | 851 settings[kSpdySettingsIds1] = |
| 862 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kMaxConcurrentPushedStreams); | 852 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kMaxConcurrentPushedStreams); |
| 863 settings[kSpdySettingsIds2] = | 853 settings[kSpdySettingsIds2] = |
| 864 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kInitialRecvWindowSize); | 854 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kInitialRecvWindowSize); |
| 865 MockConnect connect_data(SYNCHRONOUS, OK); | 855 MockConnect connect_data(SYNCHRONOUS, OK); |
| 866 scoped_ptr<SpdyFrame> settings_frame(ConstructSpdySettings(settings)); | 856 scoped_ptr<SpdyFrame> settings_frame(ConstructSpdySettings(settings)); |
| 867 MockWrite writes[] = { | 857 MockWrite writes[] = { |
| 868 CreateMockWrite(*settings_frame), | 858 CreateMockWrite(*settings_frame), |
| 869 }; | 859 }; |
| 870 SpdySession::set_default_initial_recv_window_size(kInitialRecvWindowSize); | 860 session_deps.initial_recv_window_size = kInitialRecvWindowSize; |
| 871 | 861 |
| 872 StaticSocketDataProvider data( | 862 StaticSocketDataProvider data( |
| 873 reads, arraysize(reads), writes, arraysize(writes)); | 863 reads, arraysize(reads), writes, arraysize(writes)); |
| 874 data.set_connect_data(connect_data); | 864 data.set_connect_data(connect_data); |
| 875 session_deps.socket_factory->AddSocketDataProvider(&data); | 865 session_deps.socket_factory->AddSocketDataProvider(&data); |
| 876 | 866 |
| 877 SSLSocketDataProvider ssl(SYNCHRONOUS, OK); | 867 SSLSocketDataProvider ssl(SYNCHRONOUS, OK); |
| 878 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl); | 868 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl); |
| 879 | 869 |
| 880 scoped_refptr<HttpNetworkSession> http_session( | 870 scoped_refptr<HttpNetworkSession> http_session( |
| (...skipping 1039 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1920 BoundNetLog())); | 1910 BoundNetLog())); |
| 1921 | 1911 |
| 1922 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK)); | 1912 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK)); |
| 1923 EXPECT_TRUE(session->VerifyDomainAuthentication("www.example.org")); | 1913 EXPECT_TRUE(session->VerifyDomainAuthentication("www.example.org")); |
| 1924 EXPECT_TRUE(session->VerifyDomainAuthentication("mail.example.org")); | 1914 EXPECT_TRUE(session->VerifyDomainAuthentication("mail.example.org")); |
| 1925 EXPECT_FALSE(session->VerifyDomainAuthentication("mail.example.com")); | 1915 EXPECT_FALSE(session->VerifyDomainAuthentication("mail.example.com")); |
| 1926 EXPECT_FALSE(session->VerifyDomainAuthentication("mail.google.com")); | 1916 EXPECT_FALSE(session->VerifyDomainAuthentication("mail.google.com")); |
| 1927 } | 1917 } |
| 1928 | 1918 |
| 1929 } // namespace net | 1919 } // namespace net |
| OLD | NEW |