summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/spdy/spdy_framer.h2
-rw-r--r--net/spdy/spdy_session.cc4
-rw-r--r--net/spdy/spdy_session.h2
-rw-r--r--net/spdy/spdy_session_unittest.cc88
4 files changed, 92 insertions, 4 deletions
diff --git a/net/spdy/spdy_framer.h b/net/spdy/spdy_framer.h
index 2471c36..2c95ae5 100644
--- a/net/spdy/spdy_framer.h
+++ b/net/spdy/spdy_framer.h
@@ -27,6 +27,7 @@ namespace net {
class HttpNetworkLayer;
class HttpNetworkTransactionTest;
class SpdyNetworkTransactionTest;
+class SpdySessionTest;
}
namespace spdy {
@@ -240,6 +241,7 @@ class SpdyFramer {
friend class net::SpdyNetworkTransactionTest;
friend class net::HttpNetworkTransactionTest;
friend class net::HttpNetworkLayer; // This is temporary for the server.
+ friend class net::SpdySessionTest;
friend class test::TestSpdyVisitor;
friend void test::FramerSetEnableCompressionHelper(SpdyFramer* framer,
bool compress);
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc
index ace8eaf..fe55454 100644
--- a/net/spdy/spdy_session.cc
+++ b/net/spdy/spdy_session.cc
@@ -854,11 +854,11 @@ scoped_refptr<SpdyStream> SpdySession::GetPushStream(const std::string& path) {
pushed_streams_.erase(it);
used_push_streams.Increment();
LOG(INFO) << "Push Stream Claim for: " << path;
- break;
+ return stream;
}
}
- return stream;
+ return NULL;
}
void SpdySession::GetSSLInfo(SSLInfo* ssl_info) {
diff --git a/net/spdy/spdy_session.h b/net/spdy/spdy_session.h
index de19186..cff7b82 100644
--- a/net/spdy/spdy_session.h
+++ b/net/spdy/spdy_session.h
@@ -25,6 +25,7 @@
#include "net/spdy/spdy_io_buffer.h"
#include "net/spdy/spdy_protocol.h"
#include "net/spdy/spdy_session_pool.h"
+#include "testing/gtest/include/gtest/gtest_prod.h" // For FRIEND_TEST
namespace net {
@@ -90,6 +91,7 @@ class SpdySession : public base::RefCounted<SpdySession>,
private:
friend class base::RefCounted<SpdySession>;
+ FRIEND_TEST(SpdySessionTest, GetPushStream);
enum State {
IDLE,
diff --git a/net/spdy/spdy_session_unittest.cc b/net/spdy/spdy_session_unittest.cc
index 433ea8c..feae372 100644
--- a/net/spdy/spdy_session_unittest.cc
+++ b/net/spdy/spdy_session_unittest.cc
@@ -18,6 +18,15 @@
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);
+ }
+};
+
namespace {
// Helper to manage the lifetimes of the dependencies for a
@@ -49,8 +58,6 @@ HttpNetworkSession* CreateSession(SessionDependencies* session_deps) {
NULL);
}
-typedef PlatformTest SpdySessionTest;
-
// Test the SpdyIOBuffer class.
TEST_F(SpdySessionTest, SpdyIOBuffer) {
std::priority_queue<SpdyIOBuffer> queue_;
@@ -146,6 +153,83 @@ TEST_F(SpdySessionTest, GoAway) {
session2 = NULL;
}
+// kPush is a server-issued SYN_STREAM with stream id 2, and
+// associated stream id 1. It also includes 3 headers of path,
+// status, and HTTP version.
+static const uint8 kPush[] = {
+ 0x80, 0x01, 0x00, 0x01, // SYN_STREAM for SPDY v1.
+ 0x00, 0x00, 0x00, 0x3b, // No flags 59 bytes after this 8 byte header.
+ 0x00, 0x00, 0x00, 0x02, // Stream ID of 2
+ 0x00, 0x00, 0x00, 0x01, // Associate Stream ID of 1
+ 0x00, 0x00, 0x00, 0x03, // Priority 0, 3 name/value pairs in block below.
+ 0x00, 0x04, 'p', 'a', 't', 'h',
+ 0x00, 0x07, '/', 'f', 'o', 'o', '.', 'j', 's',
+ 0x00, 0x06, 's', 't', 'a', 't', 'u', 's',
+ 0x00, 0x03, '2', '0', '0',
+ 0x00, 0x07, 'v', 'e', 'r', 's', 'i', 'o', 'n',
+ 0x00, 0x08, 'H', 'T', 'T', 'P', '/', '1', '.', '1',
+};
+
} // namespace
+TEST_F(SpdySessionTest, GetPushStream) {
+ SpdySessionTest::TurnOffCompression();
+
+ SessionDependencies session_deps;
+ session_deps.host_resolver->set_synchronous_mode(true);
+
+ MockConnect connect_data(false, OK);
+ MockRead reads[] = {
+ MockRead(false, reinterpret_cast<const char*>(kPush),
+ arraysize(kPush)),
+ MockRead(true, ERR_IO_PENDING, 0) // EOF
+ };
+ StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
+ data.set_connect_data(connect_data);
+ session_deps.socket_factory.AddSocketDataProvider(&data);
+
+ SSLSocketDataProvider ssl(false, OK);
+ session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
+
+ scoped_refptr<HttpNetworkSession> http_session(CreateSession(&session_deps));
+
+ const std::string kTestHost("www.foo.com");
+ const int kTestPort = 80;
+ HostPortPair test_host_port_pair;
+ test_host_port_pair.host = kTestHost;
+ test_host_port_pair.port = kTestPort;
+
+ scoped_refptr<SpdySessionPool> spdy_session_pool(
+ http_session->spdy_session_pool());
+ EXPECT_FALSE(spdy_session_pool->HasSession(test_host_port_pair));
+ scoped_refptr<SpdySession> session =
+ spdy_session_pool->Get(test_host_port_pair, http_session.get());
+ EXPECT_TRUE(spdy_session_pool->HasSession(test_host_port_pair));
+
+ // No push streams should exist in the beginning.
+ std::string test_push_path = "/foo.js";
+ scoped_refptr<SpdyStream> first_stream = session->GetPushStream(
+ test_push_path);
+ EXPECT_EQ(static_cast<SpdyStream*>(NULL), first_stream.get());
+
+ // Read in the data which contains a server-issued SYN_STREAM.
+ TCPSocketParams tcp_params(test_host_port_pair, MEDIUM, GURL(), false);
+ int rv = session->Connect(kTestHost, tcp_params, MEDIUM, BoundNetLog());
+ ASSERT_EQ(OK, rv);
+ MessageLoop::current()->RunAllPending();
+
+ // An unpushed path should not work.
+ scoped_refptr<SpdyStream> unpushed_stream = session->GetPushStream(
+ "/unpushed_path");
+ EXPECT_EQ(static_cast<SpdyStream*>(NULL), unpushed_stream.get());
+
+ // The pushed path should be found.
+ scoped_refptr<SpdyStream> second_stream = session->GetPushStream(
+ test_push_path);
+ ASSERT_NE(static_cast<SpdyStream*>(NULL), second_stream.get());
+ EXPECT_EQ(test_push_path, second_stream->path());
+ EXPECT_EQ(2U, second_stream->stream_id());
+ EXPECT_EQ(0, second_stream->priority());
+}
+
} // namespace net