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" |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
238 // | 238 // |
239 // TODO(jungshik): UTF-8 has to be 'enforced' without any heuristics when | 239 // TODO(jungshik): UTF-8 has to be 'enforced' without any heuristics when |
240 // we're talking to an FTP server compliant to RFC 2640 (that is, its response | 240 // we're talking to an FTP server compliant to RFC 2640 (that is, its response |
241 // to FEAT command includes 'UTF8'). | 241 // to FEAT command includes 'UTF8'). |
242 // See http://wiki.filezilla-project.org/Character_Set | 242 // See http://wiki.filezilla-project.org/Character_Set |
243 if (encoding_.empty()) | 243 if (encoding_.empty()) |
244 encoding_ = DetectEncoding(buf->data(), bytes_read); | 244 encoding_ = DetectEncoding(buf->data(), bytes_read); |
245 | 245 |
246 int64 file_size; | 246 int64 file_size; |
247 std::istringstream iss(std::string(buf->data(), bytes_read)); | 247 std::istringstream iss(std::string(buf->data(), bytes_read)); |
248 struct net::ListState state; | 248 struct net::list_state state; |
249 memset(&state, 0, sizeof(state)); | 249 memset(&state, 0, sizeof(state)); |
250 while (getline(iss, line)) { | 250 while (getline(iss, line)) { |
251 struct net::ListResult result; | 251 struct net::list_result result; |
252 std::replace(line.begin(), line.end(), '\r', '\0'); | 252 std::replace(line.begin(), line.end(), '\r', '\0'); |
253 net::LineType line_type = ParseFTPLine(line.c_str(), &state, &result); | 253 int line_type = net::ParseFTPList(line.c_str(), &state, &result); |
254 | |
255 // The original code assumed months are in range 0-11 (PRExplodedTime), | |
256 // but our Time class expects a 1-12 range. Adjust it here, because | |
257 // the third-party parsing code uses bit-shifting on the month, | |
wtc
2009/09/10 18:55:32
I now understand the bit-shifting code in ParseFTP
| |
258 // and it'd be too easy to break that logic. | |
259 result.fe_time.month++; | |
260 DCHECK_LE(1, result.fe_time.month); | |
261 DCHECK_GE(12, result.fe_time.month); | |
262 | |
254 switch (line_type) { | 263 switch (line_type) { |
255 case net::FTP_TYPE_DIRECTORY: | 264 case 'd': // Directory entry. |
256 file_entry.append(net::GetDirectoryListingEntry( | 265 file_entry.append(net::GetDirectoryListingEntry( |
257 RawByteSequenceToFilename(result.fe_fname, encoding_), | 266 RawByteSequenceToFilename(result.fe_fname, encoding_), |
258 result.fe_fname, true, 0, | 267 result.fe_fname, true, 0, |
259 base::Time::FromLocalExploded(result.fe_time))); | 268 base::Time::FromLocalExploded(result.fe_time))); |
260 break; | 269 break; |
261 case net::FTP_TYPE_FILE: | 270 case 'f': // File entry. |
262 if (StringToInt64(result.fe_size, &file_size)) | 271 if (StringToInt64(result.fe_size, &file_size)) |
263 file_entry.append(net::GetDirectoryListingEntry( | 272 file_entry.append(net::GetDirectoryListingEntry( |
264 RawByteSequenceToFilename(result.fe_fname, encoding_), | 273 RawByteSequenceToFilename(result.fe_fname, encoding_), |
265 result.fe_fname, false, file_size, | 274 result.fe_fname, false, file_size, |
266 base::Time::FromLocalExploded(result.fe_time))); | 275 base::Time::FromLocalExploded(result.fe_time))); |
267 break; | 276 break; |
268 case net::FTP_TYPE_SYMLINK: { | 277 case 'l': { // Symlink entry. |
269 std::string filename(result.fe_fname, result.fe_fnlen); | 278 std::string filename(result.fe_fname, result.fe_fnlen); |
270 | 279 |
271 // Parsers for styles 'U' and 'W' handle " -> " themselves. | 280 // Parsers for styles 'U' and 'W' handle " -> " themselves. |
272 if (state.lstyle != 'U' && state.lstyle != 'W') { | 281 if (state.lstyle != 'U' && state.lstyle != 'W') { |
273 std::string::size_type offset = filename.find(" -> "); | 282 std::string::size_type offset = filename.find(" -> "); |
274 if (offset != std::string::npos) | 283 if (offset != std::string::npos) |
275 filename = filename.substr(0, offset); | 284 filename = filename.substr(0, offset); |
276 } | 285 } |
277 | 286 |
278 if (StringToInt64(result.fe_size, &file_size)) { | 287 if (StringToInt64(result.fe_size, &file_size)) { |
279 file_entry.append(net::GetDirectoryListingEntry( | 288 file_entry.append(net::GetDirectoryListingEntry( |
280 RawByteSequenceToFilename(filename.c_str(), encoding_), | 289 RawByteSequenceToFilename(filename.c_str(), encoding_), |
281 filename, false, file_size, | 290 filename, false, file_size, |
282 base::Time::FromLocalExploded(result.fe_time))); | 291 base::Time::FromLocalExploded(result.fe_time))); |
283 } | 292 } |
284 } | 293 } |
285 break; | 294 break; |
286 case net::FTP_TYPE_JUNK: | 295 case '?': // Junk entry. |
287 case net::FTP_TYPE_COMMENT: | 296 case '"': // Comment entry. |
288 break; | 297 break; |
289 default: | 298 default: |
299 NOTREACHED(); | |
290 break; | 300 break; |
291 } | 301 } |
292 } | 302 } |
293 LogFtpServerType(state); | 303 LogFtpServerType(state); |
294 directory_html_.append(file_entry); | 304 directory_html_.append(file_entry); |
295 size_t bytes_to_copy = std::min(static_cast<size_t>(buf_size), | 305 size_t bytes_to_copy = std::min(static_cast<size_t>(buf_size), |
296 directory_html_.length()); | 306 directory_html_.length()); |
297 if (bytes_to_copy) { | 307 if (bytes_to_copy) { |
298 memcpy(buf->data(), directory_html_.c_str(), bytes_to_copy); | 308 memcpy(buf->data(), directory_html_.c_str(), bytes_to_copy); |
299 directory_html_.erase(0, bytes_to_copy); | 309 directory_html_.erase(0, bytes_to_copy); |
300 } | 310 } |
301 return bytes_to_copy; | 311 return bytes_to_copy; |
302 } | 312 } |
303 | 313 |
304 void URLRequestNewFtpJob::LogFtpServerType(const net::ListState& list_state) { | 314 void URLRequestNewFtpJob::LogFtpServerType( |
315 const struct net::list_state& list_state) { | |
305 // We can't recognize server type based on empty directory listings. Don't log | 316 // We can't recognize server type based on empty directory listings. Don't log |
306 // that as unknown, it's misleading. | 317 // that as unknown, it's misleading. |
307 if (!list_state.parsed_one) | 318 if (!list_state.parsed_one) |
308 return; | 319 return; |
309 | 320 |
310 switch (list_state.lstyle) { | 321 switch (list_state.lstyle) { |
311 case 'E': | 322 case 'E': |
312 net::UpdateFtpServerTypeHistograms(net::SERVER_EPLF); | 323 net::UpdateFtpServerTypeHistograms(net::SERVER_EPLF); |
313 break; | 324 break; |
314 case 'V': | 325 case 'V': |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
422 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( | 433 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( |
423 this, &URLRequestNewFtpJob::OnStartCompleted, rv)); | 434 this, &URLRequestNewFtpJob::OnStartCompleted, rv)); |
424 } | 435 } |
425 | 436 |
426 void URLRequestNewFtpJob::DestroyTransaction() { | 437 void URLRequestNewFtpJob::DestroyTransaction() { |
427 DCHECK(transaction_.get()); | 438 DCHECK(transaction_.get()); |
428 | 439 |
429 transaction_.reset(); | 440 transaction_.reset(); |
430 response_info_ = NULL; | 441 response_info_ = NULL; |
431 } | 442 } |
OLD | NEW |