url_request_ftp_job.cc revision 868fa2fe829687343ffae624259930155e16dbd8
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_ftp_job.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/message_loop.h" 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/auth.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/host_port_pair.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/load_flags.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h" 15b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "net/ftp/ftp_auth_cache.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/ftp/ftp_response_info.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/ftp/ftp_transaction_factory.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/http/http_response_headers.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/http/http_transaction_factory.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_error_job.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLRequestFtpJob::URLRequestFtpJob( 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRequest* request, 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetworkDelegate* network_delegate, 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FtpTransactionFactory* ftp_transaction_factory, 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FtpAuthCache* ftp_auth_cache) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : URLRequestJob(request, network_delegate), 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) priority_(DEFAULT_PRIORITY), 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) proxy_service_(request_->context()->proxy_service()), 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pac_request_(NULL), 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) http_response_info_(NULL), 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_in_progress_(false), 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_factory_(this), 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ftp_transaction_factory_(ftp_transaction_factory), 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ftp_auth_cache_(ftp_auth_cache) { 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(proxy_service_); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ftp_transaction_factory); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ftp_auth_cache); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)URLRequestFtpJob::~URLRequestFtpJob() { 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (pac_request_) 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) proxy_service_->CancelPacRequest(pac_request_); 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool URLRequestFtpJob::IsSafeRedirect(const GURL& location) { 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Disallow all redirects. 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestFtpJob::GetMimeType(std::string* mime_type) const { 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (proxy_info_.is_direct()) { 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (ftp_transaction_->GetResponseInfo()->is_directory_listing) { 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *mime_type = "text/vnd.chromium.ftp-dir"; 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // No special handling of MIME type is needed. As opposed to direct FTP 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // transaction, we do not get a raw directory listing to parse. 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return http_transaction_->GetResponseInfo()-> 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) headers->GetMimeType(mime_type); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void URLRequestFtpJob::GetResponseInfo(HttpResponseInfo* info) { 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (http_response_info_) 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *info = *http_response_info_; 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HostPortPair URLRequestFtpJob::GetSocketAddress() const { 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (proxy_info_.is_direct()) { 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!ftp_transaction_) 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return HostPortPair(); 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ftp_transaction_->GetResponseInfo()->socket_address; 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!http_transaction_) 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return HostPortPair(); 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return http_transaction_->GetResponseInfo()->socket_address; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void URLRequestFtpJob::SetPriority(RequestPriority priority) { 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) priority_ = priority; 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (http_transaction_) 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) http_transaction_->SetPriority(priority); 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void URLRequestFtpJob::Start() { 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!pac_request_); 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!ftp_transaction_); 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!http_transaction_); 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int rv = OK; 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (request_->load_flags() & LOAD_BYPASS_PROXY) { 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) proxy_info_.UseDirect(); 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_EQ(request_->context()->proxy_service(), proxy_service_); 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rv = proxy_service_->ResolveProxy( 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_->url(), 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &proxy_info_, 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&URLRequestFtpJob::OnResolveProxyComplete, 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this)), 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &pac_request_, 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_->net_log()); 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (rv == ERR_IO_PENDING) 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnResolveProxyComplete(rv); 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void URLRequestFtpJob::Kill() { 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (ftp_transaction_) 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ftp_transaction_.reset(); 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (http_transaction_) 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) http_transaction_.reset(); 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) URLRequestJob::Kill(); 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_factory_.InvalidateWeakPtrs(); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void URLRequestFtpJob::OnResolveProxyComplete(int result) { 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pac_request_ = NULL; 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (result != OK) { 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnStartCompletedAsync(result); 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Remove unsupported proxies from the list. 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) proxy_info_.RemoveProxiesWithoutScheme( 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProxyServer::SCHEME_DIRECT | 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProxyServer::SCHEME_HTTP | 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProxyServer::SCHEME_HTTPS); 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(phajdan.jr): Implement proxy fallback, http://crbug.com/171495 . 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (proxy_info_.is_direct()) 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StartFtpTransaction(); 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (proxy_info_.is_http() || proxy_info_.is_https()) 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StartHttpTransaction(); 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnStartCompletedAsync(ERR_NO_SUPPORTED_PROXIES); 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void URLRequestFtpJob::StartFtpTransaction() { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a transaction. 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!ftp_transaction_); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ftp_request_info_.url = request_->url(); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ftp_transaction_.reset(ftp_transaction_factory_->CreateTransaction()); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No matter what, we want to report our status as IO pending since we will 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be notifying our consumer asynchronously via OnStartCompleted. 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv; 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (ftp_transaction_) { 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rv = ftp_transaction_->Start( 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &ftp_request_info_, 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&URLRequestFtpJob::OnStartCompleted, 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this)), 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->net_log()); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == ERR_IO_PENDING) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ERR_FAILED; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The transaction started synchronously, but we need to notify the 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // URLRequest delegate via the message loop. 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnStartCompletedAsync(rv); 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void URLRequestFtpJob::StartHttpTransaction() { 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Create a transaction. 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!http_transaction_); 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Do not cache FTP responses sent through HTTP proxy. 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_->set_load_flags(request_->load_flags() | 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOAD_DISABLE_CACHE | 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOAD_DO_NOT_SAVE_COOKIES | 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOAD_DO_NOT_SEND_COOKIES); 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) http_request_info_.url = request_->url(); 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) http_request_info_.method = request_->method(); 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) http_request_info_.load_flags = request_->load_flags(); 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) http_request_info_.request_id = request_->identifier(); 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int rv = request_->context()->http_transaction_factory()->CreateTransaction( 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) priority_, &http_transaction_, NULL); 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (rv == OK) { 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rv = http_transaction_->Start( 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &http_request_info_, 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&URLRequestFtpJob::OnStartCompleted, 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this)), 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_->net_log()); 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (rv == ERR_IO_PENDING) 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The transaction started synchronously, but we need to notify the 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // URLRequest delegate via the message loop. 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnStartCompletedAsync(rv); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestFtpJob::OnStartCompleted(int result) { 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clear the IO_PENDING status 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStatus(URLRequestStatus()); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Note that ftp_transaction_ may be NULL due to a creation failure. 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (ftp_transaction_) { 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FTP obviously doesn't have HTTP Content-Length header. We have to pass 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the content size information manually. 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_expected_content_size( 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ftp_transaction_->GetResponseInfo()->expected_content_size); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == OK) { 220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (http_transaction_) { 221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) http_response_info_ = http_transaction_->GetResponseInfo(); 222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (http_response_info_->headers->response_code() == 401 || 224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) http_response_info_->headers->response_code() == 407) { 225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) HandleAuthNeededResponse(); 226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyHeadersComplete(); 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (ftp_transaction_ && 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ftp_transaction_->GetResponseInfo()->needs_auth) { 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) HandleAuthNeededResponse(); 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, result)); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void URLRequestFtpJob::OnStartCompletedAsync(int result) { 24090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&URLRequestFtpJob::OnStartCompleted, 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_factory_.GetWeakPtr(), result)); 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestFtpJob::OnReadCompleted(int result) { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_in_progress_ = false; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == 0) { 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyDone(URLRequestStatus()); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (result < 0) { 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, result)); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clear the IO_PENDING status 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStatus(URLRequestStatus()); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyReadComplete(result); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestFtpJob::RestartTransactionWithAuth() { 260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(auth_data_.get() && auth_data_->state == AUTH_STATE_HAVE_AUTH); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No matter what, we want to report our status as IO pending since we will 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be notifying our consumer asynchronously via OnStartCompleted. 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int rv; 267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (proxy_info_.is_direct()) { 268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rv = ftp_transaction_->RestartWithAuth( 269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) auth_data_->credentials, 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&URLRequestFtpJob::OnStartCompleted, 271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this))); 272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rv = http_transaction_->RestartWithAuth( 274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) auth_data_->credentials, 275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&URLRequestFtpJob::OnStartCompleted, 276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this))); 277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == ERR_IO_PENDING) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnStartCompletedAsync(rv); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LoadState URLRequestFtpJob::GetLoadState() const { 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (proxy_info_.is_direct()) { 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ftp_transaction_ ? 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ftp_transaction_->GetLoadState() : LOAD_STATE_IDLE; 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return http_transaction_ ? 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) http_transaction_->GetLoadState() : LOAD_STATE_IDLE; 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestFtpJob::NeedsAuth() { 295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return auth_data_.get() && auth_data_->state == AUTH_STATE_NEED_AUTH; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestFtpJob::GetAuthChallengeInfo( 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<AuthChallengeInfo>* result) { 300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(NeedsAuth()); 301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (http_response_info_) { 303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *result = http_response_info_->auth_challenge; 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<AuthChallengeInfo> auth_info(new AuthChallengeInfo); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) auth_info->is_proxy = false; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) auth_info->challenger = HostPortPair::FromURL(request_->url()); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // scheme and realm are kept empty. 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(auth_info->scheme.empty()); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(auth_info->realm.empty()); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->swap(auth_info); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestFtpJob::SetAuth(const AuthCredentials& credentials) { 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(ftp_transaction_ || http_transaction_); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(NeedsAuth()); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) auth_data_->state = AUTH_STATE_HAVE_AUTH; 321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) auth_data_->credentials = credentials; 322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (ftp_transaction_) { 324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ftp_auth_cache_->Add(request_->url().GetOrigin(), 325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) auth_data_->credentials); 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RestartTransactionWithAuth(); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestFtpJob::CancelAuth() { 332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(ftp_transaction_ || http_transaction_); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(NeedsAuth()); 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) auth_data_->state = AUTH_STATE_CANCELED; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Once the auth is cancelled, we proceed with the request as though 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // there were no auth. Schedule this for later so that we don't cause 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // any recursing into the caller as a result of this call. 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnStartCompletedAsync(OK); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UploadProgress URLRequestFtpJob::GetUploadProgress() const { 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return UploadProgress(); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestFtpJob::ReadRawData(IOBuffer* buf, 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int buf_size, 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int *bytes_read) { 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(buf_size, 0); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(bytes_read); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!read_in_progress_); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int rv; 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (proxy_info_.is_direct()) { 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rv = ftp_transaction_->Read(buf, buf_size, 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&URLRequestFtpJob::OnReadCompleted, 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this))); 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rv = http_transaction_->Read(buf, buf_size, 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&URLRequestFtpJob::OnReadCompleted, 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this))); 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv >= 0) { 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bytes_read = rv; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == ERR_IO_PENDING) { 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_in_progress_ = true; 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, rv)); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void URLRequestFtpJob::HandleAuthNeededResponse() { 380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GURL origin = request_->url().GetOrigin(); 381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 382868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (auth_data_.get()) { 383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (auth_data_->state == AUTH_STATE_CANCELED) { 384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NotifyHeadersComplete(); 385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (ftp_transaction_ && auth_data_->state == AUTH_STATE_HAVE_AUTH) 389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ftp_auth_cache_->Remove(origin, auth_data_->credentials); 390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) auth_data_ = new AuthData; 392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) auth_data_->state = AUTH_STATE_NEED_AUTH; 394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FtpAuthCache::Entry* cached_auth = NULL; 396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (ftp_transaction_ && ftp_transaction_->GetResponseInfo()->needs_auth) 397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cached_auth = ftp_auth_cache_->Lookup(origin); 398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (cached_auth) { 399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Retry using cached auth data. 400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetAuth(cached_auth->credentials); 401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Prompt for a username/password. 403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NotifyHeadersComplete(); 404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 408