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

Unified Diff: net/http/http_network_transaction.cc

Issue 1391053002: [net/http auth] Make HttpAuthHandler challenge handling asynchronous. Base URL: https://chromium.googlesource.com/chromium/src.git@auth-handler-init-split
Patch Set: Created 5 years, 2 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
« no previous file with comments | « net/http/http_network_transaction.h ('k') | net/http/http_network_transaction_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/http/http_network_transaction.cc
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc
index c12f95dfa6764397b7e7900121e191f017dda604..7644df733ab5f938b5abfb27a003b0e402733af4 100644
--- a/net/http/http_network_transaction.cc
+++ b/net/http/http_network_transaction.cc
@@ -709,6 +709,12 @@ int HttpNetworkTransaction::DoLoop(int result) {
net_log_.EndEventWithNetErrorCode(
NetLog::TYPE_HTTP_TRANSACTION_READ_HEADERS, rv);
break;
+ case STATE_HANDLE_AUTH_CHALLENGE:
+ rv = DoHandleAuthChallenge();
+ break;
+ case STATE_HANDLE_AUTH_CHALLENGE_COMPLETE:
+ rv = DoHandleAuthChallengeComplete(rv);
+ break;
case STATE_READ_BODY:
DCHECK_EQ(OK, rv);
net_log_.BeginEvent(NetLog::TYPE_HTTP_TRANSACTION_READ_BODY);
@@ -1102,17 +1108,72 @@ int HttpNetworkTransaction::DoReadHeadersComplete(int result) {
ProcessAlternativeServices(session_, *response_.headers.get(),
HostPortPair::FromURL(request_->url));
- int rv = HandleAuthChallenge();
- if (rv != OK)
- return rv;
-
if (IsSecureRequest())
stream_->GetSSLInfo(&response_.ssl_info);
- headers_valid_ = true;
+ next_state_ = STATE_HANDLE_AUTH_CHALLENGE;
return OK;
}
+int HttpNetworkTransaction::DoHandleAuthChallenge() {
+ const HttpResponseHeaders* headers = GetResponseHeaders();
+ DCHECK(headers);
+ // Note that the server or a proxy can send an authentication header with a
+ // response that doesn't have a 401 or 407 status code. This method is
+ // typically used to send the final authentication token for a multi-round
+ // authentication handshake where no further responses are necessary from the
+ // client.
+ // TODO(asanka): The logic below doesn't handle authentication headers if the
+ // status code isn't 401 or 407. Fix it.
+
+ int status = headers->response_code();
+ if (status != HTTP_UNAUTHORIZED &&
+ status != HTTP_PROXY_AUTHENTICATION_REQUIRED)
+ return OK;
+ HttpAuth::Target target = status == HTTP_PROXY_AUTHENTICATION_REQUIRED
+ ? HttpAuth::AUTH_PROXY
+ : HttpAuth::AUTH_SERVER;
+ if (target == HttpAuth::AUTH_PROXY && proxy_info_.is_direct())
+ return ERR_UNEXPECTED_PROXY_AUTH;
+
+ // This case can trigger when an HTTPS server responds with a "Proxy
+ // authentication required" status code through a non-authenticating
+ // proxy.
+ if (!auth_controllers_[target].get())
+ return ERR_UNEXPECTED_PROXY_AUTH;
+
+ if (target == HttpAuth::AUTH_SERVER && !ShouldApplyServerAuth())
+ return OK;
+
+ net_log_.BeginEvent(NetLog::TYPE_HTTP_TRANSACTION_HANDLE_AUTH_CHALLENGE);
+ pending_auth_target_ = target;
+ next_state_ = STATE_HANDLE_AUTH_CHALLENGE_COMPLETE;
+ return auth_controllers_[target]->HandleAuthChallenge(response_, io_callback_,
+ net_log_);
+}
+
+int HttpNetworkTransaction::DoHandleAuthChallengeComplete(int result) {
+ DCHECK(pending_auth_target_ == HttpAuth::AUTH_PROXY ||
+ pending_auth_target_ == HttpAuth::AUTH_SERVER);
+ net_log_.EndEventWithNetErrorCode(
+ NetLog::TYPE_HTTP_TRANSACTION_HANDLE_AUTH_CHALLENGE, result);
+ if (result == OK)
+ headers_valid_ = true;
+ // If there's no AuthHandler, then we won't be able to generate an
+ // authentication token next time around regardless of whether the caller
+ // provides credentials via ResetAuth().
+ if (!auth_controllers_[pending_auth_target_]->HaveAuthHandler()) {
+ pending_auth_target_ = HttpAuth::AUTH_NONE;
+ return result;
+ }
+ scoped_refptr<AuthChallengeInfo> auth_info =
+ auth_controllers_[pending_auth_target_]->auth_info();
+ if (auth_info.get())
+ response_.auth_challenge = auth_info;
+
+ return result;
+}
+
int HttpNetworkTransaction::DoReadBody() {
DCHECK(read_buf_.get());
DCHECK_GT(read_buf_len_, 0);
@@ -1562,39 +1623,6 @@ bool HttpNetworkTransaction::ShouldApplyServerAuth() const {
return !(request_->load_flags & LOAD_DO_NOT_SEND_AUTH_DATA);
}
-int HttpNetworkTransaction::HandleAuthChallenge() {
- scoped_refptr<HttpResponseHeaders> headers(GetResponseHeaders());
- DCHECK(headers.get());
-
- int status = headers->response_code();
- if (status != HTTP_UNAUTHORIZED &&
- status != HTTP_PROXY_AUTHENTICATION_REQUIRED)
- return OK;
- HttpAuth::Target target = status == HTTP_PROXY_AUTHENTICATION_REQUIRED ?
- HttpAuth::AUTH_PROXY : HttpAuth::AUTH_SERVER;
- if (target == HttpAuth::AUTH_PROXY && proxy_info_.is_direct())
- return ERR_UNEXPECTED_PROXY_AUTH;
-
- // This case can trigger when an HTTPS server responds with a "Proxy
- // authentication required" status code through a non-authenticating
- // proxy.
- if (!auth_controllers_[target].get())
- return ERR_UNEXPECTED_PROXY_AUTH;
-
- int rv = auth_controllers_[target]->HandleAuthChallenge(
- headers, (request_->load_flags & LOAD_DO_NOT_SEND_AUTH_DATA) != 0, false,
- net_log_);
- if (auth_controllers_[target]->HaveAuthHandler())
- pending_auth_target_ = target;
-
- scoped_refptr<AuthChallengeInfo> auth_info =
- auth_controllers_[target]->auth_info();
- if (auth_info.get())
- response_.auth_challenge = auth_info;
-
- return rv;
-}
-
bool HttpNetworkTransaction::HaveAuth(HttpAuth::Target target) const {
return auth_controllers_[target].get() &&
auth_controllers_[target]->HaveAuth();
« no previous file with comments | « net/http/http_network_transaction.h ('k') | net/http/http_network_transaction_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698