File: proxy_resolution_service_provider_browsertest.cc

package info (click to toggle)
chromium 138.0.7204.183-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,080,960 kB
  • sloc: cpp: 34,937,079; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,954; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,811; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (230 lines) | stat: -rw-r--r-- 8,499 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/base64.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "chrome/browser/ash/dbus/proxy_resolution_service_provider.h"
#include "chrome/browser/ash/login/login_manager_test.h"
#include "chrome/browser/ash/login/test/login_manager_mixin.h"
#include "chrome/browser/ash/net/system_proxy_manager.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/mixin_based_in_process_browser_test.h"
#include "chrome/test/base/testing_browser_process.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test.h"

namespace ash {

namespace {

constexpr char kLocalProxyUrl[] = "localhost:3128";

// Encode the PAC script as a data: URL.
std::string GetPacUrl(const char* pac_data) {
  std::string b64_encoded = base::Base64Encode(pac_data);
  return "data:application/x-javascript-config;base64," + b64_encoded;
}
}  // namespace

// Helper for calling ProxyResolutionServiceProvider's |ResolveProxyInternal()|
// method. Unlike the unit-tests which mock the network setup, this uses the
// default dependencies from the running browser.
class ProxyResolutionServiceProviderTestWrapper {
 public:
  ProxyResolutionServiceProviderTestWrapper() {
    DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  }

  ProxyResolutionServiceProviderTestWrapper(
      const ProxyResolutionServiceProviderTestWrapper&) = delete;
  ProxyResolutionServiceProviderTestWrapper& operator=(
      const ProxyResolutionServiceProviderTestWrapper&) = delete;

  ~ProxyResolutionServiceProviderTestWrapper() {
    DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  }

  // Calls ResolveProxyInternal() and returns its result synchronously as a
  // single string (which may be prefixed by "ERROR: " if it is an error message
  // as opposed to a proxy result).
  std::string ResolveProxyAndWait(const std::string& url) {
    DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

    base::RunLoop run_loop;

    std::string result;
    impl_.ResolveProxyInternal(
        url,
        base::BindOnce(
            &ProxyResolutionServiceProviderTestWrapper::OnResolveProxyComplete,
            &result, run_loop.QuitClosure()),
        chromeos::SystemProxyOverride::kDefault);

    run_loop.Run();

    return result;
  }

 private:
  static void OnResolveProxyComplete(std::string* result,
                                     base::RepeatingClosure quit_closure,
                                     const std::string& error,
                                     const std::string& pac_string) {
    if (!error.empty()) {
      *result = "ERROR: " + error;
    } else {
      *result = pac_string;
    }

    std::move(quit_closure).Run();
  }

  ProxyResolutionServiceProvider impl_;
};

// Base test fixture that exposes a way to invoke ProxyResolutionServiceProvider
// synchronously from the UI thread.
class ProxyResolutionServiceProviderBaseBrowserTest
    : public MixinBasedInProcessBrowserTest {
 public:
  void SetUpOnMainThread() override {
    MixinBasedInProcessBrowserTest::SetUpOnMainThread();
    proxy_service_ =
        std::make_unique<ProxyResolutionServiceProviderTestWrapper>();
  }

  void TearDownOnMainThread() override {
    proxy_service_.reset();
    MixinBasedInProcessBrowserTest::TearDownOnMainThread();
  }

  std::string ResolveProxyAndWait(const std::string& source_url) {
    return proxy_service_->ResolveProxyAndWait(source_url);
  }

 private:
  std::unique_ptr<ProxyResolutionServiceProviderTestWrapper> proxy_service_;
};

// Fixture that launches the browser with --proxy-server="https://proxy.test".
class ProxyResolutionServiceProviderManualProxyBrowserTest
    : public ProxyResolutionServiceProviderBaseBrowserTest {
 public:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    command_line->AppendSwitchASCII(switches::kProxyServer,
                                    "https://proxy.test");
  }
};

// Tests that the D-Bus proxy resolver returns the correct result when using
// --proxy-server flag. These resolutions will happen synchronously at the //net
// layer.
IN_PROC_BROWSER_TEST_F(ProxyResolutionServiceProviderManualProxyBrowserTest,
                       ResolveProxy) {
  EXPECT_EQ("HTTPS proxy.test:443",
            ResolveProxyAndWait("http://www.google.com"));
}

