Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(359)

Unified Diff: net/url_request/url_request_new_ftp_job.cc

Issue 39130: FTP Transaction code for new Portable FTP(Patch SET-3) (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 11 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/url_request/url_request_new_ftp_job.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/url_request/url_request_new_ftp_job.cc
===================================================================
--- net/url_request/url_request_new_ftp_job.cc (revision 13921)
+++ net/url_request/url_request_new_ftp_job.cc (working copy)
@@ -5,7 +5,12 @@
#include "net/url_request/url_request_new_ftp_job.h"
#include "base/file_version_info.h"
+#include "base/message_loop.h"
+#include "net/base/escape.h"
#include "net/base/net_util.h"
+#include "net/ftp/ftp_directory_parser.h"
+#include "net/ftp/ftp_response_info.h"
+#include "net/ftp/ftp_transaction_factory.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_error_job.h"
@@ -40,51 +45,159 @@
}
void URLRequestNewFtpJob::Start() {
- NOTIMPLEMENTED();
+ DCHECK(!transaction_.get());
+ request_info_.url = request_->url();
+ StartTransaction();
}
void URLRequestNewFtpJob::Kill() {
- NOTIMPLEMENTED();
+ if (!transaction_.get())
+ return;
+ DestroyTransaction();
+ URLRequestJob::Kill();
}
-uint64 URLRequestNewFtpJob::GetUploadProgress() const {
- NOTIMPLEMENTED();
- return 0;
-}
-
-void URLRequestNewFtpJob::GetResponseInfo() {
- NOTIMPLEMENTED();
-}
-
-int URLRequestNewFtpJob::GetResponseCode() const {
- NOTIMPLEMENTED();
- return -1;
-}
-
-bool URLRequestNewFtpJob::GetMoreData() {
- NOTIMPLEMENTED();
- return false;
-}
-
bool URLRequestNewFtpJob::ReadRawData(net::IOBuffer* buf,
int buf_size,
int *bytes_read) {
- NOTIMPLEMENTED();
+ DCHECK_NE(buf_size, 0);
+ DCHECK(bytes_read);
+ DCHECK(!read_in_progress_);
+ if (response_info_ == NULL) {
+ response_info_ = transaction_->GetResponseInfo();
+ if (response_info_->is_directory_listing) {
+ // Unescape the URL path and pass the raw 8bit directly to the browser.
+ directory_html_ = net::GetDirectoryListingHeader(
+ UnescapeURLComponent(request_->url().path(),
+ UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS));
+ // If this isn't top level directory (i.e. the path isn't "/",)
+ // add a link to the parent directory.
+ if (request_->url().path().length() > 1)
+ directory_html_.append(net::GetDirectoryListingEntry("..",
+ false,
+ 0,
+ base::Time()));
+ }
+ }
+ if (!directory_html_.empty()) {
+ size_t bytes_to_copy = std::min(static_cast<size_t>(buf_size),
+ directory_html_.size());
+ memcpy(buf->data(), directory_html_.c_str(), bytes_to_copy);
+ *bytes_read = bytes_to_copy;
+ directory_html_.erase(0, bytes_to_copy);
+ return true;
+ }
+ int rv = transaction_->Read(buf, buf_size, &read_callback_);
+ if (response_info_->is_directory_listing) {
+ std::string file_entry;
+ if (rv > 0) {
+ std::string line;
+ buf->data()[rv] = 0;
+ std::istringstream iss(buf->data());
+ while (getline(iss, line)) {
+ struct net::ListState state;
+ struct net::ListResult result;
+ net::LineType lt = ParseFTPLine(line.c_str(), &state, &result);
+ switch (lt) {
+ case net::FTP_TYPE_DIRECTORY:
+ file_entry.append(net::GetDirectoryListingEntry(result.fe_fname,
+ true,
+ rv,
+ base::Time()));
+ break;
+ case net::FTP_TYPE_FILE:
+ file_entry.append(net::GetDirectoryListingEntry(result.fe_fname,
+ false,
+ rv,
+ base::Time()));
+ break;
+ case net::FTP_TYPE_SYMLINK:
+ case net::FTP_TYPE_JUNK:
+ case net::FTP_TYPE_COMMENT:
+ break;
+ default:
+ break;
+ }
+ }
+ memcpy(buf->data(), file_entry.c_str(), file_entry.length());
+ *bytes_read = file_entry.length();
+ return true;
+ }
+ } else {
+ rv = transaction_->Read(buf, buf_size, &read_callback_);
+ }
+ if (rv >= 0) {
+ *bytes_read = rv;
+ return true;
+ }
+ if (rv == net::ERR_IO_PENDING) {
+ read_in_progress_ = true;
+ SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0));
+ } else {
+ NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, rv));
+ }
return false;
}
void URLRequestNewFtpJob::OnStartCompleted(int result) {
- NOTIMPLEMENTED();
+ // If the request was destroyed, then there is no more work to do.
+ if (!request_ || !request_->delegate())
+ return;
+ // If the transaction was destroyed, then the job was cancelled, and
+ // we can just ignore this notification.
+ if (!transaction_.get())
+ return;
+ // Clear the IO_PENDING status
+ SetStatus(URLRequestStatus());
+ if (result == net::OK) {
+ URLRequestJob::NotifyHeadersComplete();
+ } else {
+ NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, result));
+ }
}
void URLRequestNewFtpJob::OnReadCompleted(int result) {
- NOTIMPLEMENTED();
+ read_in_progress_ = false;
+ if (result == 0) {
+ NotifyDone(URLRequestStatus());
+ } else if (result < 0) {
+ NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, result));
+ } else {
+ // Clear the IO_PENDING status
+ SetStatus(URLRequestStatus());
+ }
+ NotifyReadComplete(result);
}
-void URLRequestNewFtpJob::DestroyTransaction() {
- NOTIMPLEMENTED();
+void URLRequestNewFtpJob::StartTransaction() {
+ // Create a transaction.
+ DCHECK(!transaction_.get());
+ DCHECK(request_->context());
+ DCHECK(request_->context()->ftp_transaction_factory());
+
+ transaction_.reset(
+ request_->context()->ftp_transaction_factory()->CreateTransaction());
+
+ // 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;
+ if (transaction_.get()) {
+ rv = transaction_->Start(&request_info_, &start_callback_);
+ if (rv == net::ERR_IO_PENDING)
+ return;
+ } else {
+ rv = net::ERR_FAILED;
+ }
+ // The transaction started synchronously, but we need to notify the
+ // URLRequest delegate via the message loop.
+ MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &URLRequestNewFtpJob::OnStartCompleted, rv));
}
-void URLRequestNewFtpJob::StartTransaction() {
- NOTIMPLEMENTED();
+void URLRequestNewFtpJob::DestroyTransaction() {
+ DCHECK(transaction_.get());
+
+ transaction_.reset();
+ response_info_ = NULL;
}
« no previous file with comments | « net/url_request/url_request_new_ftp_job.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698