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

Side by Side Diff: net/url_request/url_request_new_ftp_job.cc

Issue 115137: FTP Transaction code for new Portable FTP code.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Upload before checkin 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/url_request/url_request_new_ftp_job.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/file_version_info.h" 7 #include "base/file_version_info.h"
8 #include "base/message_loop.h"
9 #include "net/base/escape.h"
8 #include "net/base/net_util.h" 10 #include "net/base/net_util.h"
11 #include "net/ftp/ftp_directory_parser.h"
12 #include "net/ftp/ftp_response_info.h"
13 #include "net/ftp/ftp_transaction_factory.h"
9 #include "net/url_request/url_request.h" 14 #include "net/url_request/url_request.h"
10 #include "net/url_request/url_request_context.h" 15 #include "net/url_request/url_request_context.h"
11 #include "net/url_request/url_request_error_job.h" 16 #include "net/url_request/url_request_error_job.h"
12 17
13
14 URLRequestNewFtpJob::URLRequestNewFtpJob(URLRequest* request) 18 URLRequestNewFtpJob::URLRequestNewFtpJob(URLRequest* request)
15 : URLRequestJob(request), 19 : URLRequestJob(request),
16 server_auth_state_(net::AUTH_STATE_DONT_NEED_AUTH), 20 server_auth_state_(net::AUTH_STATE_DONT_NEED_AUTH),
17 ALLOW_THIS_IN_INITIALIZER_LIST( 21 ALLOW_THIS_IN_INITIALIZER_LIST(
18 start_callback_(this, &URLRequestNewFtpJob::OnStartCompleted)), 22 start_callback_(this, &URLRequestNewFtpJob::OnStartCompleted)),
19 ALLOW_THIS_IN_INITIALIZER_LIST( 23 ALLOW_THIS_IN_INITIALIZER_LIST(
20 read_callback_(this, &URLRequestNewFtpJob::OnReadCompleted)), 24 read_callback_(this, &URLRequestNewFtpJob::OnReadCompleted)),
21 read_in_progress_(false), 25 read_in_progress_(false),
22 context_(request->context()) { 26 context_(request->context()) {
23 } 27 }
24 28
25 URLRequestNewFtpJob::~URLRequestNewFtpJob() { 29 URLRequestNewFtpJob::~URLRequestNewFtpJob() {
26 } 30 }
27 31
28 // static 32 // static
29 URLRequestJob* URLRequestNewFtpJob::Factory(URLRequest* request, 33 URLRequestJob* URLRequestNewFtpJob::Factory(URLRequest* request,
30 const std::string& scheme) { 34 const std::string& scheme) {
31 DCHECK(scheme == "ftp"); 35 DCHECK(scheme == "ftp");
32 36
33 if (request->url().has_port() && 37 if (request->url().has_port() &&
34 !net::IsPortAllowedByFtp(request->url().IntPort())) 38 !net::IsPortAllowedByFtp(request->url().IntPort()))
35 return new URLRequestErrorJob(request, net::ERR_UNSAFE_PORT); 39 return new URLRequestErrorJob(request, net::ERR_UNSAFE_PORT);
36 40
37 DCHECK(request->context()); 41 DCHECK(request->context());
38 DCHECK(request->context()->ftp_transaction_factory()); 42 DCHECK(request->context()->ftp_transaction_factory());
39 return new URLRequestNewFtpJob(request); 43 return new URLRequestNewFtpJob(request);
40 } 44 }
41 45
42 void URLRequestNewFtpJob::Start() { 46 void URLRequestNewFtpJob::Start() {
43 NOTIMPLEMENTED(); 47 DCHECK(!transaction_.get());
48 request_info_.url = request_->url();
49 StartTransaction();
44 } 50 }
45 51
46 void URLRequestNewFtpJob::Kill() { 52 void URLRequestNewFtpJob::Kill() {
47 NOTIMPLEMENTED(); 53 if (!transaction_.get())
48 } 54 return;
49 55 DestroyTransaction();
50 uint64 URLRequestNewFtpJob::GetUploadProgress() const { 56 URLRequestJob::Kill();
51 NOTIMPLEMENTED();
52 return 0;
53 }
54
55 void URLRequestNewFtpJob::GetResponseInfo() {
56 NOTIMPLEMENTED();
57 }
58
59 int URLRequestNewFtpJob::GetResponseCode() const {
60 NOTIMPLEMENTED();
61 return -1;
62 }
63
64 bool URLRequestNewFtpJob::GetMoreData() {
65 NOTIMPLEMENTED();
66 return false;
67 } 57 }
68 58
69 bool URLRequestNewFtpJob::ReadRawData(net::IOBuffer* buf, 59 bool URLRequestNewFtpJob::ReadRawData(net::IOBuffer* buf,
70 int buf_size, 60 int buf_size,
71 int *bytes_read) { 61 int *bytes_read) {
72 NOTIMPLEMENTED(); 62 DCHECK_NE(buf_size, 0);
63 DCHECK(bytes_read);
64 DCHECK(!read_in_progress_);
65 if (response_info_ == NULL) {
66 response_info_ = transaction_->GetResponseInfo();
67 if (response_info_->is_directory_listing) {
68 // Unescape the URL path and pass the raw 8bit directly to the browser.
69 directory_html_ = net::GetDirectoryListingHeader(
70 UnescapeURLComponent(request_->url().path(),
71 UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS));
72 // If this isn't top level directory (i.e. the path isn't "/",)
73 // add a link to the parent directory.
74 if (request_->url().path().length() > 1)
75 directory_html_.append(net::GetDirectoryListingEntry("..",
76 false,
77 0,
78 base::Time()));
79 }
80 }
81 if (!directory_html_.empty()) {
82 size_t bytes_to_copy = std::min(static_cast<size_t>(buf_size),
83 directory_html_.size());
84 memcpy(buf->data(), directory_html_.c_str(), bytes_to_copy);
85 *bytes_read = bytes_to_copy;
86 directory_html_.erase(0, bytes_to_copy);
87 return true;
88 }
89 int rv = transaction_->Read(buf, buf_size, &read_callback_);
90 if (response_info_->is_directory_listing) {
91 std::string file_entry;
92 if (rv > 0) {
93 std::string line;
94 buf->data()[rv] = 0;
95 std::istringstream iss(buf->data());
96 while (getline(iss, line)) {
97 struct net::ListState state;
98 struct net::ListResult result;
99 // TODO(ibrar): Use a more descriptive variable name than 'lt', which
100 // looks like 'it'.
101 net::LineType lt = ParseFTPLine(line.c_str(), &state, &result);
102 switch (lt) {
103 case net::FTP_TYPE_DIRECTORY:
104 file_entry.append(net::GetDirectoryListingEntry(result.fe_fname,
105 true,
106 rv,
107 base::Time()));
108 break;
109 case net::FTP_TYPE_FILE:
110 file_entry.append(net::GetDirectoryListingEntry(result.fe_fname,
111 false,
112 rv,
113 base::Time()));
114 break;
115 case net::FTP_TYPE_SYMLINK:
116 case net::FTP_TYPE_JUNK:
117 case net::FTP_TYPE_COMMENT:
118 break;
119 default:
120 break;
121 }
122 }
123 memcpy(buf->data(), file_entry.c_str(), file_entry.length());
124 *bytes_read = file_entry.length();
125 return true;
126 }
127 } else {
128 rv = transaction_->Read(buf, buf_size, &read_callback_);
129 }
130 if (rv >= 0) {
131 *bytes_read = rv;
132 return true;
133 }
134 if (rv == net::ERR_IO_PENDING) {
135 read_in_progress_ = true;
136 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0));
137 } else {
138 NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, rv));
139 }
73 return false; 140 return false;
74 } 141 }
75 142
76 void URLRequestNewFtpJob::OnStartCompleted(int result) { 143 void URLRequestNewFtpJob::OnStartCompleted(int result) {
77 NOTIMPLEMENTED(); 144 // If the request was destroyed, then there is no more work to do.
145 if (!request_ || !request_->delegate())
146 return;
147 // If the transaction was destroyed, then the job was cancelled, and
148 // we can just ignore this notification.
149 if (!transaction_.get())
150 return;
151 // Clear the IO_PENDING status
152 SetStatus(URLRequestStatus());
153 if (result == net::OK) {
154 URLRequestJob::NotifyHeadersComplete();
155 } else {
156 NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, result));
157 }
78 } 158 }
79 159
80 void URLRequestNewFtpJob::OnReadCompleted(int result) { 160 void URLRequestNewFtpJob::OnReadCompleted(int result) {
81 NOTIMPLEMENTED(); 161 read_in_progress_ = false;
162 if (result == 0) {
163 NotifyDone(URLRequestStatus());
164 } else if (result < 0) {
165 NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, result));
166 } else {
167 // Clear the IO_PENDING status
168 SetStatus(URLRequestStatus());
169 }
170 NotifyReadComplete(result);
171 }
172
173 void URLRequestNewFtpJob::StartTransaction() {
174 // Create a transaction.
175 DCHECK(!transaction_.get());
176 DCHECK(request_->context());
177 DCHECK(request_->context()->ftp_transaction_factory());
178
179 transaction_.reset(
180 request_->context()->ftp_transaction_factory()->CreateTransaction());
181
182 // No matter what, we want to report our status as IO pending since we will
183 // be notifying our consumer asynchronously via OnStartCompleted.
184 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0));
185 int rv;
186 if (transaction_.get()) {
187 rv = transaction_->Start(&request_info_, &start_callback_);
188 if (rv == net::ERR_IO_PENDING)
189 return;
190 } else {
191 rv = net::ERR_FAILED;
192 }
193 // The transaction started synchronously, but we need to notify the
194 // URLRequest delegate via the message loop.
195 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
196 this, &URLRequestNewFtpJob::OnStartCompleted, rv));
82 } 197 }
83 198
84 void URLRequestNewFtpJob::DestroyTransaction() { 199 void URLRequestNewFtpJob::DestroyTransaction() {
85 NOTIMPLEMENTED(); 200 DCHECK(transaction_.get());
201
202 transaction_.reset();
203 response_info_ = NULL;
86 } 204 }
87
88 void URLRequestNewFtpJob::StartTransaction() {
89 NOTIMPLEMENTED();
90 }
OLDNEW
« 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