diff options
author | jungshik@google.com <jungshik@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-01 22:51:50 +0000 |
---|---|---|
committer | jungshik@google.com <jungshik@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-01 22:51:50 +0000 |
commit | c9825a4d401b014d89534020c8cf93302efd398c (patch) | |
tree | dcc654d12d5f538c2507f5f0b920cac091fe1a89 /net/base/net_util.cc | |
parent | 36c165e203d4ddf415c29b865b4c13f0b9f32d38 (diff) | |
download | chromium_src-c9825a4d401b014d89534020c8cf93302efd398c.zip chromium_src-c9825a4d401b014d89534020c8cf93302efd398c.tar.gz chromium_src-c9825a4d401b014d89534020c8cf93302efd398c.tar.bz2 |
This CL makes Chrome on par with Firefox in terms of 'GetSuggestedFilename' for file download via context-menu.
For a download initiated with a click on a link in a web page, a webkit-side change is necessary, which will be done later.
Add a field (referrer_charset) to URLRequestContext and DownloadCreateInfo. It's set to the character encoding of a document where the download request originates from when it's known (download initiated via "save as" in the context menu).
If it's not known (a download initiated by clicking on a download link or typing a url directly to the omnibox), it's initialized to the default character encoding in the user's preference. I guess this is marginally better than leaving it empty (in that case, step 2b below will be skipped and step 2c will be taken) because a user has a better control over how raw 8bit characters in C-D are interpreted (especially on Windows where a reboot is required to change the OS default codepage).
This is later passed to GetSuggestedFilename and used as one of fallback encodings (1. UTF-8, 2. origin_charset, 3. default OS codepage). With this change, we support the following:
1. RFC 2047
2. Raw-8bit-characters : a. UTF-8, b. origin_charset, c. default os codepage.
3. %-escaped UTF-8.
In this CL, for #3, I didn't add a fallback similar to one used for #2. If necessary, it can be added easily. New entries are added to 3 existing tests. What's previously not covered (raw 8bit Content-Disposition header) is now covered in all 3 tests.
BUG=1148
TEST=net unit test: NetUtilTest.GetFileNameFromCD
NetUtilTest.GetSuggestedFilename
unittest : DownloadManagerTest.TestDownloadFilename
Review URL: http://codereview.chromium.org/83002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15113 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/base/net_util.cc')
-rw-r--r-- | net/base/net_util.cc | 38 |
1 files changed, 21 insertions, 17 deletions
diff --git a/net/base/net_util.cc b/net/base/net_util.cc index 9610e40..e5c53eb 100644 --- a/net/base/net_util.cc +++ b/net/base/net_util.cc @@ -247,17 +247,22 @@ bool DecodeBQEncoding(const std::string& part, RFC2047EncodingType enc_type, } bool DecodeWord(const std::string& encoded_word, + const std::string& referrer_charset, bool *is_rfc2047, std::string* output) { - // TODO(jungshik) : Revisit this later. Do we want to pass through non-ASCII - // strings which can be mozibake? WinHTTP converts a raw 8bit string - // UTF-16 assuming it's in the OS default encoding. if (!IsStringASCII(encoded_word)) { - // Try falling back to the NativeMB encoding if the raw input is not UTF-8. + // Try UTF-8, referrer_charset and the native OS default charset in turn. if (IsStringUTF8(encoded_word)) { *output = encoded_word; } else { - *output = WideToUTF8(base::SysNativeMBToWide(encoded_word)); + std::wstring wide_output; + if (!referrer_charset.empty() && + CodepageToWide(encoded_word, referrer_charset.c_str(), + OnStringUtilConversionError::FAIL, &wide_output)) { + *output = WideToUTF8(wide_output); + } else { + *output = WideToUTF8(base::SysNativeMBToWide(encoded_word)); + } } *is_rfc2047 = false; return true; @@ -357,7 +362,9 @@ bool DecodeWord(const std::string& encoded_word, return false; } -bool DecodeParamValue(const std::string& input, std::string* output) { +bool DecodeParamValue(const std::string& input, + const std::string& referrer_charset, + std::string* output) { std::string tmp; // Tokenize with whitespace characters. StringTokenizer t(input, " \t\n\r"); @@ -378,7 +385,8 @@ bool DecodeParamValue(const std::string& input, std::string* output) { // in a single encoded-word. Firefox/Thunderbird do not support // it, either. std::string decoded; - if (!DecodeWord(t.token(), &is_previous_token_rfc2047, &decoded)) + if (!DecodeWord(t.token(), referrer_charset, &is_previous_token_rfc2047, + &decoded)) return false; tmp.append(decoded); } @@ -683,7 +691,8 @@ std::string GetSpecificHeader(const std::string& headers, return GetSpecificHeaderT(headers, name); } -std::wstring GetFileNameFromCD(const std::string& header) { +std::wstring GetFileNameFromCD(const std::string& header, + const std::string& referrer_charset) { std::string param_value = GetHeaderParamValue(header, "filename"); if (param_value.empty()) { // Some servers use 'name' parameter. @@ -692,7 +701,7 @@ std::wstring GetFileNameFromCD(const std::string& header) { if (param_value.empty()) return std::wstring(); std::string decoded; - if (DecodeParamValue(param_value, &decoded)) + if (DecodeParamValue(param_value, referrer_charset, &decoded)) return UTF8ToWide(decoded); return std::wstring(); } @@ -863,8 +872,10 @@ std::wstring StripWWW(const std::wstring& text) { std::wstring GetSuggestedFilename(const GURL& url, const std::string& content_disposition, + const std::string& referrer_charset, const std::wstring& default_name) { - std::wstring filename = GetFileNameFromCD(content_disposition); + std::wstring filename = GetFileNameFromCD(content_disposition, + referrer_charset); if (!filename.empty()) { // Remove any path information the server may have sent, take the name // only. @@ -901,13 +912,6 @@ std::wstring GetSuggestedFilename(const GURL& url, return filename; } -std::wstring GetSuggestedFilename(const GURL& url, - const std::wstring& content_disposition, - const std::wstring& default_name) { - return GetSuggestedFilename( - url, WideToUTF8(content_disposition), default_name); -} - bool IsPortAllowedByDefault(int port) { int array_size = arraysize(kRestrictedPorts); for (int i = 0; i < array_size; i++) { |