OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 "base/scoped_ptr.h" | 7 #include "base/scoped_ptr.h" |
8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
9 #include "base/field_trial.h" | 9 #include "base/field_trial.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
(...skipping 17 matching lines...) Expand all Loading... |
28 #include "net/http/http_util.h" | 28 #include "net/http/http_util.h" |
29 | 29 |
30 using base::Time; | 30 using base::Time; |
31 | 31 |
32 namespace net { | 32 namespace net { |
33 | 33 |
34 //----------------------------------------------------------------------------- | 34 //----------------------------------------------------------------------------- |
35 | 35 |
36 HttpNetworkTransaction::HttpNetworkTransaction(HttpNetworkSession* session, | 36 HttpNetworkTransaction::HttpNetworkTransaction(HttpNetworkSession* session, |
37 ClientSocketFactory* csf) | 37 ClientSocketFactory* csf) |
38 : ALLOW_THIS_IN_INITIALIZER_LIST( | 38 : pending_auth_target_(HttpAuth::AUTH_NONE), |
| 39 ALLOW_THIS_IN_INITIALIZER_LIST( |
39 io_callback_(this, &HttpNetworkTransaction::OnIOComplete)), | 40 io_callback_(this, &HttpNetworkTransaction::OnIOComplete)), |
40 user_callback_(NULL), | 41 user_callback_(NULL), |
41 session_(session), | 42 session_(session), |
42 request_(NULL), | 43 request_(NULL), |
43 pac_request_(NULL), | 44 pac_request_(NULL), |
44 socket_factory_(csf), | 45 socket_factory_(csf), |
45 connection_(session->connection_pool()), | 46 connection_(session->connection_pool()), |
46 reused_socket_(false), | 47 reused_socket_(false), |
47 using_ssl_(false), | 48 using_ssl_(false), |
48 using_proxy_(false), | 49 using_proxy_(false), |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 int rv = DoLoop(OK); | 86 int rv = DoLoop(OK); |
86 if (rv == ERR_IO_PENDING) | 87 if (rv == ERR_IO_PENDING) |
87 user_callback_ = callback; | 88 user_callback_ = callback; |
88 return rv; | 89 return rv; |
89 } | 90 } |
90 | 91 |
91 int HttpNetworkTransaction::RestartWithAuth( | 92 int HttpNetworkTransaction::RestartWithAuth( |
92 const std::wstring& username, | 93 const std::wstring& username, |
93 const std::wstring& password, | 94 const std::wstring& password, |
94 CompletionCallback* callback) { | 95 CompletionCallback* callback) { |
| 96 HttpAuth::Target target = pending_auth_target_; |
| 97 if (target == HttpAuth::AUTH_NONE) { |
| 98 NOTREACHED(); |
| 99 return ERR_UNEXPECTED; |
| 100 } |
95 | 101 |
96 DCHECK(NeedAuth(HttpAuth::AUTH_PROXY) || | 102 pending_auth_target_ = HttpAuth::AUTH_NONE; |
97 NeedAuth(HttpAuth::AUTH_SERVER)); | |
98 | 103 |
99 // Figure out whether this username password is for proxy or server. | 104 DCHECK(auth_identity_[target].invalid || |
100 // Proxy gets set first, then server. | 105 (username.empty() && password.empty())); |
101 HttpAuth::Target target = NeedAuth(HttpAuth::AUTH_PROXY) ? | |
102 HttpAuth::AUTH_PROXY : HttpAuth::AUTH_SERVER; | |
103 | 106 |
104 // Update the username/password. | 107 if (auth_identity_[target].invalid) { |
105 auth_identity_[target].source = HttpAuth::IDENT_SRC_EXTERNAL; | 108 // Update the username/password. |
106 auth_identity_[target].invalid = false; | 109 auth_identity_[target].source = HttpAuth::IDENT_SRC_EXTERNAL; |
107 auth_identity_[target].username = username; | 110 auth_identity_[target].invalid = false; |
108 auth_identity_[target].password = password; | 111 auth_identity_[target].username = username; |
| 112 auth_identity_[target].password = password; |
| 113 } |
109 | 114 |
110 PrepareForAuthRestart(target); | 115 PrepareForAuthRestart(target); |
111 | 116 |
112 DCHECK(user_callback_ == NULL); | 117 DCHECK(user_callback_ == NULL); |
113 int rv = DoLoop(OK); | 118 int rv = DoLoop(OK); |
114 if (rv == ERR_IO_PENDING) | 119 if (rv == ERR_IO_PENDING) |
115 user_callback_ = callback; | 120 user_callback_ = callback; |
116 | 121 |
117 return rv; | 122 return rv; |
118 } | 123 } |
(...skipping 968 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1087 response_.headers->HasHeaderValue("Transfer-Encoding", "chunked")) { | 1092 response_.headers->HasHeaderValue("Transfer-Encoding", "chunked")) { |
1088 chunked_decoder_.reset(new HttpChunkedDecoder()); | 1093 chunked_decoder_.reset(new HttpChunkedDecoder()); |
1089 } else { | 1094 } else { |
1090 response_body_length_ = response_.headers->GetContentLength(); | 1095 response_body_length_ = response_.headers->GetContentLength(); |
1091 // If response_body_length_ is still -1, then we have to wait for the | 1096 // If response_body_length_ is still -1, then we have to wait for the |
1092 // server to close the connection. | 1097 // server to close the connection. |
1093 } | 1098 } |
1094 } | 1099 } |
1095 | 1100 |
1096 int rv = HandleAuthChallenge(); | 1101 int rv = HandleAuthChallenge(); |
1097 if (rv == WILL_RESTART_TRANSACTION) | |
1098 return OK; | |
1099 if (rv != OK) | 1102 if (rv != OK) |
1100 return rv; | 1103 return rv; |
1101 | 1104 |
1102 if (using_ssl_ && !establishing_tunnel_) { | 1105 if (using_ssl_ && !establishing_tunnel_) { |
1103 SSLClientSocket* ssl_socket = | 1106 SSLClientSocket* ssl_socket = |
1104 reinterpret_cast<SSLClientSocket*>(connection_.socket()); | 1107 reinterpret_cast<SSLClientSocket*>(connection_.socket()); |
1105 ssl_socket->GetSSLInfo(&response_.ssl_info); | 1108 ssl_socket->GetSSLInfo(&response_.ssl_info); |
1106 } | 1109 } |
1107 | 1110 |
1108 return OK; | 1111 return OK; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1172 case ERR_CONNECTION_CLOSED: | 1175 case ERR_CONNECTION_CLOSED: |
1173 case ERR_CONNECTION_ABORTED: | 1176 case ERR_CONNECTION_ABORTED: |
1174 if (ShouldResendRequest()) | 1177 if (ShouldResendRequest()) |
1175 error = OK; | 1178 error = OK; |
1176 break; | 1179 break; |
1177 } | 1180 } |
1178 return error; | 1181 return error; |
1179 } | 1182 } |
1180 | 1183 |
1181 void HttpNetworkTransaction::ResetStateForRestart() { | 1184 void HttpNetworkTransaction::ResetStateForRestart() { |
| 1185 pending_auth_target_ = HttpAuth::AUTH_NONE; |
1182 header_buf_.reset(); | 1186 header_buf_.reset(); |
1183 header_buf_capacity_ = 0; | 1187 header_buf_capacity_ = 0; |
1184 header_buf_len_ = 0; | 1188 header_buf_len_ = 0; |
1185 header_buf_body_offset_ = -1; | 1189 header_buf_body_offset_ = -1; |
1186 header_buf_http_offset_ = -1; | 1190 header_buf_http_offset_ = -1; |
1187 response_body_length_ = -1; | 1191 response_body_length_ = -1; |
1188 response_body_read_ = 0; | 1192 response_body_read_ = 0; |
1189 read_buf_ = NULL; | 1193 read_buf_ = NULL; |
1190 read_buf_len_ = 0; | 1194 read_buf_len_ = 0; |
1191 request_headers_.clear(); | 1195 request_headers_.clear(); |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1463 // active network attacker could control its contents. Instead, we just | 1467 // active network attacker could control its contents. Instead, we just |
1464 // fail to establish the tunnel. | 1468 // fail to establish the tunnel. |
1465 DCHECK(target == HttpAuth::AUTH_PROXY); | 1469 DCHECK(target == HttpAuth::AUTH_PROXY); |
1466 return ERR_PROXY_AUTH_REQUESTED; | 1470 return ERR_PROXY_AUTH_REQUESTED; |
1467 } | 1471 } |
1468 // We found no supported challenge -- let the transaction continue | 1472 // We found no supported challenge -- let the transaction continue |
1469 // so we end up displaying the error page. | 1473 // so we end up displaying the error page. |
1470 return OK; | 1474 return OK; |
1471 } | 1475 } |
1472 | 1476 |
1473 bool has_identity_to_try; | |
1474 if (auth_handler_[target]->NeedsIdentity()) { | 1477 if (auth_handler_[target]->NeedsIdentity()) { |
1475 // Pick a new auth identity to try, by looking to the URL and auth cache. | 1478 // Pick a new auth identity to try, by looking to the URL and auth cache. |
1476 // If an identity to try is found, it is saved to auth_identity_[target]. | 1479 // If an identity to try is found, it is saved to auth_identity_[target]. |
1477 has_identity_to_try = SelectNextAuthIdentityToTry(target); | 1480 SelectNextAuthIdentityToTry(target); |
1478 } else { | 1481 } else { |
1479 // Proceed with a null identity. | 1482 // Proceed with a null identity. |
1480 // | 1483 // |
1481 // TODO(wtc): Add a safeguard against infinite transaction restarts, if | 1484 // TODO(wtc): Add a safeguard against infinite transaction restarts, if |
1482 // the server keeps returning "NTLM". | 1485 // the server keeps returning "NTLM". |
1483 auth_identity_[target].source = HttpAuth::IDENT_SRC_NONE; | 1486 auth_identity_[target].source = HttpAuth::IDENT_SRC_NONE; |
1484 auth_identity_[target].invalid = false; | 1487 auth_identity_[target].invalid = false; |
1485 auth_identity_[target].username.clear(); | 1488 auth_identity_[target].username.clear(); |
1486 auth_identity_[target].password.clear(); | 1489 auth_identity_[target].password.clear(); |
1487 has_identity_to_try = true; | |
1488 } | |
1489 DCHECK(has_identity_to_try == !auth_identity_[target].invalid); | |
1490 | |
1491 if (has_identity_to_try) { | |
1492 DCHECK(user_callback_); | |
1493 PrepareForAuthRestart(target); | |
1494 return WILL_RESTART_TRANSACTION; | |
1495 } | 1490 } |
1496 | 1491 |
1497 // We have exhausted all identity possibilities, all we can do now is | 1492 // Make a note that we are waiting for auth. This variable is inspected |
1498 // pass the challenge information back to the client. | 1493 // when the client calls RestartWithAuth() to pick up where we left off. |
1499 PopulateAuthChallenge(target); | 1494 pending_auth_target_ = target; |
| 1495 |
| 1496 if (auth_identity_[target].invalid) { |
| 1497 // We have exhausted all identity possibilities, all we can do now is |
| 1498 // pass the challenge information back to the client. |
| 1499 PopulateAuthChallenge(target); |
| 1500 } |
1500 return OK; | 1501 return OK; |
1501 } | 1502 } |
1502 | 1503 |
1503 void HttpNetworkTransaction::PopulateAuthChallenge(HttpAuth::Target target) { | 1504 void HttpNetworkTransaction::PopulateAuthChallenge(HttpAuth::Target target) { |
1504 // Populates response_.auth_challenge with the authentication challenge info. | 1505 // Populates response_.auth_challenge with the authentication challenge info. |
1505 // This info is consumed by URLRequestHttpJob::GetAuthChallengeInfo(). | 1506 // This info is consumed by URLRequestHttpJob::GetAuthChallengeInfo(). |
1506 | 1507 |
1507 AuthChallengeInfo* auth_info = new AuthChallengeInfo; | 1508 AuthChallengeInfo* auth_info = new AuthChallengeInfo; |
1508 auth_info->is_proxy = target == HttpAuth::AUTH_PROXY; | 1509 auth_info->is_proxy = target == HttpAuth::AUTH_PROXY; |
1509 auth_info->scheme = ASCIIToWide(auth_handler_[target]->scheme()); | 1510 auth_info->scheme = ASCIIToWide(auth_handler_[target]->scheme()); |
1510 // TODO(eroman): decode realm according to RFC 2047. | 1511 // TODO(eroman): decode realm according to RFC 2047. |
1511 auth_info->realm = ASCIIToWide(auth_handler_[target]->realm()); | 1512 auth_info->realm = ASCIIToWide(auth_handler_[target]->realm()); |
1512 if (target == HttpAuth::AUTH_PROXY) { | 1513 if (target == HttpAuth::AUTH_PROXY) { |
1513 auth_info->host = ASCIIToWide(proxy_info_.proxy_server().host_and_port()); | 1514 auth_info->host = ASCIIToWide(proxy_info_.proxy_server().host_and_port()); |
1514 } else { | 1515 } else { |
1515 DCHECK(target == HttpAuth::AUTH_SERVER); | 1516 DCHECK(target == HttpAuth::AUTH_SERVER); |
1516 auth_info->host = ASCIIToWide(request_->url.host()); | 1517 auth_info->host = ASCIIToWide(request_->url.host()); |
1517 } | 1518 } |
1518 response_.auth_challenge = auth_info; | 1519 response_.auth_challenge = auth_info; |
1519 } | 1520 } |
1520 | 1521 |
1521 } // namespace net | 1522 } // namespace net |
OLD | NEW |