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

Side by Side Diff: net/ftp/ftp_directory_listing_parser.cc

Issue 6670085: FTP: Detect the character encoding only after the entire listing is received. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: update histograms for SERVER_UNKNOWN Created 9 years, 9 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
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // source code is governed by a BSD-style license that can be found in the 2 // Use of this source code is governed by a BSD-style license that can be
3 // LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/ftp/ftp_directory_listing_parser.h" 5 #include "net/ftp/ftp_directory_listing_parser.h"
6 6
7 namespace net { 7 #include "base/i18n/icu_encoding_detection.h"
8 #include "base/i18n/icu_string_conversions.h"
9 #include "base/stl_util-inl.h"
10 #include "base/string_split.h"
11 #include "base/string_util.h"
12 #include "net/base/net_errors.h"
13 #include "net/ftp/ftp_directory_listing_parser_ls.h"
14 #include "net/ftp/ftp_directory_listing_parser_netware.h"
15 #include "net/ftp/ftp_directory_listing_parser_vms.h"
16 #include "net/ftp/ftp_directory_listing_parser_windows.h"
17 #include "net/ftp/ftp_server_type_histograms.h"
8 18
9 FtpDirectoryListingParser::~FtpDirectoryListingParser() { 19 namespace {
20
21 // Converts a string with unknown character encoding to UTF-16. On success
22 // fills in |converted_text| and |encoding|. Returns network error code.
23 int ConvertStringToUTF16(const std::string& text,
24 string16* converted_text,
25 std::string* encoding) {
26 std::vector<std::string> encodings;
27 if (!base::DetectAllEncodings(text, &encodings))
28 return net::ERR_ENCODING_DETECTION_FAILED;
29
30 // Use first encoding that can be used to decode the text.
eroman 2011/03/24 23:09:35 I wander if it would be more flexible to move this
Paweł Hajdan Jr. 2011/03/26 09:47:50 Yes, it sounds like a good idea. I'd prefer to do
31 for (size_t i = 0; i < encodings.size(); i++) {
32 if (base::CodepageToUTF16(text,
33 encodings[i].c_str(),
34 base::OnStringConversionError::FAIL,
35 converted_text)) {
36 *encoding = encodings[i];
37 return net::OK;
38 }
39 }
40
41 return net::ERR_ENCODING_DETECTION_FAILED;
42 }
43
44 int FillInRawName(const std::string& encoding,
45 std::vector<net::FtpDirectoryListingEntry>* entries) {
46 for (size_t i = 0; i < entries->size(); i++) {
47 if (!base::UTF16ToCodepage(entries->at(i).name, encoding.c_str(),
48 base::OnStringConversionError::FAIL,
49 &entries->at(i).raw_name)) {
50 return net::ERR_ENCODING_CONVERSION_FAILED;
51 }
52 }
53
54 return net::OK;
10 } 55 }
11 56
12 } // namespace 57 } // namespace
58
59 namespace net {
60
61 int ParseFtpDirectoryListing(const std::string& text,
62 const base::Time& current_time,
63 std::vector<FtpDirectoryListingEntry>* entries) {
64 std::string encoding;
65
66 string16 converted_text;
67 int rv = ConvertStringToUTF16(text, &converted_text, &encoding);
68 if (rv != OK)
69 return rv;
70
71 std::vector<string16> lines;
72 base::SplitString(converted_text, '\n', &lines);
73
74 // TODO(phajdan.jr): Use a table of callbacks instead of repeating code.
75
76 entries->clear();
77 if (ParseFtpDirectoryListingLs(lines, current_time, entries)) {
78 UpdateFtpServerTypeHistograms(SERVER_LS);
79 return FillInRawName(encoding, entries);
80 }
81
82 entries->clear();
83 if (ParseFtpDirectoryListingWindows(lines, entries)) {
84 UpdateFtpServerTypeHistograms(SERVER_WINDOWS);
85 return FillInRawName(encoding, entries);
86 }
87
88 entries->clear();
89 if (ParseFtpDirectoryListingVms(lines, entries)) {
90 UpdateFtpServerTypeHistograms(SERVER_VMS);
91 return FillInRawName(encoding, entries);
92 }
93
94 entries->clear();
95 if (ParseFtpDirectoryListingNetware(lines, current_time, entries)) {
96 UpdateFtpServerTypeHistograms(SERVER_NETWARE);
97 return FillInRawName(encoding, entries);
98 }
99
100 entries->clear();
101 UpdateFtpServerTypeHistograms(SERVER_UNKNOWN);
102 return ERR_UNRECOGNIZED_FTP_DIRECTORY_LISTING_FORMAT;
103 }
104
105 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698