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

Side by Side Diff: webkit/glue/ftp_directory_listing_response_delegate.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: test coverage 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
« no previous file with comments | « webkit/glue/ftp_directory_listing_response_delegate.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) 2011 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 "webkit/glue/ftp_directory_listing_response_delegate.h" 5 #include "webkit/glue/ftp_directory_listing_response_delegate.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/i18n/icu_encoding_detection.h" 9 #include "base/i18n/icu_encoding_detection.h"
10 #include "base/i18n/icu_string_conversions.h" 10 #include "base/i18n/icu_string_conversions.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/string_util.h" 12 #include "base/string_util.h"
13 #include "base/sys_string_conversions.h" 13 #include "base/sys_string_conversions.h"
14 #include "base/utf_string_conversions.h" 14 #include "base/utf_string_conversions.h"
15 #include "base/time.h" 15 #include "base/time.h"
16 #include "net/base/escape.h" 16 #include "net/base/escape.h"
17 #include "net/base/net_errors.h" 17 #include "net/base/net_errors.h"
18 #include "net/base/net_util.h" 18 #include "net/base/net_util.h"
19 #include "net/ftp/ftp_directory_listing_parser.h" 19 #include "net/ftp/ftp_directory_listing_parser.h"
20 #include "net/ftp/ftp_server_type_histograms.h"
21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURL.h" 20 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURL.h"
22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLLoaderClient.h" 21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLLoaderClient.h"
23 22
24 using net::FtpDirectoryListingEntry; 23 using net::FtpDirectoryListingEntry;
25 24
26 using WebKit::WebURLLoader; 25 using WebKit::WebURLLoader;
27 using WebKit::WebURLLoaderClient; 26 using WebKit::WebURLLoaderClient;
28 using WebKit::WebURLResponse; 27 using WebKit::WebURLResponse;
29 28
30 namespace { 29 namespace {
(...skipping 22 matching lines...) Expand all
53 52
54 } // namespace 53 } // namespace
55 54
56 namespace webkit_glue { 55 namespace webkit_glue {
57 56
58 FtpDirectoryListingResponseDelegate::FtpDirectoryListingResponseDelegate( 57 FtpDirectoryListingResponseDelegate::FtpDirectoryListingResponseDelegate(
59 WebURLLoaderClient* client, 58 WebURLLoaderClient* client,
60 WebURLLoader* loader, 59 WebURLLoader* loader,
61 const WebURLResponse& response) 60 const WebURLResponse& response)
62 : client_(client), 61 : client_(client),
63 loader_(loader), 62 loader_(loader) {
64 original_response_(response), 63 Init(response.url());
65 buffer_(base::Time::Now()),
66 updated_histograms_(false),
67 had_parsing_error_(false) {
68 Init();
69 } 64 }
70 65
71 void FtpDirectoryListingResponseDelegate::OnReceivedData(const char* data, 66 void FtpDirectoryListingResponseDelegate::OnReceivedData(const char* data,
72 int data_len) { 67 int data_len) {
73 if (had_parsing_error_) 68 buffer_.append(data, data_len);
74 return;
75
76 if (buffer_.ConsumeData(data, data_len) == net::OK)
77 ProcessReceivedEntries();
78 else
79 had_parsing_error_ = true;
80 } 69 }
81 70
82 void FtpDirectoryListingResponseDelegate::OnCompletedRequest() { 71 void FtpDirectoryListingResponseDelegate::OnCompletedRequest() {
83 if (!had_parsing_error_ && buffer_.ProcessRemainingData() == net::OK) 72 std::vector<FtpDirectoryListingEntry> entries;
84 ProcessReceivedEntries(); 73 int rv = net::ParseFtpDirectoryListing(buffer_, base::Time::Now(), &entries);
85 else 74 if (rv != net::OK) {
86 had_parsing_error_ = true; 75 SendDataToClient("<script>onListingParsingError();</script>\n");
76 return;
77 }
78 for (size_t i = 0; i < entries.size(); i++) {
79 FtpDirectoryListingEntry entry = entries[i];
87 80
88 if (had_parsing_error_) 81 // Skip the current and parent directory entries in the listing. Our header
89 SendDataToClient("<script>onListingParsingError();</script>\n"); 82 // always includes them.
83 if (EqualsASCII(entry.name, ".") || EqualsASCII(entry.name, ".."))
84 continue;
85
86 bool is_directory = (entry.type == FtpDirectoryListingEntry::DIRECTORY);
87 int64 size = entry.size;
88 if (entry.type != FtpDirectoryListingEntry::FILE)
89 size = 0;
90 SendDataToClient(net::GetDirectoryListingEntry(
91 entry.name, entry.raw_name, is_directory, size, entry.last_modified));
92 }
90 } 93 }
91 94
92 void FtpDirectoryListingResponseDelegate::Init() { 95 void FtpDirectoryListingResponseDelegate::Init(const GURL& response_url) {
93 GURL response_url(original_response_.url());
94 UnescapeRule::Type unescape_rules = UnescapeRule::SPACES | 96 UnescapeRule::Type unescape_rules = UnescapeRule::SPACES |
95 UnescapeRule::URL_SPECIAL_CHARS; 97 UnescapeRule::URL_SPECIAL_CHARS;
96 std::string unescaped_path = UnescapeURLComponent(response_url.path(), 98 std::string unescaped_path = UnescapeURLComponent(response_url.path(),
97 unescape_rules); 99 unescape_rules);
98 SendDataToClient(net::GetDirectoryListingHeader( 100 SendDataToClient(net::GetDirectoryListingHeader(
99 ConvertPathToUTF16(unescaped_path))); 101 ConvertPathToUTF16(unescaped_path)));
100 102
101 // If this isn't top level directory (i.e. the path isn't "/",) 103 // If this isn't top level directory (i.e. the path isn't "/",)
102 // add a link to the parent directory. 104 // add a link to the parent directory.
103 if (response_url.path().length() > 1) { 105 if (response_url.path().length() > 1) {
104 SendDataToClient(net::GetDirectoryListingEntry( 106 SendDataToClient(net::GetDirectoryListingEntry(
105 ASCIIToUTF16(".."), std::string(), false, 0, base::Time())); 107 ASCIIToUTF16(".."), std::string(), false, 0, base::Time()));
106 } 108 }
107 } 109 }
108 110
109 bool FtpDirectoryListingResponseDelegate::ConvertToServerEncoding(
110 const string16& filename, std::string* raw_bytes) const {
111 if (buffer_.encoding().empty()) {
112 *raw_bytes = std::string();
113 return true;
114 }
115
116 return base::UTF16ToCodepage(filename, buffer_.encoding().c_str(),
117 base::OnStringConversionError::FAIL,
118 raw_bytes);
119 }
120
121 void FtpDirectoryListingResponseDelegate::ProcessReceivedEntries() {
122 if (!updated_histograms_ && buffer_.EntryAvailable()) {
123 // Only log the server type if we got enough data to reliably detect it.
124 net::UpdateFtpServerTypeHistograms(buffer_.GetServerType());
125 updated_histograms_ = true;
126 }
127
128 while (buffer_.EntryAvailable()) {
129 FtpDirectoryListingEntry entry = buffer_.PopEntry();
130
131 // Skip the current and parent directory entries in the listing. Our header
132 // always includes them.
133 if (EqualsASCII(entry.name, ".") || EqualsASCII(entry.name, ".."))
134 continue;
135
136 bool is_directory = (entry.type == FtpDirectoryListingEntry::DIRECTORY);
137 int64 size = entry.size;
138 if (entry.type != FtpDirectoryListingEntry::FILE)
139 size = 0;
140 std::string raw_bytes;
141 if (ConvertToServerEncoding(entry.name, &raw_bytes)) {
142 SendDataToClient(net::GetDirectoryListingEntry(
143 entry.name, raw_bytes, is_directory, size, entry.last_modified));
144 } else {
145 // Consider an encoding problem a non-fatal error. The server's support
146 // for non-ASCII characters might be buggy. Display an error message,
147 // but keep trying to display the rest of the listing (most file names
148 // are ASCII anyway, we could be just unlucky with this one).
149 had_parsing_error_ = true;
150 }
151 }
152 }
153
154 void FtpDirectoryListingResponseDelegate::SendDataToClient( 111 void FtpDirectoryListingResponseDelegate::SendDataToClient(
155 const std::string& data) { 112 const std::string& data) {
156 client_->didReceiveData(loader_, data.data(), data.length()); 113 client_->didReceiveData(loader_, data.data(), data.length());
157 } 114 }
158 115
159 } // namespace webkit_glue 116 } // namespace webkit_glue
OLDNEW
« no previous file with comments | « webkit/glue/ftp_directory_listing_response_delegate.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698