Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2159)

Unified Diff: net/http/http_network_transaction.cc

Issue 3058013: Fix late binding induced mismatch of Socket and AuthController (Closed)
Patch Set: Address comments Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/http/http_network_transaction.cc
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc
index 5cc3895cfc4755d372ea82b84febab410f0c1f9f..c9036dd5ae997ad59fd7bdba2f75fb3392f96053 100644
--- a/net/http/http_network_transaction.cc
+++ b/net/http/http_network_transaction.cc
@@ -332,7 +332,8 @@ int HttpNetworkTransaction::RestartWithAuth(
if (target == HttpAuth::AUTH_PROXY && using_ssl_ && proxy_info_.is_http()) {
DCHECK(establishing_tunnel_);
- next_state_ = STATE_INIT_CONNECTION;
+ next_state_ = STATE_RESTART_TUNNEL_AUTH;
+ auth_controllers_[target] = NULL;
ResetStateForRestart();
} else {
PrepareForAuthRestart(target);
@@ -533,6 +534,13 @@ int HttpNetworkTransaction::DoLoop(int result) {
case STATE_INIT_CONNECTION_COMPLETE:
rv = DoInitConnectionComplete(rv);
break;
+ case STATE_RESTART_TUNNEL_AUTH:
+ DCHECK_EQ(OK, rv);
+ rv = DoRestartTunnelAuth();
+ break;
+ case STATE_RESTART_TUNNEL_AUTH_COMPLETE:
+ rv = DoRestartTunnelAuthComplete(rv);
+ break;
case STATE_GENERATE_PROXY_AUTH_TOKEN:
DCHECK_EQ(OK, rv);
rv = DoGenerateProxyAuthToken();
@@ -716,15 +724,6 @@ int HttpNetworkTransaction::DoInitConnection() {
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++) {
- HttpAuth::Target target = static_cast<HttpAuth::Target>(i);
- if (!auth_controllers_[target].get())
- auth_controllers_[target] = new HttpAuthController(target,
- AuthURL(target),
- session_);
- }
-
bool want_spdy_over_npn = alternate_protocol_mode_ == kUsingAlternateProtocol
&& alternate_protocol_ == HttpAlternateProtocols::NPN_SPDY_1;
using_ssl_ = request_->url.SchemeIs("https") ||
@@ -773,15 +772,10 @@ int HttpNetworkTransaction::DoInitConnection() {
request_->referrer, disable_resolver_cache);
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;
- }
+ establishing_tunnel_ = using_ssl_;
http_proxy_params = new HttpProxySocketParams(proxy_tcp_params,
request_->url, endpoint_,
- http_proxy_auth,
- using_ssl_);
+ session_, using_ssl_);
} else {
DCHECK(proxy_info_.is_socks());
char socks_version;
@@ -889,14 +883,13 @@ int HttpNetworkTransaction::DoInitConnectionComplete(int result) {
if (result == ERR_PROXY_AUTH_REQUESTED) {
DCHECK(!ssl_started);
- const HttpResponseInfo& tunnel_auth_response =
- connection_->ssl_error_response_info();
-
- 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;
+ // Other state (i.e. |using_ssl_| suggests that |connection_| will have an
eroman 2010/07/30 22:11:11 This seems like an unmatched parenthesis.
+ // SSL socket, but there was an error before that could happened. This
+ // puts the in progress HttpProxy socket into |connection_| in order to
+ // complete the auth. The tunnel restart code is carefully to remove it
+ // before returning control to the rest of this class.
+ connection_.reset(connection_->release_pending_http_proxy_connection());
+ return HandleTunnelAuthFailure(result);
}
if ((!ssl_started && result < 0 &&
@@ -976,12 +969,44 @@ int HttpNetworkTransaction::DoInitConnectionComplete(int result) {
return OK;
}
+int HttpNetworkTransaction::DoRestartTunnelAuth() {
+ next_state_ = STATE_RESTART_TUNNEL_AUTH_COMPLETE;
+ HttpProxyClientSocket* http_proxy_socket =
+ static_cast<HttpProxyClientSocket*>(connection_->socket());
+ return http_proxy_socket->RestartWithAuth(&io_callback_);
+}
+
+int HttpNetworkTransaction::DoRestartTunnelAuthComplete(int result) {
+ if (result == ERR_PROXY_AUTH_REQUESTED)
+ return HandleTunnelAuthFailure(result);
+
+ if (result == OK) {
+ // Now that we've got the HttpProxyClientSocket connected. We have
+ // to release it as an idle socket into the pool and start the connection
+ // process from the beginning. Trying to pass it in with the
+ // SSLSocketParams might cause a deadlock since params are dispatched
+ // interchangeably. This request won't necessarily get this http proxy
+ // socket, but there will be forward progress.
+ connection_->Reset();
+ establishing_tunnel_ = false;
+ next_state_ = STATE_INIT_CONNECTION;
+ return OK;
+ }
+
+ return ReconsiderProxyAfterError(result);
+}
+
int HttpNetworkTransaction::DoGenerateProxyAuthToken() {
next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE;
if (!ShouldApplyProxyAuth())
return OK;
- return auth_controllers_[HttpAuth::AUTH_PROXY]->MaybeGenerateAuthToken(
- request_, &io_callback_, net_log_);
+ HttpAuth::Target target = HttpAuth::AUTH_PROXY;
+ if (!auth_controllers_[target].get())
+ auth_controllers_[target] = new HttpAuthController(target, AuthURL(target),
+ session_);
+ return auth_controllers_[target]->MaybeGenerateAuthToken(request_,
+ &io_callback_,
+ net_log_);
}
int HttpNetworkTransaction::DoGenerateProxyAuthTokenComplete(int rv) {
@@ -993,10 +1018,15 @@ int HttpNetworkTransaction::DoGenerateProxyAuthTokenComplete(int rv) {
int HttpNetworkTransaction::DoGenerateServerAuthToken() {
next_state_ = STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE;
+ HttpAuth::Target target = HttpAuth::AUTH_SERVER;
+ if (!auth_controllers_[target].get())
+ auth_controllers_[target] = new HttpAuthController(target, AuthURL(target),
+ session_);
if (!ShouldApplyServerAuth())
return OK;
- return auth_controllers_[HttpAuth::AUTH_SERVER]->MaybeGenerateAuthToken(
- request_, &io_callback_, net_log_);
+ return auth_controllers_[target]->MaybeGenerateAuthToken(request_,
+ &io_callback_,
+ net_log_);
}
int HttpNetworkTransaction::DoGenerateServerAuthTokenComplete(int rv) {
@@ -1516,6 +1546,24 @@ void HttpNetworkTransaction::LogTransactionMetrics() const {
}
}
+int HttpNetworkTransaction::HandleTunnelAuthFailure(int error) {
+ DCHECK(establishing_tunnel_);
+ DCHECK_EQ(ERR_PROXY_AUTH_REQUESTED, error);
+ HttpProxyClientSocket* http_proxy_socket =
+ static_cast<HttpProxyClientSocket*>(connection_->socket());
+
+ const HttpResponseInfo* tunnel_auth_response =
+ http_proxy_socket->GetResponseInfo();
+ response_.headers = tunnel_auth_response->headers;
+ response_.auth_challenge = tunnel_auth_response->auth_challenge;
+ headers_valid_ = true;
+
+ auth_controllers_[HttpAuth::AUTH_PROXY] =
+ http_proxy_socket->auth_controller();
+ pending_auth_target_ = HttpAuth::AUTH_PROXY;
+ return OK;
+}
+
int HttpNetworkTransaction::HandleCertificateError(int error) {
DCHECK(using_ssl_);
DCHECK(IsCertificateError(error));

Powered by Google App Engine
This is Rietveld 408576698