blob: cbb1a804e697a0f501a460fb4826eb4c6e0d1bb3 [file] [log] [blame]
[email protected]ad425c52012-02-11 00:05:311// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]943c8082009-02-23 19:10:452// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Lily Houghton582d4622018-01-22 22:43:405#include "net/proxy_resolution/proxy_resolver_v8.h"
[email protected]c4c1b482011-07-22 17:24:266#include "base/compiler_specific.h"
thestigd8df0332014-09-04 06:33:297#include "base/files/file_util.h"
[email protected]943c8082009-02-23 19:10:458#include "base/path_service.h"
[email protected]fc9be5802013-06-11 10:56:519#include "base/strings/string_util.h"
10#include "base/strings/stringprintf.h"
[email protected]750b2f3c2013-06-07 18:41:0511#include "base/strings/utf_string_conversions.h"
[email protected]943c8082009-02-23 19:10:4512#include "net/base/net_errors.h"
Lily Houghton582d4622018-01-22 22:43:4013#include "net/proxy_resolution/pac_file_data.h"
14#include "net/proxy_resolution/proxy_info.h"
robpercival214763f2016-07-01 23:27:0115#include "net/test/gtest_util.h"
Bence Béky98447b12018-05-08 03:14:0116#include "net/test/test_with_scoped_task_environment.h"
robpercival214763f2016-07-01 23:27:0117#include "testing/gmock/include/gmock/gmock.h"
[email protected]943c8082009-02-23 19:10:4518#include "testing/gtest/include/gtest/gtest.h"
[email protected]f89276a72013-07-12 06:41:5419#include "url/gurl.h"
[email protected]943c8082009-02-23 19:10:4520
robpercival214763f2016-07-01 23:27:0121using net::test::IsError;
22using net::test::IsOk;
Eric Roman9513f522018-04-04 23:49:4723using ::testing::IsEmpty;
robpercival214763f2016-07-01 23:27:0124
[email protected]52ae80c2009-09-10 21:27:0025namespace net {
[email protected]943c8082009-02-23 19:10:4526namespace {
27
[email protected]50d7d7282009-03-02 21:45:1828// Javascript bindings for ProxyResolverV8, which returns mock values.
29// Each time one of the bindings is called into, we push the input into a
30// list, for later verification.
[email protected]501e2d42013-01-30 22:30:4931class MockJSBindings : public ProxyResolverV8::JSBindings {
[email protected]50d7d7282009-03-02 21:45:1832 public:
sammcd2284e52015-05-27 03:14:4633 MockJSBindings()
34 : my_ip_address_count(0),
35 my_ip_address_ex_count(0),
36 should_terminate(false) {}
[email protected]943c8082009-02-23 19:10:4537
dchengb03027d2014-10-21 12:00:2038 void Alert(const base::string16& message) override {
[email protected]b30a3f52010-10-16 01:05:4639 VLOG(1) << "PAC-alert: " << message; // Helpful when debugging.
[email protected]ad65a3e2013-12-25 18:18:0140 alerts.push_back(base::UTF16ToUTF8(message));
[email protected]50d7d7282009-03-02 21:45:1841 }
[email protected]943c8082009-02-23 19:10:4542
dchengb03027d2014-10-21 12:00:2043 bool ResolveDns(const std::string& host,
44 ResolveDnsOperation op,
45 std::string* output,
46 bool* terminate) override {
[email protected]8cdc8812013-02-21 05:29:4947 *terminate = should_terminate;
48
[email protected]501e2d42013-01-30 22:30:4949 if (op == MY_IP_ADDRESS) {
50 my_ip_address_count++;
51 *output = my_ip_address_result;
52 return !my_ip_address_result.empty();
53 }
[email protected]943c8082009-02-23 19:10:4554
[email protected]501e2d42013-01-30 22:30:4955 if (op == MY_IP_ADDRESS_EX) {
56 my_ip_address_ex_count++;
57 *output = my_ip_address_ex_result;
58 return !my_ip_address_ex_result.empty();
59 }
[email protected]21f20c892009-10-26 23:51:2860
[email protected]501e2d42013-01-30 22:30:4961 if (op == DNS_RESOLVE) {
62 dns_resolves.push_back(host);
63 *output = dns_resolve_result;
64 return !dns_resolve_result.empty();
65 }
[email protected]50d7d7282009-03-02 21:45:1866
[email protected]501e2d42013-01-30 22:30:4967 if (op == DNS_RESOLVE_EX) {
68 dns_resolves_ex.push_back(host);
69 *output = dns_resolve_ex_result;
70 return !dns_resolve_ex_result.empty();
71 }
72
73 CHECK(false);
74 return false;
[email protected]21f20c892009-10-26 23:51:2875 }
76
dchengb03027d2014-10-21 12:00:2077 void OnError(int line_number, const base::string16& message) override {
[email protected]50d7d7282009-03-02 21:45:1878 // Helpful when debugging.
[email protected]b30a3f52010-10-16 01:05:4679 VLOG(1) << "PAC-error: [" << line_number << "] " << message;
[email protected]50d7d7282009-03-02 21:45:1880
[email protected]ad65a3e2013-12-25 18:18:0181 errors.push_back(base::UTF16ToUTF8(message));
[email protected]50d7d7282009-03-02 21:45:1882 errors_line_number.push_back(line_number);
83 }
84
85 // Mock values to return.
86 std::string my_ip_address_result;
[email protected]21f20c892009-10-26 23:51:2887 std::string my_ip_address_ex_result;
[email protected]50d7d7282009-03-02 21:45:1888 std::string dns_resolve_result;
[email protected]21f20c892009-10-26 23:51:2889 std::string dns_resolve_ex_result;
[email protected]50d7d7282009-03-02 21:45:1890
91 // Inputs we got called with.
92 std::vector<std::string> alerts;
93 std::vector<std::string> errors;
94 std::vector<int> errors_line_number;
95 std::vector<std::string> dns_resolves;
[email protected]21f20c892009-10-26 23:51:2896 std::vector<std::string> dns_resolves_ex;
[email protected]50d7d7282009-03-02 21:45:1897 int my_ip_address_count;
[email protected]21f20c892009-10-26 23:51:2898 int my_ip_address_ex_count;
[email protected]8cdc8812013-02-21 05:29:4999
100 // Whether ResolveDns() should terminate script execution.
101 bool should_terminate;
[email protected]50d7d7282009-03-02 21:45:18102};
103
Bence Béky98447b12018-05-08 03:14:01104class ProxyResolverV8Test : public TestWithScopedTaskEnvironment {
[email protected]50d7d7282009-03-02 21:45:18105 public:
sammcd2284e52015-05-27 03:14:46106 // Creates a ProxyResolverV8 using the PAC script contained in |filename|. If
107 // called more than once, the previous ProxyResolverV8 is deleted.
108 int CreateResolver(const char* filename) {
[email protected]6cdfd7f2013-02-08 20:40:15109 base::FilePath path;
Avi Drissman5c80d832018-05-01 17:01:19110 base::PathService::Get(base::DIR_SOURCE_ROOT, &path);
[email protected]50d7d7282009-03-02 21:45:18111 path = path.AppendASCII("net");
112 path = path.AppendASCII("data");
113 path = path.AppendASCII("proxy_resolver_v8_unittest");
114 path = path.AppendASCII(filename);
115
116 // Try to read the file from disk.
117 std::string file_contents;
[email protected]82f84b92013-08-30 18:23:50118 bool ok = base::ReadFileToString(path, &file_contents);
[email protected]50d7d7282009-03-02 21:45:18119
120 // If we can't load the file from disk, something is misconfigured.
[email protected]620f5712009-08-04 22:43:12121 if (!ok) {
122 LOG(ERROR) << "Failed to read file: " << path.value();
sammcd2284e52015-05-27 03:14:46123 return ERR_FAILED;
[email protected]620f5712009-08-04 22:43:12124 }
[email protected]50d7d7282009-03-02 21:45:18125
sammcd2284e52015-05-27 03:14:46126 // Create the ProxyResolver using the PAC script.
Lily Houghton99597862018-03-07 16:40:42127 return ProxyResolverV8::Create(PacFileData::FromUTF8(file_contents),
128 bindings(), &resolver_);
[email protected]50d7d7282009-03-02 21:45:18129 }
[email protected]501e2d42013-01-30 22:30:49130
sammcd2284e52015-05-27 03:14:46131 ProxyResolverV8& resolver() {
132 DCHECK(resolver_);
133 return *resolver_;
134 }
135
136 MockJSBindings* bindings() { return &js_bindings_; }
137
[email protected]501e2d42013-01-30 22:30:49138 private:
sammcd2284e52015-05-27 03:14:46139 MockJSBindings js_bindings_;
danakj8a98ca22016-04-16 02:47:36140 std::unique_ptr<ProxyResolverV8> resolver_;
[email protected]50d7d7282009-03-02 21:45:18141};
[email protected]943c8082009-02-23 19:10:45142
143// Doesn't really matter what these values are for many of the tests.
144const GURL kQueryUrl("http://www.google.com");
145const GURL kPacUrl;
146
sammcd2284e52015-05-27 03:14:46147TEST_F(ProxyResolverV8Test, Direct) {
robpercival214763f2016-07-01 23:27:01148 ASSERT_THAT(CreateResolver("direct.js"), IsOk());
[email protected]943c8082009-02-23 19:10:45149
[email protected]52ae80c2009-09-10 21:27:00150 ProxyInfo proxy_info;
sammcd2284e52015-05-27 03:14:46151 int result = resolver().GetProxyForURL(kQueryUrl, &proxy_info, bindings());
[email protected]943c8082009-02-23 19:10:45152
robpercival214763f2016-07-01 23:27:01153 EXPECT_THAT(result, IsOk());
[email protected]943c8082009-02-23 19:10:45154 EXPECT_TRUE(proxy_info.is_direct());
[email protected]50d7d7282009-03-02 21:45:18155
sammcd2284e52015-05-27 03:14:46156 EXPECT_EQ(0U, bindings()->alerts.size());
157 EXPECT_EQ(0U, bindings()->errors.size());
[email protected]943c8082009-02-23 19:10:45158}
159
sammcd2284e52015-05-27 03:14:46160TEST_F(ProxyResolverV8Test, ReturnEmptyString) {
robpercival214763f2016-07-01 23:27:01161 ASSERT_THAT(CreateResolver("return_empty_string.js"), IsOk());
[email protected]943c8082009-02-23 19:10:45162
[email protected]52ae80c2009-09-10 21:27:00163 ProxyInfo proxy_info;
sammcd2284e52015-05-27 03:14:46164 int result = resolver().GetProxyForURL(kQueryUrl, &proxy_info, bindings());
[email protected]943c8082009-02-23 19:10:45165
robpercival214763f2016-07-01 23:27:01166 EXPECT_THAT(result, IsOk());
[email protected]943c8082009-02-23 19:10:45167 EXPECT_TRUE(proxy_info.is_direct());
[email protected]50d7d7282009-03-02 21:45:18168
sammcd2284e52015-05-27 03:14:46169 EXPECT_EQ(0U, bindings()->alerts.size());
170 EXPECT_EQ(0U, bindings()->errors.size());
[email protected]943c8082009-02-23 19:10:45171}
172
sammcd2284e52015-05-27 03:14:46173TEST_F(ProxyResolverV8Test, Basic) {
robpercival214763f2016-07-01 23:27:01174 ASSERT_THAT(CreateResolver("passthrough.js"), IsOk());
[email protected]943c8082009-02-23 19:10:45175
176 // The "FindProxyForURL" of this PAC script simply concatenates all of the
177 // arguments into a pseudo-host. The purpose of this test is to verify that
178 // the correct arguments are being passed to FindProxyForURL().
179 {
[email protected]52ae80c2009-09-10 21:27:00180 ProxyInfo proxy_info;
sammcd2284e52015-05-27 03:14:46181 int result = resolver().GetProxyForURL(GURL("http://query.com/path"),
182 &proxy_info, bindings());
robpercival214763f2016-07-01 23:27:01183 EXPECT_THAT(result, IsOk());
[email protected]943c8082009-02-23 19:10:45184 EXPECT_EQ("http.query.com.path.query.com:80",
185 proxy_info.proxy_server().ToURI());
186 }
187 {
[email protected]52ae80c2009-09-10 21:27:00188 ProxyInfo proxy_info;
sammcd2284e52015-05-27 03:14:46189 int result = resolver().GetProxyForURL(GURL("ftp://query.com:90/path"),
190 &proxy_info, bindings());
robpercival214763f2016-07-01 23:27:01191 EXPECT_THAT(result, IsOk());
[email protected]943c8082009-02-23 19:10:45192 // Note that FindProxyForURL(url, host) does not expect |host| to contain
193 // the port number.
194 EXPECT_EQ("ftp.query.com.90.path.query.com:80",
195 proxy_info.proxy_server().ToURI());
[email protected]50d7d7282009-03-02 21:45:18196
sammcd2284e52015-05-27 03:14:46197 EXPECT_EQ(0U, bindings()->alerts.size());
198 EXPECT_EQ(0U, bindings()->errors.size());
[email protected]943c8082009-02-23 19:10:45199 }
200}
201
sammcd2284e52015-05-27 03:14:46202TEST_F(ProxyResolverV8Test, BadReturnType) {
[email protected]943c8082009-02-23 19:10:45203 // These are the filenames of PAC scripts which each return a non-string
204 // types for FindProxyForURL(). They should all fail with
205 // ERR_PAC_SCRIPT_FAILED.
206 static const char* const filenames[] = {
207 "return_undefined.js",
208 "return_integer.js",
209 "return_function.js",
210 "return_object.js",
211 // TODO(eroman): Should 'null' be considered equivalent to "DIRECT" ?
sammcd2284e52015-05-27 03:14:46212 "return_null.js"};
[email protected]943c8082009-02-23 19:10:45213
214 for (size_t i = 0; i < arraysize(filenames); ++i) {
robpercival214763f2016-07-01 23:27:01215 ASSERT_THAT(CreateResolver(filenames[i]), IsOk());
[email protected]943c8082009-02-23 19:10:45216
sammcd2284e52015-05-27 03:14:46217 MockJSBindings bindings;
[email protected]52ae80c2009-09-10 21:27:00218 ProxyInfo proxy_info;
sammcd2284e52015-05-27 03:14:46219 int result = resolver().GetProxyForURL(kQueryUrl, &proxy_info, &bindings);
[email protected]943c8082009-02-23 19:10:45220
robpercival214763f2016-07-01 23:27:01221 EXPECT_THAT(result, IsError(ERR_PAC_SCRIPT_FAILED));
[email protected]50d7d7282009-03-02 21:45:18222
sammcd2284e52015-05-27 03:14:46223 EXPECT_EQ(0U, bindings.alerts.size());
224 ASSERT_EQ(1U, bindings.errors.size());
225 EXPECT_EQ("FindProxyForURL() did not return a string.", bindings.errors[0]);
226 EXPECT_EQ(-1, bindings.errors_line_number[0]);
[email protected]943c8082009-02-23 19:10:45227 }
228}
229
230// Try using a PAC script which defines no "FindProxyForURL" function.
sammcd2284e52015-05-27 03:14:46231TEST_F(ProxyResolverV8Test, NoEntryPoint) {
robpercival214763f2016-07-01 23:27:01232 EXPECT_THAT(CreateResolver("no_entrypoint.js"),
233 IsError(ERR_PAC_SCRIPT_FAILED));
[email protected]50d7d7282009-03-02 21:45:18234
sammcd2284e52015-05-27 03:14:46235 ASSERT_EQ(1U, bindings()->errors.size());
eroman8df9fd802015-02-27 23:26:28236 EXPECT_EQ("FindProxyForURL is undefined or not a function.",
sammcd2284e52015-05-27 03:14:46237 bindings()->errors[0]);
238 EXPECT_EQ(-1, bindings()->errors_line_number[0]);
[email protected]943c8082009-02-23 19:10:45239}
240
241// Try loading a malformed PAC script.
sammcd2284e52015-05-27 03:14:46242TEST_F(ProxyResolverV8Test, ParseError) {
robpercival214763f2016-07-01 23:27:01243 EXPECT_THAT(CreateResolver("missing_close_brace.js"),
244 IsError(ERR_PAC_SCRIPT_FAILED));
[email protected]943c8082009-02-23 19:10:45245
sammcd2284e52015-05-27 03:14:46246 EXPECT_EQ(0U, bindings()->alerts.size());
[email protected]50d7d7282009-03-02 21:45:18247
[email protected]620f5712009-08-04 22:43:12248 // We get one error during compilation.
sammcd2284e52015-05-27 03:14:46249 ASSERT_EQ(1U, bindings()->errors.size());
[email protected]50d7d7282009-03-02 21:45:18250
251 EXPECT_EQ("Uncaught SyntaxError: Unexpected end of input",
sammcd2284e52015-05-27 03:14:46252 bindings()->errors[0]);
253 EXPECT_EQ(5, bindings()->errors_line_number[0]);
[email protected]943c8082009-02-23 19:10:45254}
255
256// Run a PAC script several times, which has side-effects.
sammcd2284e52015-05-27 03:14:46257TEST_F(ProxyResolverV8Test, SideEffects) {
robpercival214763f2016-07-01 23:27:01258 ASSERT_THAT(CreateResolver("side_effects.js"), IsOk());
[email protected]943c8082009-02-23 19:10:45259
260 // The PAC script increments a counter each time we invoke it.
261 for (int i = 0; i < 3; ++i) {
[email protected]52ae80c2009-09-10 21:27:00262 ProxyInfo proxy_info;
sammcd2284e52015-05-27 03:14:46263 int result = resolver().GetProxyForURL(kQueryUrl, &proxy_info, bindings());
robpercival214763f2016-07-01 23:27:01264 EXPECT_THAT(result, IsOk());
[email protected]d8eb84242010-09-25 02:25:06265 EXPECT_EQ(base::StringPrintf("sideffect_%d:80", i),
[email protected]943c8082009-02-23 19:10:45266 proxy_info.proxy_server().ToURI());
267 }
268
269 // Reload the script -- the javascript environment should be reset, hence
270 // the counter starts over.
robpercival214763f2016-07-01 23:27:01271 ASSERT_THAT(CreateResolver("side_effects.js"), IsOk());
[email protected]943c8082009-02-23 19:10:45272
273 for (int i = 0; i < 3; ++i) {
[email protected]52ae80c2009-09-10 21:27:00274 ProxyInfo proxy_info;
sammcd2284e52015-05-27 03:14:46275 int result = resolver().GetProxyForURL(kQueryUrl, &proxy_info, bindings());
robpercival214763f2016-07-01 23:27:01276 EXPECT_THAT(result, IsOk());
[email protected]d8eb84242010-09-25 02:25:06277 EXPECT_EQ(base::StringPrintf("sideffect_%d:80", i),
[email protected]943c8082009-02-23 19:10:45278 proxy_info.proxy_server().ToURI());
279 }
280}
281
282// Execute a PAC script which throws an exception in FindProxyForURL.
sammcd2284e52015-05-27 03:14:46283TEST_F(ProxyResolverV8Test, UnhandledException) {
robpercival214763f2016-07-01 23:27:01284 ASSERT_THAT(CreateResolver("unhandled_exception.js"), IsOk());
[email protected]943c8082009-02-23 19:10:45285
[email protected]52ae80c2009-09-10 21:27:00286 ProxyInfo proxy_info;
sammcd2284e52015-05-27 03:14:46287 int result = resolver().GetProxyForURL(kQueryUrl, &proxy_info, bindings());
[email protected]943c8082009-02-23 19:10:45288
robpercival214763f2016-07-01 23:27:01289 EXPECT_THAT(result, IsError(ERR_PAC_SCRIPT_FAILED));
[email protected]50d7d7282009-03-02 21:45:18290
sammcd2284e52015-05-27 03:14:46291 EXPECT_EQ(0U, bindings()->alerts.size());
292 ASSERT_EQ(1U, bindings()->errors.size());
[email protected]50d7d7282009-03-02 21:45:18293 EXPECT_EQ("Uncaught ReferenceError: undefined_variable is not defined",
sammcd2284e52015-05-27 03:14:46294 bindings()->errors[0]);
295 EXPECT_EQ(3, bindings()->errors_line_number[0]);
[email protected]943c8082009-02-23 19:10:45296}
297
eroman8df9fd802015-02-27 23:26:28298// Execute a PAC script which throws an exception when first accessing
299// FindProxyForURL
sammcd2284e52015-05-27 03:14:46300TEST_F(ProxyResolverV8Test, ExceptionAccessingFindProxyForURLDuringInit) {
301 EXPECT_EQ(ERR_PAC_SCRIPT_FAILED,
302 CreateResolver("exception_findproxyforurl_during_init.js"));
eroman8df9fd802015-02-27 23:26:28303
sammcd2284e52015-05-27 03:14:46304 ASSERT_EQ(2U, bindings()->errors.size());
305 EXPECT_EQ("Uncaught crash!", bindings()->errors[0]);
306 EXPECT_EQ(9, bindings()->errors_line_number[0]);
eroman8df9fd802015-02-27 23:26:28307 EXPECT_EQ("Accessing FindProxyForURL threw an exception.",
sammcd2284e52015-05-27 03:14:46308 bindings()->errors[1]);
309 EXPECT_EQ(-1, bindings()->errors_line_number[1]);
eroman8df9fd802015-02-27 23:26:28310}
311
312// Execute a PAC script which throws an exception during the second access to
313// FindProxyForURL
sammcd2284e52015-05-27 03:14:46314TEST_F(ProxyResolverV8Test, ExceptionAccessingFindProxyForURLDuringResolve) {
robpercival214763f2016-07-01 23:27:01315 ASSERT_THAT(CreateResolver("exception_findproxyforurl_during_resolve.js"),
316 IsOk());
eroman8df9fd802015-02-27 23:26:28317
318 ProxyInfo proxy_info;
sammcd2284e52015-05-27 03:14:46319 int result = resolver().GetProxyForURL(kQueryUrl, &proxy_info, bindings());
eroman8df9fd802015-02-27 23:26:28320
robpercival214763f2016-07-01 23:27:01321 EXPECT_THAT(result, IsError(ERR_PAC_SCRIPT_FAILED));
eroman8df9fd802015-02-27 23:26:28322
sammcd2284e52015-05-27 03:14:46323 ASSERT_EQ(2U, bindings()->errors.size());
324 EXPECT_EQ("Uncaught crash!", bindings()->errors[0]);
325 EXPECT_EQ(17, bindings()->errors_line_number[0]);
eroman8df9fd802015-02-27 23:26:28326 EXPECT_EQ("Accessing FindProxyForURL threw an exception.",
sammcd2284e52015-05-27 03:14:46327 bindings()->errors[1]);
328 EXPECT_EQ(-1, bindings()->errors_line_number[1]);
eroman8df9fd802015-02-27 23:26:28329}
330
sammcd2284e52015-05-27 03:14:46331TEST_F(ProxyResolverV8Test, ReturnUnicode) {
robpercival214763f2016-07-01 23:27:01332 ASSERT_THAT(CreateResolver("return_unicode.js"), IsOk());
[email protected]943c8082009-02-23 19:10:45333
[email protected]52ae80c2009-09-10 21:27:00334 ProxyInfo proxy_info;
sammcd2284e52015-05-27 03:14:46335 int result = resolver().GetProxyForURL(kQueryUrl, &proxy_info, bindings());
[email protected]943c8082009-02-23 19:10:45336
337 // The result from this resolve was unparseable, because it
[email protected]51e413c2010-06-23 00:15:58338 // wasn't ASCII.
robpercival214763f2016-07-01 23:27:01339 EXPECT_THAT(result, IsError(ERR_PAC_SCRIPT_FAILED));
[email protected]943c8082009-02-23 19:10:45340}
341
[email protected]235786812011-12-20 02:15:31342// Test the PAC library functions that we expose in the JS environment.
sammcd2284e52015-05-27 03:14:46343TEST_F(ProxyResolverV8Test, JavascriptLibrary) {
robpercival214763f2016-07-01 23:27:01344 ASSERT_THAT(CreateResolver("pac_library_unittest.js"), IsOk());
[email protected]943c8082009-02-23 19:10:45345
[email protected]52ae80c2009-09-10 21:27:00346 ProxyInfo proxy_info;
sammcd2284e52015-05-27 03:14:46347 int result = resolver().GetProxyForURL(kQueryUrl, &proxy_info, bindings());
[email protected]943c8082009-02-23 19:10:45348
349 // If the javascript side of this unit-test fails, it will throw a javascript
350 // exception. Otherwise it will return "PROXY success:80".
Eric Roman9513f522018-04-04 23:49:47351 EXPECT_THAT(bindings()->alerts, IsEmpty());
352 EXPECT_THAT(bindings()->errors, IsEmpty());
[email protected]50d7d7282009-03-02 21:45:18353
Eric Roman9513f522018-04-04 23:49:47354 ASSERT_THAT(result, IsOk());
355 EXPECT_EQ("success:80", proxy_info.proxy_server().ToURI());
[email protected]50d7d7282009-03-02 21:45:18356}
357
358// Test marshalling/un-marshalling of values between C++/V8.
sammcd2284e52015-05-27 03:14:46359TEST_F(ProxyResolverV8Test, V8Bindings) {
robpercival214763f2016-07-01 23:27:01360 ASSERT_THAT(CreateResolver("bindings.js"), IsOk());
sammcd2284e52015-05-27 03:14:46361 bindings()->dns_resolve_result = "127.0.0.1";
[email protected]50d7d7282009-03-02 21:45:18362
[email protected]52ae80c2009-09-10 21:27:00363 ProxyInfo proxy_info;
sammcd2284e52015-05-27 03:14:46364 int result = resolver().GetProxyForURL(kQueryUrl, &proxy_info, bindings());
[email protected]50d7d7282009-03-02 21:45:18365
robpercival214763f2016-07-01 23:27:01366 EXPECT_THAT(result, IsOk());
[email protected]50d7d7282009-03-02 21:45:18367 EXPECT_TRUE(proxy_info.is_direct());
368
sammcd2284e52015-05-27 03:14:46369 EXPECT_EQ(0U, bindings()->errors.size());
[email protected]50d7d7282009-03-02 21:45:18370
371 // Alert was called 5 times.
sammcd2284e52015-05-27 03:14:46372 ASSERT_EQ(5U, bindings()->alerts.size());
373 EXPECT_EQ("undefined", bindings()->alerts[0]);
374 EXPECT_EQ("null", bindings()->alerts[1]);
375 EXPECT_EQ("undefined", bindings()->alerts[2]);
376 EXPECT_EQ("[object Object]", bindings()->alerts[3]);
377 EXPECT_EQ("exception from calling toString()", bindings()->alerts[4]);
[email protected]50d7d7282009-03-02 21:45:18378
[email protected]d35c3662010-05-05 20:04:34379 // DnsResolve was called 8 times, however only 2 of those were string
380 // parameters. (so 6 of them failed immediately).
sammcd2284e52015-05-27 03:14:46381 ASSERT_EQ(2U, bindings()->dns_resolves.size());
382 EXPECT_EQ("", bindings()->dns_resolves[0]);
383 EXPECT_EQ("arg1", bindings()->dns_resolves[1]);
[email protected]50d7d7282009-03-02 21:45:18384
385 // MyIpAddress was called two times.
sammcd2284e52015-05-27 03:14:46386 EXPECT_EQ(2, bindings()->my_ip_address_count);
[email protected]21f20c892009-10-26 23:51:28387
388 // MyIpAddressEx was called once.
sammcd2284e52015-05-27 03:14:46389 EXPECT_EQ(1, bindings()->my_ip_address_ex_count);
[email protected]21f20c892009-10-26 23:51:28390
391 // DnsResolveEx was called 2 times.
sammcd2284e52015-05-27 03:14:46392 ASSERT_EQ(2U, bindings()->dns_resolves_ex.size());
393 EXPECT_EQ("is_resolvable", bindings()->dns_resolves_ex[0]);
394 EXPECT_EQ("foobar", bindings()->dns_resolves_ex[1]);
[email protected]50d7d7282009-03-02 21:45:18395}
396
[email protected]a5e9f2c2010-03-31 22:10:11397// Test calling a binding (myIpAddress()) from the script's global scope.
398// http://crbug.com/40026
sammcd2284e52015-05-27 03:14:46399TEST_F(ProxyResolverV8Test, BindingCalledDuringInitialization) {
robpercival214763f2016-07-01 23:27:01400 ASSERT_THAT(CreateResolver("binding_from_global.js"), IsOk());
[email protected]a5e9f2c2010-03-31 22:10:11401
402 // myIpAddress() got called during initialization of the script.
sammcd2284e52015-05-27 03:14:46403 EXPECT_EQ(1, bindings()->my_ip_address_count);
[email protected]a5e9f2c2010-03-31 22:10:11404
405 ProxyInfo proxy_info;
sammcd2284e52015-05-27 03:14:46406 int result = resolver().GetProxyForURL(kQueryUrl, &proxy_info, bindings());
[email protected]a5e9f2c2010-03-31 22:10:11407
robpercival214763f2016-07-01 23:27:01408 EXPECT_THAT(result, IsOk());
[email protected]a5e9f2c2010-03-31 22:10:11409 EXPECT_FALSE(proxy_info.is_direct());
410 EXPECT_EQ("127.0.0.1:80", proxy_info.proxy_server().ToURI());
411
412 // Check that no other bindings were called.
sammcd2284e52015-05-27 03:14:46413 EXPECT_EQ(0U, bindings()->errors.size());
414 ASSERT_EQ(0U, bindings()->alerts.size());
415 ASSERT_EQ(0U, bindings()->dns_resolves.size());
416 EXPECT_EQ(0, bindings()->my_ip_address_ex_count);
417 ASSERT_EQ(0U, bindings()->dns_resolves_ex.size());
[email protected]a5e9f2c2010-03-31 22:10:11418}
419
[email protected]cd88b0c2009-09-25 04:52:39420// Try loading a PAC script that ends with a comment and has no terminal
421// newline. This should not cause problems with the PAC utility functions
422// that we add to the script's environment.
[email protected]c945a462009-09-24 02:13:57423// http://crbug.com/22864
sammcd2284e52015-05-27 03:14:46424TEST_F(ProxyResolverV8Test, EndsWithCommentNoNewline) {
robpercival214763f2016-07-01 23:27:01425 ASSERT_THAT(CreateResolver("ends_with_comment.js"), IsOk());
[email protected]c945a462009-09-24 02:13:57426
427 ProxyInfo proxy_info;
sammcd2284e52015-05-27 03:14:46428 int result = resolver().GetProxyForURL(kQueryUrl, &proxy_info, bindings());
[email protected]c945a462009-09-24 02:13:57429
robpercival214763f2016-07-01 23:27:01430 EXPECT_THAT(result, IsOk());
[email protected]c945a462009-09-24 02:13:57431 EXPECT_FALSE(proxy_info.is_direct());
432 EXPECT_EQ("success:80", proxy_info.proxy_server().ToURI());
433}
434
[email protected]cd88b0c2009-09-25 04:52:39435// Try loading a PAC script that ends with a statement and has no terminal
436// newline. This should not cause problems with the PAC utility functions
437// that we add to the script's environment.
438// http://crbug.com/22864
sammcd2284e52015-05-27 03:14:46439TEST_F(ProxyResolverV8Test, EndsWithStatementNoNewline) {
robpercival214763f2016-07-01 23:27:01440 ASSERT_THAT(CreateResolver("ends_with_statement_no_semicolon.js"), IsOk());
[email protected]cd88b0c2009-09-25 04:52:39441
442 ProxyInfo proxy_info;
sammcd2284e52015-05-27 03:14:46443 int result = resolver().GetProxyForURL(kQueryUrl, &proxy_info, bindings());
[email protected]cd88b0c2009-09-25 04:52:39444
robpercival214763f2016-07-01 23:27:01445 EXPECT_THAT(result, IsOk());
[email protected]cd88b0c2009-09-25 04:52:39446 EXPECT_FALSE(proxy_info.is_direct());
447 EXPECT_EQ("success:3", proxy_info.proxy_server().ToURI());
448}
449
[email protected]21f20c892009-10-26 23:51:28450// Test the return values from myIpAddress(), myIpAddressEx(), dnsResolve(),
451// dnsResolveEx(), isResolvable(), isResolvableEx(), when the the binding
452// returns empty string (failure). This simulates the return values from
453// those functions when the underlying DNS resolution fails.
sammcd2284e52015-05-27 03:14:46454TEST_F(ProxyResolverV8Test, DNSResolutionFailure) {
robpercival214763f2016-07-01 23:27:01455 ASSERT_THAT(CreateResolver("dns_fail.js"), IsOk());
[email protected]21f20c892009-10-26 23:51:28456
457 ProxyInfo proxy_info;
sammcd2284e52015-05-27 03:14:46458 int result = resolver().GetProxyForURL(kQueryUrl, &proxy_info, bindings());
[email protected]21f20c892009-10-26 23:51:28459
robpercival214763f2016-07-01 23:27:01460 EXPECT_THAT(result, IsOk());
[email protected]21f20c892009-10-26 23:51:28461 EXPECT_FALSE(proxy_info.is_direct());
462 EXPECT_EQ("success:80", proxy_info.proxy_server().ToURI());
463}
464
sammcd2284e52015-05-27 03:14:46465TEST_F(ProxyResolverV8Test, DNSResolutionOfInternationDomainName) {
robpercival214763f2016-07-01 23:27:01466 ASSERT_THAT(CreateResolver("international_domain_names.js"), IsOk());
[email protected]0238de42010-06-23 18:04:01467
468 // Execute FindProxyForURL().
469 ProxyInfo proxy_info;
sammcd2284e52015-05-27 03:14:46470 int result = resolver().GetProxyForURL(kQueryUrl, &proxy_info, bindings());
[email protected]0238de42010-06-23 18:04:01471
robpercival214763f2016-07-01 23:27:01472 EXPECT_THAT(result, IsOk());
[email protected]0238de42010-06-23 18:04:01473 EXPECT_TRUE(proxy_info.is_direct());
474
475 // Check that the international domain name was converted to punycode
476 // before passing it onto the bindings layer.
sammcd2284e52015-05-27 03:14:46477 ASSERT_EQ(1u, bindings()->dns_resolves.size());
478 EXPECT_EQ("xn--bcher-kva.ch", bindings()->dns_resolves[0]);
[email protected]0238de42010-06-23 18:04:01479
sammcd2284e52015-05-27 03:14:46480 ASSERT_EQ(1u, bindings()->dns_resolves_ex.size());
481 EXPECT_EQ("xn--bcher-kva.ch", bindings()->dns_resolves_ex[0]);
[email protected]0238de42010-06-23 18:04:01482}
483
[email protected]ad425c52012-02-11 00:05:31484// Test that when resolving a URL which contains an IPv6 string literal, the
485// brackets are removed from the host before passing it down to the PAC script.
486// If we don't do this, then subsequent calls to dnsResolveEx(host) will be
487// doomed to fail since it won't correspond with a valid name.
sammcd2284e52015-05-27 03:14:46488TEST_F(ProxyResolverV8Test, IPv6HostnamesNotBracketed) {
robpercival214763f2016-07-01 23:27:01489 ASSERT_THAT(CreateResolver("resolve_host.js"), IsOk());
[email protected]ad425c52012-02-11 00:05:31490
491 ProxyInfo proxy_info;
sammcd2284e52015-05-27 03:14:46492 int result = resolver().GetProxyForURL(
493 GURL("http://[abcd::efff]:99/watsupdawg"), &proxy_info, bindings());
[email protected]ad425c52012-02-11 00:05:31494
robpercival214763f2016-07-01 23:27:01495 EXPECT_THAT(result, IsOk());
[email protected]ad425c52012-02-11 00:05:31496 EXPECT_TRUE(proxy_info.is_direct());
497
498 // We called dnsResolveEx() exactly once, by passing through the "host"
499 // argument to FindProxyForURL(). The brackets should have been stripped.
sammcd2284e52015-05-27 03:14:46500 ASSERT_EQ(1U, bindings()->dns_resolves_ex.size());
501 EXPECT_EQ("abcd::efff", bindings()->dns_resolves_ex[0]);
[email protected]ad425c52012-02-11 00:05:31502}
503
[email protected]8cdc8812013-02-21 05:29:49504// Test that terminating a script within DnsResolve() leads to eventual
505// termination of the script. Also test that repeatedly calling terminate is
506// safe, and running the script again after termination still works.
sammcd2284e52015-05-27 03:14:46507TEST_F(ProxyResolverV8Test, Terminate) {
robpercival214763f2016-07-01 23:27:01508 ASSERT_THAT(CreateResolver("terminate.js"), IsOk());
[email protected]8cdc8812013-02-21 05:29:49509
510 // Terminate script execution upon reaching dnsResolve(). Note that
511 // termination may not take effect right away (so the subsequent dnsResolve()
512 // and alert() may be run).
sammcd2284e52015-05-27 03:14:46513 bindings()->should_terminate = true;
[email protected]8cdc8812013-02-21 05:29:49514
515 ProxyInfo proxy_info;
sammcd2284e52015-05-27 03:14:46516 int result =
517 resolver().GetProxyForURL(GURL("http://hang/"), &proxy_info, bindings());
[email protected]8cdc8812013-02-21 05:29:49518
519 // The script execution was terminated.
robpercival214763f2016-07-01 23:27:01520 EXPECT_THAT(result, IsError(ERR_PAC_SCRIPT_FAILED));
[email protected]8cdc8812013-02-21 05:29:49521
sammcd2284e52015-05-27 03:14:46522 EXPECT_EQ(1U, bindings()->dns_resolves.size());
523 EXPECT_GE(2U, bindings()->dns_resolves_ex.size());
524 EXPECT_GE(1U, bindings()->alerts.size());
[email protected]8cdc8812013-02-21 05:29:49525
sammcd2284e52015-05-27 03:14:46526 EXPECT_EQ(1U, bindings()->errors.size());
[email protected]8cdc8812013-02-21 05:29:49527
528 // Termination shows up as an uncaught exception without any message.
sammcd2284e52015-05-27 03:14:46529 EXPECT_EQ("", bindings()->errors[0]);
[email protected]8cdc8812013-02-21 05:29:49530
sammcd2284e52015-05-27 03:14:46531 bindings()->errors.clear();
[email protected]8cdc8812013-02-21 05:29:49532
533 // Try running the script again, this time with a different input which won't
534 // cause a termination+hang.
sammcd2284e52015-05-27 03:14:46535 result = resolver().GetProxyForURL(GURL("http://kittens/"), &proxy_info,
536 bindings());
[email protected]8cdc8812013-02-21 05:29:49537
robpercival214763f2016-07-01 23:27:01538 EXPECT_THAT(result, IsOk());
sammcd2284e52015-05-27 03:14:46539 EXPECT_EQ(0u, bindings()->errors.size());
[email protected]8cdc8812013-02-21 05:29:49540 EXPECT_EQ("kittens:88", proxy_info.proxy_server().ToURI());
541}
542
[email protected]52ae80c2009-09-10 21:27:00543} // namespace
544} // namespace net