Fix crash bug in new SSLClientSocketPool.
We also need to push additional error state out of the SSLClientSocketPool on a ERR_SSL_CLIENT_AUTH_CERT_NEEDED error.
BUG=49197
TEST=no crash when visiting https://foafssl.org/srv/idp?authreqissuer=http://foaf.me/index.php
Review URL: http://codereview.chromium.org/2827053
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@52693 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/net/socket/client_socket_handle.cc b/net/socket/client_socket_handle.cc
index 7093e14..de2fd94c 100644
--- a/net/socket/client_socket_handle.cc
+++ b/net/socket/client_socket_handle.cc
@@ -58,7 +58,7 @@
void ClientSocketHandle::ResetErrorState() {
is_ssl_error_ = false;
- tunnel_auth_response_info_ = HttpResponseInfo();
+ ssl_error_response_info_ = HttpResponseInfo();
}
LoadState ClientSocketHandle::GetLoadState() const {
diff --git a/net/socket/client_socket_handle.h b/net/socket/client_socket_handle.h
index b8e6cc34..7fdf784 100644
--- a/net/socket/client_socket_handle.h
+++ b/net/socket/client_socket_handle.h
@@ -104,27 +104,28 @@
void set_socket(ClientSocket* s) { socket_.reset(s); }
void set_idle_time(base::TimeDelta idle_time) { idle_time_ = idle_time; }
void set_pool_id(int id) { pool_id_ = id; }
- void set_tunnel_auth_response_info(
- const scoped_refptr<HttpResponseHeaders>& headers,
- const scoped_refptr<AuthChallengeInfo>& auth_challenge) {
- tunnel_auth_response_info_.headers = headers;
- tunnel_auth_response_info_.auth_challenge = auth_challenge;
- }
void set_is_ssl_error(bool is_ssl_error) { is_ssl_error_ = is_ssl_error; }
+ void set_ssl_error_response_info(const HttpResponseInfo& ssl_error_state) {
+ ssl_error_response_info_ = ssl_error_state;
+ }
+
+ // Only valid if there is no |socket_|.
+ bool is_ssl_error() const {
+ DCHECK(socket_.get() == NULL);
+ return is_ssl_error_;
+ }
+ // On an ERR_PROXY_AUTH_REQUESTED error, the |headers| and |auth_challenge|
+ // fields are filled in. On an ERR_SSL_CLIENT_AUTH_CERT_NEEDED error,
+ // the |cert_request_info| field is set.
+ const HttpResponseInfo& ssl_error_response_info() const {
+ return ssl_error_response_info_;
+ }
// These may only be used if is_initialized() is true.
const std::string& group_name() const { return group_name_; }
int id() const { return pool_id_; }
ClientSocket* socket() { return socket_.get(); }
ClientSocket* release_socket() { return socket_.release(); }
- const HttpResponseInfo& tunnel_auth_response_info() const {
- return tunnel_auth_response_info_;
- }
- // Only valid if there is no |socket_|.
- bool is_ssl_error() const {
- DCHECK(socket_.get() == NULL);
- return is_ssl_error_;
- }
bool is_reused() const { return is_reused_; }
base::TimeDelta idle_time() const { return idle_time_; }
SocketReuseType reuse_type() const {
@@ -176,7 +177,7 @@
base::TimeDelta idle_time_;
int pool_id_; // See ClientSocketPool::ReleaseSocket() for an explanation.
bool is_ssl_error_;
- HttpResponseInfo tunnel_auth_response_info_;
+ HttpResponseInfo ssl_error_response_info_;
base::TimeTicks init_time_;
base::TimeDelta setup_time_;
diff --git a/net/socket/client_socket_pool_base_unittest.cc b/net/socket/client_socket_pool_base_unittest.cc
index 9686794..55f1949 100644
--- a/net/socket/client_socket_pool_base_unittest.cc
+++ b/net/socket/client_socket_pool_base_unittest.cc
@@ -155,8 +155,9 @@
if (store_additional_error_state_) {
// Set all of the additional error state fields in some way.
handle->set_is_ssl_error(true);
- scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(""));
- handle->set_tunnel_auth_response_info(headers, NULL);
+ HttpResponseInfo info;
+ info.headers = new HttpResponseHeaders("");
+ handle->set_ssl_error_response_info(info);
}
}
@@ -626,14 +627,15 @@
TestSocketRequest req(&request_order_, &completion_count_);
// Set the additional error state members to ensure that they get cleared.
req.handle()->set_is_ssl_error(true);
- scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(""));
- req.handle()->set_tunnel_auth_response_info(headers, NULL);
+ HttpResponseInfo info;
+ info.headers = new HttpResponseHeaders("");
+ req.handle()->set_ssl_error_response_info(info);
EXPECT_EQ(ERR_CONNECTION_FAILED, req.handle()->Init("a", params_,
kDefaultPriority, &req,
pool_, log.bound()));
EXPECT_FALSE(req.handle()->socket());
EXPECT_FALSE(req.handle()->is_ssl_error());
- EXPECT_TRUE(req.handle()->tunnel_auth_response_info().headers.get() == NULL);
+ EXPECT_TRUE(req.handle()->ssl_error_response_info().headers.get() == NULL);
EXPECT_EQ(3u, log.entries().size());
EXPECT_TRUE(LogContainsBeginEvent(
@@ -1386,14 +1388,15 @@
CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
// Set the additional error state members to ensure that they get cleared.
req.handle()->set_is_ssl_error(true);
- scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(""));
- req.handle()->set_tunnel_auth_response_info(headers, NULL);
+ HttpResponseInfo info;
+ info.headers = new HttpResponseHeaders("");
+ req.handle()->set_ssl_error_response_info(info);
EXPECT_EQ(ERR_IO_PENDING, req.handle()->Init("a", params_, kDefaultPriority,
&req, pool_, log.bound()));
EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
EXPECT_FALSE(req.handle()->is_ssl_error());
- EXPECT_TRUE(req.handle()->tunnel_auth_response_info().headers.get() == NULL);
+ EXPECT_TRUE(req.handle()->ssl_error_response_info().headers.get() == NULL);
EXPECT_EQ(3u, log.entries().size());
EXPECT_TRUE(LogContainsBeginEvent(
@@ -1598,7 +1601,7 @@
EXPECT_FALSE(req.handle()->is_initialized());
EXPECT_FALSE(req.handle()->socket());
EXPECT_TRUE(req.handle()->is_ssl_error());
- EXPECT_FALSE(req.handle()->tunnel_auth_response_info().headers.get() == NULL);
+ EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
req.handle()->Reset();
}
@@ -1615,7 +1618,7 @@
EXPECT_FALSE(req.handle()->is_initialized());
EXPECT_FALSE(req.handle()->socket());
EXPECT_TRUE(req.handle()->is_ssl_error());
- EXPECT_FALSE(req.handle()->tunnel_auth_response_info().headers.get() == NULL);
+ EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
req.handle()->Reset();
}
@@ -1861,7 +1864,7 @@
EXPECT_FALSE(req.handle()->is_initialized());
EXPECT_FALSE(req.handle()->socket());
EXPECT_TRUE(req.handle()->is_ssl_error());
- EXPECT_FALSE(req.handle()->tunnel_auth_response_info().headers.get() == NULL);
+ EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
}
// http://crbug.com/44724 regression test.
diff --git a/net/socket/ssl_client_socket_pool.cc b/net/socket/ssl_client_socket_pool.cc
index cfe3df49..d7f18e9 100644
--- a/net/socket/ssl_client_socket_pool.cc
+++ b/net/socket/ssl_client_socket_pool.cc
@@ -229,15 +229,11 @@
return OK;
}
- if (result == ERR_PROXY_AUTH_REQUESTED) {
- // Extract the information needed to prompt for the proxy authentication.
- // so that when ClientSocketPoolBaseHelper calls |GetAdditionalErrorState|,
- // we can easily set the state.
- const HttpResponseInfo* tunnel_response = tunnel_socket->GetResponseInfo();
-
- http_auth_response_headers_ = tunnel_response->headers;
- http_auth_auth_challenge_ = tunnel_response->auth_challenge;
- }
+ // Extract the information needed to prompt for the proxy authentication.
+ // so that when ClientSocketPoolBaseHelper calls |GetAdditionalErrorState|,
+ // we can easily set the state.
+ if (result == ERR_PROXY_AUTH_REQUESTED)
+ error_response_info_ = *tunnel_socket->GetResponseInfo();
if (result < 0)
return result;
@@ -255,9 +251,7 @@
}
void SSLConnectJob::GetAdditionalErrorState(ClientSocketHandle * handle) {
- if (http_auth_response_headers_.get() != NULL)
- handle->set_tunnel_auth_response_info(http_auth_response_headers_,
- http_auth_auth_challenge_);
+ handle->set_ssl_error_response_info(error_response_info_);
if (!ssl_connect_start_time_.is_null())
handle->set_is_ssl_error(true);
}
@@ -313,8 +307,13 @@
base::TimeDelta::FromMinutes(10),
100);
}
- if (result == OK || IsCertificateError(result))
+
+ if (result == OK || IsCertificateError(result)) {
set_socket(ssl_socket_.release());
+ } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
+ error_response_info_.cert_request_info = new SSLCertRequestInfo;
+ ssl_socket_->GetSSLCertRequestInfo(error_response_info_.cert_request_info);
+ }
return result;
}
diff --git a/net/socket/ssl_client_socket_pool.h b/net/socket/ssl_client_socket_pool.h
index 48bba9c..fd5bbb3f 100644
--- a/net/socket/ssl_client_socket_pool.h
+++ b/net/socket/ssl_client_socket_pool.h
@@ -141,8 +141,7 @@
// The time the DoSSLConnect() method was called.
base::TimeTicks ssl_connect_start_time_;
- scoped_refptr<HttpResponseHeaders> http_auth_response_headers_;
- scoped_refptr<AuthChallengeInfo> http_auth_auth_challenge_;
+ HttpResponseInfo error_response_info_;
DISALLOW_COPY_AND_ASSIGN(SSLConnectJob);
};
diff --git a/net/socket/ssl_client_socket_pool_unittest.cc b/net/socket/ssl_client_socket_pool_unittest.cc
index 30ff5da..ca864c9a 100644
--- a/net/socket/ssl_client_socket_pool_unittest.cc
+++ b/net/socket/ssl_client_socket_pool_unittest.cc
@@ -585,7 +585,7 @@
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
EXPECT_FALSE(handle.is_ssl_error());
- const HttpResponseInfo& tunnel_info = handle.tunnel_auth_response_info();
+ const HttpResponseInfo& tunnel_info = handle.ssl_error_response_info();
EXPECT_EQ(tunnel_info.headers->response_code(), 407);
}
@@ -633,7 +633,7 @@
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
EXPECT_FALSE(handle.is_ssl_error());
- const HttpResponseInfo& tunnel_info = handle.tunnel_auth_response_info();
+ const HttpResponseInfo& tunnel_info = handle.ssl_error_response_info();
EXPECT_EQ(tunnel_info.headers->response_code(), 407);
params->http_proxy_params()->auth_controller()->ResetAuth(std::wstring(),
@@ -698,7 +698,7 @@
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
EXPECT_FALSE(handle.is_ssl_error());
- const HttpResponseInfo& tunnel_info = handle.tunnel_auth_response_info();
+ const HttpResponseInfo& tunnel_info = handle.ssl_error_response_info();
EXPECT_EQ(tunnel_info.headers->response_code(), 407);
params->http_proxy_params()->auth_controller()->ResetAuth(std::wstring(),