Commit 194c7a9c authored by rch@chromium.org's avatar rch@chromium.org

Fix crash bug in SpdyProxyClientSocket.GetPeerAddress where

spdy_stream_ was used when NULL.  We now copy the peer address
and local address from spdy_stream_ when we connect.

BUG=106073
TEST=SpdyProxyClientSocket.GetPeerAddressReturnsCorrectValue

Review URL: http://codereview.chromium.org/8771012

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@112871 0039d316-1c4b-4281-b951-d872f2087c98
parent c43b0dcb
...@@ -44,7 +44,6 @@ SpdyProxyClientSocket::SpdyProxyClientSocket( ...@@ -44,7 +44,6 @@ SpdyProxyClientSocket::SpdyProxyClientSocket(
user_buffer_(NULL), user_buffer_(NULL),
write_buffer_len_(0), write_buffer_len_(0),
write_bytes_outstanding_(0), write_bytes_outstanding_(0),
eof_has_been_read_(false),
ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
net_log_(spdy_stream->net_log()) { net_log_(spdy_stream->net_log()) {
request_.method = "CONNECT"; request_.method = "CONNECT";
...@@ -124,12 +123,11 @@ void SpdyProxyClientSocket::Disconnect() { ...@@ -124,12 +123,11 @@ void SpdyProxyClientSocket::Disconnect() {
} }
bool SpdyProxyClientSocket::IsConnected() const { bool SpdyProxyClientSocket::IsConnected() const {
return next_state_ == STATE_OPEN || next_state_ == STATE_CLOSED; return next_state_ == STATE_OPEN;
} }
bool SpdyProxyClientSocket::IsConnectedAndIdle() const { bool SpdyProxyClientSocket::IsConnectedAndIdle() const {
return IsConnected() && spdy_stream_.get() != NULL && return IsConnected() && read_buffer_.empty() && spdy_stream_->is_idle();
!spdy_stream_->is_idle();
} }
const BoundNetLog& SpdyProxyClientSocket::NetLog() const { const BoundNetLog& SpdyProxyClientSocket::NetLog() const {
...@@ -168,10 +166,7 @@ int SpdyProxyClientSocket::Read(IOBuffer* buf, int buf_len, ...@@ -168,10 +166,7 @@ int SpdyProxyClientSocket::Read(IOBuffer* buf, int buf_len,
if (next_state_ == STATE_DISCONNECTED) if (next_state_ == STATE_DISCONNECTED)
return ERR_SOCKET_NOT_CONNECTED; return ERR_SOCKET_NOT_CONNECTED;
if (!spdy_stream_ && read_buffer_.empty()) { if (next_state_ == STATE_CLOSED && read_buffer_.empty()) {
if (eof_has_been_read_)
return ERR_CONNECTION_CLOSED;
eof_has_been_read_ = true;
return 0; return 0;
} }
...@@ -212,12 +207,10 @@ int SpdyProxyClientSocket::PopulateUserReadBuffer() { ...@@ -212,12 +207,10 @@ int SpdyProxyClientSocket::PopulateUserReadBuffer() {
int SpdyProxyClientSocket::Write(IOBuffer* buf, int buf_len, int SpdyProxyClientSocket::Write(IOBuffer* buf, int buf_len,
OldCompletionCallback* callback) { OldCompletionCallback* callback) {
DCHECK(!write_callback_); DCHECK(!write_callback_);
if (next_state_ == STATE_DISCONNECTED) if (next_state_ != STATE_OPEN)
return ERR_SOCKET_NOT_CONNECTED; return ERR_SOCKET_NOT_CONNECTED;
if (!spdy_stream_) DCHECK(spdy_stream_);
return ERR_CONNECTION_CLOSED;
write_bytes_outstanding_= buf_len; write_bytes_outstanding_= buf_len;
if (buf_len <= kMaxSpdyFrameChunkSize) { if (buf_len <= kMaxSpdyFrameChunkSize) {
int rv = spdy_stream_->WriteStreamData(buf, buf_len, spdy::DATA_FLAG_NONE); int rv = spdy_stream_->WriteStreamData(buf, buf_len, spdy::DATA_FLAG_NONE);
......
...@@ -154,8 +154,6 @@ class NET_EXPORT_PRIVATE SpdyProxyClientSocket : public ProxyClientSocket, ...@@ -154,8 +154,6 @@ class NET_EXPORT_PRIVATE SpdyProxyClientSocket : public ProxyClientSocket,
// Number of bytes written which have not been confirmed // Number of bytes written which have not been confirmed
int write_bytes_outstanding_; int write_bytes_outstanding_;
// True if read has ever returned zero for eof.
bool eof_has_been_read_;
// True if the transport socket has ever sent data. // True if the transport socket has ever sent data.
bool was_ever_used_; bool was_ever_used_;
......
...@@ -149,6 +149,7 @@ SpdyProxyClientSocketTest::SpdyProxyClientSocketTest() ...@@ -149,6 +149,7 @@ SpdyProxyClientSocketTest::SpdyProxyClientSocketTest()
} }
void SpdyProxyClientSocketTest::TearDown() { void SpdyProxyClientSocketTest::TearDown() {
sock_.reset(NULL);
if (session_ != NULL) if (session_ != NULL)
session_->spdy_session_pool()->CloseAllSessions(); session_->spdy_session_pool()->CloseAllSessions();
...@@ -612,7 +613,13 @@ TEST_F(SpdyProxyClientSocketTest, GetPeerAddressReturnsCorrectValues) { ...@@ -612,7 +613,13 @@ TEST_F(SpdyProxyClientSocketTest, GetPeerAddressReturnsCorrectValues) {
EXPECT_TRUE(sock_->IsConnected()); EXPECT_TRUE(sock_->IsConnected());
EXPECT_EQ(OK, sock_->GetPeerAddress(&addr)); EXPECT_EQ(OK, sock_->GetPeerAddress(&addr));
Run(1);
EXPECT_FALSE(sock_->IsConnected());
EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
sock_->Disconnect(); sock_->Disconnect();
EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr)); EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
} }
...@@ -1022,9 +1029,10 @@ TEST_F(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsZero) { ...@@ -1022,9 +1029,10 @@ TEST_F(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsZero) {
Run(1); Run(1);
ASSERT_FALSE(sock_->IsConnected());
ASSERT_EQ(0, sock_->Read(NULL, 1, NULL));
ASSERT_EQ(0, sock_->Read(NULL, 1, NULL));
ASSERT_EQ(0, sock_->Read(NULL, 1, NULL)); ASSERT_EQ(0, sock_->Read(NULL, 1, NULL));
ASSERT_EQ(ERR_CONNECTION_CLOSED, sock_->Read(NULL, 1, NULL));
ASSERT_EQ(ERR_CONNECTION_CLOSED, sock_->Read(NULL, 1, NULL));
ASSERT_FALSE(sock_->IsConnectedAndIdle()); ASSERT_FALSE(sock_->IsConnectedAndIdle());
} }
...@@ -1096,11 +1104,15 @@ TEST_F(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsBufferedData) { ...@@ -1096,11 +1104,15 @@ TEST_F(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsBufferedData) {
Run(2); Run(2);
AssertSyncReadEquals(kMsg1, kLen1); ASSERT_FALSE(sock_->IsConnected());
scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
ASSERT_EQ(kLen1, sock_->Read(buf, kLen1, NULL));
ASSERT_EQ(std::string(kMsg1, kLen1), std::string(buf->data(), kLen1));
ASSERT_EQ(0, sock_->Read(NULL, 1, NULL)); ASSERT_EQ(0, sock_->Read(NULL, 1, NULL));
ASSERT_EQ(ERR_CONNECTION_CLOSED, sock_->Read(NULL, 1, NULL)); ASSERT_EQ(0, sock_->Read(NULL, 1, NULL));
// Verify that read *still* returns ERR_CONNECTION_CLOSED sock_->Disconnect();
ASSERT_EQ(ERR_CONNECTION_CLOSED, sock_->Read(NULL, 1, NULL)); ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->Read(NULL, 1, NULL));
} }
// Calling Write() on a closed socket is an error // Calling Write() on a closed socket is an error
...@@ -1123,7 +1135,7 @@ TEST_F(SpdyProxyClientSocketTest, WriteOnClosedStream) { ...@@ -1123,7 +1135,7 @@ TEST_F(SpdyProxyClientSocketTest, WriteOnClosedStream) {
Run(1); // Read EOF which will close the stream Run(1); // Read EOF which will close the stream
scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1)); scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
EXPECT_EQ(ERR_CONNECTION_CLOSED, sock_->Write(buf, buf->size(), NULL)); EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->Write(buf, buf->size(), NULL));
} }
// Calling Write() on a disconnected socket is an error // Calling Write() on a disconnected socket is an error
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment