diff options
author | tc@google.com <tc@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-22 05:10:59 +0000 |
---|---|---|
committer | tc@google.com <tc@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-22 05:10:59 +0000 |
commit | a7e79591fd7db823cd278ff43616ba4a22108213 (patch) | |
tree | 512e2f2a282595c51cfa3bb48e0de9d2d5a46251 | |
parent | 1ea9aac8836d5532c8d9ef5cf57f3653f0af1347 (diff) | |
download | chromium_src-a7e79591fd7db823cd278ff43616ba4a22108213.zip chromium_src-a7e79591fd7db823cd278ff43616ba4a22108213.tar.gz chromium_src-a7e79591fd7db823cd278ff43616ba4a22108213.tar.bz2 |
Move FileURLToFilePath into platform specific files. Most of the logic in this function is specific to windows' file system.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@1211 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | net/SConscript | 3 | ||||
-rw-r--r-- | net/base/net_util.cc | 71 | ||||
-rw-r--r-- | net/base/net_util_posix.cc | 70 | ||||
-rw-r--r-- | net/base/net_util_unittest.cc | 43 | ||||
-rw-r--r-- | net/base/net_util_win.cc | 111 | ||||
-rw-r--r-- | net/build/net.vcproj | 4 | ||||
-rw-r--r-- | net/net.xcodeproj/project.pbxproj | 4 |
7 files changed, 229 insertions, 77 deletions
diff --git a/net/SConscript b/net/SConscript index 932e25d..1303f8a 100644 --- a/net/SConscript +++ b/net/SConscript @@ -140,6 +140,7 @@ if env['PLATFORM'] == 'win32': ], ) input_files.extend([ + 'base/net_util_win.cc', 'base/platform_mime_util_win.cc', 'disk_cache/cache_util_win.cc', 'disk_cache/file_win.cc', @@ -154,6 +155,7 @@ if env['PLATFORM'] == 'darwin': if env['PLATFORM'] in ('darwin', 'posix'): input_files.extend([ + 'base/net_util_posix.cc', # TODO(tc): gnome-vfs? xdgmime? /etc/mime.types? #'base/platform_mime_util_linux.cc, 'disk_cache/cache_util_posix.cc', @@ -189,7 +191,6 @@ env_tests.Prepend( 'base', 'googleurl', 'gtest', - 'net', # Likewise, net must come before modp_b64 and icuuc. 'icuuc', 'modp_b64', 'zlib', diff --git a/net/base/net_util.cc b/net/base/net_util.cc index 906c16a..4e7fab7 100644 --- a/net/base/net_util.cc +++ b/net/base/net_util.cc @@ -675,77 +675,6 @@ GURL FilePathToFileURL(const std::wstring& file_path) { #endif } -bool FileURLToFilePath(const GURL& url, std::wstring* file_path) { - file_path->clear(); - - if (!url.is_valid()) - return false; - - std::string path; - std::string host = url.host(); - if (host.empty()) { - // URL contains no host, the path is the filename. In this case, the path - // will probably be preceeded with a slash, as in "/C:/foo.txt", so we - // trim out that here. - path = url.path(); - size_t first_non_slash = path.find_first_not_of("/\\"); - if (first_non_slash != std::string::npos && first_non_slash > 0) - path.erase(0, first_non_slash); - } else { - // URL contains a host: this means it's UNC. We keep the preceeding slash - // on the path. - path = "\\\\"; - path.append(host); - path.append(url.path()); - } - - if (path.empty()) - return false; - std::replace(path.begin(), path.end(), '/', '\\'); - - // GURL stores strings as percent-encoded UTF-8, this will undo if possible. - path = UnescapeURLComponent(path, - UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS); - - if (!IsStringUTF8(path.c_str())) { - // Not UTF-8, assume encoding is native codepage and we're done. We know we - // are giving the conversion function a nonempty string, and it may fail if - // the given string is not in the current encoding and give us an empty - // string back. We detect this and report failure. - *file_path = base::SysNativeMBToWide(path); - return !file_path->empty(); - } - file_path->assign(UTF8ToWide(path)); - - // Now we have an unescaped filename, but are still not sure about its - // encoding. For example, each character could be part of a UTF-8 string. - if (file_path->empty() || !IsString8Bit(*file_path)) { - // assume our 16-bit encoding is correct if it won't fit into an 8-bit - // string - return true; - } - - // Convert our narrow string into the native wide path. - std::string narrow; - if (!WideToLatin1(*file_path, &narrow)) { - NOTREACHED() << "Should have filtered out non-8-bit strings above."; - return false; - } - if (IsStringUTF8(narrow.c_str())) { - // Our string actually looks like it could be UTF-8, convert to 8-bit - // UTF-8 and then to the corresponding wide string. - *file_path = UTF8ToWide(narrow); - } else { - // Our wide string contains only 8-bit characters and it's not UTF-8, so - // we assume it's in the native codepage. - *file_path = base::SysNativeMBToWide(narrow); - } - - // Fail if 8-bit -> wide conversion failed and gave us an empty string back - // (we already filtered out empty strings above). - return !file_path->empty(); -} - std::wstring GetSpecificHeader(const std::wstring& headers, const std::wstring& name) { return GetSpecificHeaderT(headers, name); diff --git a/net/base/net_util_posix.cc b/net/base/net_util_posix.cc new file mode 100644 index 0000000..03a006a --- /dev/null +++ b/net/base/net_util_posix.cc @@ -0,0 +1,70 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "net/base/net_util.h" + +#include "base/string_util.h" +#include "googleurl/src/gurl.h" +#include "net/base/escape.h" + +namespace net { + +bool FileURLToFilePath(const GURL& url, std::wstring* file_path) { + file_path->clear(); + + if (!url.is_valid()) + return false; + + // Firefox seems to ignore the "host" of a file url if there is one. That is, + // file://foo/bar.txt maps to /bar.txt. + std::string path = url.path(); + + if (path.empty()) + return false; + + // GURL stores strings as percent-encoded 8-bit, this will undo if possible. + path = UnescapeURLComponent(path, + UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS); + + // Collapse multiple path slashes into a single path slash. + std::string new_path; + do { + new_path = path; + ReplaceSubstringsAfterOffset(&new_path, 0, "//", "/"); + path.swap(new_path); + } while (new_path != path); + + // TODO(tc): This should actually be 8-bit to wide. We may lose data if the + // string isn't UTF-8. + file_path->assign(UTF8ToWide(path)); + + return !file_path->empty(); +} + +} // namespace net diff --git a/net/base/net_util_unittest.cc b/net/base/net_util_unittest.cc index fcf99ba..f18c642 100644 --- a/net/base/net_util_unittest.cc +++ b/net/base/net_util_unittest.cc @@ -83,16 +83,22 @@ struct SuggestedFilenameCase { } // anonymous namespace -#ifdef OS_WIN -// TODO: Determine how we want windows file paths and unc paths to be -// normalized on posix systems. TEST(NetUtilTest, FileURLConversion) { // a list of test file names and the corresponding URLs const FileCase round_trip_cases[] = { +#if defined(OS_WIN) {L"C:\\foo\\bar.txt", L"file:///C:/foo/bar.txt"}, {L"\\\\some computer\\foo\\bar.txt", L"file://some%20computer/foo/bar.txt"}, // UNC {L"D:\\Name;with%some symbols*#", L"file:///D:/Name%3Bwith%25some%20symbols*%23"}, {L"D:\\Chinese\\\x6240\x6709\x4e2d\x6587\x7f51\x9875.doc", L"file:///D:/Chinese/%E6%89%80%E6%9C%89%E4%B8%AD%E6%96%87%E7%BD%91%E9%A1%B5.doc"}, +#elif defined(OS_POSIX) + {L"/foo/bar.txt", L"file:///foo/bar.txt"}, + {L"/foo/BAR.txt", L"file:///foo/BAR.txt"}, + {L"/C:/foo/bar.txt", L"file:///C:/foo/bar.txt"}, + {L"/some computer/foo/bar.txt", L"file:///some%20computer/foo/bar.txt"}, + {L"/Name;with%some symbols*#", L"file:///Name%3Bwith%25some%20symbols*%23"}, + {L"/Chinese/\x6240\x6709\x4e2d\x6587\x7f51\x9875.doc", L"file:///Chinese/%E6%89%80%E6%9C%89%E4%B8%AD%E6%96%87%E7%BD%91%E9%A1%B5.doc"}, +#endif }; // First, we'll test that we can round-trip all of the above cases of URLs @@ -110,6 +116,7 @@ TEST(NetUtilTest, FileURLConversion) { // Test that various file: URLs get decoded into the correct file type FileCase url_cases[] = { +#if defined(OS_WIN) {L"C:\\foo\\bar.txt", L"file:c|/foo\\bar.txt"}, {L"C:\\foo\\bar.txt", L"file:/c:/foo/bar.txt"}, {L"\\\\foo\\bar.txt", L"file://foo\\bar.txt"}, @@ -118,6 +125,28 @@ TEST(NetUtilTest, FileURLConversion) { {L"\\\\foo\\bar.txt", L"file:/foo/bar.txt"}, {L"\\\\foo\\bar.txt", L"file://foo\\bar.txt"}, {L"C:\\foo\\bar.txt", L"file:\\\\\\c:/foo/bar.txt"}, +#elif defined(OS_POSIX) + {L"/c:/foo/bar.txt", L"file:/c:/foo/bar.txt"}, + {L"/c:/foo/bar.txt", L"file:///c:/foo/bar.txt"}, + {L"/foo/bar.txt", L"file:/foo/bar.txt"}, + {L"/c:/foo/bar.txt", L"file:\\\\\\c:/foo/bar.txt"}, + {L"/foo/bar.txt", L"file:foo/bar.txt"}, + {L"/foo/bar.txt", L"file://foo/bar.txt"}, + {L"/foo/bar.txt", L"file:///foo/bar.txt"}, + {L"/foo/bar.txt", L"file:////foo/bar.txt"}, + {L"/foo/bar.txt", L"file:////foo//bar.txt"}, + {L"/foo/bar.txt", L"file:////foo///bar.txt"}, + {L"/foo/bar.txt", L"file:////foo////bar.txt"}, + {L"/c:/foo/bar.txt", L"file:\\\\\\c:/foo/bar.txt"}, + {L"/c:/foo/bar.txt", L"file:c:/foo/bar.txt"}, + // We get these wrong because GURL turns back slashes into forward + // slashes. + //{L"/foo%5Cbar.txt", L"file://foo\\bar.txt"}, + //{L"/c|/foo%5Cbar.txt", L"file:c|/foo\\bar.txt"}, + //{L"/foo%5Cbar.txt", L"file://foo\\bar.txt"}, + //{L"/foo%5Cbar.txt", L"file:////foo\\bar.txt"}, + //{L"/foo%5Cbar.txt", L"file://foo\\bar.txt"}, +#endif }; for (size_t i = 0; i < ARRAYSIZE_UNSAFE(url_cases); i++) { net::FileURLToFilePath(GURL(WideToUTF16(url_cases[i].url)), &output); @@ -125,9 +154,14 @@ TEST(NetUtilTest, FileURLConversion) { } // Here, we test that UTF-8 encoded strings get decoded properly, even when - // they might be stored with wide characters + // they might be stored with wide characters. On posix systems, just treat + // this as a stream of bytes. const wchar_t utf8[] = L"file:///d:/Chinese/\xe6\x89\x80\xe6\x9c\x89\xe4\xb8\xad\xe6\x96\x87\xe7\xbd\x91\xe9\xa1\xb5.doc"; +#if defined(OS_WIN) const wchar_t wide[] = L"D:\\Chinese\\\x6240\x6709\x4e2d\x6587\x7f51\x9875.doc"; +#elif defined(OS_POSIX) + const wchar_t wide[] = L"/d:/Chinese/\xe6\x89\x80\xe6\x9c\x89\xe4\xb8\xad\xe6\x96\x87\xe7\xbd\x91\xe9\xa1\xb5.doc"; +#endif EXPECT_TRUE(net::FileURLToFilePath(GURL(WideToUTF16(utf8)), &output)); EXPECT_EQ(std::wstring(wide), output); @@ -145,7 +179,6 @@ TEST(NetUtilTest, FileURLConversion) { // Test that if a file URL is malformed, we get a failure EXPECT_FALSE(net::FileURLToFilePath(GURL("filefoobar"), &output)); } -#endif // Just a bunch of fake headers. const wchar_t* google_headers = diff --git a/net/base/net_util_win.cc b/net/base/net_util_win.cc new file mode 100644 index 0000000..9295b7e --- /dev/null +++ b/net/base/net_util_win.cc @@ -0,0 +1,111 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "net/base/net_util.h" + +#include "base/string_piece.h" +#include "base/string_util.h" +#include "base/sys_string_conversions.h" +#include "googleurl/src/gurl.h" +#include "net/base/escape.h" + +namespace net { + +bool FileURLToFilePath(const GURL& url, std::wstring* file_path) { + file_path->clear(); + + if (!url.is_valid()) + return false; + + std::string path; + std::string host = url.host(); + if (host.empty()) { + // URL contains no host, the path is the filename. In this case, the path + // will probably be preceeded with a slash, as in "/C:/foo.txt", so we + // trim out that here. + path = url.path(); + size_t first_non_slash = path.find_first_not_of("/\\"); + if (first_non_slash != std::string::npos && first_non_slash > 0) + path.erase(0, first_non_slash); + } else { + // URL contains a host: this means it's UNC. We keep the preceeding slash + // on the path. + path = "\\\\"; + path.append(host); + path.append(url.path()); + } + + if (path.empty()) + return false; + std::replace(path.begin(), path.end(), '/', '\\'); + + // GURL stores strings as percent-encoded UTF-8, this will undo if possible. + path = UnescapeURLComponent(path, + UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS); + + if (!IsStringUTF8(path.c_str())) { + // Not UTF-8, assume encoding is native codepage and we're done. We know we + // are giving the conversion function a nonempty string, and it may fail if + // the given string is not in the current encoding and give us an empty + // string back. We detect this and report failure. + *file_path = base::SysNativeMBToWide(path); + return !file_path->empty(); + } + file_path->assign(UTF8ToWide(path)); + + // Now we have an unescaped filename, but are still not sure about its + // encoding. For example, each character could be part of a UTF-8 string. + if (file_path->empty() || !IsString8Bit(*file_path)) { + // assume our 16-bit encoding is correct if it won't fit into an 8-bit + // string + return true; + } + + // Convert our narrow string into the native wide path. + std::string narrow; + if (!WideToLatin1(*file_path, &narrow)) { + NOTREACHED() << "Should have filtered out non-8-bit strings above."; + return false; + } + if (IsStringUTF8(narrow.c_str())) { + // Our string actually looks like it could be UTF-8, convert to 8-bit + // UTF-8 and then to the corresponding wide string. + *file_path = UTF8ToWide(narrow); + } else { + // Our wide string contains only 8-bit characters and it's not UTF-8, so + // we assume it's in the native codepage. + *file_path = base::SysNativeMBToWide(narrow); + } + + // Fail if 8-bit -> wide conversion failed and gave us an empty string back + // (we already filtered out empty strings above). + return !file_path->empty(); +} + +} // namespace net diff --git a/net/build/net.vcproj b/net/build/net.vcproj index 3951c7f..069db63 100644 --- a/net/build/net.vcproj +++ b/net/build/net.vcproj @@ -357,6 +357,10 @@ > </File> <File + RelativePath="..\base\net_util_win.cc" + > + </File> + <File RelativePath="..\base\net_util.h" > </File> diff --git a/net/net.xcodeproj/project.pbxproj b/net/net.xcodeproj/project.pbxproj index b45a5a2..cd1bbfd 100644 --- a/net/net.xcodeproj/project.pbxproj +++ b/net/net.xcodeproj/project.pbxproj @@ -26,6 +26,7 @@ 048268080E5B3B3200A30786 /* http_chunked_decoder_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BED33570E5A194700A747DB /* http_chunked_decoder_unittest.cc */; }; 048268090E5B3B4800A30786 /* mime_util_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BED325E0E5A181C00A747DB /* mime_util_unittest.cc */; }; 0482692A0E5B624D00A30786 /* http_cache.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BED334C0E5A194700A747DB /* http_cache.cc */; }; + 533102E70E5E3EBF00FF8E32 /* net_util_posix.cc in Sources */ = {isa = PBXBuildFile; fileRef = 533102E60E5E3EBF00FF8E32 /* net_util_posix.cc */; }; 7B4DF64A0E5B98DF004D7619 /* client_socket_pool_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BED326A0E5A181C00A747DB /* client_socket_pool_unittest.cc */; }; 7B4DF6A90E5B98E7004D7619 /* data_url_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BED325F0E5A181C00A747DB /* data_url_unittest.cc */; }; 7B4DF6B10E5B98ED004D7619 /* escape_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BED32BF0E5A181C00A747DB /* escape_unittest.cc */; }; @@ -298,6 +299,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 533102E60E5E3EBF00FF8E32 /* net_util_posix.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = net_util_posix.cc; sourceTree = "<group>"; }; 7B8501F10E5A372500730B43 /* googleurl.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = googleurl.xcodeproj; path = build/googleurl.xcodeproj; sourceTree = "<group>"; }; 7B8502620E5A38BB00730B43 /* modp_b64.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = modp_b64.xcodeproj; path = third_party/modp_b64/modp_b64.xcodeproj; sourceTree = "<group>"; }; 7BA015570E5A1C3E00044150 /* icu.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = icu.xcodeproj; path = third_party/icu38/build/icu.xcodeproj; sourceTree = "<group>"; }; @@ -763,6 +765,7 @@ 7BED32A30E5A181C00A747DB /* net_resources.h */, 7BED32A10E5A181C00A747DB /* net_util.cc */, 7BED32A00E5A181C00A747DB /* net_util.h */, + 533102E60E5E3EBF00FF8E32 /* net_util_posix.cc */, 7BED329F0E5A181C00A747DB /* net_util_unittest.cc */, 7BED329E0E5A181C00A747DB /* platform_mime_util.h */, 7BED329D0E5A181C00A747DB /* platform_mime_util_mac.mm */, @@ -1231,6 +1234,7 @@ 7B8504540E5B2E9600730B43 /* url_request_job_tracker.cc in Sources */, 821F23CC0E5E106D003C7E38 /* url_request_simple_job.cc in Sources */, 821F20A50E5CD414003C7E38 /* url_request_view_cache_job.cc in Sources */, + 533102E70E5E3EBF00FF8E32 /* net_util_posix.cc in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; |