Chromium Code Reviews| Index: net/url_request/url_request_new_ftp_job.cc |
| diff --git a/net/url_request/url_request_new_ftp_job.cc b/net/url_request/url_request_new_ftp_job.cc |
| index f467357c4a1f55da36fa42eb6a125638888e9356..7d0832c790131903b6c2253362b9fe10b141c1e1 100644 |
| --- a/net/url_request/url_request_new_ftp_job.cc |
| +++ b/net/url_request/url_request_new_ftp_job.cc |
| @@ -8,6 +8,7 @@ |
| #include "base/file_version_info.h" |
| #include "base/message_loop.h" |
| #include "base/sys_string_conversions.h" |
| +#include "net/base/auth.h" |
| #include "net/base/escape.h" |
| #include "net/base/net_errors.h" |
| #include "net/base/net_util.h" |
| @@ -60,7 +61,6 @@ string16 RawByteSequenceToFilename(const char* raw_filename, |
| URLRequestNewFtpJob::URLRequestNewFtpJob(URLRequest* request) |
| : URLRequestJob(request), |
| - server_auth_state_(net::AUTH_STATE_DONT_NEED_AUTH), |
| response_info_(NULL), |
| dir_listing_buf_size_(0), |
| ALLOW_THIS_IN_INITIALIZER_LIST( |
| @@ -106,6 +106,54 @@ net::LoadState URLRequestNewFtpJob::GetLoadState() const { |
| transaction_->GetLoadState() : net::LOAD_STATE_IDLE; |
| } |
| +bool URLRequestNewFtpJob::NeedsAuth() { |
| + // Note that we only have to worry about cases where an actual FTP server |
| + // requires auth (and not a proxy), because connecting to FTP via proxy |
| + // effectively means the browser communicates via HTTP, and uses HTTP's |
| + // Proxy-Authenticate protocol when proxy servers require auth. |
| + return server_auth_ && server_auth_->state == net::AUTH_STATE_NEED_AUTH; |
|
wtc
2009/08/25 20:52:50
Just FYI: URLRequestHttpJob::NeedsAuth sets
the au
|
| +} |
| + |
| +void URLRequestNewFtpJob::GetAuthChallengeInfo( |
| + scoped_refptr<net::AuthChallengeInfo>* result) { |
| + DCHECK((server_auth_ != NULL) && |
| + (server_auth_->state == net::AUTH_STATE_NEED_AUTH)); |
| + scoped_refptr<net::AuthChallengeInfo> auth_info = new net::AuthChallengeInfo; |
| + auth_info->is_proxy = false; |
| + auth_info->host_and_port = ASCIIToWide( |
| + net::GetHostAndPort(request_->url())); |
| + auth_info->scheme = L""; |
| + auth_info->realm = L""; |
| + result->swap(auth_info); |
| +} |
| + |
| +void URLRequestNewFtpJob::SetAuth(const std::wstring& username, |
| + const std::wstring& password) { |
| + DCHECK(server_auth_ && server_auth_->state == net::AUTH_STATE_NEED_AUTH); |
|
wtc
2009/08/25 20:52:50
This conditional expression is equivalent to Needs
|
| + server_auth_->state = net::AUTH_STATE_HAVE_AUTH; |
| + server_auth_->username = username; |
| + server_auth_->password = password; |
| + |
| + // Resend the request with the new username and password. |
| + // Do this asynchronously in case we were called from within a |
| + // NotifyDataAvailable callback. |
| + // TODO(mpcomplete): hmm... is it possible 'this' gets deleted before the task |
| + // is run? |
| + MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( |
|
wtc
2009/08/25 20:52:50
URLRequestHttpJob just call RestartTransactionWith
|
| + this, &URLRequestNewFtpJob::RestartWithAuth)); |
| +} |
| + |
| +void URLRequestNewFtpJob::CancelAuth() { |
| + DCHECK(server_auth_ && server_auth_->state == net::AUTH_STATE_NEED_AUTH); |
|
wtc
2009/08/25 20:52:50
This conditional expression is equivalent to Needs
|
| + server_auth_->state = net::AUTH_STATE_CANCELED; |
| + |
| + // Once the auth is cancelled, we proceed with the request as though |
| + // there were no auth. Schedule this for later so that we don't cause |
| + // any recursing into the caller as a result of this call. |
| + MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( |
|
wtc
2009/08/25 20:52:50
URLRequestHttpJob::CancelAuth posts a task for
OnS
|
| + this, &URLRequestNewFtpJob::NotifyHeadersComplete)); |
| +} |
| + |
| bool URLRequestNewFtpJob::ReadRawData(net::IOBuffer* buf, |
| int buf_size, |
| int *bytes_read) { |
| @@ -251,7 +299,13 @@ void URLRequestNewFtpJob::OnStartCompleted(int result) { |
| if (result == net::OK) { |
| NotifyHeadersComplete(); |
| } else { |
|
wtc
2009/08/25 20:52:50
Use "else if" here.
|
| - NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, result)); |
| + if (transaction_->GetResponseInfo()->auth_needed) { |
| + server_auth_ = new net::AuthData(); |
| + server_auth_->state = net::AUTH_STATE_NEED_AUTH; |
| + NotifyHeadersComplete(); |
| + } else { |
| + NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, result)); |
| + } |
| } |
| } |
| @@ -273,6 +327,23 @@ void URLRequestNewFtpJob::OnReadCompleted(int result) { |
| NotifyReadComplete(result); |
| } |
| +void URLRequestNewFtpJob::RestartWithAuth() { |
|
wtc
2009/08/25 20:52:50
Perhaps rename this method RestartTransactionWithA
|
| + DCHECK(server_auth_ && server_auth_->state == net::AUTH_STATE_HAVE_AUTH); |
| + |
|
wtc
2009/08/25 20:52:50
URLRequestHttpJob::RestartTransactionWithAuth also
|
| + // No matter what, we want to report our status as IO pending since we will |
| + // be notifying our consumer asynchronously via OnStartCompleted. |
| + SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); |
| + |
| + int rv = transaction_->RestartWithAuth(server_auth_->username, |
| + server_auth_->password, |
| + &start_callback_); |
| + if (rv == net::ERR_IO_PENDING) |
| + return; |
| + |
| + MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( |
| + this, &URLRequestNewFtpJob::OnStartCompleted, rv)); |
| +} |
| + |
| void URLRequestNewFtpJob::StartTransaction() { |
| // Create a transaction. |
| DCHECK(!transaction_.get()); |