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()); |