diff options
Diffstat (limited to 'net/spdy')
-rw-r--r-- | net/spdy/spdy_proxy_client_socket.cc | 73 | ||||
-rw-r--r-- | net/spdy/spdy_proxy_client_socket.h | 6 |
2 files changed, 67 insertions, 12 deletions
diff --git a/net/spdy/spdy_proxy_client_socket.cc b/net/spdy/spdy_proxy_client_socket.cc index 7b2c83b..9dd5145 100644 --- a/net/spdy/spdy_proxy_client_socket.cc +++ b/net/spdy/spdy_proxy_client_socket.cc @@ -34,7 +34,7 @@ SpdyProxyClientSocket::SpdyProxyClientSocket( next_state_(STATE_DISCONNECTED), spdy_stream_(spdy_stream), old_read_callback_(NULL), - write_callback_(NULL), + old_write_callback_(NULL), endpoint_(endpoint), auth_( new HttpAuthController(HttpAuth::AUTH_PROXY, @@ -126,7 +126,8 @@ void SpdyProxyClientSocket::Disconnect() { write_buffer_len_ = 0; write_bytes_outstanding_ = 0; - write_callback_ = NULL; + old_write_callback_ = NULL; + write_callback_.Reset(); next_state_ = STATE_DISCONNECTED; @@ -244,7 +245,45 @@ int SpdyProxyClientSocket::PopulateUserReadBuffer() { int SpdyProxyClientSocket::Write(IOBuffer* buf, int buf_len, OldCompletionCallback* callback) { - DCHECK(!write_callback_); + DCHECK(!old_write_callback_ && write_callback_.is_null()); + if (next_state_ != STATE_OPEN) + return ERR_SOCKET_NOT_CONNECTED; + + DCHECK(spdy_stream_); + write_bytes_outstanding_= buf_len; + if (buf_len <= kMaxSpdyFrameChunkSize) { + int rv = spdy_stream_->WriteStreamData(buf, buf_len, spdy::DATA_FLAG_NONE); + if (rv == ERR_IO_PENDING) { + old_write_callback_ = callback; + write_buffer_len_ = buf_len; + } + return rv; + } + + // Since a SPDY Data frame can only include kMaxSpdyFrameChunkSize bytes + // we need to send multiple data frames + for (int i = 0; i < buf_len; i += kMaxSpdyFrameChunkSize) { + int len = std::min(kMaxSpdyFrameChunkSize, buf_len - i); + scoped_refptr<DrainableIOBuffer> iobuf(new DrainableIOBuffer(buf, i + len)); + iobuf->SetOffset(i); + int rv = spdy_stream_->WriteStreamData(iobuf, len, spdy::DATA_FLAG_NONE); + if (rv > 0) { + write_bytes_outstanding_ -= rv; + } else if (rv != ERR_IO_PENDING) { + return rv; + } + } + if (write_bytes_outstanding_ > 0) { + old_write_callback_ = callback; + write_buffer_len_ = buf_len; + return ERR_IO_PENDING; + } else { + return buf_len; + } +} +int SpdyProxyClientSocket::Write(IOBuffer* buf, int buf_len, + const CompletionCallback& callback) { + DCHECK(!old_write_callback_ && write_callback_.is_null()); if (next_state_ != STATE_OPEN) return ERR_SOCKET_NOT_CONNECTED; @@ -532,7 +571,7 @@ void SpdyProxyClientSocket::OnDataReceived(const char* data, int length) { } void SpdyProxyClientSocket::OnDataSent(int length) { - DCHECK(write_callback_); + DCHECK(old_write_callback_ || !write_callback_.is_null()); write_bytes_outstanding_ -= length; @@ -542,9 +581,15 @@ void SpdyProxyClientSocket::OnDataSent(int length) { int rv = write_buffer_len_; write_buffer_len_ = 0; write_bytes_outstanding_ = 0; - OldCompletionCallback* c = write_callback_; - write_callback_ = NULL; - c->Run(rv); + if (old_write_callback_) { + OldCompletionCallback* c = old_write_callback_; + old_write_callback_ = NULL; + c->Run(rv); + } else { + CompletionCallback c = write_callback_; + write_callback_.Reset(); + c.Run(rv); + } } } @@ -561,8 +606,10 @@ void SpdyProxyClientSocket::OnClose(int status) { next_state_ = STATE_DISCONNECTED; base::WeakPtr<SpdyProxyClientSocket> weak_ptr = weak_factory_.GetWeakPtr(); - OldCompletionCallback* write_callback = write_callback_; - write_callback_ = NULL; + OldCompletionCallback* old_write_callback = old_write_callback_; + CompletionCallback write_callback = write_callback_; + old_write_callback_ = NULL; + write_callback_.Reset(); write_buffer_len_ = 0; write_bytes_outstanding_ = 0; @@ -584,8 +631,12 @@ void SpdyProxyClientSocket::OnClose(int status) { OnDataReceived(NULL, 0); } // This may have been deleted by read_callback_, so check first. - if (weak_ptr && write_callback) - write_callback->Run(ERR_CONNECTION_CLOSED); + if (weak_ptr && (old_write_callback || !write_callback.is_null())) { + if (old_write_callback) + old_write_callback->Run(ERR_CONNECTION_CLOSED); + else + write_callback.Run(ERR_CONNECTION_CLOSED); + } } void SpdyProxyClientSocket::set_chunk_callback(ChunkCallback* /*callback*/) { diff --git a/net/spdy/spdy_proxy_client_socket.h b/net/spdy/spdy_proxy_client_socket.h index fb2d9a3..9fb97e8 100644 --- a/net/spdy/spdy_proxy_client_socket.h +++ b/net/spdy/spdy_proxy_client_socket.h @@ -84,6 +84,9 @@ class NET_EXPORT_PRIVATE SpdyProxyClientSocket : public ProxyClientSocket, virtual int Write(IOBuffer* buf, int buf_len, OldCompletionCallback* callback) OVERRIDE; + virtual int Write(IOBuffer* buf, + int buf_len, + const CompletionCallback& callback) OVERRIDE; virtual bool SetReceiveBufferSize(int32 size) OVERRIDE; virtual bool SetSendBufferSize(int32 size) OVERRIDE; virtual int GetPeerAddress(AddressList* address) const OVERRIDE; @@ -137,7 +140,8 @@ class NET_EXPORT_PRIVATE SpdyProxyClientSocket : public ProxyClientSocket, OldCompletionCallback* old_read_callback_; CompletionCallback read_callback_; // Stores the callback to the layer above, called on completing Write(). - OldCompletionCallback* write_callback_; + OldCompletionCallback* old_write_callback_; + CompletionCallback write_callback_; // CONNECT request and response. HttpRequestInfo request_; |