Index: net/http/http_network_transaction.cc |
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc |
index 53b8a6653accb0b66e5304bd687f890a5b8a1a25..3a286131914697f79d88ae094d30514d70034237 100644 |
--- a/net/http/http_network_transaction.cc |
+++ b/net/http/http_network_transaction.cc |
@@ -40,6 +40,7 @@ |
#include "net/socket/client_socket_factory.h" |
#include "net/socket/socks_client_socket_pool.h" |
#include "net/socket/ssl_client_socket.h" |
+#include "net/socket/ssl_client_socket_pool.h" |
#include "net/socket/tcp_client_socket_pool.h" |
#include "net/spdy/spdy_http_stream.h" |
#include "net/spdy/spdy_session.h" |
@@ -259,7 +260,7 @@ int HttpNetworkTransaction::Start(const HttpRequestInfo* request_info, |
int HttpNetworkTransaction::RestartIgnoringLastError( |
CompletionCallback* callback) { |
- if (connection_->socket()->IsConnectedAndIdle()) { |
+ if (connection_->socket() && connection_->socket()->IsConnectedAndIdle()) { |
// TODO(wtc): Should we update any of the connection histograms that we |
// update in DoSSLConnectComplete if |result| is OK? |
if (using_spdy_) { |
@@ -269,7 +270,8 @@ int HttpNetworkTransaction::RestartIgnoringLastError( |
next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN; |
} |
} else { |
- connection_->socket()->Disconnect(); |
+ if (connection_->socket()) |
+ connection_->socket()->Disconnect(); |
connection_->Reset(); |
next_state_ = STATE_INIT_CONNECTION; |
} |
@@ -313,8 +315,8 @@ int HttpNetworkTransaction::RestartWithAuth( |
if (target == HttpAuth::AUTH_PROXY && using_ssl_ && proxy_info_.is_http()) { |
DCHECK(establishing_tunnel_); |
+ next_state_ = STATE_INIT_CONNECTION; |
ResetStateForRestart(); |
- next_state_ = STATE_TUNNEL_RESTART_WITH_AUTH; |
} else { |
PrepareForAuthRestart(target); |
} |
@@ -376,22 +378,8 @@ int HttpNetworkTransaction::Read(IOBuffer* buf, int buf_len, |
State next_state = STATE_NONE; |
- // Are we using SPDY or HTTP? |
- if (using_spdy_) { |
- DCHECK(!http_stream_.get()); |
- DCHECK(spdy_http_stream_->GetResponseInfo()->headers); |
- next_state = STATE_SPDY_READ_BODY; |
- } else { |
- DCHECK(!spdy_http_stream_.get()); |
- next_state = STATE_READ_BODY; |
- |
- if (!connection_->is_initialized()) |
- return 0; // connection_->has been reset. Treat like EOF. |
- } |
- |
scoped_refptr<HttpResponseHeaders> headers = GetResponseHeaders(); |
- DCHECK(headers.get()); |
- if (establishing_tunnel_) { |
+ if (headers_valid_ && headers.get() && establishing_tunnel_) { |
// We're trying to read the body of the response but we're still trying |
// to establish an SSL tunnel through the proxy. We can't read these |
// bytes when establishing a tunnel because they might be controlled by |
@@ -407,6 +395,19 @@ int HttpNetworkTransaction::Read(IOBuffer* buf, int buf_len, |
return ERR_TUNNEL_CONNECTION_FAILED; |
} |
+ // Are we using SPDY or HTTP? |
+ if (using_spdy_) { |
+ DCHECK(!http_stream_.get()); |
+ DCHECK(spdy_http_stream_->GetResponseInfo()->headers); |
+ next_state = STATE_SPDY_READ_BODY; |
+ } else { |
+ DCHECK(!spdy_http_stream_.get()); |
+ next_state = STATE_READ_BODY; |
+ |
+ if (!connection_->is_initialized()) |
+ return 0; // |*connection_| has been reset. Treat like EOF. |
+ } |
+ |
read_buf_ = buf; |
read_buf_len_ = buf_len; |
@@ -516,17 +517,6 @@ int HttpNetworkTransaction::DoLoop(int result) { |
case STATE_INIT_CONNECTION_COMPLETE: |
rv = DoInitConnectionComplete(rv); |
break; |
- case STATE_TUNNEL_RESTART_WITH_AUTH: |
- DCHECK_EQ(OK, rv); |
- rv = DoTunnelRestartWithAuth(); |
- break; |
- case STATE_SSL_CONNECT: |
- DCHECK_EQ(OK, rv); |
- rv = DoSSLConnect(); |
- break; |
- case STATE_SSL_CONNECT_COMPLETE: |
- rv = DoSSLConnectComplete(rv); |
- break; |
case STATE_GENERATE_PROXY_AUTH_TOKEN: |
DCHECK_EQ(OK, rv); |
rv = DoGenerateProxyAuthToken(); |
@@ -701,6 +691,7 @@ int HttpNetworkTransaction::DoResolveProxyComplete(int result) { |
int HttpNetworkTransaction::DoInitConnection() { |
DCHECK(!connection_->is_initialized()); |
DCHECK(proxy_info_.proxy_server().is_valid()); |
+ next_state_ = STATE_INIT_CONNECTION_COMPLETE; |
// Now that the proxy server has been resolved, create the auth_controllers_. |
for (int i = 0; i < HttpAuth::AUTH_NUM_TARGETS; i++) { |
@@ -711,17 +702,11 @@ int HttpNetworkTransaction::DoInitConnection() { |
session_); |
} |
- next_state_ = STATE_INIT_CONNECTION_COMPLETE; |
- |
- using_ssl_ = request_->url.SchemeIs("https") || |
- (alternate_protocol_mode_ == kUsingAlternateProtocol && |
- alternate_protocol_ == HttpAlternateProtocols::NPN_SPDY_1); |
- |
+ bool want_spdy = alternate_protocol_mode_ == kUsingAlternateProtocol |
+ && alternate_protocol_ == HttpAlternateProtocols::NPN_SPDY_1; |
+ using_ssl_ = request_->url.SchemeIs("https") || want_spdy; |
using_spdy_ = false; |
- |
- // Build the string used to uniquely identify connections of this type. |
- // Determine the host and port to connect to. |
- std::string connection_group; |
+ response_.was_fetched_via_proxy = !proxy_info_.is_direct(); |
// Use the fixed testing ports if they've been provided. |
if (using_ssl_) { |
@@ -731,17 +716,18 @@ int HttpNetworkTransaction::DoInitConnection() { |
endpoint_.port = session_->fixed_http_port(); |
} |
- response_.was_fetched_via_proxy = !proxy_info_.is_direct(); |
- |
// Check first if we have a spdy session for this group. If so, then go |
// straight to using that. |
if (session_->spdy_session_pool()->HasSession(endpoint_)) { |
using_spdy_ = true; |
reused_socket_ = true; |
+ next_state_ = STATE_SPDY_SEND_REQUEST; |
return OK; |
} |
- connection_group = endpoint_.ToString(); |
+ // Build the string used to uniquely identify connections of this type. |
+ // Determine the host and port to connect to. |
+ std::string connection_group = endpoint_.ToString(); |
DCHECK(!connection_group.empty()); |
if (using_ssl_) |
@@ -752,202 +738,171 @@ int HttpNetworkTransaction::DoInitConnection() { |
request_->load_flags & LOAD_VALIDATE_CACHE || |
request_->load_flags & LOAD_DISABLE_CACHE; |
- int rv; |
- if (!proxy_info_.is_direct()) { |
- ProxyServer proxy_server = proxy_info_.proxy_server(); |
- HostPortPair proxy_host_port_pair(proxy_server.HostNoBrackets(), |
- proxy_server.port()); |
+ // Build up the connection parameters. |
+ scoped_refptr<TCPSocketParams> tcp_params; |
+ scoped_refptr<HttpProxySocketParams> http_proxy_params; |
+ scoped_refptr<SOCKSSocketParams> socks_params; |
+ scoped_ptr<HostPortPair> proxy_host_port; |
- scoped_refptr<TCPSocketParams> tcp_params = |
- new TCPSocketParams(proxy_host_port_pair, request_->priority, |
+ if (proxy_info_.is_direct()) { |
+ tcp_params = new TCPSocketParams(endpoint_, request_->priority, |
+ request_->referrer, |
+ disable_resolver_cache); |
+ } else { |
+ ProxyServer proxy_server = proxy_info_.proxy_server(); |
+ proxy_host_port.reset(new HostPortPair(proxy_server.HostNoBrackets(), |
+ proxy_server.port())); |
+ scoped_refptr<TCPSocketParams> proxy_tcp_params = |
+ new TCPSocketParams(*proxy_host_port, request_->priority, |
request_->referrer, disable_resolver_cache); |
- if (proxy_info_.is_socks()) { |
- const char* socks_version; |
- bool socks_v5; |
- if (proxy_info_.proxy_server().scheme() == ProxyServer::SCHEME_SOCKS5) { |
- socks_version = "5"; |
- socks_v5 = true; |
- } else { |
- socks_version = "4"; |
- socks_v5 = false; |
- } |
- |
- connection_group = |
- StringPrintf("socks%s/%s", socks_version, connection_group.c_str()); |
- |
- scoped_refptr<SOCKSSocketParams> socks_params = |
- new SOCKSSocketParams(tcp_params, socks_v5, endpoint_, |
- request_->priority, request_->referrer); |
- |
- rv = connection_->Init( |
- connection_group, socks_params, request_->priority, |
- &io_callback_, |
- session_->GetSocketPoolForSOCKSProxy(proxy_host_port_pair), net_log_); |
- } else { |
- DCHECK(proxy_info_.is_http()); |
+ if (proxy_info_.is_http()) { |
scoped_refptr<HttpAuthController> http_proxy_auth; |
if (using_ssl_) { |
http_proxy_auth = auth_controllers_[HttpAuth::AUTH_PROXY]; |
establishing_tunnel_ = true; |
} |
+ http_proxy_params = new HttpProxySocketParams(proxy_tcp_params, |
+ request_->url, endpoint_, |
+ http_proxy_auth, |
+ using_ssl_); |
+ } else { |
+ DCHECK(proxy_info_.is_socks()); |
+ char socks_version; |
+ if (proxy_server.scheme() == ProxyServer::SCHEME_SOCKS5) |
+ socks_version = '5'; |
+ else |
+ socks_version = '4'; |
+ connection_group = |
+ StringPrintf("socks%c/%s", socks_version, connection_group.c_str()); |
- scoped_refptr<HttpProxySocketParams> http_proxy_params = |
- new HttpProxySocketParams(tcp_params, request_->url, endpoint_, |
- http_proxy_auth, using_ssl_); |
- |
- rv = connection_->Init(connection_group, http_proxy_params, |
- request_->priority, &io_callback_, |
- session_->GetSocketPoolForHTTPProxy( |
- proxy_host_port_pair), |
- net_log_); |
+ socks_params = new SOCKSSocketParams(proxy_tcp_params, |
+ socks_version == '5', |
+ endpoint_, |
+ request_->priority, |
+ request_->referrer); |
} |
- } else { |
- scoped_refptr<TCPSocketParams> tcp_params = |
- new TCPSocketParams(endpoint_, request_->priority, request_->referrer, |
- disable_resolver_cache); |
- rv = connection_->Init(connection_group, tcp_params, request_->priority, |
- &io_callback_, session_->tcp_socket_pool(), |
- net_log_); |
} |
- return rv; |
-} |
- |
-int HttpNetworkTransaction::DoInitConnectionComplete(int result) { |
- if (result < 0) { |
- if (result == ERR_RETRY_CONNECTION) { |
- DCHECK(establishing_tunnel_); |
- next_state_ = STATE_INIT_CONNECTION; |
- connection_->socket()->Disconnect(); |
- connection_->Reset(); |
- return OK; |
- } |
- |
- if (result == ERR_PROXY_AUTH_REQUESTED) { |
- DCHECK(establishing_tunnel_); |
- HttpProxyClientSocket* tunnel_socket = |
- static_cast<HttpProxyClientSocket*>(connection_->socket()); |
- DCHECK(tunnel_socket); |
- DCHECK(!tunnel_socket->IsConnected()); |
- const HttpResponseInfo* auth_response = tunnel_socket->GetResponseInfo(); |
- |
- response_.headers = auth_response->headers; |
- headers_valid_ = true; |
- response_.auth_challenge = auth_response->auth_challenge; |
- pending_auth_target_ = HttpAuth::AUTH_PROXY; |
- return OK; |
+ // Deal with SSL - which layers on top of any given proxy. |
+ if (using_ssl_) { |
+ if (ContainsKey(*g_tls_intolerant_servers, GetHostAndPort(request_->url))) { |
+ LOG(WARNING) << "Falling back to SSLv3 because host is TLS intolerant: " |
+ << GetHostAndPort(request_->url); |
+ ssl_config_.tls1_enabled = false; |
} |
- if (alternate_protocol_mode_ == kUsingAlternateProtocol) { |
- // Mark the alternate protocol as broken and fallback. |
- MarkBrokenAlternateProtocolAndFallback(); |
- return OK; |
- } |
+ int load_flags = request_->load_flags; |
+ if (g_ignore_certificate_errors) |
+ load_flags |= LOAD_IGNORE_ALL_CERT_ERRORS; |
+ if (request_->load_flags & LOAD_VERIFY_EV_CERT) |
+ ssl_config_.verify_ev_cert = true; |
+ |
+ scoped_refptr<SSLSocketParams> ssl_params = |
+ new SSLSocketParams(tcp_params, http_proxy_params, socks_params, |
+ proxy_info_.proxy_server().scheme(), |
+ request_->url.HostNoBrackets(), ssl_config_, |
+ load_flags, want_spdy); |
+ |
+ scoped_refptr<SSLClientSocketPool> ssl_pool; |
+ if (proxy_info_.is_direct()) |
+ ssl_pool = session_->ssl_socket_pool(); |
+ else |
+ ssl_pool = session_->GetSocketPoolForSSLWithProxy(*proxy_host_port); |
- return ReconsiderProxyAfterError(result); |
+ return connection_->Init(connection_group, ssl_params, request_->priority, |
+ &io_callback_, ssl_pool, net_log_); |
} |
- DCHECK_EQ(OK, result); |
- if (establishing_tunnel_) { |
- DCHECK(connection_->socket()->IsConnected()); |
- establishing_tunnel_ = false; |
+ // Finally, get the connection started. |
+ if (proxy_info_.is_http()) { |
+ return connection_->Init( |
+ connection_group, http_proxy_params, request_->priority, &io_callback_, |
+ session_->GetSocketPoolForHTTPProxy(*proxy_host_port), net_log_); |
} |
- if (using_spdy_) { |
- DCHECK(!connection_->is_initialized()); |
- // TODO(cbentzel): Add auth support to spdy. See http://crbug.com/46620 |
- next_state_ = STATE_SPDY_SEND_REQUEST; |
- return OK; |
+ if (proxy_info_.is_socks()) { |
+ return connection_->Init( |
+ connection_group, socks_params, request_->priority, &io_callback_, |
+ session_->GetSocketPoolForSOCKSProxy(*proxy_host_port), net_log_); |
} |
- LogHttpConnectedMetrics(*connection_); |
+ DCHECK(proxy_info_.is_direct()); |
+ return connection_->Init(connection_group, tcp_params, request_->priority, |
+ &io_callback_, session_->tcp_socket_pool(), |
+ net_log_); |
+} |
- // Set the reused_socket_ flag to indicate that we are using a keep-alive |
- // connection. This flag is used to handle errors that occur while we are |
- // trying to reuse a keep-alive connection. |
- reused_socket_ = connection_->is_reused(); |
- if (reused_socket_) { |
- if (using_ssl_) { |
- SSLClientSocket* ssl_socket = |
- reinterpret_cast<SSLClientSocket*>(connection_->socket()); |
- response_.was_npn_negotiated = ssl_socket->wasNpnNegotiated(); |
+int HttpNetworkTransaction::DoInitConnectionComplete(int result) { |
+ // |result| may be the result of any of the stacked pools. The following |
+ // logic is used when determining how to interpret an error. |
+ // If |result| < 0: |
+ // and connection_->socket() != NULL, then the SSL handshake ran and it |
+ // is a potentially recoverable error. |
+ // and connection_->socket == NULL and connection_->is_ssl_error() is true, |
+ // then the SSL handshake ran with an unrecoverable error. |
+ // otherwise, the error came from one of the other pools. |
+ bool ssl_started = using_ssl_ && (result == OK || connection_->socket() || |
+ connection_->is_ssl_error()); |
+ |
+ if (ssl_started && (result == OK || IsCertificateError(result))) { |
+ SSLClientSocket* ssl_socket = |
+ static_cast<SSLClientSocket*>(connection_->socket()); |
+ if (ssl_socket->wasNpnNegotiated()) { |
+ response_.was_npn_negotiated = true; |
+ std::string proto; |
+ ssl_socket->GetNextProto(&proto); |
+ if (SSLClientSocket::NextProtoFromString(proto) == |
+ SSLClientSocket::kProtoSPDY1) |
+ using_spdy_ = true; |
} |
- next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN; |
- } else { |
- // Now we have a TCP connected socket. Perform other connection setup as |
- // needed. |
- UpdateConnectionTypeHistograms(CONNECTION_HTTP); |
- if (using_ssl_) |
- next_state_ = STATE_SSL_CONNECT; |
- else |
- next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN; |
} |
- return OK; |
-} |
- |
-int HttpNetworkTransaction::DoTunnelRestartWithAuth() { |
- next_state_ = STATE_INIT_CONNECTION_COMPLETE; |
- HttpProxyClientSocket* tunnel_socket = |
- reinterpret_cast<HttpProxyClientSocket*>(connection_->socket()); |
+ if (result == ERR_PROXY_AUTH_REQUESTED) { |
+ DCHECK(!ssl_started); |
+ const HttpResponseInfo& tunnel_auth_response = |
+ connection_->tunnel_auth_response_info(); |
- return tunnel_socket->RestartWithAuth(&io_callback_); |
-} |
- |
-int HttpNetworkTransaction::DoSSLConnect() { |
- next_state_ = STATE_SSL_CONNECT_COMPLETE; |
+ response_.headers = tunnel_auth_response.headers; |
+ response_.auth_challenge = tunnel_auth_response.auth_challenge; |
+ headers_valid_ = true; |
+ pending_auth_target_ = HttpAuth::AUTH_PROXY; |
+ return OK; |
+ } |
- if (ContainsKey(*g_tls_intolerant_servers, GetHostAndPort(request_->url))) { |
- LOG(WARNING) << "Falling back to SSLv3 because host is TLS intolerant: " |
- << GetHostAndPort(request_->url); |
- ssl_config_.tls1_enabled = false; |
+ if ((!ssl_started && result < 0 && |
+ alternate_protocol_mode_ == kUsingAlternateProtocol) || |
+ result == ERR_NPN_NEGOTIATION_FAILED) { |
+ // Mark the alternate protocol as broken and fallback. |
+ MarkBrokenAlternateProtocolAndFallback(); |
+ return OK; |
} |
- if (request_->load_flags & LOAD_VERIFY_EV_CERT) |
- ssl_config_.verify_ev_cert = true; |
+ if (result < 0 && !ssl_started) |
+ return ReconsiderProxyAfterError(result); |
+ establishing_tunnel_ = false; |
- ssl_connect_start_time_ = base::TimeTicks::Now(); |
+ if (connection_->socket()) { |
+ LogHttpConnectedMetrics(*connection_); |
- // Add a SSL socket on top of our existing transport socket. |
- ClientSocket* s = connection_->release_socket(); |
- s = session_->socket_factory()->CreateSSLClientSocket( |
- s, request_->url.HostNoBrackets(), ssl_config_); |
- connection_->set_socket(s); |
- return connection_->socket()->Connect(&io_callback_); |
-} |
+ // Set the reused_socket_ flag to indicate that we are using a keep-alive |
+ // connection. This flag is used to handle errors that occur while we are |
+ // trying to reuse a keep-alive connection. |
+ reused_socket_ = connection_->is_reused(); |
+ // TODO(vandebo) should we exclude SPDY in the following if? |
+ if (!reused_socket_) |
+ UpdateConnectionTypeHistograms(CONNECTION_HTTP); |
-int HttpNetworkTransaction::DoSSLConnectComplete(int result) { |
- SSLClientSocket* ssl_socket = |
- reinterpret_cast<SSLClientSocket*>(connection_->socket()); |
- |
- SSLClientSocket::NextProtoStatus status = |
- SSLClientSocket::kNextProtoUnsupported; |
- std::string proto; |
- // GetNextProto will fail and and trigger a NOTREACHED if we pass in a socket |
- // that hasn't had SSL_ImportFD called on it. If we get a certificate error |
- // here, then we know that we called SSL_ImportFD. |
- if (result == OK || IsCertificateError(result)) |
- status = ssl_socket->GetNextProto(&proto); |
- |
- if (status == SSLClientSocket::kNextProtoNegotiated) { |
- ssl_socket->setWasNpnNegotiated(true); |
- response_.was_npn_negotiated = true; |
- if (SSLClientSocket::NextProtoFromString(proto) == |
- SSLClientSocket::kProtoSPDY1) { |
- using_spdy_ = true; |
+ if (!using_ssl_) { |
+ DCHECK_EQ(OK, result); |
+ next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN; |
+ return result; |
} |
} |
- if (alternate_protocol_mode_ == kUsingAlternateProtocol && |
- alternate_protocol_ == HttpAlternateProtocols::NPN_SPDY_1 && |
- !using_spdy_) { |
- // We tried using the NPN_SPDY_1 alternate protocol, but failed, so we |
- // fallback. |
- MarkBrokenAlternateProtocolAndFallback(); |
- return OK; |
- } |
- |
+ // Handle SSL errors below. |
+ DCHECK(using_ssl_); |
+ DCHECK(ssl_started); |
if (IsCertificateError(result)) { |
if (using_spdy_ && request_->url.SchemeIs("http")) { |
// We ignore certificate errors for http over spdy. |
@@ -964,36 +919,19 @@ int HttpNetworkTransaction::DoSSLConnectComplete(int result) { |
} |
} |
- if (result == OK) { |
- DCHECK(ssl_connect_start_time_ != base::TimeTicks()); |
- base::TimeDelta connect_duration = |
- base::TimeTicks::Now() - ssl_connect_start_time_; |
- |
- if (using_spdy_) { |
- UMA_HISTOGRAM_CUSTOM_TIMES("Net.SpdyConnectionLatency", |
- connect_duration, |
- base::TimeDelta::FromMilliseconds(1), |
- base::TimeDelta::FromMinutes(10), |
- 100); |
- |
- UpdateConnectionTypeHistograms(CONNECTION_SPDY); |
- // TODO(cbentzel): Add auth support to spdy. See http://crbug.com/46620 |
- next_state_ = STATE_SPDY_SEND_REQUEST; |
- } else { |
- UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency", |
- connect_duration, |
- base::TimeDelta::FromMilliseconds(1), |
- base::TimeDelta::FromMinutes(10), |
- 100); |
+ if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) |
+ return HandleCertificateRequest(result); |
+ if (result < 0) |
+ return HandleSSLHandshakeError(result); |
- next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN; |
- } |
- } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { |
- result = HandleCertificateRequest(result); |
+ if (using_spdy_) { |
+ UpdateConnectionTypeHistograms(CONNECTION_SPDY); |
+ // TODO(cbentzel): Add auth support to spdy. See http://crbug.com/46620 |
+ next_state_ = STATE_SPDY_SEND_REQUEST; |
} else { |
- result = HandleSSLHandshakeError(result); |
+ next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN; |
} |
- return result; |
+ return OK; |
} |
int HttpNetworkTransaction::DoGenerateProxyAuthToken() { |
@@ -1191,7 +1129,7 @@ int HttpNetworkTransaction::DoReadHeadersComplete(int result) { |
if (using_ssl_) { |
SSLClientSocket* ssl_socket = |
- reinterpret_cast<SSLClientSocket*>(connection_->socket()); |
+ static_cast<SSLClientSocket*>(connection_->socket()); |
ssl_socket->GetSSLInfo(&response_.ssl_info); |
} |
@@ -1534,7 +1472,7 @@ int HttpNetworkTransaction::HandleCertificateError(int error) { |
DCHECK(IsCertificateError(error)); |
SSLClientSocket* ssl_socket = |
- reinterpret_cast<SSLClientSocket*>(connection_->socket()); |
+ static_cast<SSLClientSocket*>(connection_->socket()); |
ssl_socket->GetSSLInfo(&response_.ssl_info); |
// Add the bad certificate to the set of allowed certificates in the |
@@ -1546,29 +1484,11 @@ int HttpNetworkTransaction::HandleCertificateError(int error) { |
bad_cert.cert_status = response_.ssl_info.cert_status; |
ssl_config_.allowed_bad_certs.push_back(bad_cert); |
+ int load_flags = request_->load_flags; |
if (g_ignore_certificate_errors) |
+ load_flags |= LOAD_IGNORE_ALL_CERT_ERRORS; |
+ if (ssl_socket->IgnoreCertError(error, load_flags)) |
return OK; |
- |
- const int kCertFlags = LOAD_IGNORE_CERT_COMMON_NAME_INVALID | |
- LOAD_IGNORE_CERT_DATE_INVALID | |
- LOAD_IGNORE_CERT_AUTHORITY_INVALID | |
- LOAD_IGNORE_CERT_WRONG_USAGE; |
- if (request_->load_flags & kCertFlags) { |
- switch (error) { |
- case ERR_CERT_COMMON_NAME_INVALID: |
- if (request_->load_flags & LOAD_IGNORE_CERT_COMMON_NAME_INVALID) |
- error = OK; |
- break; |
- case ERR_CERT_DATE_INVALID: |
- if (request_->load_flags & LOAD_IGNORE_CERT_DATE_INVALID) |
- error = OK; |
- break; |
- case ERR_CERT_AUTHORITY_INVALID: |
- if (request_->load_flags & LOAD_IGNORE_CERT_AUTHORITY_INVALID) |
- error = OK; |
- break; |
- } |
- } |
return error; |
} |
@@ -1585,7 +1505,7 @@ int HttpNetworkTransaction::HandleCertificateRequest(int error) { |
response_.cert_request_info = new SSLCertRequestInfo; |
SSLClientSocket* ssl_socket = |
- reinterpret_cast<SSLClientSocket*>(connection_->socket()); |
+ static_cast<SSLClientSocket*>(connection_->socket()); |
ssl_socket->GetSSLCertRequestInfo(response_.cert_request_info); |
// Close the connection while the user is selecting a certificate to send |
@@ -1690,11 +1610,13 @@ bool HttpNetworkTransaction::ShouldResendRequest(int error) const { |
} |
void HttpNetworkTransaction::ResetConnectionAndRequestForResend() { |
- connection_->socket()->Disconnect(); |
+ if (connection_->socket()) |
+ connection_->socket()->Disconnect(); |
connection_->Reset(); |
// We need to clear request_headers_ because it contains the real request |
// headers, but we may need to resend the CONNECT request first to recreate |
// the SSL tunnel. |
+ |
request_headers_.clear(); |
next_state_ = STATE_INIT_CONNECTION; // Resend the request. |
} |