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

Side by Side Diff: net/base/net_util.cc

Issue 9317018: referrer_charset is a lie. It's really the user's default_charset. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 10 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/base/net_util.h ('k') | net/base/net_util_unittest.cc » ('j') | 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/base/net_util.h" 5 #include "net/base/net_util.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <iterator> 8 #include <iterator>
9 #include <map> 9 #include <map>
10 10
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 output_length = ucnv_toAlgorithmic(UCNV_UTF8, converter, buf, output_length, 232 output_length = ucnv_toAlgorithmic(UCNV_UTF8, converter, buf, output_length,
233 decoded.data(), decoded.length(), &err); 233 decoded.data(), decoded.length(), &err);
234 ucnv_close(converter); 234 ucnv_close(converter);
235 if (U_FAILURE(err)) 235 if (U_FAILURE(err))
236 return false; 236 return false;
237 output->resize(output_length); 237 output->resize(output_length);
238 return true; 238 return true;
239 } 239 }
240 240
241 bool DecodeWord(const std::string& encoded_word, 241 bool DecodeWord(const std::string& encoded_word,
242 const std::string& referrer_charset, 242 const std::string& default_charset,
243 bool* is_rfc2047, 243 bool* is_rfc2047,
244 std::string* output) { 244 std::string* output) {
245 *is_rfc2047 = false; 245 *is_rfc2047 = false;
246 output->clear(); 246 output->clear();
247 if (encoded_word.empty()) 247 if (encoded_word.empty())
248 return true; 248 return true;
249 249
250 if (!IsStringASCII(encoded_word)) { 250 if (!IsStringASCII(encoded_word)) {
251 // Try UTF-8, referrer_charset and the native OS default charset in turn. 251 // Try UTF-8, default_charset and the native OS default charset in turn.
252 if (IsStringUTF8(encoded_word)) { 252 if (IsStringUTF8(encoded_word)) {
253 *output = encoded_word; 253 *output = encoded_word;
254 } else { 254 } else {
255 string16 utf16_output; 255 string16 utf16_output;
256 if (!referrer_charset.empty() && 256 if (!default_charset.empty() &&
257 base::CodepageToUTF16(encoded_word, referrer_charset.c_str(), 257 base::CodepageToUTF16(encoded_word, default_charset.c_str(),
258 base::OnStringConversionError::FAIL, 258 base::OnStringConversionError::FAIL,
259 &utf16_output)) { 259 &utf16_output)) {
260 *output = UTF16ToUTF8(utf16_output); 260 *output = UTF16ToUTF8(utf16_output);
261 } else { 261 } else {
262 *output = WideToUTF8(base::SysNativeMBToWide(encoded_word)); 262 *output = WideToUTF8(base::SysNativeMBToWide(encoded_word));
263 } 263 }
264 } 264 }
265 265
266 return true; 266 return true;
267 } 267 }
(...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after
919 ReplaceSubstringsAfterOffset(&filename, 0, "\\", "_"); 919 ReplaceSubstringsAfterOffset(&filename, 0, "\\", "_");
920 } 920 }
921 } 921 }
922 922
923 // Returns the filename determined from the last component of the path portion 923 // Returns the filename determined from the last component of the path portion
924 // of the URL. Returns an empty string if the URL doesn't have a path or is 924 // of the URL. Returns an empty string if the URL doesn't have a path or is
925 // invalid. If the generated filename is not reliable, 925 // invalid. If the generated filename is not reliable,
926 // |should_overwrite_extension| will be set to true, in which case a better 926 // |should_overwrite_extension| will be set to true, in which case a better
927 // extension should be determined based on the content type. 927 // extension should be determined based on the content type.
928 std::string GetFileNameFromURL(const GURL& url, 928 std::string GetFileNameFromURL(const GURL& url,
929 const std::string& referrer_charset, 929 const std::string& default_charset,
930 bool* should_overwrite_extension) { 930 bool* should_overwrite_extension) {
931 // about: and data: URLs don't have file names, but esp. data: URLs may 931 // about: and data: URLs don't have file names, but esp. data: URLs may
932 // contain parts that look like ones (i.e., contain a slash). Therefore we 932 // contain parts that look like ones (i.e., contain a slash). Therefore we
933 // don't attempt to divine a file name out of them. 933 // don't attempt to divine a file name out of them.
934 if (!url.is_valid() || url.SchemeIs("about") || url.SchemeIs("data")) 934 if (!url.is_valid() || url.SchemeIs("about") || url.SchemeIs("data"))
935 return std::string(); 935 return std::string();
936 936
937 const std::string unescaped_url_filename = UnescapeURLComponent( 937 const std::string unescaped_url_filename = UnescapeURLComponent(
938 url.ExtractFileName(), 938 url.ExtractFileName(),
939 UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS); 939 UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS);
940 940
941 // The URL's path should be escaped UTF-8, but may not be. 941 // The URL's path should be escaped UTF-8, but may not be.
942 std::string decoded_filename = unescaped_url_filename; 942 std::string decoded_filename = unescaped_url_filename;
943 if (!IsStringASCII(decoded_filename)) { 943 if (!IsStringASCII(decoded_filename)) {
944 bool ignore; 944 bool ignore;
945 // TODO(jshin): this is probably not robust enough. To be sure, we need 945 // TODO(jshin): this is probably not robust enough. To be sure, we need
946 // encoding detection. 946 // encoding detection.
947 DecodeWord(unescaped_url_filename, referrer_charset, &ignore, 947 DecodeWord(unescaped_url_filename, default_charset, &ignore,
948 &decoded_filename); 948 &decoded_filename);
949 } 949 }
950 // If the URL contains a (possibly empty) query, assume it is a generator, and 950 // If the URL contains a (possibly empty) query, assume it is a generator, and
951 // allow the determined extension to be overwritten. 951 // allow the determined extension to be overwritten.
952 *should_overwrite_extension = !decoded_filename.empty() && url.has_query(); 952 *should_overwrite_extension = !decoded_filename.empty() && url.has_query();
953 953
954 return decoded_filename; 954 return decoded_filename;
955 } 955 }
956 956
957 #if defined(OS_WIN) 957 #if defined(OS_WIN)
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
1180 if (numDelimsSeen != 2) 1180 if (numDelimsSeen != 2)
1181 return false; 1181 return false;
1182 if (temp_charset.empty() || temp_value.empty()) 1182 if (temp_charset.empty() || temp_value.empty())
1183 return false; 1183 return false;
1184 decoded_charset->swap(temp_charset); 1184 decoded_charset->swap(temp_charset);
1185 value->swap(temp_value); 1185 value->swap(temp_value);
1186 return true; 1186 return true;
1187 } 1187 }
1188 1188
1189 bool DecodeFilenameValue(const std::string& input, 1189 bool DecodeFilenameValue(const std::string& input,
1190 const std::string& referrer_charset, 1190 const std::string& default_charset,
1191 std::string* output) { 1191 std::string* output) {
1192 std::string tmp; 1192 std::string tmp;
1193 // Tokenize with whitespace characters. 1193 // Tokenize with whitespace characters.
1194 StringTokenizer t(input, " \t\n\r"); 1194 StringTokenizer t(input, " \t\n\r");
1195 t.set_options(StringTokenizer::RETURN_DELIMS); 1195 t.set_options(StringTokenizer::RETURN_DELIMS);
1196 bool is_previous_token_rfc2047 = true; 1196 bool is_previous_token_rfc2047 = true;
1197 while (t.GetNext()) { 1197 while (t.GetNext()) {
1198 if (t.token_is_delim()) { 1198 if (t.token_is_delim()) {
1199 // If the previous non-delimeter token is not RFC2047-encoded, 1199 // If the previous non-delimeter token is not RFC2047-encoded,
1200 // put in a space in its place. Otheriwse, skip over it. 1200 // put in a space in its place. Otheriwse, skip over it.
1201 if (!is_previous_token_rfc2047) { 1201 if (!is_previous_token_rfc2047) {
1202 tmp.push_back(' '); 1202 tmp.push_back(' ');
1203 } 1203 }
1204 continue; 1204 continue;
1205 } 1205 }
1206 // We don't support a single multibyte character split into 1206 // We don't support a single multibyte character split into
1207 // adjacent encoded words. Some broken mail clients emit headers 1207 // adjacent encoded words. Some broken mail clients emit headers
1208 // with that problem, but most web servers usually encode a filename 1208 // with that problem, but most web servers usually encode a filename
1209 // in a single encoded-word. Firefox/Thunderbird do not support 1209 // in a single encoded-word. Firefox/Thunderbird do not support
1210 // it, either. 1210 // it, either.
1211 std::string decoded; 1211 std::string decoded;
1212 if (!DecodeWord(t.token(), referrer_charset, &is_previous_token_rfc2047, 1212 if (!DecodeWord(t.token(), default_charset, &is_previous_token_rfc2047,
1213 &decoded)) 1213 &decoded))
1214 return false; 1214 return false;
1215 tmp.append(decoded); 1215 tmp.append(decoded);
1216 } 1216 }
1217 output->swap(tmp); 1217 output->swap(tmp);
1218 return true; 1218 return true;
1219 } 1219 }
1220 1220
1221 bool DecodeExtValue(const std::string& param_value, std::string* decoded) { 1221 bool DecodeExtValue(const std::string& param_value, std::string* decoded) {
1222 if (param_value.find('"') != std::string::npos) 1222 if (param_value.find('"') != std::string::npos)
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
1394 *file_path = FilePath(leaf_name); 1394 *file_path = FilePath(leaf_name);
1395 } else { 1395 } else {
1396 *file_path = file_path->Append(leaf_name); 1396 *file_path = file_path->Append(leaf_name);
1397 } 1397 }
1398 } 1398 }
1399 #endif 1399 #endif
1400 } 1400 }
1401 1401
1402 string16 GetSuggestedFilename(const GURL& url, 1402 string16 GetSuggestedFilename(const GURL& url,
1403 const std::string& content_disposition, 1403 const std::string& content_disposition,
1404 const std::string& referrer_charset, 1404 const std::string& default_charset,
1405 const std::string& suggested_name, 1405 const std::string& suggested_name,
1406 const std::string& mime_type, 1406 const std::string& mime_type,
1407 const std::string& default_name) { 1407 const std::string& default_name) {
1408 // TODO: this function to be updated to match the httpbis recommendations. 1408 // TODO: this function to be updated to match the httpbis recommendations.
1409 // Talk to abarth for the latest news. 1409 // Talk to abarth for the latest news.
1410 1410
1411 // We don't translate this fallback string, "download". If localization is 1411 // We don't translate this fallback string, "download". If localization is
1412 // needed, the caller should provide localized fallback in |default_name|. 1412 // needed, the caller should provide localized fallback in |default_name|.
1413 static const char* kFinalFallbackName = "download"; 1413 static const char* kFinalFallbackName = "download";
1414 std::string filename; // In UTF-8 1414 std::string filename; // In UTF-8
1415 bool overwrite_extension = false; 1415 bool overwrite_extension = false;
1416 1416
1417 // Try to extract a filename from content-disposition first. 1417 // Try to extract a filename from content-disposition first.
1418 if (!content_disposition.empty()) { 1418 if (!content_disposition.empty()) {
1419 HttpContentDisposition header(content_disposition, referrer_charset); 1419 HttpContentDisposition header(content_disposition, default_charset);
1420 filename = header.filename(); 1420 filename = header.filename();
1421 } 1421 }
1422 1422
1423 // Then try to use the suggested name. 1423 // Then try to use the suggested name.
1424 if (filename.empty() && !suggested_name.empty()) 1424 if (filename.empty() && !suggested_name.empty())
1425 filename = suggested_name; 1425 filename = suggested_name;
1426 1426
1427 // Now try extracting the filename from the URL. GetFileNameFromURL() only 1427 // Now try extracting the filename from the URL. GetFileNameFromURL() only
1428 // looks at the last component of the URL and doesn't return the hostname as a 1428 // looks at the last component of the URL and doesn't return the hostname as a
1429 // failover. 1429 // failover.
1430 if (filename.empty()) 1430 if (filename.empty())
1431 filename = GetFileNameFromURL(url, referrer_charset, &overwrite_extension); 1431 filename = GetFileNameFromURL(url, default_charset, &overwrite_extension);
1432 1432
1433 // Finally try the URL hostname, but only if there's no default specified in 1433 // Finally try the URL hostname, but only if there's no default specified in
1434 // |default_name|. Some schemes (e.g.: file:, about:, data:) do not have a 1434 // |default_name|. Some schemes (e.g.: file:, about:, data:) do not have a
1435 // host name. 1435 // host name.
1436 if (filename.empty() && default_name.empty() && 1436 if (filename.empty() && default_name.empty() &&
1437 url.is_valid() && !url.host().empty()) { 1437 url.is_valid() && !url.host().empty()) {
1438 // TODO(jungshik) : Decode a 'punycoded' IDN hostname. (bug 1264451) 1438 // TODO(jungshik) : Decode a 'punycoded' IDN hostname. (bug 1264451)
1439 filename = url.host(); 1439 filename = url.host();
1440 } 1440 }
1441 1441
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1473 std::string path = filename.empty() ? default_name : filename; 1473 std::string path = filename.empty() ? default_name : filename;
1474 file_util::ReplaceIllegalCharactersInPath(&path, '-'); 1474 file_util::ReplaceIllegalCharactersInPath(&path, '-');
1475 FilePath result(path); 1475 FilePath result(path);
1476 GenerateSafeFileName(mime_type, overwrite_extension, &result); 1476 GenerateSafeFileName(mime_type, overwrite_extension, &result);
1477 return UTF8ToUTF16(result.value()); 1477 return UTF8ToUTF16(result.value());
1478 #endif 1478 #endif
1479 } 1479 }
1480 1480
1481 FilePath GenerateFileName(const GURL& url, 1481 FilePath GenerateFileName(const GURL& url,
1482 const std::string& content_disposition, 1482 const std::string& content_disposition,
1483 const std::string& referrer_charset, 1483 const std::string& default_charset,
1484 const std::string& suggested_name, 1484 const std::string& suggested_name,
1485 const std::string& mime_type, 1485 const std::string& mime_type,
1486 const std::string& default_file_name) { 1486 const std::string& default_file_name) {
1487 string16 file_name = GetSuggestedFilename(url, 1487 string16 file_name = GetSuggestedFilename(url,
1488 content_disposition, 1488 content_disposition,
1489 referrer_charset, 1489 default_charset,
1490 suggested_name, 1490 suggested_name,
1491 mime_type, 1491 mime_type,
1492 default_file_name); 1492 default_file_name);
1493 1493
1494 #if defined(OS_WIN) 1494 #if defined(OS_WIN)
1495 FilePath generated_name(file_name); 1495 FilePath generated_name(file_name);
1496 #else 1496 #else
1497 FilePath generated_name(base::SysWideToNativeMB(UTF16ToWide(file_name))); 1497 FilePath generated_name(base::SysWideToNativeMB(UTF16ToWide(file_name)));
1498 #endif 1498 #endif
1499 DCHECK(!generated_name.empty()); 1499 DCHECK(!generated_name.empty());
(...skipping 903 matching lines...) Expand 10 before | Expand all | Expand 10 after
2403 2403
2404 NetworkInterface::NetworkInterface(const std::string& name, 2404 NetworkInterface::NetworkInterface(const std::string& name,
2405 const IPAddressNumber& address) 2405 const IPAddressNumber& address)
2406 : name(name), address(address) { 2406 : name(name), address(address) {
2407 } 2407 }
2408 2408
2409 NetworkInterface::~NetworkInterface() { 2409 NetworkInterface::~NetworkInterface() {
2410 } 2410 }
2411 2411
2412 } // namespace net 2412 } // namespace net
OLDNEW
« no previous file with comments | « net/base/net_util.h ('k') | net/base/net_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698