| 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..45c3c4a173b563a59f7681ecdb2d06dbccccf153 100644
|
| --- a/net/socket_stream/socket_stream.cc
|
| +++ b/net/socket_stream/socket_stream.cc
|
| @@ -143,6 +143,7 @@ void SocketStream::Close() {
|
| return;
|
| if (socket_->IsConnected())
|
| socket_->Disconnect();
|
| + next_state_ = STATE_NONE;
|
| // Close asynchronously, so that delegate won't be called
|
| // back before returning Close().
|
| MessageLoop::current()->PostTask(
|
| @@ -182,18 +183,22 @@ 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);
|
| 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 +212,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,11 +259,9 @@ 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;
|
| @@ -279,16 +281,17 @@ 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) {
|
| do {
|
| State state = next_state_;
|
| next_state_ = STATE_NONE;
|
| switch (state) {
|
| + case STATE_NONE:
|
| + DCHECK_LE(result, OK);
|
| + if (result == OK)
|
| + result = ERR_CONNECTION_CLOSED;
|
| + Finish(result);
|
| + return;
|
| case STATE_RESOLVE_PROXY:
|
| DCHECK_EQ(OK, result);
|
| result = DoResolveProxy();
|
| @@ -346,12 +349,7 @@ int SocketStream::DoLoop(int result) {
|
| 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 +366,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 +428,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 +532,8 @@ int SocketStream::DoReadTunnelHeadersComplete(int result) {
|
|
|
| if (result == 0) {
|
| // 0 indicates end-of-file, so socket was closed.
|
| - Finish();
|
| - return result;
|
| + DCHECK_EQ(next_state_, STATE_NONE);
|
| + return ERR_CONNECTION_CLOSED;
|
| }
|
|
|
| tunnel_response_headers_len_ += result;
|
| @@ -542,8 +542,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) {
|
| + DCHECK_EQ(next_state_, STATE_NONE);
|
| return ERR_RESPONSE_HEADERS_TOO_BIG;
|
| + }
|
|
|
| next_state_ = STATE_READ_TUNNEL_HEADERS;
|
| return OK;
|
| @@ -554,6 +556,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.
|
| + DCHECK_EQ(next_state_, STATE_NONE);
|
| return ERR_TUNNEL_CONNECTION_FAILED;
|
| }
|
| switch (headers->response_code()) {
|
| @@ -562,7 +565,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) {
|
| + DCHECK_EQ(next_state_, STATE_NONE);
|
| + return result;
|
| + }
|
| if ((eoh < tunnel_response_headers_len_) && delegate_)
|
| delegate_->OnReceivedData(
|
| this, tunnel_response_headers_->headers() + eoh,
|
| @@ -583,6 +590,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 +641,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 +664,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 +751,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());
|
|
|