willchan@chromium.org | ef2bf42 | 2012-05-11 03:27:09 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
wtc@chromium.org | b65ce094 | 2009-03-16 20:13:33 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
phajdan.jr@chromium.org | e7fe528 | 2010-03-16 12:40:13 | [diff] [blame] | 5 | #include "net/url_request/url_request_ftp_job.h" |
wtc@chromium.org | b65ce094 | 2009-03-16 20:13:33 | [diff] [blame] | 6 | |
phajdan.jr@chromium.org | f539333 | 2009-06-03 15:01:29 | [diff] [blame] | 7 | #include "base/compiler_specific.h" |
skyostil | 4891b25b | 2015-06-11 11:43:45 | [diff] [blame] | 8 | #include "base/location.h" |
| 9 | #include "base/single_thread_task_runner.h" |
avi@chromium.org | 750b2f3c | 2013-06-07 18:41:05 | [diff] [blame] | 10 | #include "base/strings/utf_string_conversions.h" |
gab | f767595f | 2016-05-11 18:50:35 | [diff] [blame] | 11 | #include "base/threading/thread_task_runner_handle.h" |
phajdan.jr@chromium.org | 8b8a197d | 2009-08-26 15:57:58 | [diff] [blame] | 12 | #include "net/base/auth.h" |
bryner@chromium.org | 6d81b48 | 2011-02-22 19:47:19 | [diff] [blame] | 13 | #include "net/base/host_port_pair.h" |
phajdan.jr@chromium.org | 4549925 | 2013-01-23 17:12:56 | [diff] [blame] | 14 | #include "net/base/load_flags.h" |
phajdan.jr@chromium.org | 597cf6e | 2009-05-29 09:43:26 | [diff] [blame] | 15 | #include "net/base/net_errors.h" |
pauljensen@chromium.org | e0f35c9 | 2013-05-08 16:04:34 | [diff] [blame] | 16 | #include "net/ftp/ftp_auth_cache.h" |
wtc@chromium.org | 581e0d0 | 2009-05-11 17:01:17 | [diff] [blame] | 17 | #include "net/ftp/ftp_response_info.h" |
| 18 | #include "net/ftp/ftp_transaction_factory.h" |
phajdan.jr@chromium.org | 4549925 | 2013-01-23 17:12:56 | [diff] [blame] | 19 | #include "net/http/http_response_headers.h" |
| 20 | #include "net/http/http_transaction_factory.h" |
wtc@chromium.org | b65ce094 | 2009-03-16 20:13:33 | [diff] [blame] | 21 | #include "net/url_request/url_request.h" |
| 22 | #include "net/url_request/url_request_context.h" |
| 23 | #include "net/url_request/url_request_error_job.h" |
| 24 | |
tfarina@chromium.org | 03ea3c52 | 2010-12-12 01:47:54 | [diff] [blame] | 25 | namespace net { |
| 26 | |
asanka | 4cdf16d3 | 2016-10-06 22:00:24 | [diff] [blame] | 27 | class URLRequestFtpJob::AuthData { |
| 28 | public: |
| 29 | AuthState state; // Whether we need, have, or gave up on authentication. |
| 30 | AuthCredentials credentials; // The credentials to use for auth. |
| 31 | |
| 32 | AuthData(); |
| 33 | ~AuthData(); |
| 34 | }; |
| 35 | |
| 36 | URLRequestFtpJob::AuthData::AuthData() : state(AUTH_STATE_NEED_AUTH) {} |
| 37 | |
Chris Watkins | 7a41d355 | 2017-12-01 02:13:27 | [diff] [blame] | 38 | URLRequestFtpJob::AuthData::~AuthData() = default; |
asanka | 4cdf16d3 | 2016-10-06 22:00:24 | [diff] [blame] | 39 | |
shalev@chromium.org | b9cf48b | 2012-07-11 15:45:59 | [diff] [blame] | 40 | URLRequestFtpJob::URLRequestFtpJob( |
| 41 | URLRequest* request, |
| 42 | NetworkDelegate* network_delegate, |
| 43 | FtpTransactionFactory* ftp_transaction_factory, |
| 44 | FtpAuthCache* ftp_auth_cache) |
| 45 | : URLRequestJob(request, network_delegate), |
akalin@chromium.org | 5033ab8 | 2013-03-22 20:17:46 | [diff] [blame] | 46 | priority_(DEFAULT_PRIORITY), |
Lily Houghton | 8c2f97d | 2018-01-22 05:06:59 | [diff] [blame] | 47 | proxy_resolution_service_( |
| 48 | request_->context()->proxy_resolution_service()), |
phajdan.jr@chromium.org | 7886251 | 2013-04-08 20:12:43 | [diff] [blame] | 49 | http_response_info_(NULL), |
wtc@chromium.org | b65ce094 | 2009-03-16 20:13:33 | [diff] [blame] | 50 | read_in_progress_(false), |
shalev@chromium.org | b9cf48b | 2012-07-11 15:45:59 | [diff] [blame] | 51 | ftp_transaction_factory_(ftp_transaction_factory), |
n.bansal@samsung.com | 0981210 | 2014-05-24 00:04:11 | [diff] [blame] | 52 | ftp_auth_cache_(ftp_auth_cache), |
| 53 | weak_factory_(this) { |
Lily Houghton | 8c2f97d | 2018-01-22 05:06:59 | [diff] [blame] | 54 | DCHECK(proxy_resolution_service_); |
shalev@chromium.org | b9cf48b | 2012-07-11 15:45:59 | [diff] [blame] | 55 | DCHECK(ftp_transaction_factory); |
| 56 | DCHECK(ftp_auth_cache); |
wtc@chromium.org | b65ce094 | 2009-03-16 20:13:33 | [diff] [blame] | 57 | } |
| 58 | |
akalin@chromium.org | 5033ab8 | 2013-03-22 20:17:46 | [diff] [blame] | 59 | URLRequestFtpJob::~URLRequestFtpJob() { |
mmenke | 8a79ddb | 2015-10-27 12:30:58 | [diff] [blame] | 60 | Kill(); |
akalin@chromium.org | 5033ab8 | 2013-03-22 20:17:46 | [diff] [blame] | 61 | } |
| 62 | |
phajdan.jr@chromium.org | 4549925 | 2013-01-23 17:12:56 | [diff] [blame] | 63 | bool URLRequestFtpJob::IsSafeRedirect(const GURL& location) { |
| 64 | // Disallow all redirects. |
| 65 | return false; |
| 66 | } |
| 67 | |
phajdan.jr@chromium.org | e7fe528 | 2010-03-16 12:40:13 | [diff] [blame] | 68 | bool URLRequestFtpJob::GetMimeType(std::string* mime_type) const { |
phajdan.jr@chromium.org | 4549925 | 2013-01-23 17:12:56 | [diff] [blame] | 69 | if (proxy_info_.is_direct()) { |
| 70 | if (ftp_transaction_->GetResponseInfo()->is_directory_listing) { |
| 71 | *mime_type = "text/vnd.chromium.ftp-dir"; |
| 72 | return true; |
| 73 | } |
| 74 | } else { |
Mike West | 80462a1 | 2018-11-27 16:05:06 | [diff] [blame] | 75 | std::string proxy_mime; |
| 76 | http_transaction_->GetResponseInfo()->headers->GetMimeType(&proxy_mime); |
| 77 | if (proxy_mime == "text/vnd.chromium.ftp-dir") { |
| 78 | *mime_type = "text/vnd.chromium.ftp-dir"; |
| 79 | return true; |
| 80 | } |
phajdan.jr@chromium.org | 64d50ed | 2009-09-22 21:05:47 | [diff] [blame] | 81 | } |
Mike West | 80462a1 | 2018-11-27 16:05:06 | [diff] [blame] | 82 | |
| 83 | // FTP resources other than directory listings ought to be handled as raw |
| 84 | // binary data, not sniffed into HTML or etc. |
| 85 | *mime_type = "application/octet-stream"; |
| 86 | return true; |
phajdan.jr@chromium.org | 64d50ed | 2009-09-22 21:05:47 | [diff] [blame] | 87 | } |
| 88 | |
phajdan.jr@chromium.org | 4549925 | 2013-01-23 17:12:56 | [diff] [blame] | 89 | void URLRequestFtpJob::GetResponseInfo(HttpResponseInfo* info) { |
phajdan.jr@chromium.org | 7886251 | 2013-04-08 20:12:43 | [diff] [blame] | 90 | if (http_response_info_) |
| 91 | *info = *http_response_info_; |
phajdan.jr@chromium.org | 4549925 | 2013-01-23 17:12:56 | [diff] [blame] | 92 | } |
| 93 | |
bryner@chromium.org | 6d81b48 | 2011-02-22 19:47:19 | [diff] [blame] | 94 | HostPortPair URLRequestFtpJob::GetSocketAddress() const { |
phajdan.jr@chromium.org | 4549925 | 2013-01-23 17:12:56 | [diff] [blame] | 95 | if (proxy_info_.is_direct()) { |
| 96 | if (!ftp_transaction_) |
| 97 | return HostPortPair(); |
| 98 | return ftp_transaction_->GetResponseInfo()->socket_address; |
| 99 | } else { |
| 100 | if (!http_transaction_) |
| 101 | return HostPortPair(); |
| 102 | return http_transaction_->GetResponseInfo()->socket_address; |
bryner@chromium.org | 6d81b48 | 2011-02-22 19:47:19 | [diff] [blame] | 103 | } |
bryner@chromium.org | 6d81b48 | 2011-02-22 19:47:19 | [diff] [blame] | 104 | } |
| 105 | |
akalin@chromium.org | 5033ab8 | 2013-03-22 20:17:46 | [diff] [blame] | 106 | void URLRequestFtpJob::SetPriority(RequestPriority priority) { |
| 107 | priority_ = priority; |
| 108 | if (http_transaction_) |
| 109 | http_transaction_->SetPriority(priority); |
| 110 | } |
| 111 | |
| 112 | void URLRequestFtpJob::Start() { |
Lily Houghton | 00e124d | 2018-01-12 21:40:39 | [diff] [blame] | 113 | DCHECK(!proxy_resolve_request_); |
akalin@chromium.org | 5033ab8 | 2013-03-22 20:17:46 | [diff] [blame] | 114 | DCHECK(!ftp_transaction_); |
| 115 | DCHECK(!http_transaction_); |
| 116 | |
| 117 | int rv = OK; |
| 118 | if (request_->load_flags() & LOAD_BYPASS_PROXY) { |
| 119 | proxy_info_.UseDirect(); |
| 120 | } else { |
Lily Houghton | 8c2f97d | 2018-01-22 05:06:59 | [diff] [blame] | 121 | DCHECK_EQ(request_->context()->proxy_resolution_service(), |
| 122 | proxy_resolution_service_); |
| 123 | rv = proxy_resolution_service_->ResolveProxy( |
ryansturm | 7bd591a | 2016-07-18 21:57:38 | [diff] [blame] | 124 | request_->url(), "GET", &proxy_info_, |
akalin@chromium.org | 5033ab8 | 2013-03-22 20:17:46 | [diff] [blame] | 125 | base::Bind(&URLRequestFtpJob::OnResolveProxyComplete, |
| 126 | base::Unretained(this)), |
Eric Roman | 3d8546a | 2018-09-10 17:00:52 | [diff] [blame] | 127 | &proxy_resolve_request_, request_->net_log()); |
akalin@chromium.org | 5033ab8 | 2013-03-22 20:17:46 | [diff] [blame] | 128 | |
| 129 | if (rv == ERR_IO_PENDING) |
| 130 | return; |
| 131 | } |
| 132 | OnResolveProxyComplete(rv); |
| 133 | } |
| 134 | |
| 135 | void URLRequestFtpJob::Kill() { |
Lily Houghton | 00e124d | 2018-01-12 21:40:39 | [diff] [blame] | 136 | if (proxy_resolve_request_) { |
Lily Houghton | 0e9a499 | 2018-07-30 22:40:37 | [diff] [blame] | 137 | proxy_resolve_request_.reset(); |
mmenke | 8a79ddb | 2015-10-27 12:30:58 | [diff] [blame] | 138 | } |
akalin@chromium.org | 5033ab8 | 2013-03-22 20:17:46 | [diff] [blame] | 139 | if (ftp_transaction_) |
| 140 | ftp_transaction_.reset(); |
| 141 | if (http_transaction_) |
| 142 | http_transaction_.reset(); |
| 143 | URLRequestJob::Kill(); |
| 144 | weak_factory_.InvalidateWeakPtrs(); |
erg@google.com | 5394e42 | 2011-01-20 22:07:43 | [diff] [blame] | 145 | } |
| 146 | |
phajdan.jr@chromium.org | 4549925 | 2013-01-23 17:12:56 | [diff] [blame] | 147 | void URLRequestFtpJob::OnResolveProxyComplete(int result) { |
Lily Houghton | 00e124d | 2018-01-12 21:40:39 | [diff] [blame] | 148 | proxy_resolve_request_ = NULL; |
erg@google.com | 5394e42 | 2011-01-20 22:07:43 | [diff] [blame] | 149 | |
phajdan.jr@chromium.org | 4549925 | 2013-01-23 17:12:56 | [diff] [blame] | 150 | if (result != OK) { |
| 151 | OnStartCompletedAsync(result); |
| 152 | return; |
| 153 | } |
| 154 | |
| 155 | // Remove unsupported proxies from the list. |
| 156 | proxy_info_.RemoveProxiesWithoutScheme( |
| 157 | ProxyServer::SCHEME_DIRECT | |
| 158 | ProxyServer::SCHEME_HTTP | |
| 159 | ProxyServer::SCHEME_HTTPS); |
| 160 | |
| 161 | // TODO(phajdan.jr): Implement proxy fallback, http://crbug.com/171495 . |
| 162 | if (proxy_info_.is_direct()) |
| 163 | StartFtpTransaction(); |
| 164 | else if (proxy_info_.is_http() || proxy_info_.is_https()) |
| 165 | StartHttpTransaction(); |
| 166 | else |
| 167 | OnStartCompletedAsync(ERR_NO_SUPPORTED_PROXIES); |
| 168 | } |
| 169 | |
| 170 | void URLRequestFtpJob::StartFtpTransaction() { |
| 171 | // Create a transaction. |
| 172 | DCHECK(!ftp_transaction_); |
| 173 | |
| 174 | ftp_request_info_.url = request_->url(); |
tfh | 4aeb2a5 | 2015-12-24 11:49:35 | [diff] [blame] | 175 | ftp_transaction_ = ftp_transaction_factory_->CreateTransaction(); |
erg@google.com | 5394e42 | 2011-01-20 22:07:43 | [diff] [blame] | 176 | |
erg@google.com | 5394e42 | 2011-01-20 22:07:43 | [diff] [blame] | 177 | int rv; |
phajdan.jr@chromium.org | 4549925 | 2013-01-23 17:12:56 | [diff] [blame] | 178 | if (ftp_transaction_) { |
| 179 | rv = ftp_transaction_->Start( |
| 180 | &ftp_request_info_, |
rhalavati@google.com | f0ac8132 | 2018-01-16 20:34:41 | [diff] [blame] | 181 | base::Bind(&URLRequestFtpJob::OnStartCompleted, base::Unretained(this)), |
| 182 | request_->net_log(), request_->traffic_annotation()); |
erg@google.com | 5394e42 | 2011-01-20 22:07:43 | [diff] [blame] | 183 | if (rv == ERR_IO_PENDING) |
| 184 | return; |
| 185 | } else { |
| 186 | rv = ERR_FAILED; |
| 187 | } |
| 188 | // The transaction started synchronously, but we need to notify the |
| 189 | // URLRequest delegate via the message loop. |
phajdan.jr@chromium.org | 4549925 | 2013-01-23 17:12:56 | [diff] [blame] | 190 | OnStartCompletedAsync(rv); |
| 191 | } |
| 192 | |
| 193 | void URLRequestFtpJob::StartHttpTransaction() { |
| 194 | // Create a transaction. |
| 195 | DCHECK(!http_transaction_); |
| 196 | |
| 197 | // Do not cache FTP responses sent through HTTP proxy. |
akalin@chromium.org | bb1c466 | 2013-11-14 00:00:07 | [diff] [blame] | 198 | request_->SetLoadFlags(request_->load_flags() | |
| 199 | LOAD_DISABLE_CACHE | |
| 200 | LOAD_DO_NOT_SAVE_COOKIES | |
| 201 | LOAD_DO_NOT_SEND_COOKIES); |
phajdan.jr@chromium.org | 4549925 | 2013-01-23 17:12:56 | [diff] [blame] | 202 | |
| 203 | http_request_info_.url = request_->url(); |
| 204 | http_request_info_.method = request_->method(); |
| 205 | http_request_info_.load_flags = request_->load_flags(); |
Ramin Halavati | b5e433e | 2018-02-07 07:41:10 | [diff] [blame] | 206 | http_request_info_.traffic_annotation = |
| 207 | net::MutableNetworkTrafficAnnotationTag(request_->traffic_annotation()); |
phajdan.jr@chromium.org | 4549925 | 2013-01-23 17:12:56 | [diff] [blame] | 208 | |
| 209 | int rv = request_->context()->http_transaction_factory()->CreateTransaction( |
rvargas@chromium.org | 027bd85a | 2013-12-27 22:39:10 | [diff] [blame] | 210 | priority_, &http_transaction_); |
phajdan.jr@chromium.org | 4549925 | 2013-01-23 17:12:56 | [diff] [blame] | 211 | if (rv == OK) { |
| 212 | rv = http_transaction_->Start( |
| 213 | &http_request_info_, |
| 214 | base::Bind(&URLRequestFtpJob::OnStartCompleted, |
rvargas@chromium.org | 027bd85a | 2013-12-27 22:39:10 | [diff] [blame] | 215 | base::Unretained(this)), |
phajdan.jr@chromium.org | 4549925 | 2013-01-23 17:12:56 | [diff] [blame] | 216 | request_->net_log()); |
| 217 | if (rv == ERR_IO_PENDING) |
| 218 | return; |
| 219 | } |
| 220 | // The transaction started synchronously, but we need to notify the |
| 221 | // URLRequest delegate via the message loop. |
| 222 | OnStartCompletedAsync(rv); |
erg@google.com | 5394e42 | 2011-01-20 22:07:43 | [diff] [blame] | 223 | } |
| 224 | |
| 225 | void URLRequestFtpJob::OnStartCompleted(int result) { |
phajdan.jr@chromium.org | 4549925 | 2013-01-23 17:12:56 | [diff] [blame] | 226 | // Note that ftp_transaction_ may be NULL due to a creation failure. |
| 227 | if (ftp_transaction_) { |
shalev@chromium.org | e072757f | 2012-07-12 20:16:04 | [diff] [blame] | 228 | // FTP obviously doesn't have HTTP Content-Length header. We have to pass |
| 229 | // the content size information manually. |
| 230 | set_expected_content_size( |
phajdan.jr@chromium.org | 4549925 | 2013-01-23 17:12:56 | [diff] [blame] | 231 | ftp_transaction_->GetResponseInfo()->expected_content_size); |
shalev@chromium.org | e072757f | 2012-07-12 20:16:04 | [diff] [blame] | 232 | } |
erg@google.com | 5394e42 | 2011-01-20 22:07:43 | [diff] [blame] | 233 | |
| 234 | if (result == OK) { |
phajdan.jr@chromium.org | 7886251 | 2013-04-08 20:12:43 | [diff] [blame] | 235 | if (http_transaction_) { |
| 236 | http_response_info_ = http_transaction_->GetResponseInfo(); |
bengr@chromium.org | d8fc472 | 2014-06-13 13:17:15 | [diff] [blame] | 237 | SetProxyServer(http_response_info_->proxy_server); |
phajdan.jr@chromium.org | 7886251 | 2013-04-08 20:12:43 | [diff] [blame] | 238 | |
| 239 | if (http_response_info_->headers->response_code() == 401 || |
| 240 | http_response_info_->headers->response_code() == 407) { |
| 241 | HandleAuthNeededResponse(); |
| 242 | return; |
| 243 | } |
| 244 | } |
erg@google.com | 5394e42 | 2011-01-20 22:07:43 | [diff] [blame] | 245 | NotifyHeadersComplete(); |
phajdan.jr@chromium.org | 4549925 | 2013-01-23 17:12:56 | [diff] [blame] | 246 | } else if (ftp_transaction_ && |
| 247 | ftp_transaction_->GetResponseInfo()->needs_auth) { |
phajdan.jr@chromium.org | 7886251 | 2013-04-08 20:12:43 | [diff] [blame] | 248 | HandleAuthNeededResponse(); |
| 249 | return; |
erg@google.com | 5394e42 | 2011-01-20 22:07:43 | [diff] [blame] | 250 | } else { |
xunjieli | 26ede96 | 2015-11-23 19:39:13 | [diff] [blame] | 251 | NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, result)); |
erg@google.com | 5394e42 | 2011-01-20 22:07:43 | [diff] [blame] | 252 | } |
| 253 | } |
| 254 | |
phajdan.jr@chromium.org | 4549925 | 2013-01-23 17:12:56 | [diff] [blame] | 255 | void URLRequestFtpJob::OnStartCompletedAsync(int result) { |
skyostil | 4891b25b | 2015-06-11 11:43:45 | [diff] [blame] | 256 | base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 257 | FROM_HERE, base::Bind(&URLRequestFtpJob::OnStartCompleted, |
| 258 | weak_factory_.GetWeakPtr(), result)); |
phajdan.jr@chromium.org | 4549925 | 2013-01-23 17:12:56 | [diff] [blame] | 259 | } |
| 260 | |
erg@google.com | 5394e42 | 2011-01-20 22:07:43 | [diff] [blame] | 261 | void URLRequestFtpJob::OnReadCompleted(int result) { |
| 262 | read_in_progress_ = false; |
xunjieli | 26ede96 | 2015-11-23 19:39:13 | [diff] [blame] | 263 | ReadRawDataComplete(result); |
erg@google.com | 5394e42 | 2011-01-20 22:07:43 | [diff] [blame] | 264 | } |
| 265 | |
| 266 | void URLRequestFtpJob::RestartTransactionWithAuth() { |
rsleevi@chromium.org | 9049948 | 2013-06-01 00:39:50 | [diff] [blame] | 267 | DCHECK(auth_data_.get() && auth_data_->state == AUTH_STATE_HAVE_AUTH); |
erg@google.com | 5394e42 | 2011-01-20 22:07:43 | [diff] [blame] | 268 | |
phajdan.jr@chromium.org | 7886251 | 2013-04-08 20:12:43 | [diff] [blame] | 269 | int rv; |
| 270 | if (proxy_info_.is_direct()) { |
| 271 | rv = ftp_transaction_->RestartWithAuth( |
| 272 | auth_data_->credentials, |
| 273 | base::Bind(&URLRequestFtpJob::OnStartCompleted, |
| 274 | base::Unretained(this))); |
| 275 | } else { |
| 276 | rv = http_transaction_->RestartWithAuth( |
| 277 | auth_data_->credentials, |
| 278 | base::Bind(&URLRequestFtpJob::OnStartCompleted, |
| 279 | base::Unretained(this))); |
| 280 | } |
erg@google.com | 5394e42 | 2011-01-20 22:07:43 | [diff] [blame] | 281 | if (rv == ERR_IO_PENDING) |
| 282 | return; |
| 283 | |
phajdan.jr@chromium.org | 4549925 | 2013-01-23 17:12:56 | [diff] [blame] | 284 | OnStartCompletedAsync(rv); |
erg@google.com | 5394e42 | 2011-01-20 22:07:43 | [diff] [blame] | 285 | } |
| 286 | |
tfarina@chromium.org | 03ea3c52 | 2010-12-12 01:47:54 | [diff] [blame] | 287 | LoadState URLRequestFtpJob::GetLoadState() const { |
Lily Houghton | 00e124d | 2018-01-12 21:40:39 | [diff] [blame] | 288 | if (proxy_resolve_request_) |
Lily Houghton | 0e9a499 | 2018-07-30 22:40:37 | [diff] [blame] | 289 | return proxy_resolve_request_->GetLoadState(); |
phajdan.jr@chromium.org | 4549925 | 2013-01-23 17:12:56 | [diff] [blame] | 290 | if (proxy_info_.is_direct()) { |
| 291 | return ftp_transaction_ ? |
| 292 | ftp_transaction_->GetLoadState() : LOAD_STATE_IDLE; |
| 293 | } else { |
| 294 | return http_transaction_ ? |
| 295 | http_transaction_->GetLoadState() : LOAD_STATE_IDLE; |
| 296 | } |
phajdan.jr@chromium.org | bf5ad68 | 2009-08-12 19:19:28 | [diff] [blame] | 297 | } |
| 298 | |
phajdan.jr@chromium.org | e7fe528 | 2010-03-16 12:40:13 | [diff] [blame] | 299 | bool URLRequestFtpJob::NeedsAuth() { |
rsleevi@chromium.org | 9049948 | 2013-06-01 00:39:50 | [diff] [blame] | 300 | return auth_data_.get() && auth_data_->state == AUTH_STATE_NEED_AUTH; |
phajdan.jr@chromium.org | 8b8a197d | 2009-08-26 15:57:58 | [diff] [blame] | 301 | } |
| 302 | |
phajdan.jr@chromium.org | e7fe528 | 2010-03-16 12:40:13 | [diff] [blame] | 303 | void URLRequestFtpJob::GetAuthChallengeInfo( |
tfarina@chromium.org | 03ea3c52 | 2010-12-12 01:47:54 | [diff] [blame] | 304 | scoped_refptr<AuthChallengeInfo>* result) { |
phajdan.jr@chromium.org | 7886251 | 2013-04-08 20:12:43 | [diff] [blame] | 305 | DCHECK(NeedsAuth()); |
| 306 | |
| 307 | if (http_response_info_) { |
| 308 | *result = http_response_info_->auth_challenge; |
| 309 | return; |
| 310 | } |
| 311 | |
tfarina@chromium.org | 03ea3c52 | 2010-12-12 01:47:54 | [diff] [blame] | 312 | scoped_refptr<AuthChallengeInfo> auth_info(new AuthChallengeInfo); |
phajdan.jr@chromium.org | 8b8a197d | 2009-08-26 15:57:58 | [diff] [blame] | 313 | auth_info->is_proxy = false; |
Daniel Cheng | 88186bd5 | 2017-10-20 08:14:46 | [diff] [blame] | 314 | auth_info->challenger = url::Origin::Create(request_->url()); |
cbentzel@chromium.org | 79cb5c1 | 2011-09-12 13:12:04 | [diff] [blame] | 315 | // scheme and realm are kept empty. |
| 316 | DCHECK(auth_info->scheme.empty()); |
| 317 | DCHECK(auth_info->realm.empty()); |
phajdan.jr@chromium.org | 8b8a197d | 2009-08-26 15:57:58 | [diff] [blame] | 318 | result->swap(auth_info); |
| 319 | } |
| 320 | |
cbentzel@chromium.org | f3cf980 | 2011-10-28 18:44:58 | [diff] [blame] | 321 | void URLRequestFtpJob::SetAuth(const AuthCredentials& credentials) { |
phajdan.jr@chromium.org | 7886251 | 2013-04-08 20:12:43 | [diff] [blame] | 322 | DCHECK(ftp_transaction_ || http_transaction_); |
phajdan.jr@chromium.org | 8b8a197d | 2009-08-26 15:57:58 | [diff] [blame] | 323 | DCHECK(NeedsAuth()); |
phajdan.jr@chromium.org | 8b8a197d | 2009-08-26 15:57:58 | [diff] [blame] | 324 | |
phajdan.jr@chromium.org | 7886251 | 2013-04-08 20:12:43 | [diff] [blame] | 325 | auth_data_->state = AUTH_STATE_HAVE_AUTH; |
| 326 | auth_data_->credentials = credentials; |
| 327 | |
| 328 | if (ftp_transaction_) { |
| 329 | ftp_auth_cache_->Add(request_->url().GetOrigin(), |
| 330 | auth_data_->credentials); |
| 331 | } |
phajdan.jr@chromium.org | 60a3df5 | 2009-09-22 16:13:24 | [diff] [blame] | 332 | |
phajdan.jr@chromium.org | 8b8a197d | 2009-08-26 15:57:58 | [diff] [blame] | 333 | RestartTransactionWithAuth(); |
| 334 | } |
| 335 | |
phajdan.jr@chromium.org | e7fe528 | 2010-03-16 12:40:13 | [diff] [blame] | 336 | void URLRequestFtpJob::CancelAuth() { |
phajdan.jr@chromium.org | 7886251 | 2013-04-08 20:12:43 | [diff] [blame] | 337 | DCHECK(ftp_transaction_ || http_transaction_); |
phajdan.jr@chromium.org | 8b8a197d | 2009-08-26 15:57:58 | [diff] [blame] | 338 | DCHECK(NeedsAuth()); |
phajdan.jr@chromium.org | 7886251 | 2013-04-08 20:12:43 | [diff] [blame] | 339 | |
| 340 | auth_data_->state = AUTH_STATE_CANCELED; |
phajdan.jr@chromium.org | 8b8a197d | 2009-08-26 15:57:58 | [diff] [blame] | 341 | |
| 342 | // Once the auth is cancelled, we proceed with the request as though |
| 343 | // there were no auth. Schedule this for later so that we don't cause |
| 344 | // any recursing into the caller as a result of this call. |
phajdan.jr@chromium.org | 4549925 | 2013-01-23 17:12:56 | [diff] [blame] | 345 | OnStartCompletedAsync(OK); |
phajdan.jr@chromium.org | 8b8a197d | 2009-08-26 15:57:58 | [diff] [blame] | 346 | } |
| 347 | |
xunjieli | 26ede96 | 2015-11-23 19:39:13 | [diff] [blame] | 348 | int URLRequestFtpJob::ReadRawData(IOBuffer* buf, int buf_size) { |
wtc@chromium.org | 581e0d0 | 2009-05-11 17:01:17 | [diff] [blame] | 349 | DCHECK_NE(buf_size, 0); |
wtc@chromium.org | 581e0d0 | 2009-05-11 17:01:17 | [diff] [blame] | 350 | DCHECK(!read_in_progress_); |
wtc@chromium.org | 4c62d8c3 | 2009-06-05 02:14:16 | [diff] [blame] | 351 | |
phajdan.jr@chromium.org | 4549925 | 2013-01-23 17:12:56 | [diff] [blame] | 352 | int rv; |
xunjieli | 26ede96 | 2015-11-23 19:39:13 | [diff] [blame] | 353 | |
phajdan.jr@chromium.org | 4549925 | 2013-01-23 17:12:56 | [diff] [blame] | 354 | if (proxy_info_.is_direct()) { |
| 355 | rv = ftp_transaction_->Read(buf, buf_size, |
| 356 | base::Bind(&URLRequestFtpJob::OnReadCompleted, |
| 357 | base::Unretained(this))); |
| 358 | } else { |
| 359 | rv = http_transaction_->Read(buf, buf_size, |
| 360 | base::Bind(&URLRequestFtpJob::OnReadCompleted, |
| 361 | base::Unretained(this))); |
| 362 | } |
| 363 | |
xunjieli | 26ede96 | 2015-11-23 19:39:13 | [diff] [blame] | 364 | if (rv == ERR_IO_PENDING) |
wtc@chromium.org | 581e0d0 | 2009-05-11 17:01:17 | [diff] [blame] | 365 | read_in_progress_ = true; |
xunjieli | 26ede96 | 2015-11-23 19:39:13 | [diff] [blame] | 366 | return rv; |
wtc@chromium.org | b65ce094 | 2009-03-16 20:13:33 | [diff] [blame] | 367 | } |
| 368 | |
phajdan.jr@chromium.org | 7886251 | 2013-04-08 20:12:43 | [diff] [blame] | 369 | void URLRequestFtpJob::HandleAuthNeededResponse() { |
| 370 | GURL origin = request_->url().GetOrigin(); |
| 371 | |
rsleevi@chromium.org | 9049948 | 2013-06-01 00:39:50 | [diff] [blame] | 372 | if (auth_data_.get()) { |
phajdan.jr@chromium.org | 7886251 | 2013-04-08 20:12:43 | [diff] [blame] | 373 | if (auth_data_->state == AUTH_STATE_CANCELED) { |
| 374 | NotifyHeadersComplete(); |
| 375 | return; |
| 376 | } |
| 377 | |
| 378 | if (ftp_transaction_ && auth_data_->state == AUTH_STATE_HAVE_AUTH) |
| 379 | ftp_auth_cache_->Remove(origin, auth_data_->credentials); |
| 380 | } else { |
Jeremy Roman | 0579ed6 | 2017-08-29 15:56:19 | [diff] [blame] | 381 | auth_data_ = std::make_unique<AuthData>(); |
phajdan.jr@chromium.org | 7886251 | 2013-04-08 20:12:43 | [diff] [blame] | 382 | } |
| 383 | auth_data_->state = AUTH_STATE_NEED_AUTH; |
| 384 | |
| 385 | FtpAuthCache::Entry* cached_auth = NULL; |
| 386 | if (ftp_transaction_ && ftp_transaction_->GetResponseInfo()->needs_auth) |
| 387 | cached_auth = ftp_auth_cache_->Lookup(origin); |
| 388 | if (cached_auth) { |
| 389 | // Retry using cached auth data. |
| 390 | SetAuth(cached_auth->credentials); |
| 391 | } else { |
| 392 | // Prompt for a username/password. |
| 393 | NotifyHeadersComplete(); |
| 394 | } |
| 395 | } |
| 396 | |
tfarina@chromium.org | 03ea3c52 | 2010-12-12 01:47:54 | [diff] [blame] | 397 | } // namespace net |