summaryrefslogtreecommitdiffstats
path: root/net/proxy
diff options
context:
space:
mode:
Diffstat (limited to 'net/proxy')
-rw-r--r--net/proxy/proxy_resolver_v8.cc31
-rw-r--r--net/proxy/proxy_resolver_v8_unittest.cc24
2 files changed, 49 insertions, 6 deletions
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