static const char kMsg1[] = "\0hello!\xff";
static const int kLen1 = 8;
-static const char kMsg2[] = "\00012345678\0";
+static const char kMsg2[] = "\0a2345678\0";
static const int kLen2 = 10;
static const char kMsg3[] = "bye!";
static const int kLen3 = 4;
protected:
void Initialize(MockRead* reads, size_t reads_count, MockWrite* writes,
size_t writes_count);
+ void PopulateConnectRequestIR(SpdyHeaderBlock* syn_ir);
+ void PopulateConnectReplyIR(SpdyHeaderBlock* block, const char* status);
SpdyFrame* ConstructConnectRequestFrame();
SpdyFrame* ConstructConnectAuthRequestFrame();
SpdyFrame* ConstructConnectReplyFrame();
NextProto,
SpdyProxyClientSocketTest,
testing::Values(kProtoDeprecatedSPDY2,
- kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2,
- kProtoHTTP2Draft04));
+ kProtoSPDY3, kProtoSPDY31, kProtoSPDY4));
SpdyProxyClientSocketTest::SpdyProxyClientSocketTest()
: spdy_util_(GetParam()),
proxy_(ProxyServer::SCHEME_HTTPS, proxy_host_port_),
endpoint_spdy_session_key_(endpoint_host_port_pair_,
proxy_,
- kPrivacyModeDisabled) {
+ PRIVACY_MODE_DISABLED) {
session_deps_.net_log = net_log_.bound().net_log();
}
void SpdyProxyClientSocketTest::TearDown() {
- sock_.reset(NULL);
if (session_.get() != NULL)
session_->spdy_session_pool()->CloseAllSessions();
const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
ASSERT_TRUE(response != NULL);
ASSERT_EQ(200, response->headers->response_code());
- ASSERT_EQ("Connection Established", response->headers->GetStatusText());
}
void SpdyProxyClientSocketTest::AssertSyncReadEquals(const char* data,
write_callback_.WaitForResult();
}
+void SpdyProxyClientSocketTest::PopulateConnectRequestIR(
+ SpdyHeaderBlock* block) {
+ (*block)[spdy_util_.GetMethodKey()] = "CONNECT";
+ (*block)[spdy_util_.GetPathKey()] = kOriginHostPort;
+ (*block)[spdy_util_.GetHostKey()] = kOriginHost;
+ (*block)["user-agent"] = kUserAgent;
+ spdy_util_.MaybeAddVersionHeader(block);
+}
+
+void SpdyProxyClientSocketTest::PopulateConnectReplyIR(SpdyHeaderBlock* block,
+ const char* status) {
+ (*block)[spdy_util_.GetStatusKey()] = status;
+ spdy_util_.MaybeAddVersionHeader(block);
+}
+
// Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
SpdyFrame*
SpdyProxyClientSocketTest::ConstructConnectRequestFrame() {
- const SpdyHeaderInfo kSynStartHeader = {
- SYN_STREAM,
- kStreamId,
- 0,
- net::ConvertRequestPriorityToSpdyPriority(
- LOWEST, spdy_util_.spdy_version()),
- 0,
- CONTROL_FLAG_NONE,
- false,
- RST_STREAM_INVALID,
- NULL,
- 0,
- DATA_FLAG_NONE
- };
- bool spdy2 = spdy_util_.is_spdy2();
- const char* const kConnectHeaders[] = {
- spdy2 ? "method" : ":method", "CONNECT",
- spdy2 ? "url" : ":path", kOriginHostPort,
- spdy2 ? "host" : ":host", kOriginHost,
- "user-agent", kUserAgent,
- spdy2 ? "version" : ":version", "HTTP/1.1",
- };
- return spdy_util_.ConstructSpdyFrame(
- kSynStartHeader, NULL, 0, kConnectHeaders, arraysize(kConnectHeaders)/2);
+ SpdyHeaderBlock block;
+ PopulateConnectRequestIR(&block);
+ return spdy_util_.ConstructSpdySyn(kStreamId, block, LOWEST, false, false);
}
// Constructs a SPDY SYN_STREAM frame for a CONNECT request which includes
// Proxy-Authorization headers.
-SpdyFrame*
-SpdyProxyClientSocketTest::ConstructConnectAuthRequestFrame() {
- const SpdyHeaderInfo kSynStartHeader = {
- SYN_STREAM,
- kStreamId,
- 0,
- net::ConvertRequestPriorityToSpdyPriority(
- LOWEST, spdy_util_.spdy_version()),
- 0,
- CONTROL_FLAG_NONE,
- false,
- RST_STREAM_INVALID,
- NULL,
- 0,
- DATA_FLAG_NONE
- };
- bool spdy2 = spdy_util_.is_spdy2();
- const char* const kConnectHeaders[] = {
- spdy2 ? "method" : ":method", "CONNECT",
- spdy2 ? "url" : ":path", kOriginHostPort,
- spdy2 ? "host" : ":host", kOriginHost,
- "user-agent", kUserAgent,
- spdy2 ? "version" : ":version", "HTTP/1.1",
- "proxy-authorization", "Basic Zm9vOmJhcg==",
- };
- return spdy_util_.ConstructSpdyFrame(
- kSynStartHeader, NULL, 0, kConnectHeaders, arraysize(kConnectHeaders)/2);
+SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectAuthRequestFrame() {
+ SpdyHeaderBlock block;
+ PopulateConnectRequestIR(&block);
+ block["proxy-authorization"] = "Basic Zm9vOmJhcg==";
+ return spdy_util_.ConstructSpdySyn(kStreamId, block, LOWEST, false, false);
}
// Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectReplyFrame() {
- bool spdy2 = spdy_util_.is_spdy2();
- const char* const kStandardReplyHeaders[] = {
- spdy2 ? "status" : ":status", "200 Connection Established",
- spdy2 ? "version" : ":version", "HTTP/1.1"
- };
- return spdy_util_.ConstructSpdyControlFrame(NULL,
- 0,
- false,
- kStreamId,
- LOWEST,
- SYN_REPLY,
- CONTROL_FLAG_NONE,
- kStandardReplyHeaders,
- arraysize(kStandardReplyHeaders),
- 0);
+ SpdyHeaderBlock block;
+ PopulateConnectReplyIR(&block, "200");
+ SpdySynReplyIR reply_ir(kStreamId);
+ return spdy_util_.ConstructSpdyReply(kStreamId, block);
}
-// Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
-SpdyFrame*
-SpdyProxyClientSocketTest::ConstructConnectAuthReplyFrame() {
- bool spdy2 = spdy_util_.is_spdy2();
-
- const char* const kStandardReplyHeaders[] = {
- spdy2 ? "status" : ":status", "407 Proxy Authentication Required",
- spdy2 ? "version" : ":version", "HTTP/1.1",
- "proxy-authenticate", "Basic realm=\"MyRealm1\"",
- };
-
- return spdy_util_.ConstructSpdyControlFrame(NULL,
- 0,
- false,
- kStreamId,
- LOWEST,
- SYN_REPLY,
- CONTROL_FLAG_NONE,
- kStandardReplyHeaders,
- arraysize(kStandardReplyHeaders),
- 0);
+// Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT,
+// including Proxy-Authenticate headers.
+SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectAuthReplyFrame() {
+ SpdyHeaderBlock block;
+ PopulateConnectReplyIR(&block, "407");
+ block["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
+ return spdy_util_.ConstructSpdyReply(kStreamId, block);
}
// Constructs a SPDY SYN_REPLY frame with an HTTP 302 redirect.
-SpdyFrame*
-SpdyProxyClientSocketTest::ConstructConnectRedirectReplyFrame() {
- bool spdy2 = spdy_util_.is_spdy2();
-
- const char* const kStandardReplyHeaders[] = {
- spdy2 ? "status" : ":status", "302 Found",
- spdy2 ? "version" : ":version", "HTTP/1.1",
- "location", kRedirectUrl,
- "set-cookie", "foo=bar"
- };
-
- return spdy_util_.ConstructSpdyControlFrame(NULL,
- 0,
- false,
- kStreamId,
- LOWEST,
- SYN_REPLY,
- CONTROL_FLAG_NONE,
- kStandardReplyHeaders,
- arraysize(kStandardReplyHeaders),
- 0);
+SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectRedirectReplyFrame() {
+ SpdyHeaderBlock block;
+ PopulateConnectReplyIR(&block, "302");
+ block["location"] = kRedirectUrl;
+ block["set-cookie"] = "foo=bar";
+ return spdy_util_.ConstructSpdyReply(kStreamId, block);
}
// Constructs a SPDY SYN_REPLY frame with an HTTP 500 error.
-SpdyFrame*
-SpdyProxyClientSocketTest::ConstructConnectErrorReplyFrame() {
- bool spdy2 = spdy_util_.is_spdy2();
-
- const char* const kStandardReplyHeaders[] = {
- spdy2 ? "status" : ":status", "500 Internal Server Error",
- spdy2 ? "version" : ":version", "HTTP/1.1",
- };
-
- return spdy_util_.ConstructSpdyControlFrame(NULL,
- 0,
- false,
- kStreamId,
- LOWEST,
- SYN_REPLY,
- CONTROL_FLAG_NONE,
- kStandardReplyHeaders,
- arraysize(kStandardReplyHeaders),
- 0);
+SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectErrorReplyFrame() {
+ SpdyHeaderBlock block;
+ PopulateConnectReplyIR(&block, "500");
+ return spdy_util_.ConstructSpdyReply(kStreamId, block);
}
SpdyFrame* SpdyProxyClientSocketTest::ConstructBodyFrame(
const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
ASSERT_TRUE(response != NULL);
ASSERT_EQ(407, response->headers->response_code());
- ASSERT_EQ("Proxy Authentication Required",
- response->headers->GetStatusText());
}
TEST_P(SpdyProxyClientSocketTest, ConnectWithAuthCredentials) {
TEST_P(SpdyProxyClientSocketTest, ConnectRedirects) {
scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+ scoped_ptr<SpdyFrame> rst(
+ spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
MockWrite writes[] = {
- CreateMockWrite(*conn, 0, SYNCHRONOUS),
+ CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
};
scoped_ptr<SpdyFrame> resp(ConstructConnectRedirectReplyFrame());
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC),
- MockRead(ASYNC, 0, 2), // EOF
+ CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
std::string location;
ASSERT_TRUE(headers->IsRedirect(&location));
ASSERT_EQ(location, kRedirectUrl);
+
+ // Let the RST_STREAM write while |rst| is in-scope.
+ base::MessageLoop::current()->RunUntilIdle();
}
TEST_P(SpdyProxyClientSocketTest, ConnectFails) {
TEST_P(SpdyProxyClientSocketTest, WasEverUsedReturnsCorrectValues) {
scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+ scoped_ptr<SpdyFrame> rst(
+ spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
MockWrite writes[] = {
- CreateMockWrite(*conn, 0, SYNCHRONOUS),
+ CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
};
scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC),
- MockRead(ASYNC, 0, 2), // EOF
+ CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
EXPECT_TRUE(sock_->WasEverUsed());
sock_->Disconnect();
EXPECT_TRUE(sock_->WasEverUsed());
+
+ // Let the RST_STREAM write while |rst| is in-scope.
+ base::MessageLoop::current()->RunUntilIdle();
}
// ----------- GetPeerAddress
TEST_P(SpdyProxyClientSocketTest,
ReadOnDisconnectSocketReturnsNotConnected) {
scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+ scoped_ptr<SpdyFrame> rst(
+ spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
MockWrite writes[] = {
- CreateMockWrite(*conn, 0, SYNCHRONOUS),
+ CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
};
scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC),
- MockRead(ASYNC, 0, 2), // EOF
+ CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
sock_->Read(NULL, 1, CompletionCallback()));
+
+ // Let the RST_STREAM write while |rst| is in-scope.
+ base::MessageLoop::current()->RunUntilIdle();
}
// Reading buffered data from an already closed socket should return
// Calling Write() on a disconnected socket is an error
TEST_P(SpdyProxyClientSocketTest, WriteOnDisconnectedSocket) {
scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+ scoped_ptr<SpdyFrame> rst(
+ spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
MockWrite writes[] = {
- CreateMockWrite(*conn, 0, SYNCHRONOUS),
+ CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
};
scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC),
- MockRead(ASYNC, 0, 2), // EOF
+ CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
sock_->Write(buf.get(), buf->size(), CompletionCallback()));
+
+ // Let the RST_STREAM write while |rst| is in-scope.
+ base::MessageLoop::current()->RunUntilIdle();
}
// If the socket is closed with a pending Write(), the callback
// should not be called.
TEST_P(SpdyProxyClientSocketTest, DisconnectWithWritePending) {
scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+ scoped_ptr<SpdyFrame> rst(
+ spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
MockWrite writes[] = {
- CreateMockWrite(*conn, 0, SYNCHRONOUS),
- MockWrite(SYNCHRONOUS, 0, 2), // EOF
+ CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
+ MockWrite(SYNCHRONOUS, 0, 3), // EOF
};
scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC),
- MockRead(ASYNC, 0, 3), // EOF
+ CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 4), // EOF
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
EXPECT_FALSE(sock_->IsConnected());
EXPECT_FALSE(write_callback_.have_result());
+
+ // Let the RST_STREAM write while |rst| is in-scope.
+ base::MessageLoop::current()->RunUntilIdle();
}
// If the socket is Disconnected with a pending Read(), the callback
// should not be called.
TEST_P(SpdyProxyClientSocketTest, DisconnectWithReadPending) {
scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+ scoped_ptr<SpdyFrame> rst(
+ spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
MockWrite writes[] = {
- CreateMockWrite(*conn, 0, SYNCHRONOUS),
+ CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
};
scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC),
- MockRead(ASYNC, 0, 2), // EOF
+ CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
EXPECT_FALSE(sock_->IsConnected());
EXPECT_FALSE(read_callback_.have_result());
+
+ // Let the RST_STREAM write while |rst| is in-scope.
+ base::MessageLoop::current()->RunUntilIdle();
}
// If the socket is Reset when both a read and write are pending,
EXPECT_TRUE(sock_.get());
EXPECT_TRUE(read_callback_.have_result());
EXPECT_TRUE(write_callback_.have_result());
+
+ // Let the RST_STREAM write while |rst| is in-scope.
+ base::MessageLoop::current()->RunUntilIdle();
}
// Makes sure the proxy client socket's source gets the expected NetLog events
// and only the expected NetLog events (No SpdySession events).
TEST_P(SpdyProxyClientSocketTest, NetLog) {
scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+ scoped_ptr<SpdyFrame> rst(
+ spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
MockWrite writes[] = {
- CreateMockWrite(*conn, 0, SYNCHRONOUS),
+ CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 3),
};
scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC),
- CreateMockRead(*msg1, 2, ASYNC),
- MockRead(ASYNC, 0, 3), // EOF
+ CreateMockRead(*resp, 1, ASYNC), CreateMockRead(*msg1, 2, ASYNC),
+ MockRead(ASYNC, 0, 4), // EOF
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
NetLog::TYPE_SOCKET_BYTES_RECEIVED,
NetLog::PHASE_NONE));
EXPECT_TRUE(LogContainsEndEvent(entry_list, 9, NetLog::TYPE_SOCKET_ALIVE));
+
+ // Let the RST_STREAM write while |rst| is in-scope.
+ base::MessageLoop::current()->RunUntilIdle();
}
// CompletionCallback that causes the SpdyProxyClientSocket to be
EXPECT_FALSE(sock_.get());
EXPECT_TRUE(read_callback.have_result());
EXPECT_FALSE(write_callback_.have_result());
+
+ // Let the RST_STREAM write while |rst| is in-scope.
+ base::MessageLoop::current()->RunUntilIdle();
}
} // namespace net