Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 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 "net/base/net_util.h" | 5 #include "net/base/net_util.h" |
| 6 | 6 |
| 7 #include <unicode/regex.h> | 7 #include <unicode/regex.h> |
| 8 #include <unicode/ucnv.h> | 8 #include <unicode/ucnv.h> |
| 9 #include <unicode/uidna.h> | 9 #include <unicode/uidna.h> |
| 10 #include <unicode/ulocdata.h> | 10 #include <unicode/ulocdata.h> |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 57 #include "base/time.h" | 57 #include "base/time.h" |
| 58 #include "base/utf_offset_string_conversions.h" | 58 #include "base/utf_offset_string_conversions.h" |
| 59 #include "base/utf_string_conversions.h" | 59 #include "base/utf_string_conversions.h" |
| 60 #include "googleurl/src/gurl.h" | 60 #include "googleurl/src/gurl.h" |
| 61 #include "googleurl/src/url_canon.h" | 61 #include "googleurl/src/url_canon.h" |
| 62 #include "googleurl/src/url_canon_ip.h" | 62 #include "googleurl/src/url_canon_ip.h" |
| 63 #include "googleurl/src/url_parse.h" | 63 #include "googleurl/src/url_parse.h" |
| 64 #include "grit/net_resources.h" | 64 #include "grit/net_resources.h" |
| 65 #include "net/base/dns_util.h" | 65 #include "net/base/dns_util.h" |
| 66 #include "net/base/escape.h" | 66 #include "net/base/escape.h" |
| 67 #include "net/base/mime_util.h" | |
| 67 #include "net/base/net_module.h" | 68 #include "net/base/net_module.h" |
| 68 #if defined(OS_WIN) | 69 #if defined(OS_WIN) |
| 69 #include "net/base/winsock_init.h" | 70 #include "net/base/winsock_init.h" |
| 70 #endif | 71 #endif |
| 71 #include "unicode/datefmt.h" | 72 #include "unicode/datefmt.h" |
| 72 | 73 |
| 73 using base::Time; | 74 using base::Time; |
| 74 | 75 |
| 75 namespace net { | 76 namespace net { |
| 76 | 77 |
| (...skipping 837 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 914 } | 915 } |
| 915 | 916 |
| 916 char* do_strdup(const char* src) { | 917 char* do_strdup(const char* src) { |
| 917 #if defined(OS_WIN) | 918 #if defined(OS_WIN) |
| 918 return _strdup(src); | 919 return _strdup(src); |
| 919 #else | 920 #else |
| 920 return strdup(src); | 921 return strdup(src); |
| 921 #endif | 922 #endif |
| 922 } | 923 } |
| 923 | 924 |
| 925 void TrimGeneratedFileName(std::string& filename) { | |
| 926 if (!filename.empty()) { | |
| 927 // Remove "." from the beginning and end of the file name to avoid tricks | |
| 928 // with hidden files, "..", and "." | |
| 929 TrimString(filename, ".", &filename); | |
| 930 #if defined(OS_WIN) | |
| 931 // Handle CreateFile() stripping trailing dots and spaces on filenames | |
| 932 // http://support.microsoft.com/kb/115827 | |
| 933 std::string::size_type pos = filename.find_last_not_of(" ."); | |
| 934 if (pos == std::string::npos) | |
| 935 filename.resize(0); | |
| 936 else | |
| 937 filename.resize(++pos); | |
| 938 #endif | |
| 939 } | |
| 940 } | |
| 941 | |
| 942 std::string GetFileNameFromURL(const GURL& url, | |
| 943 const std::string& referrer_charset) { | |
| 944 // about: and data: URLs don't have file names, but esp. data: URLs may | |
| 945 // contain parts that look like ones (i.e., contain a slash). Therefore we | |
| 946 // don't attempt to divine a file name out of them. | |
| 947 if (!url.is_valid() || url.SchemeIs("about") || url.SchemeIs("data")) | |
| 948 return ""; | |
|
rvargas (doing something else)
2011/07/26 00:10:57
nit: return std::string();
asanka
2011/07/28 20:04:38
Done.
| |
| 949 | |
| 950 const std::string unescaped_url_filename = UnescapeURLComponent( | |
| 951 url.ExtractFileName(), | |
| 952 UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS); | |
| 953 | |
| 954 // The URL's path should be escaped UTF-8, but may not be. | |
| 955 std::string decoded_filename = unescaped_url_filename; | |
| 956 if (!IsStringASCII(decoded_filename)) { | |
| 957 bool ignore; | |
| 958 // TODO(jshin): this is probably not robust enough. To be sure, we need | |
| 959 // encoding detection. | |
| 960 DecodeWord(unescaped_url_filename, referrer_charset, &ignore, | |
| 961 &decoded_filename); | |
| 962 } | |
| 963 | |
| 964 return decoded_filename; | |
| 965 } | |
| 966 | |
| 967 #if defined(OS_WIN) | |
| 968 // Returns whether the specified extension is automatically integrated into the | |
| 969 // windows shell. | |
| 970 bool IsShellIntegratedExtension(const string16& extension) { | |
| 971 string16 extension_lower = StringToLowerASCII(extension); | |
| 972 | |
| 973 static const wchar_t* const integrated_extensions[] = { | |
| 974 // See <http://msdn.microsoft.com/en-us/library/ms811694.aspx>. | |
| 975 L"local", | |
| 976 // Right-clicking on shortcuts can be magical. | |
| 977 L"lnk", | |
| 978 }; | |
| 979 | |
| 980 for (int i = 0; i < arraysize(integrated_extensions); ++i) { | |
| 981 if (extension_lower == integrated_extensions[i]) | |
| 982 return true; | |
| 983 } | |
| 984 | |
| 985 // See <http://www.juniper.net/security/auto/vulnerabilities/vuln2612.html>. | |
| 986 // That vulnerability report is not exactly on point, but files become magical | |
| 987 // if their end in a CLSID. Here we block extensions that look like CLSIDs. | |
| 988 if (!extension_lower.empty() && extension_lower[0] == L'{' && | |
| 989 extension_lower[extension_lower.length() - 1] == L'}') | |
| 990 return true; | |
| 991 | |
| 992 return false; | |
| 993 } | |
| 994 | |
| 995 // Returns whether the specified file name is a reserved name on windows. | |
| 996 // This includes names like "com2.zip" (which correspond to devices) and | |
| 997 // desktop.ini and thumbs.db which have special meaning to the windows shell. | |
| 998 bool IsReservedName(const string16& filename) { | |
| 999 // This list is taken from the MSDN article "Naming a file" | |
| 1000 // http://msdn2.microsoft.com/en-us/library/aa365247(VS.85).aspx | |
| 1001 // I also added clock$ because GetSaveFileName seems to consider it as a | |
| 1002 // reserved name too. | |
| 1003 static const wchar_t* const known_devices[] = { | |
| 1004 L"con", L"prn", L"aux", L"nul", L"com1", L"com2", L"com3", L"com4", L"com5", | |
| 1005 L"com6", L"com7", L"com8", L"com9", L"lpt1", L"lpt2", L"lpt3", L"lpt4", | |
| 1006 L"lpt5", L"lpt6", L"lpt7", L"lpt8", L"lpt9", L"clock$" | |
| 1007 }; | |
| 1008 string16 filename_lower = StringToLowerASCII(filename); | |
| 1009 | |
| 1010 for (int i = 0; i < arraysize(known_devices); ++i) { | |
| 1011 // Exact match. | |
| 1012 if (filename_lower == known_devices[i]) | |
| 1013 return true; | |
| 1014 // Starts with "DEVICE.". | |
| 1015 if (filename_lower.find(string16(known_devices[i]) + L".") == 0) | |
| 1016 return true; | |
| 1017 } | |
| 1018 | |
| 1019 static const wchar_t* const magic_names[] = { | |
| 1020 // These file names are used by the "Customize folder" feature of the shell. | |
| 1021 L"desktop.ini", | |
| 1022 L"thumbs.db", | |
| 1023 }; | |
| 1024 | |
| 1025 for (int i = 0; i < arraysize(magic_names); ++i) { | |
| 1026 if (filename_lower == magic_names[i]) | |
| 1027 return true; | |
| 1028 } | |
| 1029 | |
| 1030 return false; | |
| 1031 } | |
| 1032 #endif // OS_WIN | |
| 1033 | |
| 1034 void GenerateSafeExtension(const std::string& mime_type, FilePath* file_name) { | |
| 1035 // We're worried about two things here: | |
| 1036 // | |
| 1037 // 1) Usability. If the site fails to provide a file extension, we want to | |
| 1038 // guess a reasonable file extension based on the content type. | |
| 1039 // | |
| 1040 // 2) Shell integration. Some file extensions automatically integrate with | |
| 1041 // the shell. We block these extensions to prevent a malicious web site | |
| 1042 // from integrating with the user's shell. | |
| 1043 | |
| 1044 // See if our file name already contains an extension. | |
| 1045 FilePath::StringType extension = file_name->Extension(); | |
| 1046 if (!extension.empty()) | |
| 1047 extension.erase(extension.begin()); // Erase preceding '.'. | |
| 1048 | |
| 1049 #if defined(OS_WIN) | |
| 1050 static const FilePath::CharType default_extension[] = | |
| 1051 FILE_PATH_LITERAL("download"); | |
| 1052 | |
| 1053 // Rename shell-integrated extensions. | |
| 1054 // TODO(asanka): Consider stripping out the bad extension and replacing it | |
| 1055 // with the preferred extension for the MIME type if one is available. | |
| 1056 if (IsShellIntegratedExtension(extension)) | |
| 1057 extension.assign(default_extension); | |
| 1058 #endif | |
| 1059 | |
| 1060 if (extension.empty() && !mime_type.empty()) { | |
| 1061 // The GetPreferredExtensionForMimeType call will end up going to disk. Do | |
| 1062 // this on another thread to avoid slowing the IO thread. | |
| 1063 // http://crbug.com/61827 | |
| 1064 // TODO(asanka): Remove this ScopedAllowIO once all callers have switched | |
| 1065 // over to IO safe threads. | |
| 1066 base::ThreadRestrictions::ScopedAllowIO allow_io; | |
| 1067 net::GetPreferredExtensionForMimeType(mime_type, &extension); | |
| 1068 } | |
| 1069 | |
| 1070 *file_name = file_name->ReplaceExtension(extension); | |
| 1071 } | |
| 1072 | |
| 924 } // namespace | 1073 } // namespace |
| 925 | 1074 |
| 926 const FormatUrlType kFormatUrlOmitNothing = 0; | 1075 const FormatUrlType kFormatUrlOmitNothing = 0; |
| 927 const FormatUrlType kFormatUrlOmitUsernamePassword = 1 << 0; | 1076 const FormatUrlType kFormatUrlOmitUsernamePassword = 1 << 0; |
| 928 const FormatUrlType kFormatUrlOmitHTTP = 1 << 1; | 1077 const FormatUrlType kFormatUrlOmitHTTP = 1 << 1; |
| 929 const FormatUrlType kFormatUrlOmitTrailingSlashOnBareHostname = 1 << 2; | 1078 const FormatUrlType kFormatUrlOmitTrailingSlashOnBareHostname = 1 << 2; |
| 930 const FormatUrlType kFormatUrlOmitAll = kFormatUrlOmitUsernamePassword | | 1079 const FormatUrlType kFormatUrlOmitAll = kFormatUrlOmitUsernamePassword | |
| 931 kFormatUrlOmitHTTP | kFormatUrlOmitTrailingSlashOnBareHostname; | 1080 kFormatUrlOmitHTTP | kFormatUrlOmitTrailingSlashOnBareHostname; |
| 932 | 1081 |
| 933 // TODO(viettrungluu): We don't want non-POD globals; change this. | 1082 // TODO(viettrungluu): We don't want non-POD globals; change this. |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 961 | 1110 |
| 962 #if defined(OS_POSIX) | 1111 #if defined(OS_POSIX) |
| 963 ReplaceSubstringsAfterOffset(&url_string, 0, | 1112 ReplaceSubstringsAfterOffset(&url_string, 0, |
| 964 FILE_PATH_LITERAL("\\"), FILE_PATH_LITERAL("%5C")); | 1113 FILE_PATH_LITERAL("\\"), FILE_PATH_LITERAL("%5C")); |
| 965 #endif | 1114 #endif |
| 966 | 1115 |
| 967 return GURL(url_string); | 1116 return GURL(url_string); |
| 968 } | 1117 } |
| 969 | 1118 |
| 970 std::string GetSpecificHeader(const std::string& headers, | 1119 std::string GetSpecificHeader(const std::string& headers, |
| 971 const std::string& name) { | 1120 const std::string& name) { |
| 972 // We want to grab the Value from the "Key: Value" pairs in the headers, | 1121 // We want to grab the Value from the "Key: Value" pairs in the headers, |
| 973 // which should look like this (no leading spaces, \n-separated) (we format | 1122 // which should look like this (no leading spaces, \n-separated) (we format |
| 974 // them this way in url_request_inet.cc): | 1123 // them this way in url_request_inet.cc): |
| 975 // HTTP/1.1 200 OK\n | 1124 // HTTP/1.1 200 OK\n |
| 976 // ETag: "6d0b8-947-24f35ec0"\n | 1125 // ETag: "6d0b8-947-24f35ec0"\n |
| 977 // Content-Length: 2375\n | 1126 // Content-Length: 2375\n |
| 978 // Content-Type: text/html; charset=UTF-8\n | 1127 // Content-Type: text/html; charset=UTF-8\n |
| 979 // Last-Modified: Sun, 03 Sep 2006 04:34:43 GMT\n | 1128 // Last-Modified: Sun, 03 Sep 2006 04:34:43 GMT\n |
| 980 if (headers.empty()) | 1129 if (headers.empty()) |
| 981 return std::string(); | 1130 return std::string(); |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1241 result.append(");</script>\n"); | 1390 result.append(");</script>\n"); |
| 1242 | 1391 |
| 1243 return result; | 1392 return result; |
| 1244 } | 1393 } |
| 1245 | 1394 |
| 1246 string16 StripWWW(const string16& text) { | 1395 string16 StripWWW(const string16& text) { |
| 1247 const string16 www(ASCIIToUTF16("www.")); | 1396 const string16 www(ASCIIToUTF16("www.")); |
| 1248 return StartsWith(text, www, true) ? text.substr(www.length()) : text; | 1397 return StartsWith(text, www, true) ? text.substr(www.length()) : text; |
| 1249 } | 1398 } |
| 1250 | 1399 |
| 1400 void GenerateSafeFileName(const std::string& mime_type, FilePath* file_path) { | |
| 1401 // Make sure we get the right file extension | |
| 1402 GenerateSafeExtension(mime_type, file_path); | |
| 1403 | |
| 1404 #if defined(OS_WIN) | |
| 1405 // Prepend "_" to the file name if it's a reserved name | |
| 1406 FilePath::StringType leaf_name = file_path->BaseName().value(); | |
| 1407 DCHECK(!leaf_name.empty()); | |
| 1408 if (IsReservedName(leaf_name)) { | |
| 1409 leaf_name = FilePath::StringType(FILE_PATH_LITERAL("_")) + leaf_name; | |
| 1410 *file_path = file_path->DirName(); | |
| 1411 if (file_path->value() == FilePath::kCurrentDirectory) { | |
| 1412 *file_path = FilePath(leaf_name); | |
| 1413 } else { | |
| 1414 *file_path = file_path->Append(leaf_name); | |
| 1415 } | |
| 1416 } | |
| 1417 #endif | |
| 1418 } | |
| 1419 | |
| 1251 string16 GetSuggestedFilename(const GURL& url, | 1420 string16 GetSuggestedFilename(const GURL& url, |
| 1252 const std::string& content_disposition, | 1421 const std::string& content_disposition, |
| 1253 const std::string& referrer_charset, | 1422 const std::string& referrer_charset, |
| 1254 const std::string& suggested_name, | 1423 const std::string& suggested_name, |
| 1424 const std::string& mime_type, | |
| 1255 const string16& default_name) { | 1425 const string16& default_name) { |
| 1256 // TODO: this function to be updated to match the httpbis recommendations. | 1426 // TODO: this function to be updated to match the httpbis recommendations. |
| 1257 // Talk to abarth for the latest news. | 1427 // Talk to abarth for the latest news. |
| 1258 | 1428 |
| 1259 // We don't translate this fallback string, "download". If localization is | 1429 // We don't translate this fallback string, "download". If localization is |
| 1260 // needed, the caller should provide localized fallback default_name. | 1430 // needed, the caller should provide localized fallback in |default_name|. |
| 1261 static const char* kFinalFallbackName = "download"; | 1431 static const char* kFinalFallbackName = "download"; |
| 1432 std::string filename; // In UTF-8 | |
| 1262 | 1433 |
| 1263 std::string filename; | 1434 // Try to extract a filename from content-disposition first. |
| 1264 | 1435 if (!content_disposition.empty()) { |
| 1265 // Try to extract from content-disposition first. | |
| 1266 if (!content_disposition.empty()) | |
| 1267 filename = GetFileNameFromCD(content_disposition, referrer_charset); | 1436 filename = GetFileNameFromCD(content_disposition, referrer_charset); |
| 1268 | 1437 TrimGeneratedFileName(filename); |
| 1269 // Then try to use suggested name. | |
| 1270 if (filename.empty() && !suggested_name.empty()) | |
| 1271 filename = suggested_name; | |
| 1272 | |
| 1273 if (!filename.empty()) { | |
| 1274 // Replace any path information the server may have sent, by changing | |
| 1275 // path separators with underscores. | |
| 1276 ReplaceSubstringsAfterOffset(&filename, 0, "/", "_"); | |
| 1277 ReplaceSubstringsAfterOffset(&filename, 0, "\\", "_"); | |
| 1278 | |
| 1279 // Next, remove "." from the beginning and end of the file name to avoid | |
| 1280 // tricks with hidden files, "..", and "." | |
| 1281 TrimString(filename, ".", &filename); | |
| 1282 } | 1438 } |
| 1283 | 1439 |
| 1284 if (filename.empty()) { | 1440 // Then try to use the suggested name. |
| 1285 // about: and data: URLs don't have file names, but esp. data: URLs may | 1441 if (filename.empty() && !suggested_name.empty()) { |
| 1286 // contain parts that look like ones (i.e., contain a slash). | 1442 filename = suggested_name; |
| 1287 // Therefore we don't attempt to divine a file name out of them. | 1443 TrimGeneratedFileName(filename); |
| 1288 if (url.SchemeIs("about") || url.SchemeIs("data")) { | |
| 1289 return default_name.empty() ? ASCIIToUTF16(kFinalFallbackName) | |
| 1290 : default_name; | |
| 1291 } | |
| 1292 | |
| 1293 if (url.is_valid()) { | |
| 1294 const std::string unescaped_url_filename = UnescapeURLComponent( | |
| 1295 url.ExtractFileName(), | |
| 1296 UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS); | |
| 1297 | |
| 1298 // The URL's path should be escaped UTF-8, but may not be. | |
| 1299 std::string decoded_filename = unescaped_url_filename; | |
| 1300 if (!IsStringASCII(decoded_filename)) { | |
| 1301 bool ignore; | |
| 1302 // TODO(jshin): this is probably not robust enough. To be sure, we | |
| 1303 // need encoding detection. | |
| 1304 DecodeWord(unescaped_url_filename, referrer_charset, &ignore, | |
| 1305 &decoded_filename); | |
| 1306 } | |
| 1307 | |
| 1308 filename = decoded_filename; | |
| 1309 } | |
| 1310 } | 1444 } |
| 1311 | 1445 |
| 1312 #if defined(OS_WIN) | 1446 // Now try extracting the filename from the URL. This only looks at the last |
| 1313 { // Handle CreateFile() stripping trailing dots and spaces on filenames | 1447 // component of the URL and doesn't failover to returning the hostname. |
|
rvargas (doing something else)
2011/07/26 00:10:57
nit: failover as a verb
asanka
2011/07/28 20:04:38
Done.
| |
| 1314 // http://support.microsoft.com/kb/115827 | |
| 1315 std::string::size_type pos = filename.find_last_not_of(" ."); | |
| 1316 if (pos == std::string::npos) | |
| 1317 filename.resize(0); | |
| 1318 else | |
| 1319 filename.resize(++pos); | |
| 1320 } | |
| 1321 #endif | |
| 1322 // Trim '.' once more. | |
| 1323 TrimString(filename, ".", &filename); | |
| 1324 | |
| 1325 // If there's no filename or it gets trimed to be empty, use | |
| 1326 // the URL hostname or default_name | |
| 1327 if (filename.empty()) { | 1448 if (filename.empty()) { |
| 1328 if (!default_name.empty()) { | 1449 filename = GetFileNameFromURL(url, referrer_charset); |
| 1329 return default_name; | 1450 TrimGeneratedFileName(filename); |
| 1330 } else if (url.is_valid()) { | |
| 1331 // Some schemes (e.g. file) do not have a hostname. Even though it's | |
| 1332 // not likely to reach here, let's hardcode the last fallback name. | |
| 1333 // TODO(jungshik) : Decode a 'punycoded' IDN hostname. (bug 1264451) | |
| 1334 filename = url.host().empty() ? kFinalFallbackName : url.host(); | |
| 1335 } else { | |
| 1336 NOTREACHED(); | |
| 1337 } | |
| 1338 } | 1451 } |
| 1339 | 1452 |
| 1453 // Finally try the URL hostname, but only if there's no default specified in | |
| 1454 // |generated_path| | |
| 1455 if (filename.empty() && default_name.empty() && | |
|
rvargas (doing something else)
2011/07/26 00:10:57
The previous logic didn't reach this point for dat
asanka
2011/07/28 20:04:38
Shouldn't the !url.host().empty() exclude 'about'
rvargas (doing something else)
2011/07/29 01:34:53
Yes. Please add a comment about that (we are losin
| |
| 1456 url.is_valid() && !url.host().empty()) { | |
| 1457 // Some schemes (e.g. file) do not have a hostname. Even though it's not | |
| 1458 // likely to reach here, let's hardcode the last fallback name. | |
| 1459 // TODO(jungshik) : Decode a 'punycoded' IDN hostname. (bug 1264451) | |
| 1460 filename = url.host(); | |
| 1461 TrimGeneratedFileName(filename); | |
|
rvargas (doing something else)
2011/07/26 00:10:57
Looks like it's better to call this after the next
asanka
2011/07/28 20:04:38
I did it this way so that if trimming the filename
rvargas (doing something else)
2011/07/29 01:34:53
I'm not so sure about that. For instance, if the s
| |
| 1462 } | |
| 1463 | |
| 1464 if (filename.empty() && default_name.empty()) { | |
| 1465 filename = kFinalFallbackName; | |
| 1466 } | |
| 1467 | |
| 1468 // Replace any path information by changing path separators with | |
| 1469 // underscores. | |
| 1470 ReplaceSubstringsAfterOffset(&filename, 0, "/", "_"); | |
| 1471 ReplaceSubstringsAfterOffset(&filename, 0, "\\", "_"); | |
| 1472 | |
| 1340 #if defined(OS_WIN) | 1473 #if defined(OS_WIN) |
| 1341 string16 path = UTF8ToUTF16(filename); | 1474 string16 path = (filename.empty())? default_name : UTF8ToUTF16(filename); |
| 1342 file_util::ReplaceIllegalCharactersInPath(&path, '-'); | 1475 file_util::ReplaceIllegalCharactersInPath(&path, '-'); |
| 1343 return path; | 1476 FilePath result(path); |
| 1477 GenerateSafeFileName(mime_type, &result); | |
| 1478 return result.value(); | |
| 1344 #else | 1479 #else |
| 1345 std::string path = filename; | 1480 std::string path = (filename.empty())? UTF16ToUTF8(default_name) : filename; |
| 1346 file_util::ReplaceIllegalCharactersInPath(&path, '-'); | 1481 file_util::ReplaceIllegalCharactersInPath(&path, '-'); |
| 1347 return UTF8ToUTF16(path); | 1482 FilePath result(path); |
| 1483 GenerateSafeFileName(mime_type, &result); | |
| 1484 return UTF8ToUTF16(result.value()); | |
| 1348 #endif | 1485 #endif |
| 1349 } | 1486 } |
| 1350 | 1487 |
| 1488 FilePath GenerateFileName(const GURL& url, | |
| 1489 const std::string& content_disposition, | |
| 1490 const std::string& referrer_charset, | |
| 1491 const std::string& suggested_name, | |
| 1492 const std::string& mime_type, | |
| 1493 const string16& default_name) { | |
| 1494 string16 file_name = GetSuggestedFilename( | |
| 1495 url, content_disposition, referrer_charset, | |
| 1496 suggested_name, mime_type, default_name); | |
| 1497 | |
| 1498 #if defined(OS_WIN) | |
| 1499 FilePath generated_name(file_name); | |
| 1500 #else | |
| 1501 FilePath generated_name(base::SysWideToNativeMB(UTF16ToWide(file_name))); | |
| 1502 #endif | |
| 1503 DCHECK(!generated_name.empty()); | |
| 1504 | |
| 1505 return generated_name; | |
| 1506 } | |
| 1507 | |
| 1351 bool IsPortAllowedByDefault(int port) { | 1508 bool IsPortAllowedByDefault(int port) { |
| 1352 int array_size = arraysize(kRestrictedPorts); | 1509 int array_size = arraysize(kRestrictedPorts); |
| 1353 for (int i = 0; i < array_size; i++) { | 1510 for (int i = 0; i < array_size; i++) { |
| 1354 if (kRestrictedPorts[i] == port) { | 1511 if (kRestrictedPorts[i] == port) { |
| 1355 return false; | 1512 return false; |
| 1356 } | 1513 } |
| 1357 } | 1514 } |
| 1358 return true; | 1515 return true; |
| 1359 } | 1516 } |
| 1360 | 1517 |
| (...skipping 886 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2247 | 2404 |
| 2248 NetworkInterface::NetworkInterface(const std::string& name, | 2405 NetworkInterface::NetworkInterface(const std::string& name, |
| 2249 const IPAddressNumber& address) | 2406 const IPAddressNumber& address) |
| 2250 : name(name), address(address) { | 2407 : name(name), address(address) { |
| 2251 } | 2408 } |
| 2252 | 2409 |
| 2253 NetworkInterface::~NetworkInterface() { | 2410 NetworkInterface::~NetworkInterface() { |
| 2254 } | 2411 } |
| 2255 | 2412 |
| 2256 } // namespace net | 2413 } // namespace net |
| OLD | NEW |