| 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 |