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

Side by Side 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 unified diff | 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/http/http_network_transaction.h" 5 #include "net/http/http_network_transaction.h"
6 6
7 #include <set> 7 #include <set>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after
702 case STATE_READ_HEADERS: 702 case STATE_READ_HEADERS:
703 DCHECK_EQ(OK, rv); 703 DCHECK_EQ(OK, rv);
704 net_log_.BeginEvent(NetLog::TYPE_HTTP_TRANSACTION_READ_HEADERS); 704 net_log_.BeginEvent(NetLog::TYPE_HTTP_TRANSACTION_READ_HEADERS);
705 rv = DoReadHeaders(); 705 rv = DoReadHeaders();
706 break; 706 break;
707 case STATE_READ_HEADERS_COMPLETE: 707 case STATE_READ_HEADERS_COMPLETE:
708 rv = DoReadHeadersComplete(rv); 708 rv = DoReadHeadersComplete(rv);
709 net_log_.EndEventWithNetErrorCode( 709 net_log_.EndEventWithNetErrorCode(
710 NetLog::TYPE_HTTP_TRANSACTION_READ_HEADERS, rv); 710 NetLog::TYPE_HTTP_TRANSACTION_READ_HEADERS, rv);
711 break; 711 break;
712 case STATE_HANDLE_AUTH_CHALLENGE:
713 rv = DoHandleAuthChallenge();
714 break;
715 case STATE_HANDLE_AUTH_CHALLENGE_COMPLETE:
716 rv = DoHandleAuthChallengeComplete(rv);
717 break;
712 case STATE_READ_BODY: 718 case STATE_READ_BODY:
713 DCHECK_EQ(OK, rv); 719 DCHECK_EQ(OK, rv);
714 net_log_.BeginEvent(NetLog::TYPE_HTTP_TRANSACTION_READ_BODY); 720 net_log_.BeginEvent(NetLog::TYPE_HTTP_TRANSACTION_READ_BODY);
715 rv = DoReadBody(); 721 rv = DoReadBody();
716 break; 722 break;
717 case STATE_READ_BODY_COMPLETE: 723 case STATE_READ_BODY_COMPLETE:
718 rv = DoReadBodyComplete(rv); 724 rv = DoReadBodyComplete(rv);
719 net_log_.EndEventWithNetErrorCode( 725 net_log_.EndEventWithNetErrorCode(
720 NetLog::TYPE_HTTP_TRANSACTION_READ_BODY, rv); 726 NetLog::TYPE_HTTP_TRANSACTION_READ_BODY, rv);
721 break; 727 break;
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
1095 if (response_.headers->response_code() / 100 == 1 && 1101 if (response_.headers->response_code() / 100 == 1 &&
1096 !ForWebSocketHandshake()) { 1102 !ForWebSocketHandshake()) {
1097 response_.headers = new HttpResponseHeaders(std::string()); 1103 response_.headers = new HttpResponseHeaders(std::string());
1098 next_state_ = STATE_READ_HEADERS; 1104 next_state_ = STATE_READ_HEADERS;
1099 return OK; 1105 return OK;
1100 } 1106 }
1101 1107
1102 ProcessAlternativeServices(session_, *response_.headers.get(), 1108 ProcessAlternativeServices(session_, *response_.headers.get(),
1103 HostPortPair::FromURL(request_->url)); 1109 HostPortPair::FromURL(request_->url));
1104 1110
1105 int rv = HandleAuthChallenge();
1106 if (rv != OK)
1107 return rv;
1108
1109 if (IsSecureRequest()) 1111 if (IsSecureRequest())
1110 stream_->GetSSLInfo(&response_.ssl_info); 1112 stream_->GetSSLInfo(&response_.ssl_info);
1111 1113
1112 headers_valid_ = true; 1114 next_state_ = STATE_HANDLE_AUTH_CHALLENGE;
1113 return OK; 1115 return OK;
1114 } 1116 }
1115 1117
1118 int HttpNetworkTransaction::DoHandleAuthChallenge() {
1119 const HttpResponseHeaders* headers = GetResponseHeaders();
1120 DCHECK(headers);
1121 // Note that the server or a proxy can send an authentication header with a
1122 // response that doesn't have a 401 or 407 status code. This method is
1123 // typically used to send the final authentication token for a multi-round
1124 // authentication handshake where no further responses are necessary from the
1125 // client.
1126 // TODO(asanka): The logic below doesn't handle authentication headers if the
1127 // status code isn't 401 or 407. Fix it.
1128
1129 int status = headers->response_code();
1130 if (status != HTTP_UNAUTHORIZED &&
1131 status != HTTP_PROXY_AUTHENTICATION_REQUIRED)
1132 return OK;
1133 HttpAuth::Target target = status == HTTP_PROXY_AUTHENTICATION_REQUIRED
1134 ? HttpAuth::AUTH_PROXY
1135 : HttpAuth::AUTH_SERVER;
1136 if (target == HttpAuth::AUTH_PROXY && proxy_info_.is_direct())
1137 return ERR_UNEXPECTED_PROXY_AUTH;
1138
1139 // This case can trigger when an HTTPS server responds with a "Proxy
1140 // authentication required" status code through a non-authenticating
1141 // proxy.
1142 if (!auth_controllers_[target].get())
1143 return ERR_UNEXPECTED_PROXY_AUTH;
1144
1145 if (target == HttpAuth::AUTH_SERVER && !ShouldApplyServerAuth())
1146 return OK;
1147
1148 net_log_.BeginEvent(NetLog::TYPE_HTTP_TRANSACTION_HANDLE_AUTH_CHALLENGE);
1149 pending_auth_target_ = target;
1150 next_state_ = STATE_HANDLE_AUTH_CHALLENGE_COMPLETE;
1151 return auth_controllers_[target]->HandleAuthChallenge(response_, io_callback_,
1152 net_log_);
1153 }
1154
1155 int HttpNetworkTransaction::DoHandleAuthChallengeComplete(int result) {
1156 DCHECK(pending_auth_target_ == HttpAuth::AUTH_PROXY ||
1157 pending_auth_target_ == HttpAuth::AUTH_SERVER);
1158 net_log_.EndEventWithNetErrorCode(
1159 NetLog::TYPE_HTTP_TRANSACTION_HANDLE_AUTH_CHALLENGE, result);
1160 if (result == OK)
1161 headers_valid_ = true;
1162 // If there's no AuthHandler, then we won't be able to generate an
1163 // authentication token next time around regardless of whether the caller
1164 // provides credentials via ResetAuth().
1165 if (!auth_controllers_[pending_auth_target_]->HaveAuthHandler()) {
1166 pending_auth_target_ = HttpAuth::AUTH_NONE;
1167 return result;
1168 }
1169 scoped_refptr<AuthChallengeInfo> auth_info =
1170 auth_controllers_[pending_auth_target_]->auth_info();
1171 if (auth_info.get())
1172 response_.auth_challenge = auth_info;
1173
1174 return result;
1175 }
1176
1116 int HttpNetworkTransaction::DoReadBody() { 1177 int HttpNetworkTransaction::DoReadBody() {
1117 DCHECK(read_buf_.get()); 1178 DCHECK(read_buf_.get());
1118 DCHECK_GT(read_buf_len_, 0); 1179 DCHECK_GT(read_buf_len_, 0);
1119 DCHECK(stream_ != NULL); 1180 DCHECK(stream_ != NULL);
1120 1181
1121 next_state_ = STATE_READ_BODY_COMPLETE; 1182 next_state_ = STATE_READ_BODY_COMPLETE;
1122 return stream_->ReadResponseBody( 1183 return stream_->ReadResponseBody(
1123 read_buf_.get(), read_buf_len_, io_callback_); 1184 read_buf_.get(), read_buf_len_, io_callback_);
1124 } 1185 }
1125 1186
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
1555 } 1616 }
1556 1617
1557 bool HttpNetworkTransaction::ShouldApplyProxyAuth() const { 1618 bool HttpNetworkTransaction::ShouldApplyProxyAuth() const {
1558 return UsingHttpProxyWithoutTunnel(); 1619 return UsingHttpProxyWithoutTunnel();
1559 } 1620 }
1560 1621
1561 bool HttpNetworkTransaction::ShouldApplyServerAuth() const { 1622 bool HttpNetworkTransaction::ShouldApplyServerAuth() const {
1562 return !(request_->load_flags & LOAD_DO_NOT_SEND_AUTH_DATA); 1623 return !(request_->load_flags & LOAD_DO_NOT_SEND_AUTH_DATA);
1563 } 1624 }
1564 1625
1565 int HttpNetworkTransaction::HandleAuthChallenge() {
1566 scoped_refptr<HttpResponseHeaders> headers(GetResponseHeaders());
1567 DCHECK(headers.get());
1568
1569 int status = headers->response_code();
1570 if (status != HTTP_UNAUTHORIZED &&
1571 status != HTTP_PROXY_AUTHENTICATION_REQUIRED)
1572 return OK;
1573 HttpAuth::Target target = status == HTTP_PROXY_AUTHENTICATION_REQUIRED ?
1574 HttpAuth::AUTH_PROXY : HttpAuth::AUTH_SERVER;
1575 if (target == HttpAuth::AUTH_PROXY && proxy_info_.is_direct())
1576 return ERR_UNEXPECTED_PROXY_AUTH;
1577
1578 // This case can trigger when an HTTPS server responds with a "Proxy
1579 // authentication required" status code through a non-authenticating
1580 // proxy.
1581 if (!auth_controllers_[target].get())
1582 return ERR_UNEXPECTED_PROXY_AUTH;
1583
1584 int rv = auth_controllers_[target]->HandleAuthChallenge(
1585 headers, (request_->load_flags & LOAD_DO_NOT_SEND_AUTH_DATA) != 0, false,
1586 net_log_);
1587 if (auth_controllers_[target]->HaveAuthHandler())
1588 pending_auth_target_ = target;
1589
1590 scoped_refptr<AuthChallengeInfo> auth_info =
1591 auth_controllers_[target]->auth_info();
1592 if (auth_info.get())
1593 response_.auth_challenge = auth_info;
1594
1595 return rv;
1596 }
1597
1598 bool HttpNetworkTransaction::HaveAuth(HttpAuth::Target target) const { 1626 bool HttpNetworkTransaction::HaveAuth(HttpAuth::Target target) const {
1599 return auth_controllers_[target].get() && 1627 return auth_controllers_[target].get() &&
1600 auth_controllers_[target]->HaveAuth(); 1628 auth_controllers_[target]->HaveAuth();
1601 } 1629 }
1602 1630
1603 GURL HttpNetworkTransaction::AuthURL(HttpAuth::Target target) const { 1631 GURL HttpNetworkTransaction::AuthURL(HttpAuth::Target target) const {
1604 switch (target) { 1632 switch (target) {
1605 case HttpAuth::AUTH_PROXY: { 1633 case HttpAuth::AUTH_PROXY: {
1606 if (!proxy_info_.proxy_server().is_valid() || 1634 if (!proxy_info_.proxy_server().is_valid() ||
1607 proxy_info_.proxy_server().is_direct()) { 1635 proxy_info_.proxy_server().is_direct()) {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1672 DCHECK(stream_request_); 1700 DCHECK(stream_request_);
1673 1701
1674 // Since the transaction can restart with auth credentials, it may create a 1702 // Since the transaction can restart with auth credentials, it may create a
1675 // stream more than once. Accumulate all of the connection attempts across 1703 // stream more than once. Accumulate all of the connection attempts across
1676 // those streams by appending them to the vector: 1704 // those streams by appending them to the vector:
1677 for (const auto& attempt : stream_request_->connection_attempts()) 1705 for (const auto& attempt : stream_request_->connection_attempts())
1678 connection_attempts_.push_back(attempt); 1706 connection_attempts_.push_back(attempt);
1679 } 1707 }
1680 1708
1681 } // namespace net 1709 } // namespace net
OLDNEW
« 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