diff options
author | eroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-23 18:04:01 +0000 |
---|---|---|
committer | eroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-23 18:04:01 +0000 |
commit | 0238de41ca1bdce286ac08d21c7634c36787ad7f (patch) | |
tree | fbdbdd2d5e0b3bfb4be2b6cd0e48d2ceaf8d1aa7 /net | |
parent | f2bd5397e9dbc5954aa78eef1ae9fed0f599650f (diff) | |
download | chromium_src-0238de41ca1bdce286ac08d21c7634c36787ad7f.zip chromium_src-0238de41ca1bdce286ac08d21c7634c36787ad7f.tar.gz chromium_src-0238de41ca1bdce286ac08d21c7634c36787ad7f.tar.bz2 |
Add support for international domain names in PAC scripts. This converts non-ASCII hostnames in dnsResolve() and dnsResolveEx() to punycode.
BUG=47234
TEST=ProxyResolverV8Test.DNSResolutionOfInternationDomainName
Review URL: http://codereview.chromium.org/2842017
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@50624 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rwxr-xr-x | net/data/proxy_resolver_v8_unittest/international_domain_names.js | 16 | ||||
-rw-r--r-- | net/proxy/proxy_resolver_v8.cc | 31 | ||||
-rw-r--r-- | net/proxy/proxy_resolver_v8_unittest.cc | 24 |
3 files changed, 65 insertions, 6 deletions
diff --git a/net/data/proxy_resolver_v8_unittest/international_domain_names.js b/net/data/proxy_resolver_v8_unittest/international_domain_names.js new file mode 100755 index 0000000..546af13 --- /dev/null +++ b/net/data/proxy_resolver_v8_unittest/international_domain_names.js @@ -0,0 +1,16 @@ +// Try resolving hostnames containing non-ASCII characters. + +function FindProxyForURL(url, host) { + // This international hostname has a non-ASCII character. It is represented + // in punycode as 'xn--bcher-kva.ch' + var idn = 'B\u00fccher.ch'; + + // We disregard the actual return value -- all we care about is that on + // the C++ end the bindings were passed the punycode equivalent of this + // unicode hostname. + dnsResolve(idn); + dnsResolveEx(idn); + + return "DIRECT"; +} + diff --git a/net/proxy/proxy_resolver_v8.cc b/net/proxy/proxy_resolver_v8.cc index 05f16e9..4b54cb7 100644 --- a/net/proxy/proxy_resolver_v8.cc +++ b/net/proxy/proxy_resolver_v8.cc @@ -6,7 +6,9 @@ #include "base/logging.h" #include "base/string_util.h" +#include "base/utf_string_conversions.h" #include "googleurl/src/gurl.h" +#include "googleurl/src/url_canon.h" #include "net/base/host_cache.h" #include "net/base/net_errors.h" #include "net/base/net_log.h" @@ -109,13 +111,30 @@ bool GetHostnameArgument(const v8::Arguments& args, std::string* hostname) { const string16 hostname_utf16 = V8StringToUTF16(args[0]->ToString()); - // TODO(eroman): Convert international domain names to punycode. Right - // now we fail if the hostname isn't entered in ASCII. - // crbug.com/47234 - if (!IsStringASCII(hostname_utf16)) + // If the hostname is already in ASCII, simply return it as is. + if (IsStringASCII(hostname_utf16)) { + *hostname = UTF16ToASCII(hostname_utf16); + return true; + } + + // Otherwise try to convert it from IDN to punycode. + const int kInitialBufferSize = 256; + url_canon::RawCanonOutputT<char16, kInitialBufferSize> punycode_output; + if (!url_canon::IDNToASCII(hostname_utf16.data(), + hostname_utf16.length(), + &punycode_output)) { return false; - *hostname = UTF16ToASCII(hostname_utf16); - return true; + } + + // |punycode_output| should now be ASCII; convert it to a std::string. + // (We could use UTF16ToASCII() instead, but that requires an extra string + // copy. Since ASCII is a subset of UTF8 the following is equivalent). + bool success = UTF16ToUTF8(punycode_output.data(), + punycode_output.length(), + hostname); + DCHECK(success); + DCHECK(IsStringASCII(*hostname)); + return success; } } // namespace diff --git a/net/proxy/proxy_resolver_v8_unittest.cc b/net/proxy/proxy_resolver_v8_unittest.cc index 5146fc6..9f9f50d 100644 --- a/net/proxy/proxy_resolver_v8_unittest.cc +++ b/net/proxy/proxy_resolver_v8_unittest.cc @@ -548,5 +548,29 @@ TEST(ProxyResolverV8Test, DNSResolutionFailure) { EXPECT_EQ("success:80", proxy_info.proxy_server().ToURI()); } +TEST(ProxyResolverV8Test, DNSResolutionOfInternationDomainName) { + ProxyResolverV8WithMockBindings resolver; + int result = resolver.SetPacScriptFromDisk("international_domain_names.js"); + EXPECT_EQ(OK, result); + + // Execute FindProxyForURL(). + ProxyInfo proxy_info; + result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL, + BoundNetLog()); + + EXPECT_EQ(OK, result); + EXPECT_TRUE(proxy_info.is_direct()); + + // Check that the international domain name was converted to punycode + // before passing it onto the bindings layer. + MockJSBindings* bindings = resolver.mock_js_bindings(); + + ASSERT_EQ(1u, bindings->dns_resolves.size()); + EXPECT_EQ("xn--bcher-kva.ch", bindings->dns_resolves[0]); + + ASSERT_EQ(1u, bindings->dns_resolves_ex.size()); + EXPECT_EQ("xn--bcher-kva.ch", bindings->dns_resolves_ex[0]); +} + } // namespace } // namespace net |