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.cc153
1 files changed, 99 insertions, 54 deletions
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc
index 27db570..ccc956b 100644
--- a/net/http/http_network_transaction.cc
+++ b/net/http/http_network_transaction.cc
@@ -353,9 +353,10 @@ int HttpNetworkTransaction::RestartIgnoringLastError(
// TODO(wtc): Should we update any of the connection histograms that we
// update in DoSSLConnectComplete if |result| is OK?
if (using_spdy_) {
+ // TODO(cbentzel): Add auth support to spdy. See http://crbug.com/46620
next_state_ = STATE_SPDY_SEND_REQUEST;
} else {
- next_state_ = STATE_SEND_REQUEST;
+ next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN;
}
} else {
connection_->socket()->Disconnect();
@@ -481,9 +482,9 @@ void HttpNetworkTransaction::DidDrainBodyForAuthRestart(bool keep_alive) {
// often enough to be worth the trouble.
if (using_ssl_ && proxy_info_.is_http() &&
ssl_connect_start_time_.is_null())
- next_state_ = STATE_TUNNEL_SEND_REQUEST;
+ next_state_ = STATE_TUNNEL_GENERATE_AUTH_TOKEN;
else
- next_state_ = STATE_SEND_REQUEST;
+ next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN;
connection_->set_is_reused(true);
reused_socket_ = true;
} else {
@@ -554,11 +555,14 @@ LoadState HttpNetworkTransaction::GetLoadState() const {
return LOAD_STATE_RESOLVING_PROXY_FOR_URL;
case STATE_INIT_CONNECTION_COMPLETE:
return connection_->GetLoadState();
+ case STATE_TUNNEL_GENERATE_AUTH_TOKEN_COMPLETE:
case STATE_TUNNEL_SEND_REQUEST_COMPLETE:
case STATE_TUNNEL_READ_HEADERS_COMPLETE:
return LOAD_STATE_ESTABLISHING_PROXY_TUNNEL;
case STATE_SSL_CONNECT_COMPLETE:
return LOAD_STATE_SSL_HANDSHAKE;
+ case STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE:
+ case STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE:
case STATE_SEND_REQUEST_COMPLETE:
case STATE_SPDY_SEND_REQUEST_COMPLETE:
return LOAD_STATE_SENDING_REQUEST;
@@ -631,6 +635,13 @@ int HttpNetworkTransaction::DoLoop(int result) {
case STATE_INIT_CONNECTION_COMPLETE:
rv = DoInitConnectionComplete(rv);
break;
+ case STATE_TUNNEL_GENERATE_AUTH_TOKEN:
+ DCHECK_EQ(OK, rv);
+ rv = DoTunnelGenerateAuthToken();
+ break;
+ case STATE_TUNNEL_GENERATE_AUTH_TOKEN_COMPLETE:
+ rv = DoTunnelGenerateAuthTokenComplete(rv);
+ break;
case STATE_TUNNEL_SEND_REQUEST:
DCHECK_EQ(OK, rv);
net_log_.BeginEvent(NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST,
@@ -660,6 +671,20 @@ int HttpNetworkTransaction::DoLoop(int result) {
case STATE_SSL_CONNECT_COMPLETE:
rv = DoSSLConnectComplete(rv);
break;
+ case STATE_GENERATE_PROXY_AUTH_TOKEN:
+ DCHECK_EQ(OK, rv);
+ rv = DoGenerateProxyAuthToken();
+ break;
+ case STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE:
+ rv = DoGenerateProxyAuthTokenComplete(rv);
+ break;
+ case STATE_GENERATE_SERVER_AUTH_TOKEN:
+ DCHECK_EQ(OK, rv);
+ rv = DoGenerateServerAuthToken();
+ break;
+ case STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE:
+ rv = DoGenerateServerAuthTokenComplete(rv);
+ break;
case STATE_SEND_REQUEST:
DCHECK_EQ(OK, rv);
net_log_.BeginEvent(NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST, NULL);
@@ -934,6 +959,7 @@ int HttpNetworkTransaction::DoInitConnectionComplete(int result) {
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;
}
@@ -950,7 +976,7 @@ int HttpNetworkTransaction::DoInitConnectionComplete(int result) {
reinterpret_cast<SSLClientSocket*>(connection_->socket());
response_.was_npn_negotiated = ssl_socket->wasNpnNegotiated();
}
- next_state_ = STATE_SEND_REQUEST;
+ next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN;
} else {
// Now we have a TCP connected socket. Perform other connection setup as
// needed.
@@ -959,9 +985,9 @@ int HttpNetworkTransaction::DoInitConnectionComplete(int result) {
if (proxy_info_.is_direct() || proxy_info_.is_socks())
next_state_ = STATE_SSL_CONNECT;
else
- next_state_ = STATE_TUNNEL_SEND_REQUEST;
+ next_state_ = STATE_TUNNEL_GENERATE_AUTH_TOKEN;
} else {
- next_state_ = STATE_SEND_REQUEST;
+ next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN;
}
}
@@ -975,27 +1001,29 @@ void HttpNetworkTransaction::ClearTunnelState() {
headers_valid_ = false;
}
+int HttpNetworkTransaction::DoTunnelGenerateAuthToken() {
+ next_state_ = STATE_TUNNEL_GENERATE_AUTH_TOKEN_COMPLETE;
+ return MaybeGenerateAuthToken(HttpAuth::AUTH_PROXY);
+}
+
+int HttpNetworkTransaction::DoTunnelGenerateAuthTokenComplete(int rv) {
+ DCHECK_NE(ERR_IO_PENDING, rv);
+ if (rv == OK)
+ next_state_ = STATE_TUNNEL_SEND_REQUEST;
+ return rv;
+}
+
int HttpNetworkTransaction::DoTunnelSendRequest() {
next_state_ = STATE_TUNNEL_SEND_REQUEST_COMPLETE;
// This is constructed lazily (instead of within our Start method), so that
// we have proxy info available.
if (request_headers_.empty()) {
- // Figure out if we can/should add Proxy-Authentication headers.
- bool have_proxy_auth =
- HaveAuth(HttpAuth::AUTH_PROXY) ||
- SelectPreemptiveAuth(HttpAuth::AUTH_PROXY);
-
- std::string request_line;
- HttpRequestHeaders request_headers;
HttpRequestHeaders authorization_headers;
-
- // TODO(wtc): If BuildAuthorizationHeader fails (returns an authorization
- // header with no credentials), we should return an error to prevent
- // entering an infinite auth restart loop. See http://crbug.com/21050.
- if (have_proxy_auth)
+ if (HaveAuth(HttpAuth::AUTH_PROXY))
AddAuthorizationHeader(HttpAuth::AUTH_PROXY, &authorization_headers);
-
+ std::string request_line;
+ HttpRequestHeaders request_headers;
BuildTunnelRequest(request_, authorization_headers, endpoint_,
&request_line, &request_headers);
if (net_log_.HasListener()) {
@@ -1162,6 +1190,7 @@ int HttpNetworkTransaction::DoSSLConnectComplete(int result) {
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",
@@ -1170,7 +1199,7 @@ int HttpNetworkTransaction::DoSSLConnectComplete(int result) {
base::TimeDelta::FromMinutes(10),
100);
- next_state_ = STATE_SEND_REQUEST;
+ next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN;
}
} else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
result = HandleCertificateRequest(result);
@@ -1180,6 +1209,34 @@ int HttpNetworkTransaction::DoSSLConnectComplete(int result) {
return result;
}
+int HttpNetworkTransaction::DoGenerateProxyAuthToken() {
+ next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE;
+ if (!ShouldApplyProxyAuth())
+ return OK;
+ return MaybeGenerateAuthToken(HttpAuth::AUTH_PROXY);
+}
+
+int HttpNetworkTransaction::DoGenerateProxyAuthTokenComplete(int rv) {
+ DCHECK_NE(ERR_IO_PENDING, rv);
+ if (rv == OK)
+ next_state_ = STATE_GENERATE_SERVER_AUTH_TOKEN;
+ return rv;
+}
+
+int HttpNetworkTransaction::DoGenerateServerAuthToken() {
+ next_state_ = STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE;
+ if (!ShouldApplyServerAuth())
+ return OK;
+ return MaybeGenerateAuthToken(HttpAuth::AUTH_SERVER);
+}
+
+int HttpNetworkTransaction::DoGenerateServerAuthTokenComplete(int rv) {
+ DCHECK_NE(ERR_IO_PENDING, rv);
+ if (rv == OK)
+ next_state_ = STATE_SEND_REQUEST;
+ return rv;
+}
+
int HttpNetworkTransaction::DoSendRequest() {
next_state_ = STATE_SEND_REQUEST_COMPLETE;
@@ -1196,27 +1253,17 @@ int HttpNetworkTransaction::DoSendRequest() {
if (request_headers_.empty()) {
// Figure out if we can/should add Proxy-Authentication & Authentication
// headers.
- bool have_proxy_auth =
- ShouldApplyProxyAuth() &&
- (HaveAuth(HttpAuth::AUTH_PROXY) ||
- SelectPreemptiveAuth(HttpAuth::AUTH_PROXY));
- bool have_server_auth =
- ShouldApplyServerAuth() &&
- (HaveAuth(HttpAuth::AUTH_SERVER) ||
- SelectPreemptiveAuth(HttpAuth::AUTH_SERVER));
-
- std::string request_line;
- HttpRequestHeaders request_headers;
HttpRequestHeaders authorization_headers;
-
- // TODO(wtc): If BuildAuthorizationHeader fails (returns an authorization
- // header with no credentials), we should return an error to prevent
- // entering an infinite auth restart loop. See http://crbug.com/21050.
+ bool have_proxy_auth = (ShouldApplyProxyAuth() &&
+ HaveAuth(HttpAuth::AUTH_PROXY));
+ bool have_server_auth = (ShouldApplyServerAuth() &&
+ HaveAuth(HttpAuth::AUTH_SERVER));
if (have_proxy_auth)
AddAuthorizationHeader(HttpAuth::AUTH_PROXY, &authorization_headers);
if (have_server_auth)
AddAuthorizationHeader(HttpAuth::AUTH_SERVER, &authorization_headers);
-
+ std::string request_line;
+ HttpRequestHeaders request_headers;
BuildRequestHeaders(request_, authorization_headers, request_body,
!using_ssl_ && proxy_info_.is_http(), &request_line,
&request_headers);
@@ -1244,15 +1291,12 @@ int HttpNetworkTransaction::DoSendRequest() {
int HttpNetworkTransaction::DoSendRequestComplete(int result) {
if (result < 0)
return HandleIOError(result);
-
next_state_ = STATE_READ_HEADERS;
-
return OK;
}
int HttpNetworkTransaction::DoReadHeaders() {
next_state_ = STATE_READ_HEADERS_COMPLETE;
-
return http_stream_->ReadResponseHeaders(&io_callback_);
}
@@ -1927,11 +1971,10 @@ bool HttpNetworkTransaction::ShouldApplyServerAuth() const {
return !(request_->load_flags & LOAD_DO_NOT_SEND_AUTH_DATA);
}
-void HttpNetworkTransaction::AddAuthorizationHeader(
- HttpAuth::Target target, HttpRequestHeaders* authorization_headers) const {
- DCHECK(HaveAuth(target));
-
- // Add a Authorization/Proxy-Authorization header line.
+int HttpNetworkTransaction::MaybeGenerateAuthToken(HttpAuth::Target target) {
+ bool needs_auth = HaveAuth(target) || SelectPreemptiveAuth(target);
+ if (!needs_auth)
+ return OK;
const std::wstring* username = NULL;
const std::wstring* password = NULL;
const HttpAuth::Identity& identity = auth_identity_[target];
@@ -1939,17 +1982,19 @@ void HttpNetworkTransaction::AddAuthorizationHeader(
username = &identity.username;
password = &identity.password;
}
- std::string auth_token;
- int rv = auth_handler_[target]->GenerateAuthToken(
- username, password, request_, NULL, &auth_token);
- if (rv == OK) {
- authorization_headers->SetHeader(
- HttpAuth::GetAuthorizationHeaderName(target), auth_token);
- }
+ DCHECK(auth_token_[target].empty());
+ return auth_handler_[target]->GenerateAuthToken(
+ username, password, request_, &io_callback_, &auth_token_[target]);
+}
- // TODO(cbentzel): Evict username and password from cache on non-OK return?
- // TODO(cbentzel): Never use this scheme again if
- // ERR_UNSUPPORTED_AUTH_SCHEME is returned.
+void HttpNetworkTransaction::AddAuthorizationHeader(
+ HttpAuth::Target target, HttpRequestHeaders* authorization_headers) {
+ DCHECK(HaveAuth(target));
+ DCHECK(!auth_token_[target].empty());
+ authorization_headers->SetHeader(
+ HttpAuth::GetAuthorizationHeaderName(target),
+ auth_token_[target]);
+ auth_token_[target].clear();
}
GURL HttpNetworkTransaction::AuthOrigin(HttpAuth::Target target) const {