summaryrefslogtreecommitdiffstats
path: root/net/http/http_network_transaction.cc
diff options
context:
space:
mode:
Diffstat (limited to 'net/http/http_network_transaction.cc')
-rw-r--r--net/http/http_network_transaction.cc80
1 files changed, 42 insertions, 38 deletions
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc
index c549cb3..36a752f 100644
--- a/net/http/http_network_transaction.cc
+++ b/net/http/http_network_transaction.cc
@@ -80,9 +80,13 @@ int HttpNetworkTransaction::Start(const HttpRequestInfo* request_info,
int HttpNetworkTransaction::RestartIgnoringLastError(
CompletionCallback* callback) {
- // TODO(wtc): If the connection is no longer alive, call
- // connection_.socket()->ReconnectIgnoringLastError().
- next_state_ = STATE_WRITE_HEADERS;
+ if (connection_.socket()->IsConnected()) {
+ next_state_ = STATE_WRITE_HEADERS;
+ } else {
+ connection_.set_socket(NULL);
+ connection_.Reset();
+ next_state_ = STATE_INIT_CONNECTION;
+ }
int rv = DoLoop(OK);
if (rv == ERR_IO_PENDING)
user_callback_ = callback;
@@ -249,7 +253,7 @@ LoadState HttpNetworkTransaction::GetLoadState() const {
return LOAD_STATE_RESOLVING_PROXY_FOR_URL;
case STATE_RESOLVE_HOST_COMPLETE:
return LOAD_STATE_RESOLVING_HOST;
- case STATE_CONNECT_COMPLETE:
+ case STATE_TCP_CONNECT_COMPLETE:
return LOAD_STATE_CONNECTING;
case STATE_WRITE_HEADERS_COMPLETE:
case STATE_WRITE_BODY_COMPLETE:
@@ -408,23 +412,23 @@ int HttpNetworkTransaction::DoLoop(int result) {
rv = DoResolveHostComplete(rv);
TRACE_EVENT_END("http.resolve_host", request_, request_->url.spec());
break;
- case STATE_CONNECT:
+ case STATE_TCP_CONNECT:
DCHECK_EQ(OK, rv);
TRACE_EVENT_BEGIN("http.connect", request_, request_->url.spec());
- rv = DoConnect();
+ rv = DoTCPConnect();
break;
- case STATE_CONNECT_COMPLETE:
- rv = DoConnectComplete(rv);
+ case STATE_TCP_CONNECT_COMPLETE:
+ rv = DoTCPConnectComplete(rv);
TRACE_EVENT_END("http.connect", request_, request_->url.spec());
break;
- case STATE_SSL_CONNECT_OVER_TUNNEL:
+ case STATE_SSL_CONNECT:
DCHECK_EQ(OK, rv);
- TRACE_EVENT_BEGIN("http.ssl_tunnel", request_, request_->url.spec());
- rv = DoSSLConnectOverTunnel();
+ TRACE_EVENT_BEGIN("http.ssl_connect", request_, request_->url.spec());
+ rv = DoSSLConnect();
break;
- case STATE_SSL_CONNECT_OVER_TUNNEL_COMPLETE:
- rv = DoSSLConnectOverTunnelComplete(rv);
- TRACE_EVENT_END("http.ssl_tunnel", request_, request_->url.spec());
+ case STATE_SSL_CONNECT_COMPLETE:
+ rv = DoSSLConnectComplete(rv);
+ TRACE_EVENT_END("http.ssl_connect", request_, request_->url.spec());
break;
case STATE_WRITE_HEADERS:
DCHECK_EQ(OK, rv);
@@ -578,48 +582,42 @@ int HttpNetworkTransaction::DoResolveHostComplete(int result) {
bool ok = (result == OK);
DidFinishDnsResolutionWithStatus(ok, request_->referrer, this);
if (ok) {
- next_state_ = STATE_CONNECT;
+ next_state_ = STATE_TCP_CONNECT;
} else {
result = ReconsiderProxyAfterError(result);
}
return result;
}
-int HttpNetworkTransaction::DoConnect() {
- next_state_ = STATE_CONNECT_COMPLETE;
+int HttpNetworkTransaction::DoTCPConnect() {
+ next_state_ = STATE_TCP_CONNECT_COMPLETE;
DCHECK(!connection_.socket());
ClientSocket* s = socket_factory_->CreateTCPClientSocket(addresses_);
-
- // If we are using a direct SSL connection, then go ahead and create the SSL
- // wrapper socket now. Otherwise, we need to first issue a CONNECT request.
- if (using_ssl_ && !using_tunnel_)
- s = socket_factory_->CreateSSLClientSocket(s, request_->url.host(),
- ssl_config_);
-
connection_.set_socket(s);
return connection_.socket()->Connect(&io_callback_);
}
-int HttpNetworkTransaction::DoConnectComplete(int result) {
- if (IsCertificateError(result))
- result = HandleCertificateError(result);
-
+int HttpNetworkTransaction::DoTCPConnectComplete(int result) {
+ // If we are using a direct SSL connection, then go ahead and establish the
+ // SSL connection, now. Otherwise, we need to first issue a CONNECT request.
if (result == OK) {
- next_state_ = STATE_WRITE_HEADERS;
- if (using_tunnel_)
- establishing_tunnel_ = true;
+ if (using_ssl_ && !using_tunnel_) {
+ next_state_ = STATE_SSL_CONNECT;
+ } else {
+ next_state_ = STATE_WRITE_HEADERS;
+ if (using_tunnel_)
+ establishing_tunnel_ = true;
+ }
} else {
- result = HandleSSLHandshakeError(result);
- if (result != OK)
- result = ReconsiderProxyAfterError(result);
+ result = ReconsiderProxyAfterError(result);
}
return result;
}
-int HttpNetworkTransaction::DoSSLConnectOverTunnel() {
- next_state_ = STATE_SSL_CONNECT_OVER_TUNNEL_COMPLETE;
+int HttpNetworkTransaction::DoSSLConnect() {
+ next_state_ = STATE_SSL_CONNECT_COMPLETE;
// Add a SSL socket on top of our existing transport socket.
ClientSocket* s = connection_.release_socket();
@@ -629,7 +627,7 @@ int HttpNetworkTransaction::DoSSLConnectOverTunnel() {
return connection_.socket()->Connect(&io_callback_);
}
-int HttpNetworkTransaction::DoSSLConnectOverTunnelComplete(int result) {
+int HttpNetworkTransaction::DoSSLConnectComplete(int result) {
if (IsCertificateError(result))
result = HandleCertificateError(result);
@@ -1019,7 +1017,7 @@ int HttpNetworkTransaction::DidReadResponseHeaders() {
// The proxy sent extraneous data after the headers.
return ERR_TUNNEL_CONNECTION_FAILED;
}
- next_state_ = STATE_SSL_CONNECT_OVER_TUNNEL;
+ next_state_ = STATE_SSL_CONNECT;
// Reset for the real request and response headers.
request_headers_.clear();
request_headers_bytes_sent_ = 0;
@@ -1150,6 +1148,12 @@ int HttpNetworkTransaction::HandleCertificateError(int error) {
SSLClientSocket* ssl_socket =
reinterpret_cast<SSLClientSocket*>(connection_.socket());
ssl_socket->GetSSLInfo(&response_.ssl_info);
+
+ // Add the bad certificate to the set of allowed certificates in the
+ // SSL info object. This data structure will be consulted after calling
+ // RestartIgnoringLastError(). And the user will be asked interactively
+ // before RestartIgnoringLastError() is ever called.
+ ssl_config_.allowed_bad_certs_.insert(response_.ssl_info.cert);
}
return error;
}