url_request_ftp_job.cc revision f2477e01787aa58f445919b809d89e252beef54f
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" 89ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/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. 181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) request_->SetLoadFlags(request_->load_flags() | 182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) LOAD_DISABLE_CACHE | 183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) LOAD_DO_NOT_SAVE_COOKIES | 184f2477e01787aa58f445919b809d89e252beef54fTorne (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) 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int rv = request_->context()->http_transaction_factory()->CreateTransaction( 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) priority_, &http_transaction_, NULL); 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (rv == OK) { 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rv = http_transaction_->Start( 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &http_request_info_, 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&URLRequestFtpJob::OnStartCompleted, 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this)), 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_->net_log()); 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (rv == ERR_IO_PENDING) 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The transaction started synchronously, but we need to notify the 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // URLRequest delegate via the message loop. 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnStartCompletedAsync(rv); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestFtpJob::OnStartCompleted(int result) { 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clear the IO_PENDING status 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStatus(URLRequestStatus()); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Note that ftp_transaction_ may be NULL due to a creation failure. 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (ftp_transaction_) { 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FTP obviously doesn't have HTTP Content-Length header. We have to pass 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the content size information manually. 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_expected_content_size( 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ftp_transaction_->GetResponseInfo()->expected_content_size); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == OK) { 219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (http_transaction_) { 220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) http_response_info_ = http_transaction_->GetResponseInfo(); 221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (http_response_info_->headers->response_code() == 401 || 223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) http_response_info_->headers->response_code() == 407) { 224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) HandleAuthNeededResponse(); 225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyHeadersComplete(); 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (ftp_transaction_ && 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ftp_transaction_->GetResponseInfo()->needs_auth) { 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) HandleAuthNeededResponse(); 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, result)); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void URLRequestFtpJob::OnStartCompletedAsync(int result) { 23990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&URLRequestFtpJob::OnStartCompleted, 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_factory_.GetWeakPtr(), result)); 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestFtpJob::OnReadCompleted(int result) { 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_in_progress_ = false; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == 0) { 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyDone(URLRequestStatus()); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (result < 0) { 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, result)); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clear the IO_PENDING status 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStatus(URLRequestStatus()); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyReadComplete(result); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestFtpJob::RestartTransactionWithAuth() { 259868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(auth_data_.get() && auth_data_->state == AUTH_STATE_HAVE_AUTH); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No matter what, we want to report our status as IO pending since we will 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be notifying our consumer asynchronously via OnStartCompleted. 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int rv; 266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (proxy_info_.is_direct()) { 267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rv = ftp_transaction_->RestartWithAuth( 268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) auth_data_->credentials, 269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&URLRequestFtpJob::OnStartCompleted, 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this))); 271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rv = http_transaction_->RestartWithAuth( 273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) auth_data_->credentials, 274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&URLRequestFtpJob::OnStartCompleted, 275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this))); 276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == ERR_IO_PENDING) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnStartCompletedAsync(rv); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LoadState URLRequestFtpJob::GetLoadState() const { 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (proxy_info_.is_direct()) { 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ftp_transaction_ ? 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ftp_transaction_->GetLoadState() : LOAD_STATE_IDLE; 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return http_transaction_ ? 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) http_transaction_->GetLoadState() : LOAD_STATE_IDLE; 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestFtpJob::NeedsAuth() { 294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return auth_data_.get() && auth_data_->state == AUTH_STATE_NEED_AUTH; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestFtpJob::GetAuthChallengeInfo( 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<AuthChallengeInfo>* result) { 299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(NeedsAuth()); 300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (http_response_info_) { 302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *result = http_response_info_->auth_challenge; 303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<AuthChallengeInfo> auth_info(new AuthChallengeInfo); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) auth_info->is_proxy = false; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) auth_info->challenger = HostPortPair::FromURL(request_->url()); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // scheme and realm are kept empty. 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(auth_info->scheme.empty()); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(auth_info->realm.empty()); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->swap(auth_info); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestFtpJob::SetAuth(const AuthCredentials& credentials) { 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(ftp_transaction_ || http_transaction_); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(NeedsAuth()); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) auth_data_->state = AUTH_STATE_HAVE_AUTH; 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) auth_data_->credentials = credentials; 321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (ftp_transaction_) { 323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ftp_auth_cache_->Add(request_->url().GetOrigin(), 324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) auth_data_->credentials); 325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RestartTransactionWithAuth(); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestFtpJob::CancelAuth() { 331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(ftp_transaction_ || http_transaction_); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(NeedsAuth()); 333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) auth_data_->state = AUTH_STATE_CANCELED; 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Once the auth is cancelled, we proceed with the request as though 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // there were no auth. Schedule this for later so that we don't cause 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // any recursing into the caller as a result of this call. 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnStartCompletedAsync(OK); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UploadProgress URLRequestFtpJob::GetUploadProgress() const { 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return UploadProgress(); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestFtpJob::ReadRawData(IOBuffer* buf, 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int buf_size, 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int *bytes_read) { 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(buf_size, 0); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(bytes_read); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!read_in_progress_); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int rv; 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (proxy_info_.is_direct()) { 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rv = ftp_transaction_->Read(buf, buf_size, 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&URLRequestFtpJob::OnReadCompleted, 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this))); 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rv = http_transaction_->Read(buf, buf_size, 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&URLRequestFtpJob::OnReadCompleted, 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this))); 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv >= 0) { 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bytes_read = rv; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == ERR_IO_PENDING) { 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_in_progress_ = true; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, rv)); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void URLRequestFtpJob::HandleAuthNeededResponse() { 379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GURL origin = request_->url().GetOrigin(); 380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 381868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (auth_data_.get()) { 382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (auth_data_->state == AUTH_STATE_CANCELED) { 383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NotifyHeadersComplete(); 384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (ftp_transaction_ && auth_data_->state == AUTH_STATE_HAVE_AUTH) 388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ftp_auth_cache_->Remove(origin, auth_data_->credentials); 389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) auth_data_ = new AuthData; 391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) auth_data_->state = AUTH_STATE_NEED_AUTH; 393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FtpAuthCache::Entry* cached_auth = NULL; 395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (ftp_transaction_ && ftp_transaction_->GetResponseInfo()->needs_auth) 396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cached_auth = ftp_auth_cache_->Lookup(origin); 397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (cached_auth) { 398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Retry using cached auth data. 399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetAuth(cached_auth->credentials); 400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Prompt for a username/password. 402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NotifyHeadersComplete(); 403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 407