Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/url_request/url_request_new_ftp_job.h" | 5 #include "net/url_request/url_request_new_ftp_job.h" |
| 6 | 6 |
| 7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
| 8 #include "base/file_version_info.h" | 8 #include "base/file_version_info.h" |
| 9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
| 10 #include "base/sys_string_conversions.h" | 10 #include "base/sys_string_conversions.h" |
| 11 #include "net/base/auth.h" | |
| 11 #include "net/base/escape.h" | 12 #include "net/base/escape.h" |
| 12 #include "net/base/net_errors.h" | 13 #include "net/base/net_errors.h" |
| 13 #include "net/base/net_util.h" | 14 #include "net/base/net_util.h" |
| 14 #include "net/ftp/ftp_directory_parser.h" | 15 #include "net/ftp/ftp_directory_parser.h" |
| 15 #include "net/ftp/ftp_response_info.h" | 16 #include "net/ftp/ftp_response_info.h" |
| 16 #include "net/ftp/ftp_transaction_factory.h" | 17 #include "net/ftp/ftp_transaction_factory.h" |
| 17 #include "net/url_request/url_request.h" | 18 #include "net/url_request/url_request.h" |
| 18 #include "net/url_request/url_request_context.h" | 19 #include "net/url_request/url_request_context.h" |
| 19 #include "net/url_request/url_request_error_job.h" | 20 #include "net/url_request/url_request_error_job.h" |
| 20 #include "unicode/ucsdet.h" | 21 #include "unicode/ucsdet.h" |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 53 if (!CodepageToUTF16(raw_filename, encoding.c_str(), | 54 if (!CodepageToUTF16(raw_filename, encoding.c_str(), |
| 54 OnStringUtilConversionError::SUBSTITUTE, &filename)) | 55 OnStringUtilConversionError::SUBSTITUTE, &filename)) |
| 55 filename = WideToUTF16Hack(base::SysNativeMBToWide(raw_filename)); | 56 filename = WideToUTF16Hack(base::SysNativeMBToWide(raw_filename)); |
| 56 return filename; | 57 return filename; |
| 57 } | 58 } |
| 58 | 59 |
| 59 } // namespace | 60 } // namespace |
| 60 | 61 |
| 61 URLRequestNewFtpJob::URLRequestNewFtpJob(URLRequest* request) | 62 URLRequestNewFtpJob::URLRequestNewFtpJob(URLRequest* request) |
| 62 : URLRequestJob(request), | 63 : URLRequestJob(request), |
| 63 server_auth_state_(net::AUTH_STATE_DONT_NEED_AUTH), | |
| 64 response_info_(NULL), | 64 response_info_(NULL), |
| 65 dir_listing_buf_size_(0), | 65 dir_listing_buf_size_(0), |
| 66 ALLOW_THIS_IN_INITIALIZER_LIST( | 66 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 67 start_callback_(this, &URLRequestNewFtpJob::OnStartCompleted)), | 67 start_callback_(this, &URLRequestNewFtpJob::OnStartCompleted)), |
| 68 ALLOW_THIS_IN_INITIALIZER_LIST( | 68 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 69 read_callback_(this, &URLRequestNewFtpJob::OnReadCompleted)), | 69 read_callback_(this, &URLRequestNewFtpJob::OnReadCompleted)), |
| 70 read_in_progress_(false), | 70 read_in_progress_(false), |
| 71 context_(request->context()) { | 71 context_(request->context()) { |
| 72 } | 72 } |
| 73 | 73 |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 99 return; | 99 return; |
| 100 DestroyTransaction(); | 100 DestroyTransaction(); |
| 101 URLRequestJob::Kill(); | 101 URLRequestJob::Kill(); |
| 102 } | 102 } |
| 103 | 103 |
| 104 net::LoadState URLRequestNewFtpJob::GetLoadState() const { | 104 net::LoadState URLRequestNewFtpJob::GetLoadState() const { |
| 105 return transaction_.get() ? | 105 return transaction_.get() ? |
| 106 transaction_->GetLoadState() : net::LOAD_STATE_IDLE; | 106 transaction_->GetLoadState() : net::LOAD_STATE_IDLE; |
| 107 } | 107 } |
| 108 | 108 |
| 109 bool URLRequestNewFtpJob::NeedsAuth() { | |
| 110 // Note that we only have to worry about cases where an actual FTP server | |
| 111 // requires auth (and not a proxy), because connecting to FTP via proxy | |
| 112 // effectively means the browser communicates via HTTP, and uses HTTP's | |
| 113 // Proxy-Authenticate protocol when proxy servers require auth. | |
| 114 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
| |
| 115 } | |
| 116 | |
| 117 void URLRequestNewFtpJob::GetAuthChallengeInfo( | |
| 118 scoped_refptr<net::AuthChallengeInfo>* result) { | |
| 119 DCHECK((server_auth_ != NULL) && | |
| 120 (server_auth_->state == net::AUTH_STATE_NEED_AUTH)); | |
| 121 scoped_refptr<net::AuthChallengeInfo> auth_info = new net::AuthChallengeInfo; | |
| 122 auth_info->is_proxy = false; | |
| 123 auth_info->host_and_port = ASCIIToWide( | |
| 124 net::GetHostAndPort(request_->url())); | |
| 125 auth_info->scheme = L""; | |
| 126 auth_info->realm = L""; | |
| 127 result->swap(auth_info); | |
| 128 } | |
| 129 | |
| 130 void URLRequestNewFtpJob::SetAuth(const std::wstring& username, | |
| 131 const std::wstring& password) { | |
| 132 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
| |
| 133 server_auth_->state = net::AUTH_STATE_HAVE_AUTH; | |
| 134 server_auth_->username = username; | |
| 135 server_auth_->password = password; | |
| 136 | |
| 137 // Resend the request with the new username and password. | |
| 138 // Do this asynchronously in case we were called from within a | |
| 139 // NotifyDataAvailable callback. | |
| 140 // TODO(mpcomplete): hmm... is it possible 'this' gets deleted before the task | |
| 141 // is run? | |
| 142 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( | |
|
wtc
2009/08/25 20:52:50
URLRequestHttpJob just call RestartTransactionWith
| |
| 143 this, &URLRequestNewFtpJob::RestartWithAuth)); | |
| 144 } | |
| 145 | |
| 146 void URLRequestNewFtpJob::CancelAuth() { | |
| 147 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
| |
| 148 server_auth_->state = net::AUTH_STATE_CANCELED; | |
| 149 | |
| 150 // Once the auth is cancelled, we proceed with the request as though | |
| 151 // there were no auth. Schedule this for later so that we don't cause | |
| 152 // any recursing into the caller as a result of this call. | |
| 153 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( | |
|
wtc
2009/08/25 20:52:50
URLRequestHttpJob::CancelAuth posts a task for
OnS
| |
| 154 this, &URLRequestNewFtpJob::NotifyHeadersComplete)); | |
| 155 } | |
| 156 | |
| 109 bool URLRequestNewFtpJob::ReadRawData(net::IOBuffer* buf, | 157 bool URLRequestNewFtpJob::ReadRawData(net::IOBuffer* buf, |
| 110 int buf_size, | 158 int buf_size, |
| 111 int *bytes_read) { | 159 int *bytes_read) { |
| 112 DCHECK_NE(buf_size, 0); | 160 DCHECK_NE(buf_size, 0); |
| 113 DCHECK(bytes_read); | 161 DCHECK(bytes_read); |
| 114 DCHECK(!read_in_progress_); | 162 DCHECK(!read_in_progress_); |
| 115 if (response_info_ == NULL) { | 163 if (response_info_ == NULL) { |
| 116 response_info_ = transaction_->GetResponseInfo(); | 164 response_info_ = transaction_->GetResponseInfo(); |
| 117 if (response_info_->is_directory_listing) { | 165 if (response_info_->is_directory_listing) { |
| 118 std::string escaped_path = | 166 std::string escaped_path = |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 243 if (!request_ || !request_->delegate()) | 291 if (!request_ || !request_->delegate()) |
| 244 return; | 292 return; |
| 245 // If the transaction was destroyed, then the job was cancelled, and | 293 // If the transaction was destroyed, then the job was cancelled, and |
| 246 // we can just ignore this notification. | 294 // we can just ignore this notification. |
| 247 if (!transaction_.get()) | 295 if (!transaction_.get()) |
| 248 return; | 296 return; |
| 249 // Clear the IO_PENDING status | 297 // Clear the IO_PENDING status |
| 250 SetStatus(URLRequestStatus()); | 298 SetStatus(URLRequestStatus()); |
| 251 if (result == net::OK) { | 299 if (result == net::OK) { |
| 252 NotifyHeadersComplete(); | 300 NotifyHeadersComplete(); |
| 253 } else { | 301 } else { |
|
wtc
2009/08/25 20:52:50
Use "else if" here.
| |
| 254 NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, result)); | 302 if (transaction_->GetResponseInfo()->auth_needed) { |
| 303 server_auth_ = new net::AuthData(); | |
| 304 server_auth_->state = net::AUTH_STATE_NEED_AUTH; | |
| 305 NotifyHeadersComplete(); | |
| 306 } else { | |
| 307 NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, result)); | |
| 308 } | |
| 255 } | 309 } |
| 256 } | 310 } |
| 257 | 311 |
| 258 void URLRequestNewFtpJob::OnReadCompleted(int result) { | 312 void URLRequestNewFtpJob::OnReadCompleted(int result) { |
| 259 read_in_progress_ = false; | 313 read_in_progress_ = false; |
| 260 if (result == 0) { | 314 if (result == 0) { |
| 261 NotifyDone(URLRequestStatus()); | 315 NotifyDone(URLRequestStatus()); |
| 262 } else if (result < 0) { | 316 } else if (result < 0) { |
| 263 NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, result)); | 317 NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, result)); |
| 264 } else { | 318 } else { |
| 265 // TODO(ibrar): find the best place to delete dir_listing_buf_ | 319 // TODO(ibrar): find the best place to delete dir_listing_buf_ |
| 266 // Filter for Directory listing. | 320 // Filter for Directory listing. |
| 267 if (response_info_->is_directory_listing) | 321 if (response_info_->is_directory_listing) |
| 268 result = ProcessFtpDir(dir_listing_buf_, dir_listing_buf_size_, result); | 322 result = ProcessFtpDir(dir_listing_buf_, dir_listing_buf_size_, result); |
| 269 | 323 |
| 270 // Clear the IO_PENDING status | 324 // Clear the IO_PENDING status |
| 271 SetStatus(URLRequestStatus()); | 325 SetStatus(URLRequestStatus()); |
| 272 } | 326 } |
| 273 NotifyReadComplete(result); | 327 NotifyReadComplete(result); |
| 274 } | 328 } |
| 275 | 329 |
| 330 void URLRequestNewFtpJob::RestartWithAuth() { | |
|
wtc
2009/08/25 20:52:50
Perhaps rename this method RestartTransactionWithA
| |
| 331 DCHECK(server_auth_ && server_auth_->state == net::AUTH_STATE_HAVE_AUTH); | |
| 332 | |
|
wtc
2009/08/25 20:52:50
URLRequestHttpJob::RestartTransactionWithAuth also
| |
| 333 // No matter what, we want to report our status as IO pending since we will | |
| 334 // be notifying our consumer asynchronously via OnStartCompleted. | |
| 335 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); | |
| 336 | |
| 337 int rv = transaction_->RestartWithAuth(server_auth_->username, | |
| 338 server_auth_->password, | |
| 339 &start_callback_); | |
| 340 if (rv == net::ERR_IO_PENDING) | |
| 341 return; | |
| 342 | |
| 343 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( | |
| 344 this, &URLRequestNewFtpJob::OnStartCompleted, rv)); | |
| 345 } | |
| 346 | |
| 276 void URLRequestNewFtpJob::StartTransaction() { | 347 void URLRequestNewFtpJob::StartTransaction() { |
| 277 // Create a transaction. | 348 // Create a transaction. |
| 278 DCHECK(!transaction_.get()); | 349 DCHECK(!transaction_.get()); |
| 279 DCHECK(request_->context()); | 350 DCHECK(request_->context()); |
| 280 DCHECK(request_->context()->ftp_transaction_factory()); | 351 DCHECK(request_->context()->ftp_transaction_factory()); |
| 281 | 352 |
| 282 transaction_.reset( | 353 transaction_.reset( |
| 283 request_->context()->ftp_transaction_factory()->CreateTransaction()); | 354 request_->context()->ftp_transaction_factory()->CreateTransaction()); |
| 284 | 355 |
| 285 // No matter what, we want to report our status as IO pending since we will | 356 // No matter what, we want to report our status as IO pending since we will |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 299 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( | 370 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( |
| 300 this, &URLRequestNewFtpJob::OnStartCompleted, rv)); | 371 this, &URLRequestNewFtpJob::OnStartCompleted, rv)); |
| 301 } | 372 } |
| 302 | 373 |
| 303 void URLRequestNewFtpJob::DestroyTransaction() { | 374 void URLRequestNewFtpJob::DestroyTransaction() { |
| 304 DCHECK(transaction_.get()); | 375 DCHECK(transaction_.get()); |
| 305 | 376 |
| 306 transaction_.reset(); | 377 transaction_.reset(); |
| 307 response_info_ = NULL; | 378 response_info_ = NULL; |
| 308 } | 379 } |
| OLD | NEW |