// Simple PAC script that returns the same two proxies for all requests.
const char kPacData[] =
    "function FindProxyForURL(url, host) {\n"
    "  return 'PROXY foo1; PROXY foo2';\n"
    "}\n";

// Fixture that launches the browser with --proxy-pac-url="data:...".
class ProxyResolutionServiceProviderPacBrowserTest
    : public ProxyResolutionServiceProviderBaseBrowserTest {
 public:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    command_line->AppendSwitchASCII(switches::kProxyPacUrl,
                                    GetPacUrl(kPacData));
  }
};

// Tests that the D-Bus proxy resolver returns the correct result when using
// --proxy-pac-url flag. These resolutions will happen asynchronously at the
// //net layer, as they need to query a PAC script.
IN_PROC_BROWSER_TEST_F(ProxyResolutionServiceProviderPacBrowserTest,
                       ResolveProxy) {
  EXPECT_EQ("PROXY foo1:80;PROXY foo2:80",
            ResolveProxyAndWait("http://www.google.com"));
}

// PAC script that returns a proxy for all url except for a whitelisted domain.
const char kPacDataWithWhitelistedDomain[] =
    "function FindProxyForURL(url, host) {\n"
    "  if (dnsDomainIs(host, '.direct.com'))\n"
    "    return 'DIRECT';\n"
    "  return 'PROXY foo1';\n"
    "}\n";

// Fixture that launches the browser with --proxy-pac-url="data:..." and
// System-proxy enabled. With System-proxy enabled and configured, all system
// service connections going trough an http web proxy will be connected through
// a local proxy that will perform the proxy authentication and connection
// setup.
class ProxyResolutionServiceProviderSystemProxyPolicyTest
    : public ProxyResolutionServiceProviderBaseBrowserTest {
 public:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    command_line->AppendSwitchASCII(switches::kProxyPacUrl,
                                    GetPacUrl(kPacDataWithWhitelistedDomain));
  }

 protected:
  void SetLocalProxyAddress(const std::string& local_proxy_url) {
    SystemProxyManager::Get()->SetSystemProxyEnabledForTest(true);
    SystemProxyManager::Get()->SetSystemServicesProxyUrlForTest(
        local_proxy_url);
  }
};

// Tests that the proxy resolver returns the address of the local proxy when
// set.
IN_PROC_BROWSER_TEST_F(ProxyResolutionServiceProviderSystemProxyPolicyTest,
                       ResolveProxyLocalProxySet) {
  SetLocalProxyAddress(kLocalProxyUrl);
  EXPECT_EQ("PROXY localhost:3128; PROXY foo1:80",
            ResolveProxyAndWait("http://www.google.com"));
}

// Tests that the proxy list semicolon separator is not appended if the local
// proxy is not set.
IN_PROC_BROWSER_TEST_F(ProxyResolutionServiceProviderSystemProxyPolicyTest,
                       ResolveProxyNoSeparator) {
  SetLocalProxyAddress(/* local_proxy_url= */ std::string());
  EXPECT_EQ("PROXY foo1:80", ResolveProxyAndWait("http://www.google.com"));
}

// Tests that the proxy resolver doesn't return the local proxy address for
// DIRECT connections.
IN_PROC_BROWSER_TEST_F(ProxyResolutionServiceProviderSystemProxyPolicyTest,
                       ResolveProxyDirect) {
  SetLocalProxyAddress(kLocalProxyUrl);
  EXPECT_EQ("DIRECT", ResolveProxyAndWait("http://www.test.direct.com"));
}

class ProxyResolutionServiceAtLoginScreen
    : public ProxyResolutionServiceProviderBaseBrowserTest {
 public:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    command_line->AppendSwitchASCII(switches::kProxyPacUrl,
                                    GetPacUrl(kPacData));
  }

 protected:
  LoginManagerMixin login_manager_{&mixin_host_};
};

// Tests that the D-Bus proxy resolver returns the proxy configured at the
// sign-in screen.
IN_PROC_BROWSER_TEST_F(ProxyResolutionServiceAtLoginScreen, ResolveProxy) {
  EXPECT_EQ("PROXY foo1:80;PROXY foo2:80",
            ResolveProxyAndWait("http://www.google.com"));
}

}  // namespace ash