| Index: net/socket_stream/socket_stream.cc
|
| diff --git a/net/socket_stream/socket_stream.cc b/net/socket_stream/socket_stream.cc
|
| index 1dcf1f841dd3ca04852df51c2bd2c8ffda959bee..a74eb13decf62d632636d4d262dce3fe081f40b7 100644
|
| --- a/net/socket_stream/socket_stream.cc
|
| +++ b/net/socket_stream/socket_stream.cc
|
| @@ -89,6 +89,7 @@ void SocketStream::Connect() {
|
| DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) <<
|
| "The current MessageLoop must be TYPE_IO";
|
| ssl_config_service()->GetSSLConfig(&ssl_config_);
|
| + DCHECK_EQ(next_state_, STATE_NONE);
|
|
|
| AddRef(); // Released in Finish()
|
| // Open a connection asynchronously, so that delegate won't be called
|
| @@ -104,7 +105,7 @@ bool SocketStream::SendData(const char* data, int len) {
|
| "The current MessageLoop must exist";
|
| DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) <<
|
| "The current MessageLoop must be TYPE_IO";
|
| - if (!socket_.get() || !socket_->IsConnected())
|
| + if (!socket_.get() || !socket_->IsConnected() || next_state_ == STATE_NONE)
|
| return false;
|
| if (write_buf_) {
|
| int current_amount_send = write_buf_size_ - write_buf_offset_;
|
| @@ -139,10 +140,10 @@ void SocketStream::Close() {
|
| "The current MessageLoop must exist";
|
| DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) <<
|
| "The current MessageLoop must be TYPE_IO";
|
| - if (!socket_.get())
|
| + if (!socket_.get() || !socket_->IsConnected() || next_state_ == STATE_NONE)
|
| return;
|
| - if (socket_->IsConnected())
|
| - socket_->Disconnect();
|
| + socket_->Disconnect();
|
| + next_state_ = STATE_CLOSE;
|
| // Close asynchronously, so that delegate won't be called
|
| // back before returning Close().
|
| MessageLoop::current()->PostTask(
|
| @@ -182,18 +183,23 @@ void SocketStream::DetachDelegate() {
|
| Close();
|
| }
|
|
|
| -void SocketStream::Finish() {
|
| +void SocketStream::Finish(int result) {
|
| DCHECK(MessageLoop::current()) <<
|
| "The current MessageLoop must exist";
|
| DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) <<
|
| "The current MessageLoop must be TYPE_IO";
|
| + DCHECK_LT(result, 0);
|
| + DCHECK_EQ(next_state_, STATE_NONE);
|
| DLOG(INFO) << "Finish";
|
| + if (delegate_)
|
| + delegate_->OnError(this, result);
|
| +
|
| Delegate* delegate = delegate_;
|
| delegate_ = NULL;
|
| if (delegate) {
|
| delegate->OnClose(this);
|
| - Release();
|
| }
|
| + Release();
|
| }
|
|
|
| void SocketStream::SetHostResolver(HostResolver* host_resolver) {
|
| @@ -207,17 +213,16 @@ void SocketStream::SetClientSocketFactory(
|
| factory_ = factory;
|
| }
|
|
|
| -void SocketStream::DidEstablishConnection() {
|
| +int SocketStream::DidEstablishConnection() {
|
| if (!socket_.get() || !socket_->IsConnected()) {
|
| - Finish();
|
| - return;
|
| + return ERR_CONNECTION_FAILED;
|
| }
|
| next_state_ = STATE_READ_WRITE;
|
|
|
| if (delegate_)
|
| delegate_->OnConnected(this, max_pending_send_allowed_);
|
|
|
| - return;
|
| + return OK;
|
| }
|
|
|
| void SocketStream::DidReceiveData(int result) {
|
| @@ -255,14 +260,12 @@ void SocketStream::DidSendData(int result) {
|
|
|
| void SocketStream::OnIOCompleted(int result) {
|
| DoLoop(result);
|
| - // TODO(ukai): notify error.
|
| }
|
|
|
| void SocketStream::OnReadCompleted(int result) {
|
| - // TODO(ukai): notify error.
|
| if (result == 0) {
|
| // 0 indicates end-of-file, so socket was closed.
|
| - next_state_ = STATE_NONE;
|
| + next_state_ = STATE_CLOSE;
|
| } else if (result > 0 && read_buf_) {
|
| DidReceiveData(result);
|
| result = OK;
|
| @@ -271,7 +274,6 @@ void SocketStream::OnReadCompleted(int result) {
|
| }
|
|
|
| void SocketStream::OnWriteCompleted(int result) {
|
| - // TODO(ukai): notify error.
|
| if (result >= 0 && write_buf_) {
|
| DidSendData(result);
|
| result = OK;
|
| @@ -279,11 +281,9 @@ void SocketStream::OnWriteCompleted(int result) {
|
| DoLoop(result);
|
| }
|
|
|
| -int SocketStream::DoLoop(int result) {
|
| - if (next_state_ == STATE_NONE) {
|
| - Finish();
|
| - return ERR_CONNECTION_CLOSED;
|
| - }
|
| +void SocketStream::DoLoop(int result) {
|
| + if (next_state_ == STATE_NONE)
|
| + return;
|
|
|
| do {
|
| State state = next_state_;
|
| @@ -341,17 +341,18 @@ int SocketStream::DoLoop(int result) {
|
| case STATE_READ_WRITE:
|
| result = DoReadWrite(result);
|
| break;
|
| + case STATE_CLOSE:
|
| + DCHECK_LE(result, OK);
|
| + if (result == OK)
|
| + result = ERR_CONNECTION_CLOSED;
|
| + Finish(result);
|
| + return;
|
| default:
|
| NOTREACHED() << "bad state";
|
| result = ERR_UNEXPECTED;
|
| break;
|
| }
|
| - } while (result != ERR_IO_PENDING && next_state_ != STATE_NONE);
|
| -
|
| - if (result != ERR_IO_PENDING)
|
| - Finish();
|
| -
|
| - return result;
|
| + } while (result != ERR_IO_PENDING);
|
| }
|
|
|
| int SocketStream::DoResolveProxy() {
|
| @@ -368,6 +369,8 @@ int SocketStream::DoResolveProxyComplete(int result) {
|
| pac_request_ = NULL;
|
| if (result != OK) {
|
| LOG(ERROR) << "Failed to resolve proxy: " << result;
|
| + if (delegate_)
|
| + delegate_->OnError(this, result);
|
| proxy_info_.UseDirect();
|
| }
|
|
|
| @@ -428,9 +431,9 @@ int SocketStream::DoTcpConnectComplete(int result) {
|
| else if (is_secure()) {
|
| next_state_ = STATE_SSL_CONNECT;
|
| } else {
|
| - DidEstablishConnection();
|
| + result = DidEstablishConnection();
|
| }
|
| - return OK;
|
| + return result;
|
| }
|
|
|
| int SocketStream::DoWriteTunnelHeaders() {
|
| @@ -532,8 +535,8 @@ int SocketStream::DoReadTunnelHeadersComplete(int result) {
|
|
|
| if (result == 0) {
|
| // 0 indicates end-of-file, so socket was closed.
|
| - Finish();
|
| - return result;
|
| + next_state_ = STATE_CLOSE;
|
| + return ERR_CONNECTION_CLOSED;
|
| }
|
|
|
| tunnel_response_headers_len_ += result;
|
| @@ -542,8 +545,10 @@ int SocketStream::DoReadTunnelHeadersComplete(int result) {
|
| int eoh = HttpUtil::LocateEndOfHeaders(
|
| tunnel_response_headers_->headers(), tunnel_response_headers_len_, 0);
|
| if (eoh == -1) {
|
| - if (tunnel_response_headers_len_ >= kMaxTunnelResponseHeadersSize)
|
| + if (tunnel_response_headers_len_ >= kMaxTunnelResponseHeadersSize) {
|
| + next_state_ = STATE_CLOSE;
|
| return ERR_RESPONSE_HEADERS_TOO_BIG;
|
| + }
|
|
|
| next_state_ = STATE_READ_TUNNEL_HEADERS;
|
| return OK;
|
| @@ -554,6 +559,7 @@ int SocketStream::DoReadTunnelHeadersComplete(int result) {
|
| HttpUtil::AssembleRawHeaders(tunnel_response_headers_->headers(), eoh));
|
| if (headers->GetParsedHttpVersion() < HttpVersion(1, 0)) {
|
| // Require the "HTTP/1.x" status line.
|
| + next_state_ = STATE_CLOSE;
|
| return ERR_TUNNEL_CONNECTION_FAILED;
|
| }
|
| switch (headers->response_code()) {
|
| @@ -562,7 +568,11 @@ int SocketStream::DoReadTunnelHeadersComplete(int result) {
|
| DCHECK_EQ(eoh, tunnel_response_headers_len_);
|
| next_state_ = STATE_SSL_CONNECT;
|
| } else {
|
| - DidEstablishConnection();
|
| + result = DidEstablishConnection();
|
| + if (result < 0) {
|
| + next_state_ = STATE_CLOSE;
|
| + return result;
|
| + }
|
| if ((eoh < tunnel_response_headers_len_) && delegate_)
|
| delegate_->OnReceivedData(
|
| this, tunnel_response_headers_->headers() + eoh,
|
| @@ -583,6 +593,7 @@ int SocketStream::DoReadTunnelHeadersComplete(int result) {
|
| MessageLoop::current()->PostTask(
|
| FROM_HERE,
|
| NewRunnableMethod(this, &SocketStream::DoAuthRequired));
|
| + next_state_ = STATE_AUTH_REQUIRED;
|
| return ERR_IO_PENDING;
|
| }
|
| default:
|
| @@ -633,17 +644,15 @@ int SocketStream::DoSSLConnectComplete(int result) {
|
| result = HandleCertificateError(result);
|
|
|
| if (result == OK)
|
| - DidEstablishConnection();
|
| + result = DidEstablishConnection();
|
| return result;
|
| }
|
|
|
| int SocketStream::DoReadWrite(int result) {
|
| if (result < OK) {
|
| - Finish();
|
| return result;
|
| }
|
| if (!socket_.get() || !socket_->IsConnected()) {
|
| - Finish();
|
| return ERR_CONNECTION_CLOSED;
|
| }
|
|
|
| @@ -658,7 +667,6 @@ int SocketStream::DoReadWrite(int result) {
|
| return OK;
|
| } else if (result == 0) {
|
| // 0 indicates end-of-file, so socket was closed.
|
| - Finish();
|
| return ERR_CONNECTION_CLOSED;
|
| }
|
| // If read is pending, try write as well.
|
| @@ -746,6 +754,7 @@ void SocketStream::DoAuthRequired() {
|
| }
|
|
|
| void SocketStream::DoRestartWithAuth() {
|
| + DCHECK_EQ(next_state_, STATE_AUTH_REQUIRED);
|
| auth_cache_.Add(ProxyAuthOrigin(), auth_handler_,
|
| auth_identity_.username, auth_identity_.password,
|
| std::string());
|
|
|