OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |