| Index: net/spdy/spdy_session_unittest.cc
|
| ===================================================================
|
| --- net/spdy/spdy_session_unittest.cc (revision 124866)
|
| +++ net/spdy/spdy_session_unittest.cc (working copy)
|
| @@ -1,1123 +0,0 @@
|
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "net/spdy/spdy_session.h"
|
| -
|
| -#include "net/base/ip_endpoint.h"
|
| -#include "net/base/net_log_unittest.h"
|
| -#include "net/spdy/spdy_io_buffer.h"
|
| -#include "net/spdy/spdy_session_pool.h"
|
| -#include "net/spdy/spdy_stream.h"
|
| -#include "net/spdy/spdy_test_util.h"
|
| -#include "testing/platform_test.h"
|
| -
|
| -namespace net {
|
| -
|
| -// TODO(cbentzel): Expose compression setter/getter in public SpdySession
|
| -// interface rather than going through all these contortions.
|
| -class SpdySessionTest : public PlatformTest {
|
| - public:
|
| - static void TurnOffCompression() {
|
| - spdy::SpdyFramer::set_enable_compression_default(false);
|
| - }
|
| - protected:
|
| - virtual void TearDown() {
|
| - // Wanted to be 100% sure PING is disabled.
|
| - SpdySession::set_enable_ping_based_connection_checking(false);
|
| - }
|
| -};
|
| -
|
| -class TestSpdyStreamDelegate : public net::SpdyStream::Delegate {
|
| - public:
|
| - explicit TestSpdyStreamDelegate(const CompletionCallback& callback)
|
| - : callback_(callback) {}
|
| - virtual ~TestSpdyStreamDelegate() {}
|
| -
|
| - virtual bool OnSendHeadersComplete(int status) { return true; }
|
| -
|
| - virtual int OnSendBody() {
|
| - return ERR_UNEXPECTED;
|
| - }
|
| -
|
| - virtual int OnSendBodyComplete(int /*status*/, bool* /*eof*/) {
|
| - return ERR_UNEXPECTED;
|
| - }
|
| -
|
| - virtual int OnResponseReceived(const spdy::SpdyHeaderBlock& response,
|
| - base::Time response_time,
|
| - int status) {
|
| - return status;
|
| - }
|
| -
|
| - virtual void OnDataReceived(const char* buffer, int bytes) {
|
| - }
|
| -
|
| - virtual void OnDataSent(int length) {
|
| - }
|
| -
|
| - virtual void OnClose(int status) {
|
| - CompletionCallback callback = callback_;
|
| - callback_.Reset();
|
| - callback.Run(OK);
|
| - }
|
| -
|
| - virtual void set_chunk_callback(net::ChunkCallback *) {}
|
| -
|
| - private:
|
| - CompletionCallback callback_;
|
| -};
|
| -
|
| -// Test the SpdyIOBuffer class.
|
| -TEST_F(SpdySessionTest, SpdyIOBuffer) {
|
| - std::priority_queue<SpdyIOBuffer> queue_;
|
| - const size_t kQueueSize = 100;
|
| -
|
| - // Insert 100 items; pri 100 to 1.
|
| - for (size_t index = 0; index < kQueueSize; ++index) {
|
| - SpdyIOBuffer buffer(new IOBuffer(), 0, kQueueSize - index, NULL);
|
| - queue_.push(buffer);
|
| - }
|
| -
|
| - // Insert several priority 0 items last.
|
| - const size_t kNumDuplicates = 12;
|
| - IOBufferWithSize* buffers[kNumDuplicates];
|
| - for (size_t index = 0; index < kNumDuplicates; ++index) {
|
| - buffers[index] = new IOBufferWithSize(index+1);
|
| - queue_.push(SpdyIOBuffer(buffers[index], buffers[index]->size(), 0, NULL));
|
| - }
|
| -
|
| - EXPECT_EQ(kQueueSize + kNumDuplicates, queue_.size());
|
| -
|
| - // Verify the P0 items come out in FIFO order.
|
| - for (size_t index = 0; index < kNumDuplicates; ++index) {
|
| - SpdyIOBuffer buffer = queue_.top();
|
| - EXPECT_EQ(0, buffer.priority());
|
| - EXPECT_EQ(index + 1, buffer.size());
|
| - queue_.pop();
|
| - }
|
| -
|
| - int priority = 1;
|
| - while (queue_.size()) {
|
| - SpdyIOBuffer buffer = queue_.top();
|
| - EXPECT_EQ(priority++, buffer.priority());
|
| - queue_.pop();
|
| - }
|
| -}
|
| -
|
| -TEST_F(SpdySessionTest, GoAway) {
|
| - SpdySessionDependencies session_deps;
|
| - session_deps.host_resolver->set_synchronous_mode(true);
|
| -
|
| - MockConnect connect_data(SYNCHRONOUS, OK);
|
| - scoped_ptr<spdy::SpdyFrame> goaway(ConstructSpdyGoAway());
|
| - MockRead reads[] = {
|
| - CreateMockRead(*goaway),
|
| - MockRead(SYNCHRONOUS, 0, 0) // EOF
|
| - };
|
| - StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
|
| - data.set_connect_data(connect_data);
|
| - session_deps.socket_factory->AddSocketDataProvider(&data);
|
| -
|
| - SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
|
| - session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
|
| -
|
| - scoped_refptr<HttpNetworkSession> http_session(
|
| - SpdySessionDependencies::SpdyCreateSession(&session_deps));
|
| -
|
| - const std::string kTestHost("www.foo.com");
|
| - const int kTestPort = 80;
|
| - HostPortPair test_host_port_pair(kTestHost, kTestPort);
|
| - HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
|
| -
|
| - SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
|
| - EXPECT_FALSE(spdy_session_pool->HasSession(pair));
|
| - scoped_refptr<SpdySession> session =
|
| - spdy_session_pool->Get(pair, BoundNetLog());
|
| - EXPECT_TRUE(spdy_session_pool->HasSession(pair));
|
| -
|
| - scoped_refptr<TransportSocketParams> transport_params(
|
| - new TransportSocketParams(test_host_port_pair,
|
| - MEDIUM,
|
| - false,
|
| - false));
|
| - scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
|
| - EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
|
| - transport_params, MEDIUM, CompletionCallback(),
|
| - http_session->GetTransportSocketPool(),
|
| - BoundNetLog()));
|
| - EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
|
| -
|
| - // Flush the SpdySession::OnReadComplete() task.
|
| - MessageLoop::current()->RunAllPending();
|
| -
|
| - EXPECT_FALSE(spdy_session_pool->HasSession(pair));
|
| -
|
| - scoped_refptr<SpdySession> session2 =
|
| - spdy_session_pool->Get(pair, BoundNetLog());
|
| -
|
| - // Delete the first session.
|
| - session = NULL;
|
| -
|
| - // Delete the second session.
|
| - spdy_session_pool->Remove(session2);
|
| - session2 = NULL;
|
| -}
|
| -
|
| -TEST_F(SpdySessionTest, Ping) {
|
| - SpdySessionDependencies session_deps;
|
| - session_deps.host_resolver->set_synchronous_mode(true);
|
| -
|
| - MockConnect connect_data(SYNCHRONOUS, OK);
|
| - scoped_ptr<spdy::SpdyFrame> read_ping(ConstructSpdyPing());
|
| - MockRead reads[] = {
|
| - CreateMockRead(*read_ping),
|
| - CreateMockRead(*read_ping),
|
| - MockRead(SYNCHRONOUS, 0, 0) // EOF
|
| - };
|
| - scoped_ptr<spdy::SpdyFrame> write_ping(ConstructSpdyPing());
|
| - MockRead writes[] = {
|
| - CreateMockRead(*write_ping),
|
| - CreateMockRead(*write_ping),
|
| - };
|
| - StaticSocketDataProvider data(
|
| - reads, arraysize(reads), writes, arraysize(writes));
|
| - data.set_connect_data(connect_data);
|
| - session_deps.socket_factory->AddSocketDataProvider(&data);
|
| -
|
| - SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
|
| - session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
|
| -
|
| - scoped_refptr<HttpNetworkSession> http_session(
|
| - SpdySessionDependencies::SpdyCreateSession(&session_deps));
|
| -
|
| - static const char kStreamUrl[] = "http://www.google.com/";
|
| - GURL url(kStreamUrl);
|
| -
|
| - const std::string kTestHost("www.google.com");
|
| - const int kTestPort = 80;
|
| - HostPortPair test_host_port_pair(kTestHost, kTestPort);
|
| - HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
|
| -
|
| - SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
|
| - EXPECT_FALSE(spdy_session_pool->HasSession(pair));
|
| - scoped_refptr<SpdySession> session =
|
| - spdy_session_pool->Get(pair, BoundNetLog());
|
| - EXPECT_TRUE(spdy_session_pool->HasSession(pair));
|
| -
|
| -
|
| - scoped_refptr<TransportSocketParams> transport_params(
|
| - new TransportSocketParams(test_host_port_pair,
|
| - MEDIUM,
|
| - false,
|
| - false));
|
| - scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
|
| - EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
|
| - transport_params, MEDIUM, CompletionCallback(),
|
| - http_session->GetTransportSocketPool(),
|
| - BoundNetLog()));
|
| - EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
|
| -
|
| - scoped_refptr<SpdyStream> spdy_stream1;
|
| - TestCompletionCallback callback1;
|
| - EXPECT_EQ(OK, session->CreateStream(url,
|
| - MEDIUM,
|
| - &spdy_stream1,
|
| - BoundNetLog(),
|
| - callback1.callback()));
|
| - scoped_ptr<TestSpdyStreamDelegate> delegate(
|
| - new TestSpdyStreamDelegate(callback1.callback()));
|
| - spdy_stream1->SetDelegate(delegate.get());
|
| -
|
| - base::TimeTicks before_ping_time = base::TimeTicks::Now();
|
| -
|
| - // Enable sending of PING.
|
| - SpdySession::set_enable_ping_based_connection_checking(true);
|
| - SpdySession::set_connection_at_risk_of_loss_seconds(0);
|
| - SpdySession::set_trailing_ping_delay_time_ms(0);
|
| - SpdySession::set_hung_interval_ms(50);
|
| -
|
| - session->SendPrefacePingIfNoneInFlight();
|
| -
|
| - EXPECT_EQ(OK, callback1.WaitForResult());
|
| -
|
| - session->CheckPingStatus(before_ping_time);
|
| -
|
| - EXPECT_EQ(0, session->pings_in_flight());
|
| - EXPECT_GT(session->next_ping_id(), static_cast<uint32>(1));
|
| - EXPECT_FALSE(session->trailing_ping_pending());
|
| - EXPECT_FALSE(session->check_ping_status_pending());
|
| - EXPECT_GE(session->received_data_time(), before_ping_time);
|
| -
|
| - EXPECT_FALSE(spdy_session_pool->HasSession(pair));
|
| -
|
| - // Delete the first session.
|
| - session = NULL;
|
| -}
|
| -
|
| -TEST_F(SpdySessionTest, FailedPing) {
|
| - SpdySessionDependencies session_deps;
|
| - session_deps.host_resolver->set_synchronous_mode(true);
|
| -
|
| - MockConnect connect_data(SYNCHRONOUS, OK);
|
| - scoped_ptr<spdy::SpdyFrame> read_ping(ConstructSpdyPing());
|
| - MockRead reads[] = {
|
| - CreateMockRead(*read_ping),
|
| - MockRead(SYNCHRONOUS, 0, 0) // EOF
|
| - };
|
| - scoped_ptr<spdy::SpdyFrame> write_ping(ConstructSpdyPing());
|
| - MockRead writes[] = {
|
| - CreateMockRead(*write_ping),
|
| - };
|
| - StaticSocketDataProvider data(
|
| - reads, arraysize(reads), writes, arraysize(writes));
|
| - data.set_connect_data(connect_data);
|
| - session_deps.socket_factory->AddSocketDataProvider(&data);
|
| -
|
| - SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
|
| - session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
|
| -
|
| - scoped_refptr<HttpNetworkSession> http_session(
|
| - SpdySessionDependencies::SpdyCreateSession(&session_deps));
|
| -
|
| - static const char kStreamUrl[] = "http://www.gmail.com/";
|
| - GURL url(kStreamUrl);
|
| -
|
| - const std::string kTestHost("www.gmail.com");
|
| - const int kTestPort = 80;
|
| - HostPortPair test_host_port_pair(kTestHost, kTestPort);
|
| - HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
|
| -
|
| - SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
|
| - EXPECT_FALSE(spdy_session_pool->HasSession(pair));
|
| - scoped_refptr<SpdySession> session =
|
| - spdy_session_pool->Get(pair, BoundNetLog());
|
| - EXPECT_TRUE(spdy_session_pool->HasSession(pair));
|
| -
|
| - scoped_refptr<TransportSocketParams> transport_params(
|
| - new TransportSocketParams(test_host_port_pair,
|
| - MEDIUM,
|
| - false,
|
| - false));
|
| - scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
|
| - EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
|
| - transport_params, MEDIUM, CompletionCallback(),
|
| - http_session->GetTransportSocketPool(),
|
| - BoundNetLog()));
|
| - EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
|
| -
|
| - scoped_refptr<SpdyStream> spdy_stream1;
|
| - TestCompletionCallback callback1;
|
| - EXPECT_EQ(OK, session->CreateStream(url,
|
| - MEDIUM,
|
| - &spdy_stream1,
|
| - BoundNetLog(),
|
| - callback1.callback()));
|
| - scoped_ptr<TestSpdyStreamDelegate> delegate(
|
| - new TestSpdyStreamDelegate(callback1.callback()));
|
| - spdy_stream1->SetDelegate(delegate.get());
|
| -
|
| - // Enable sending of PING.
|
| - SpdySession::set_enable_ping_based_connection_checking(true);
|
| - SpdySession::set_connection_at_risk_of_loss_seconds(0);
|
| - SpdySession::set_trailing_ping_delay_time_ms(0);
|
| - SpdySession::set_hung_interval_ms(0);
|
| -
|
| - // Send a PING frame.
|
| - session->WritePingFrame(1);
|
| - EXPECT_LT(0, session->pings_in_flight());
|
| - EXPECT_GT(session->next_ping_id(), static_cast<uint32>(1));
|
| - EXPECT_TRUE(session->check_ping_status_pending());
|
| -
|
| - // Assert session is not closed.
|
| - EXPECT_FALSE(session->IsClosed());
|
| - EXPECT_LT(0u, session->num_active_streams());
|
| - EXPECT_TRUE(spdy_session_pool->HasSession(pair));
|
| -
|
| - // We set last time we have received any data in 1 sec less than now.
|
| - // CheckPingStatus will trigger timeout because hung interval is zero.
|
| - base::TimeTicks now = base::TimeTicks::Now();
|
| - session->received_data_time_ = now - base::TimeDelta::FromSeconds(1);
|
| - session->CheckPingStatus(now);
|
| -
|
| - EXPECT_TRUE(session->IsClosed());
|
| - EXPECT_EQ(0u, session->num_active_streams());
|
| - EXPECT_EQ(0u, session->num_unclaimed_pushed_streams());
|
| - EXPECT_FALSE(spdy_session_pool->HasSession(pair));
|
| -
|
| - // Delete the first session.
|
| - session = NULL;
|
| -}
|
| -
|
| -class StreamReleaserCallback : public TestCompletionCallbackBase {
|
| - public:
|
| - StreamReleaserCallback(SpdySession* session,
|
| - SpdyStream* first_stream)
|
| - : session_(session),
|
| - first_stream_(first_stream),
|
| - ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
|
| - base::Bind(&StreamReleaserCallback::OnComplete,
|
| - base::Unretained(this)))) {
|
| - }
|
| -
|
| - virtual ~StreamReleaserCallback() {}
|
| -
|
| - scoped_refptr<SpdyStream>* stream() { return &stream_; }
|
| -
|
| - const CompletionCallback& callback() const { return callback_; }
|
| -
|
| - private:
|
| - void OnComplete(int result) {
|
| - session_->CloseSessionOnError(ERR_FAILED, false, "On complete.");
|
| - session_ = NULL;
|
| - first_stream_->Cancel();
|
| - first_stream_ = NULL;
|
| - stream_->Cancel();
|
| - stream_ = NULL;
|
| - SetResult(result);
|
| - }
|
| -
|
| - scoped_refptr<SpdySession> session_;
|
| - scoped_refptr<SpdyStream> first_stream_;
|
| - scoped_refptr<SpdyStream> stream_;
|
| - CompletionCallback callback_;
|
| -};
|
| -
|
| -// TODO(kristianm): Could also test with more sessions where some are idle,
|
| -// and more than one session to a HostPortPair.
|
| -TEST_F(SpdySessionTest, CloseIdleSessions) {
|
| - SpdySessionDependencies session_deps;
|
| - scoped_refptr<HttpNetworkSession> http_session(
|
| - SpdySessionDependencies::SpdyCreateSession(&session_deps));
|
| - SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
|
| -
|
| - // Set up session 1
|
| - const std::string kTestHost1("http://www.a.com");
|
| - HostPortPair test_host_port_pair1(kTestHost1, 80);
|
| - HostPortProxyPair pair1(test_host_port_pair1, ProxyServer::Direct());
|
| - scoped_refptr<SpdySession> session1 =
|
| - spdy_session_pool->Get(pair1, BoundNetLog());
|
| - scoped_refptr<SpdyStream> spdy_stream1;
|
| - TestCompletionCallback callback1;
|
| - GURL url1(kTestHost1);
|
| - EXPECT_EQ(OK, session1->CreateStream(url1,
|
| - MEDIUM, /* priority, not important */
|
| - &spdy_stream1,
|
| - BoundNetLog(),
|
| - callback1.callback()));
|
| -
|
| - // Set up session 2
|
| - const std::string kTestHost2("http://www.b.com");
|
| - HostPortPair test_host_port_pair2(kTestHost2, 80);
|
| - HostPortProxyPair pair2(test_host_port_pair2, ProxyServer::Direct());
|
| - scoped_refptr<SpdySession> session2 =
|
| - spdy_session_pool->Get(pair2, BoundNetLog());
|
| - scoped_refptr<SpdyStream> spdy_stream2;
|
| - TestCompletionCallback callback2;
|
| - GURL url2(kTestHost2);
|
| - EXPECT_EQ(OK, session2->CreateStream(
|
| - url2, MEDIUM, /* priority, not important */
|
| - &spdy_stream2, BoundNetLog(), callback2.callback()));
|
| -
|
| - // Set up session 3
|
| - const std::string kTestHost3("http://www.c.com");
|
| - HostPortPair test_host_port_pair3(kTestHost3, 80);
|
| - HostPortProxyPair pair3(test_host_port_pair3, ProxyServer::Direct());
|
| - scoped_refptr<SpdySession> session3 =
|
| - spdy_session_pool->Get(pair3, BoundNetLog());
|
| - scoped_refptr<SpdyStream> spdy_stream3;
|
| - TestCompletionCallback callback3;
|
| - GURL url3(kTestHost3);
|
| - EXPECT_EQ(OK, session3->CreateStream(
|
| - url3, MEDIUM, /* priority, not important */
|
| - &spdy_stream3, BoundNetLog(), callback3.callback()));
|
| -
|
| - // All sessions are active and not closed
|
| - EXPECT_TRUE(session1->is_active());
|
| - EXPECT_FALSE(session1->IsClosed());
|
| - EXPECT_TRUE(session2->is_active());
|
| - EXPECT_FALSE(session2->IsClosed());
|
| - EXPECT_TRUE(session3->is_active());
|
| - EXPECT_FALSE(session3->IsClosed());
|
| -
|
| - // Should not do anything, all are active
|
| - spdy_session_pool->CloseIdleSessions();
|
| - EXPECT_TRUE(session1->is_active());
|
| - EXPECT_FALSE(session1->IsClosed());
|
| - EXPECT_TRUE(session2->is_active());
|
| - EXPECT_FALSE(session2->IsClosed());
|
| - EXPECT_TRUE(session3->is_active());
|
| - EXPECT_FALSE(session3->IsClosed());
|
| -
|
| - // Make sessions 1 and 3 inactive, but keep them open.
|
| - // Session 2 still open and active
|
| - session1->CloseStream(spdy_stream1->stream_id(), OK);
|
| - session3->CloseStream(spdy_stream3->stream_id(), OK);
|
| - EXPECT_FALSE(session1->is_active());
|
| - EXPECT_FALSE(session1->IsClosed());
|
| - EXPECT_TRUE(session2->is_active());
|
| - EXPECT_FALSE(session2->IsClosed());
|
| - EXPECT_FALSE(session3->is_active());
|
| - EXPECT_FALSE(session3->IsClosed());
|
| -
|
| - // Should close session 1 and 3, 2 should be left open
|
| - spdy_session_pool->CloseIdleSessions();
|
| - EXPECT_FALSE(session1->is_active());
|
| - EXPECT_TRUE(session1->IsClosed());
|
| - EXPECT_TRUE(session2->is_active());
|
| - EXPECT_FALSE(session2->IsClosed());
|
| - EXPECT_FALSE(session3->is_active());
|
| - EXPECT_TRUE(session3->IsClosed());
|
| -
|
| - // Should not do anything
|
| - spdy_session_pool->CloseIdleSessions();
|
| - EXPECT_TRUE(session2->is_active());
|
| - EXPECT_FALSE(session2->IsClosed());
|
| -
|
| - // Make 2 not active
|
| - session2->CloseStream(spdy_stream2->stream_id(), OK);
|
| - EXPECT_FALSE(session2->is_active());
|
| - EXPECT_FALSE(session2->IsClosed());
|
| -
|
| - // This should close session 2
|
| - spdy_session_pool->CloseIdleSessions();
|
| - EXPECT_FALSE(session2->is_active());
|
| - EXPECT_TRUE(session2->IsClosed());
|
| -}
|
| -
|
| -// Start with max concurrent streams set to 1. Request two streams. Receive a
|
| -// settings frame setting max concurrent streams to 2. Have the callback
|
| -// release the stream, which releases its reference (the last) to the session.
|
| -// Make sure nothing blows up.
|
| -// http://crbug.com/57331
|
| -TEST_F(SpdySessionTest, OnSettings) {
|
| - SpdySessionDependencies session_deps;
|
| - session_deps.host_resolver->set_synchronous_mode(true);
|
| -
|
| - spdy::SpdySettings new_settings;
|
| - spdy::SettingsFlagsAndId id(0);
|
| - id.set_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS);
|
| - const size_t max_concurrent_streams = 2;
|
| - new_settings.push_back(spdy::SpdySetting(id, max_concurrent_streams));
|
| -
|
| - // Set up the socket so we read a SETTINGS frame that raises max concurrent
|
| - // streams to 2.
|
| - MockConnect connect_data(SYNCHRONOUS, OK);
|
| - scoped_ptr<spdy::SpdyFrame> settings_frame(
|
| - ConstructSpdySettings(new_settings));
|
| - MockRead reads[] = {
|
| - CreateMockRead(*settings_frame),
|
| - MockRead(SYNCHRONOUS, 0, 0) // EOF
|
| - };
|
| -
|
| - StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
|
| - data.set_connect_data(connect_data);
|
| - session_deps.socket_factory->AddSocketDataProvider(&data);
|
| -
|
| - SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
|
| - session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
|
| -
|
| - scoped_refptr<HttpNetworkSession> http_session(
|
| - SpdySessionDependencies::SpdyCreateSession(&session_deps));
|
| -
|
| - const std::string kTestHost("www.foo.com");
|
| - const int kTestPort = 80;
|
| - HostPortPair test_host_port_pair(kTestHost, kTestPort);
|
| - HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
|
| -
|
| - // Initialize the SpdySettingsStorage with 1 max concurrent streams.
|
| - SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
|
| - spdy::SpdySettings old_settings;
|
| - id.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST);
|
| - old_settings.push_back(spdy::SpdySetting(id, 1));
|
| - spdy_session_pool->http_server_properties()->SetSpdySettings(
|
| - test_host_port_pair, old_settings);
|
| -
|
| - // Create a session.
|
| - EXPECT_FALSE(spdy_session_pool->HasSession(pair));
|
| - scoped_refptr<SpdySession> session =
|
| - spdy_session_pool->Get(pair, BoundNetLog());
|
| - ASSERT_TRUE(spdy_session_pool->HasSession(pair));
|
| -
|
| - scoped_refptr<TransportSocketParams> transport_params(
|
| - new TransportSocketParams(test_host_port_pair,
|
| - MEDIUM,
|
| - false,
|
| - false));
|
| - scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
|
| - EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
|
| - transport_params, MEDIUM, CompletionCallback(),
|
| - http_session->GetTransportSocketPool(),
|
| - BoundNetLog()));
|
| - EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
|
| -
|
| - // Create 2 streams. First will succeed. Second will be pending.
|
| - scoped_refptr<SpdyStream> spdy_stream1;
|
| - TestCompletionCallback callback1;
|
| - GURL url("http://www.google.com");
|
| - EXPECT_EQ(OK,
|
| - session->CreateStream(url,
|
| - MEDIUM, /* priority, not important */
|
| - &spdy_stream1,
|
| - BoundNetLog(),
|
| - callback1.callback()));
|
| -
|
| - StreamReleaserCallback stream_releaser(session, spdy_stream1);
|
| -
|
| - ASSERT_EQ(ERR_IO_PENDING,
|
| - session->CreateStream(url,
|
| - MEDIUM, /* priority, not important */
|
| - stream_releaser.stream(),
|
| - BoundNetLog(),
|
| - stream_releaser.callback()));
|
| -
|
| - // Make sure |stream_releaser| holds the last refs.
|
| - session = NULL;
|
| - spdy_stream1 = NULL;
|
| -
|
| - EXPECT_EQ(OK, stream_releaser.WaitForResult());
|
| -}
|
| -
|
| -// Start with max concurrent streams set to 1. Request two streams. When the
|
| -// first completes, have the callback close itself, which should trigger the
|
| -// second stream creation. Then cancel that one immediately. Don't crash.
|
| -// http://crbug.com/63532
|
| -TEST_F(SpdySessionTest, CancelPendingCreateStream) {
|
| - SpdySessionDependencies session_deps;
|
| - session_deps.host_resolver->set_synchronous_mode(true);
|
| -
|
| - MockRead reads[] = {
|
| - MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
|
| - };
|
| -
|
| - StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
|
| - MockConnect connect_data(SYNCHRONOUS, OK);
|
| -
|
| - data.set_connect_data(connect_data);
|
| - session_deps.socket_factory->AddSocketDataProvider(&data);
|
| -
|
| - SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
|
| - session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
|
| -
|
| - scoped_refptr<HttpNetworkSession> http_session(
|
| - SpdySessionDependencies::SpdyCreateSession(&session_deps));
|
| -
|
| - const std::string kTestHost("www.foo.com");
|
| - const int kTestPort = 80;
|
| - HostPortPair test_host_port_pair(kTestHost, kTestPort);
|
| - HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
|
| -
|
| - // Initialize the SpdySettingsStorage with 1 max concurrent streams.
|
| - SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
|
| - spdy::SpdySettings settings;
|
| - spdy::SettingsFlagsAndId id(0);
|
| - id.set_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS);
|
| - id.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST);
|
| - settings.push_back(spdy::SpdySetting(id, 1));
|
| - spdy_session_pool->http_server_properties()->SetSpdySettings(
|
| - test_host_port_pair, settings);
|
| -
|
| - // Create a session.
|
| - EXPECT_FALSE(spdy_session_pool->HasSession(pair));
|
| - scoped_refptr<SpdySession> session =
|
| - spdy_session_pool->Get(pair, BoundNetLog());
|
| - ASSERT_TRUE(spdy_session_pool->HasSession(pair));
|
| -
|
| - scoped_refptr<TransportSocketParams> transport_params(
|
| - new TransportSocketParams(test_host_port_pair,
|
| - MEDIUM,
|
| - false,
|
| - false));
|
| - scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
|
| - EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
|
| - transport_params, MEDIUM, CompletionCallback(),
|
| - http_session->GetTransportSocketPool(),
|
| - BoundNetLog()));
|
| - EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
|
| -
|
| - // Use scoped_ptr to let us invalidate the memory when we want to, to trigger
|
| - // a valgrind error if the callback is invoked when it's not supposed to be.
|
| - scoped_ptr<TestCompletionCallback> callback(new TestCompletionCallback);
|
| -
|
| - // Create 2 streams. First will succeed. Second will be pending.
|
| - scoped_refptr<SpdyStream> spdy_stream1;
|
| - GURL url("http://www.google.com");
|
| - ASSERT_EQ(OK,
|
| - session->CreateStream(url,
|
| - MEDIUM, /* priority, not important */
|
| - &spdy_stream1,
|
| - BoundNetLog(),
|
| - callback->callback()));
|
| -
|
| - scoped_refptr<SpdyStream> spdy_stream2;
|
| - ASSERT_EQ(ERR_IO_PENDING,
|
| - session->CreateStream(url,
|
| - MEDIUM, /* priority, not important */
|
| - &spdy_stream2,
|
| - BoundNetLog(),
|
| - callback->callback()));
|
| -
|
| - // Release the first one, this will allow the second to be created.
|
| - spdy_stream1->Cancel();
|
| - spdy_stream1 = NULL;
|
| -
|
| - session->CancelPendingCreateStreams(&spdy_stream2);
|
| - callback.reset();
|
| -
|
| - // Should not crash when running the pending callback.
|
| - MessageLoop::current()->RunAllPending();
|
| -}
|
| -
|
| -TEST_F(SpdySessionTest, SendSettingsOnNewSession) {
|
| - SpdySessionDependencies session_deps;
|
| - session_deps.host_resolver->set_synchronous_mode(true);
|
| -
|
| - MockRead reads[] = {
|
| - MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
|
| - };
|
| -
|
| - // Create the bogus setting that we want to verify is sent out.
|
| - // Note that it will be marked as SETTINGS_FLAG_PERSISTED when sent out. But
|
| - // to set it into the SpdySettingsStorage, we need to mark as
|
| - // SETTINGS_FLAG_PLEASE_PERSIST.
|
| - spdy::SpdySettings settings;
|
| - const uint32 kBogusSettingId = 0xABAB;
|
| - const uint32 kBogusSettingValue = 0xCDCD;
|
| - spdy::SettingsFlagsAndId id(0);
|
| - id.set_id(kBogusSettingId);
|
| - id.set_flags(spdy::SETTINGS_FLAG_PERSISTED);
|
| - settings.push_back(spdy::SpdySetting(id, kBogusSettingValue));
|
| - MockConnect connect_data(SYNCHRONOUS, OK);
|
| - scoped_ptr<spdy::SpdyFrame> settings_frame(
|
| - ConstructSpdySettings(settings));
|
| - MockWrite writes[] = {
|
| - CreateMockWrite(*settings_frame),
|
| - };
|
| -
|
| - StaticSocketDataProvider data(
|
| - reads, arraysize(reads), writes, arraysize(writes));
|
| - data.set_connect_data(connect_data);
|
| - session_deps.socket_factory->AddSocketDataProvider(&data);
|
| -
|
| - SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
|
| - session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
|
| -
|
| - scoped_refptr<HttpNetworkSession> http_session(
|
| - SpdySessionDependencies::SpdyCreateSession(&session_deps));
|
| -
|
| - const std::string kTestHost("www.foo.com");
|
| - const int kTestPort = 80;
|
| - HostPortPair test_host_port_pair(kTestHost, kTestPort);
|
| - HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
|
| -
|
| - id.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST);
|
| - settings.clear();
|
| - settings.push_back(spdy::SpdySetting(id, kBogusSettingValue));
|
| - SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
|
| - spdy_session_pool->http_server_properties()->SetSpdySettings(
|
| - test_host_port_pair, settings);
|
| - EXPECT_FALSE(spdy_session_pool->HasSession(pair));
|
| - scoped_refptr<SpdySession> session =
|
| - spdy_session_pool->Get(pair, BoundNetLog());
|
| - EXPECT_TRUE(spdy_session_pool->HasSession(pair));
|
| -
|
| - scoped_refptr<TransportSocketParams> transport_params(
|
| - new TransportSocketParams(test_host_port_pair,
|
| - MEDIUM,
|
| - false,
|
| - false));
|
| - scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
|
| - EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
|
| - transport_params, MEDIUM, CompletionCallback(),
|
| - http_session->GetTransportSocketPool(),
|
| - BoundNetLog()));
|
| - EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
|
| - MessageLoop::current()->RunAllPending();
|
| - EXPECT_TRUE(data.at_write_eof());
|
| -}
|
| -
|
| -// This test has two variants, one for each style of closing the connection.
|
| -// If |clean_via_close_current_sessions| is false, the sessions are closed
|
| -// manually, calling SpdySessionPool::Remove() directly. If it is true,
|
| -// sessions are closed with SpdySessionPool::CloseCurrentSessions().
|
| -void IPPoolingTest(bool clean_via_close_current_sessions) {
|
| - const int kTestPort = 80;
|
| - struct TestHosts {
|
| - std::string name;
|
| - std::string iplist;
|
| - HostPortProxyPair pair;
|
| - AddressList addresses;
|
| - } test_hosts[] = {
|
| - { "www.foo.com", "192.0.2.33,192.168.0.1,192.168.0.5" },
|
| - { "images.foo.com", "192.168.0.2,192.168.0.3,192.168.0.5,192.0.2.33" },
|
| - { "js.foo.com", "192.168.0.4,192.168.0.3" },
|
| - };
|
| -
|
| - SpdySessionDependencies session_deps;
|
| - session_deps.host_resolver->set_synchronous_mode(true);
|
| - for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_hosts); i++) {
|
| - session_deps.host_resolver->rules()->AddIPLiteralRule(test_hosts[i].name,
|
| - test_hosts[i].iplist, "");
|
| -
|
| - // This test requires that the HostResolver cache be populated. Normal
|
| - // code would have done this already, but we do it manually.
|
| - HostResolver::RequestInfo info(HostPortPair(test_hosts[i].name, kTestPort));
|
| - session_deps.host_resolver->Resolve(
|
| - info, &test_hosts[i].addresses, CompletionCallback(), NULL,
|
| - BoundNetLog());
|
| -
|
| - // Setup a HostPortProxyPair
|
| - test_hosts[i].pair = HostPortProxyPair(
|
| - HostPortPair(test_hosts[i].name, kTestPort), ProxyServer::Direct());
|
| - }
|
| -
|
| - MockConnect connect_data(SYNCHRONOUS, OK);
|
| - MockRead reads[] = {
|
| - MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
|
| - };
|
| -
|
| - StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
|
| - data.set_connect_data(connect_data);
|
| - session_deps.socket_factory->AddSocketDataProvider(&data);
|
| -
|
| - SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
|
| - session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
|
| -
|
| - scoped_refptr<HttpNetworkSession> http_session(
|
| - SpdySessionDependencies::SpdyCreateSession(&session_deps));
|
| -
|
| - // Setup the first session to the first host.
|
| - SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
|
| - EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[0].pair));
|
| - scoped_refptr<SpdySession> session =
|
| - spdy_session_pool->Get(test_hosts[0].pair, BoundNetLog());
|
| - EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[0].pair));
|
| -
|
| - HostPortPair test_host_port_pair(test_hosts[0].name, kTestPort);
|
| - scoped_refptr<TransportSocketParams> transport_params(
|
| - new TransportSocketParams(test_host_port_pair,
|
| - MEDIUM,
|
| - false,
|
| - false));
|
| - scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
|
| - EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
|
| - transport_params, MEDIUM, CompletionCallback(),
|
| - http_session->GetTransportSocketPool(),
|
| - BoundNetLog()));
|
| - EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
|
| -
|
| - // TODO(rtenneti): MockClientSocket::GetPeerAddress return's 0 as the port
|
| - // number. Fix it to return port 80 and then use GetPeerAddress to AddAlias.
|
| - const addrinfo* address = test_hosts[0].addresses.head();
|
| - SpdySessionPoolPeer pool_peer(spdy_session_pool);
|
| - pool_peer.AddAlias(address, test_hosts[0].pair);
|
| -
|
| - // Flush the SpdySession::OnReadComplete() task.
|
| - MessageLoop::current()->RunAllPending();
|
| -
|
| - // The third host has no overlap with the first, so it can't pool IPs.
|
| - EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[2].pair));
|
| -
|
| - // The second host overlaps with the first, and should IP pool.
|
| - EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[1].pair));
|
| -
|
| - // Verify that the second host, through a proxy, won't share the IP.
|
| - HostPortProxyPair proxy_pair(test_hosts[1].pair.first,
|
| - ProxyServer::FromPacString("HTTP http://proxy.foo.com/"));
|
| - EXPECT_FALSE(spdy_session_pool->HasSession(proxy_pair));
|
| -
|
| - // Overlap between 2 and 3 does is not transitive to 1.
|
| - EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[2].pair));
|
| -
|
| - // Create a new session to host 2.
|
| - scoped_refptr<SpdySession> session2 =
|
| - spdy_session_pool->Get(test_hosts[2].pair, BoundNetLog());
|
| -
|
| - // Verify that we have sessions for everything.
|
| - EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[0].pair));
|
| - EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[1].pair));
|
| - EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[2].pair));
|
| -
|
| - // Cleanup the sessions.
|
| - if (!clean_via_close_current_sessions) {
|
| - spdy_session_pool->Remove(session);
|
| - session = NULL;
|
| - spdy_session_pool->Remove(session2);
|
| - session2 = NULL;
|
| - } else {
|
| - spdy_session_pool->CloseCurrentSessions();
|
| - }
|
| -
|
| - // Verify that the map is all cleaned up.
|
| - EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[0].pair));
|
| - EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[1].pair));
|
| - EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[2].pair));
|
| -}
|
| -
|
| -TEST_F(SpdySessionTest, IPPooling) {
|
| - IPPoolingTest(false);
|
| -}
|
| -
|
| -TEST_F(SpdySessionTest, IPPoolingCloseCurrentSessions) {
|
| - IPPoolingTest(true);
|
| -}
|
| -
|
| -TEST_F(SpdySessionTest, ClearSettingsStorage) {
|
| - SpdySettingsStorage settings_storage;
|
| - const std::string kTestHost("www.foo.com");
|
| - const int kTestPort = 80;
|
| - HostPortPair test_host_port_pair(kTestHost, kTestPort);
|
| - spdy::SpdySettings test_settings;
|
| - spdy::SettingsFlagsAndId id(0);
|
| - id.set_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS);
|
| - id.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST);
|
| - const size_t max_concurrent_streams = 2;
|
| - test_settings.push_back(spdy::SpdySetting(id, max_concurrent_streams));
|
| -
|
| - settings_storage.Set(test_host_port_pair, test_settings);
|
| - EXPECT_NE(0u, settings_storage.Get(test_host_port_pair).size());
|
| - settings_storage.Clear();
|
| - EXPECT_EQ(0u, settings_storage.Get(test_host_port_pair).size());
|
| -}
|
| -
|
| -TEST_F(SpdySessionTest, ClearSettingsStorageOnIPAddressChanged) {
|
| - const std::string kTestHost("www.foo.com");
|
| - const int kTestPort = 80;
|
| - HostPortPair test_host_port_pair(kTestHost, kTestPort);
|
| -
|
| - SpdySessionDependencies session_deps;
|
| - scoped_refptr<HttpNetworkSession> http_session(
|
| - SpdySessionDependencies::SpdyCreateSession(&session_deps));
|
| - SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
|
| -
|
| - HttpServerProperties* test_http_server_properties =
|
| - spdy_session_pool->http_server_properties();
|
| - spdy::SettingsFlagsAndId id(0);
|
| - id.set_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS);
|
| - id.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST);
|
| - const size_t max_concurrent_streams = 2;
|
| - spdy::SpdySettings test_settings;
|
| - test_settings.push_back(spdy::SpdySetting(id, max_concurrent_streams));
|
| -
|
| - test_http_server_properties->SetSpdySettings(test_host_port_pair,
|
| - test_settings);
|
| - EXPECT_NE(0u, test_http_server_properties->GetSpdySettings(
|
| - test_host_port_pair).size());
|
| - spdy_session_pool->OnIPAddressChanged();
|
| - EXPECT_EQ(0u, test_http_server_properties->GetSpdySettings(
|
| - test_host_port_pair).size());
|
| -}
|
| -
|
| -TEST_F(SpdySessionTest, NeedsCredentials) {
|
| - SpdySessionDependencies session_deps;
|
| -
|
| - MockConnect connect_data(SYNCHRONOUS, OK);
|
| - MockRead reads[] = {
|
| - MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
|
| - };
|
| - StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
|
| - data.set_connect_data(connect_data);
|
| - session_deps.socket_factory->AddSocketDataProvider(&data);
|
| -
|
| - SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
|
| - ssl.origin_bound_cert_type = CLIENT_CERT_ECDSA_SIGN;
|
| - ssl.protocol_negotiated = SSLClientSocket::kProtoSPDY3;
|
| - session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
|
| -
|
| - scoped_refptr<HttpNetworkSession> http_session(
|
| - SpdySessionDependencies::SpdyCreateSession(&session_deps));
|
| -
|
| - const std::string kTestHost("www.foo.com");
|
| - const int kTestPort = 80;
|
| - HostPortPair test_host_port_pair(kTestHost, kTestPort);
|
| - HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
|
| -
|
| - SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
|
| - EXPECT_FALSE(spdy_session_pool->HasSession(pair));
|
| - scoped_refptr<SpdySession> session =
|
| - spdy_session_pool->Get(pair, BoundNetLog());
|
| - EXPECT_TRUE(spdy_session_pool->HasSession(pair));
|
| -
|
| - SSLConfig ssl_config;
|
| - scoped_refptr<TransportSocketParams> transport_params(
|
| - new TransportSocketParams(test_host_port_pair,
|
| - MEDIUM,
|
| - false,
|
| - false));
|
| - scoped_refptr<SOCKSSocketParams> socks_params;
|
| - scoped_refptr<HttpProxySocketParams> http_proxy_params;
|
| - scoped_refptr<SSLSocketParams> ssl_params(
|
| - new SSLSocketParams(transport_params,
|
| - socks_params,
|
| - http_proxy_params,
|
| - ProxyServer::SCHEME_DIRECT,
|
| - test_host_port_pair,
|
| - ssl_config,
|
| - 0,
|
| - false,
|
| - false));
|
| - scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
|
| - EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
|
| - ssl_params, MEDIUM, CompletionCallback(),
|
| - http_session->GetSSLSocketPool(),
|
| - BoundNetLog()));
|
| -
|
| - EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), true, OK));
|
| -
|
| - EXPECT_FALSE(session->NeedsCredentials(test_host_port_pair));
|
| - const std::string kTestHost2("www.bar.com");
|
| - HostPortPair test_host_port_pair2(kTestHost2, kTestPort);
|
| - EXPECT_TRUE(session->NeedsCredentials(test_host_port_pair2));
|
| -
|
| - // Flush the SpdySession::OnReadComplete() task.
|
| - MessageLoop::current()->RunAllPending();
|
| -
|
| - spdy_session_pool->Remove(session);
|
| - EXPECT_FALSE(spdy_session_pool->HasSession(pair));
|
| -}
|
| -
|
| -TEST_F(SpdySessionTest, SendCredentials) {
|
| - SpdySessionDependencies session_deps;
|
| -
|
| - MockConnect connect_data(SYNCHRONOUS, OK);
|
| - MockRead reads[] = {
|
| - MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
|
| - };
|
| - spdy::SpdySettings settings;
|
| - scoped_ptr<spdy::SpdyFrame> settings_frame(
|
| - ConstructSpdySettings(settings));
|
| - MockWrite writes[] = {
|
| - CreateMockWrite(*settings_frame),
|
| - };
|
| - StaticSocketDataProvider data(reads, arraysize(reads),
|
| - writes, arraysize(writes));
|
| - data.set_connect_data(connect_data);
|
| - session_deps.socket_factory->AddSocketDataProvider(&data);
|
| -
|
| - SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
|
| - ssl.origin_bound_cert_type = CLIENT_CERT_ECDSA_SIGN;
|
| - ssl.protocol_negotiated = SSLClientSocket::kProtoSPDY3;
|
| - session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
|
| -
|
| - scoped_refptr<HttpNetworkSession> http_session(
|
| - SpdySessionDependencies::SpdyCreateSession(&session_deps));
|
| -
|
| - const std::string kTestHost("www.foo.com");
|
| - const int kTestPort = 80;
|
| - HostPortPair test_host_port_pair(kTestHost, kTestPort);
|
| - HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
|
| -
|
| - SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
|
| - EXPECT_FALSE(spdy_session_pool->HasSession(pair));
|
| - scoped_refptr<SpdySession> session =
|
| - spdy_session_pool->Get(pair, BoundNetLog());
|
| - EXPECT_TRUE(spdy_session_pool->HasSession(pair));
|
| -
|
| - SSLConfig ssl_config;
|
| - scoped_refptr<TransportSocketParams> transport_params(
|
| - new TransportSocketParams(test_host_port_pair,
|
| - MEDIUM,
|
| - false,
|
| - false));
|
| - scoped_refptr<SOCKSSocketParams> socks_params;
|
| - scoped_refptr<HttpProxySocketParams> http_proxy_params;
|
| - scoped_refptr<SSLSocketParams> ssl_params(
|
| - new SSLSocketParams(transport_params,
|
| - socks_params,
|
| - http_proxy_params,
|
| - ProxyServer::SCHEME_DIRECT,
|
| - test_host_port_pair,
|
| - ssl_config,
|
| - 0,
|
| - false,
|
| - false));
|
| - scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
|
| - EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
|
| - ssl_params, MEDIUM, CompletionCallback(),
|
| - http_session->GetSSLSocketPool(),
|
| - BoundNetLog()));
|
| -
|
| - EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), true, OK));
|
| -
|
| - EXPECT_FALSE(session->NeedsCredentials(test_host_port_pair));
|
| - const std::string kTestHost2("www.bar.com");
|
| - HostPortPair test_host_port_pair2(kTestHost2, kTestPort);
|
| - EXPECT_TRUE(session->NeedsCredentials(test_host_port_pair2));
|
| -
|
| - // Flush the SpdySession::OnReadComplete() task.
|
| - MessageLoop::current()->RunAllPending();
|
| -
|
| - spdy_session_pool->Remove(session);
|
| - EXPECT_FALSE(spdy_session_pool->HasSession(pair));
|
| -}
|
| -
|
| -TEST_F(SpdySessionTest, CloseSessionOnError) {
|
| - SpdySessionDependencies session_deps;
|
| - session_deps.host_resolver->set_synchronous_mode(true);
|
| -
|
| - MockConnect connect_data(SYNCHRONOUS, OK);
|
| - scoped_ptr<spdy::SpdyFrame> goaway(ConstructSpdyGoAway());
|
| - MockRead reads[] = {
|
| - CreateMockRead(*goaway),
|
| - MockRead(SYNCHRONOUS, 0, 0) // EOF
|
| - };
|
| -
|
| - net::CapturingBoundNetLog log(net::CapturingNetLog::kUnbounded);
|
| -
|
| - StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
|
| - data.set_connect_data(connect_data);
|
| - session_deps.socket_factory->AddSocketDataProvider(&data);
|
| -
|
| - SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
|
| - session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
|
| -
|
| - scoped_refptr<HttpNetworkSession> http_session(
|
| - SpdySessionDependencies::SpdyCreateSession(&session_deps));
|
| -
|
| - const std::string kTestHost("www.foo.com");
|
| - const int kTestPort = 80;
|
| - HostPortPair test_host_port_pair(kTestHost, kTestPort);
|
| - HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
|
| -
|
| - SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
|
| - EXPECT_FALSE(spdy_session_pool->HasSession(pair));
|
| - scoped_refptr<SpdySession> session =
|
| - spdy_session_pool->Get(pair, log.bound());
|
| - EXPECT_TRUE(spdy_session_pool->HasSession(pair));
|
| -
|
| - scoped_refptr<TransportSocketParams> transport_params(
|
| - new TransportSocketParams(test_host_port_pair,
|
| - MEDIUM,
|
| - false,
|
| - false));
|
| - scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
|
| - EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
|
| - transport_params, MEDIUM, CompletionCallback(),
|
| - http_session->GetTransportSocketPool(),
|
| - log.bound()));
|
| - EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
|
| -
|
| - // Flush the SpdySession::OnReadComplete() task.
|
| - MessageLoop::current()->RunAllPending();
|
| -
|
| - EXPECT_FALSE(spdy_session_pool->HasSession(pair));
|
| -
|
| - // Check that the NetLog was filled reasonably.
|
| - net::CapturingNetLog::EntryList entries;
|
| - log.GetEntries(&entries);
|
| - EXPECT_LT(0u, entries.size());
|
| -
|
| - // Check that we logged SPDY_SESSION_CLOSE correctly.
|
| - int pos = net::ExpectLogContainsSomewhere(
|
| - entries, 0,
|
| - net::NetLog::TYPE_SPDY_SESSION_CLOSE,
|
| - net::NetLog::PHASE_NONE);
|
| -
|
| - CapturingNetLog::Entry entry = entries[pos];
|
| - NetLogSpdySessionCloseParameter* request_params =
|
| - static_cast<NetLogSpdySessionCloseParameter*>(
|
| - entry.extra_parameters.get());
|
| - EXPECT_EQ(ERR_CONNECTION_CLOSED, request_params->status());
|
| -}
|
| -
|
| -} // namespace net
|
|
|