| Index: net/spdy/spdy_proxy_client_socket.cc
|
| diff --git a/net/spdy/spdy_proxy_client_socket.cc b/net/spdy/spdy_proxy_client_socket.cc
|
| index 7b2c83bbc83d558cd9360f10490dd89ead5005f7..9dd5145b2168d352c91f76b2c61268eddd739688 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*/) {
|
|
|