xref: /aosp_15_r20/external/cronet/net/docs/proxy.md (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker# Proxy support in Chrome
2*6777b538SAndroid Build Coastguard Worker
3*6777b538SAndroid Build Coastguard WorkerThis document establishes basic proxy terminology and describes Chrome-specific
4*6777b538SAndroid Build Coastguard Workerproxy behaviors.
5*6777b538SAndroid Build Coastguard Worker
6*6777b538SAndroid Build Coastguard Worker[TOC]
7*6777b538SAndroid Build Coastguard Worker
8*6777b538SAndroid Build Coastguard Worker## Proxy server identifiers
9*6777b538SAndroid Build Coastguard Worker
10*6777b538SAndroid Build Coastguard WorkerA proxy server is an intermediary used for network requests. A proxy server can
11*6777b538SAndroid Build Coastguard Workerbe described by its address, along with the proxy scheme that should be used to
12*6777b538SAndroid Build Coastguard Workercommunicate with it.
13*6777b538SAndroid Build Coastguard Worker
14*6777b538SAndroid Build Coastguard WorkerThis can be written as a string using either the "PAC format" or the "URI
15*6777b538SAndroid Build Coastguard Workerformat".
16*6777b538SAndroid Build Coastguard Worker
17*6777b538SAndroid Build Coastguard WorkerThe PAC format is how one names a proxy server in [Proxy
18*6777b538SAndroid Build Coastguard Workerauto-config](https://en.wikipedia.org/wiki/Proxy_auto-config) scripts. For
19*6777b538SAndroid Build Coastguard Workerexample:
20*6777b538SAndroid Build Coastguard Worker* `PROXY foo:2138`
21*6777b538SAndroid Build Coastguard Worker* `SOCKS5 foo:1080`
22*6777b538SAndroid Build Coastguard Worker* `DIRECT`
23*6777b538SAndroid Build Coastguard Worker
24*6777b538SAndroid Build Coastguard WorkerThe "URI format" instead encodes the information as a URL. For example:
25*6777b538SAndroid Build Coastguard Worker* `foo:2138`
26*6777b538SAndroid Build Coastguard Worker* `http://foo:2138`
27*6777b538SAndroid Build Coastguard Worker* `socks5://foo:1080`
28*6777b538SAndroid Build Coastguard Worker* `direct://`
29*6777b538SAndroid Build Coastguard Worker
30*6777b538SAndroid Build Coastguard WorkerThe port number is optional in both formats. When omitted, a per-scheme default
31*6777b538SAndroid Build Coastguard Workeris used.
32*6777b538SAndroid Build Coastguard Worker
33*6777b538SAndroid Build Coastguard WorkerSee the [Proxy server schemes](#Proxy-server-schemes) section for details on
34*6777b538SAndroid Build Coastguard Workerwhat schemes Chrome supports, and how to write them in the PAC and URI formats.
35*6777b538SAndroid Build Coastguard Worker
36*6777b538SAndroid Build Coastguard WorkerMost UI surfaces in Chrome (including command lines and policy) expect URI
37*6777b538SAndroid Build Coastguard Workerformatted proxy server identifiers. However outside of Chrome, proxy servers
38*6777b538SAndroid Build Coastguard Workerare generally identified less precisely by just an address -- the proxy
39*6777b538SAndroid Build Coastguard Workerscheme is assumed based on context.
40*6777b538SAndroid Build Coastguard Worker
41*6777b538SAndroid Build Coastguard WorkerIn Windows' proxy settings there are host and port fields for the
42*6777b538SAndroid Build Coastguard Worker"HTTP", "Secure", "FTP", and "SOCKS" proxy. With the exception of "SOCKS",
43*6777b538SAndroid Build Coastguard Workerthose are all identifiers for insecure HTTP proxy servers (proxy scheme is
44*6777b538SAndroid Build Coastguard Workerassumed as HTTP).
45*6777b538SAndroid Build Coastguard Worker
46*6777b538SAndroid Build Coastguard Worker## Proxy resolution
47*6777b538SAndroid Build Coastguard Worker
48*6777b538SAndroid Build Coastguard WorkerProxying in Chrome is done at the URL level.
49*6777b538SAndroid Build Coastguard Worker
50*6777b538SAndroid Build Coastguard WorkerWhen the browser is asked to fetch a URL, it needs to decide which IP endpoint
51*6777b538SAndroid Build Coastguard Workerto send the request to. This can be either a proxy server, or the target host.
52*6777b538SAndroid Build Coastguard Worker
53*6777b538SAndroid Build Coastguard WorkerThis is called proxy resolution. The input to proxy resolution is a URL, and
54*6777b538SAndroid Build Coastguard Workerthe output is an ordered list of [proxy server
55*6777b538SAndroid Build Coastguard Workeridentifiers](#Proxy-server-identifiers).
56*6777b538SAndroid Build Coastguard Worker
57*6777b538SAndroid Build Coastguard WorkerWhat proxies to use can be described using either:
58*6777b538SAndroid Build Coastguard Worker
59*6777b538SAndroid Build Coastguard Worker* [Manual proxy settings](#Manual-proxy-settings) - proxy resolution is defined
60*6777b538SAndroid Build Coastguard Worker  using a declarative set of rules. These rules are expressed as a mapping from
61*6777b538SAndroid Build Coastguard Worker  URL scheme to proxy server identifier(s), and a list of proxy bypass rules for
62*6777b538SAndroid Build Coastguard Worker  when to go DIRECT instead of using the mapped proxy.
63*6777b538SAndroid Build Coastguard Worker
64*6777b538SAndroid Build Coastguard Worker* PAC script - proxy resolution is defined using a JavaScript program, that is
65*6777b538SAndroid Build Coastguard Worker  invoked whenever fetching a URL to get the list of proxy server identifiers
66*6777b538SAndroid Build Coastguard Worker  to use.
67*6777b538SAndroid Build Coastguard Worker
68*6777b538SAndroid Build Coastguard Worker* Auto-detect - the WPAD protocol is used to probe the network (using DHCP/DNS)
69*6777b538SAndroid Build Coastguard Worker  and possibly discover the URL of a PAC script.
70*6777b538SAndroid Build Coastguard Worker
71*6777b538SAndroid Build Coastguard Worker## Proxy server schemes
72*6777b538SAndroid Build Coastguard Worker
73*6777b538SAndroid Build Coastguard WorkerWhen using an explicit proxy in the browser, multiple layers of the network
74*6777b538SAndroid Build Coastguard Workerrequest are impacted, depending on the scheme that is used. Some implications
75*6777b538SAndroid Build Coastguard Workerof the proxy scheme are:
76*6777b538SAndroid Build Coastguard Worker
77*6777b538SAndroid Build Coastguard Worker* Is communication to the proxy done over a secure channel?
78*6777b538SAndroid Build Coastguard Worker* Is name resolution (ex: DNS) done client side, or proxy side?
79*6777b538SAndroid Build Coastguard Worker* What authentication schemes to the proxy server are supported?
80*6777b538SAndroid Build Coastguard Worker* What network traffic can be sent through the proxy?
81*6777b538SAndroid Build Coastguard Worker
82*6777b538SAndroid Build Coastguard WorkerChrome supports these proxy server schemes:
83*6777b538SAndroid Build Coastguard Worker
84*6777b538SAndroid Build Coastguard Worker* [DIRECT](#DIRECT-proxy-scheme)
85*6777b538SAndroid Build Coastguard Worker* [HTTP](#HTTP-proxy-scheme)
86*6777b538SAndroid Build Coastguard Worker* [HTTPS](#HTTPS-proxy-scheme)
87*6777b538SAndroid Build Coastguard Worker* [SOCKSv4](#SOCKSv4-proxy-scheme)
88*6777b538SAndroid Build Coastguard Worker* [SOCKSv5](#SOCKSv5-proxy-scheme)
89*6777b538SAndroid Build Coastguard Worker* [QUIC](#QUIC-proxy-scheme)
90*6777b538SAndroid Build Coastguard Worker
91*6777b538SAndroid Build Coastguard Worker### DIRECT proxy scheme
92*6777b538SAndroid Build Coastguard Worker
93*6777b538SAndroid Build Coastguard Worker* Default port: N/A (neither host nor port are applicable)
94*6777b538SAndroid Build Coastguard Worker* Example identifier (PAC): `DIRECT`
95*6777b538SAndroid Build Coastguard Worker* Example identifier (URI): `direct://`
96*6777b538SAndroid Build Coastguard Worker
97*6777b538SAndroid Build Coastguard WorkerThis is a pseudo proxy scheme that indicates instead of using a proxy we are
98*6777b538SAndroid Build Coastguard Workersending the request directly to the target server.
99*6777b538SAndroid Build Coastguard Worker
100*6777b538SAndroid Build Coastguard WorkerIt is imprecise to call this a "proxy server", but it is a convenient abstraction.
101*6777b538SAndroid Build Coastguard Worker
102*6777b538SAndroid Build Coastguard Worker### HTTP proxy scheme
103*6777b538SAndroid Build Coastguard Worker
104*6777b538SAndroid Build Coastguard Worker* Default port: 80
105*6777b538SAndroid Build Coastguard Worker* Example identifier (PAC): `PROXY proxy:8080`, `proxy` (non-standard; don't use)
106*6777b538SAndroid Build Coastguard Worker* Example identifiers (URI): `http://proxy:8080`, `proxy:8080` (can omit scheme)
107*6777b538SAndroid Build Coastguard Worker
108*6777b538SAndroid Build Coastguard WorkerGenerally when one refers to a "proxy server" or "web proxy", they are talking
109*6777b538SAndroid Build Coastguard Workerabout an HTTP proxy.
110*6777b538SAndroid Build Coastguard Worker
111*6777b538SAndroid Build Coastguard WorkerWhen using an HTTP proxy in Chrome, name resolution is always deferred to the
112*6777b538SAndroid Build Coastguard Workerproxy. HTTP proxies can proxy `http://`, `https://`, `ws://` and `wss://` URLs.
113*6777b538SAndroid Build Coastguard Worker
114*6777b538SAndroid Build Coastguard WorkerCommunication to HTTP proxy servers is insecure, meaning proxied `http://`
115*6777b538SAndroid Build Coastguard Workerrequests are sent in the clear. When proxying `https://` requests through an
116*6777b538SAndroid Build Coastguard WorkerHTTP proxy, the TLS exchange is forwarded through the proxy using the `CONNECT`
117*6777b538SAndroid Build Coastguard Workermethod, so end-to-end encryption is not broken. However when establishing the
118*6777b538SAndroid Build Coastguard Workertunnel, the hostname of the target URL is sent to the proxy server in the
119*6777b538SAndroid Build Coastguard Workerclear.
120*6777b538SAndroid Build Coastguard Worker
121*6777b538SAndroid Build Coastguard WorkerHTTP proxies in Chrome support the same HTTP authentiation schemes as for
122*6777b538SAndroid Build Coastguard Workertarget servers: Basic, Digest, Negotiate, NTLM.
123*6777b538SAndroid Build Coastguard Worker
124*6777b538SAndroid Build Coastguard Worker### HTTPS proxy scheme
125*6777b538SAndroid Build Coastguard Worker
126*6777b538SAndroid Build Coastguard Worker* Default port: 443
127*6777b538SAndroid Build Coastguard Worker* Example identifier (PAC): `HTTPS proxy:8080`
128*6777b538SAndroid Build Coastguard Worker* Example identifier (URI): `https://proxy:8080`
129*6777b538SAndroid Build Coastguard Worker
130*6777b538SAndroid Build Coastguard WorkerThis works like an [HTTP proxy](#HTTP-proxy-scheme), except the
131*6777b538SAndroid Build Coastguard Workercommunication to the proxy server is protected by TLS, and may negotiate
132*6777b538SAndroid Build Coastguard WorkerHTTP/2 (but not QUIC).
133*6777b538SAndroid Build Coastguard Worker
134*6777b538SAndroid Build Coastguard WorkerBecause the connection to the proxy server is secure, https:// requests
135*6777b538SAndroid Build Coastguard Workersent through the proxy are not sent in the clear as with an HTTP proxy.
136*6777b538SAndroid Build Coastguard WorkerSimilarly, since CONNECT requests are sent over a protected channel, the
137*6777b538SAndroid Build Coastguard Workerhostnames for proxied https:// URLs is also not revealed.
138*6777b538SAndroid Build Coastguard Worker
139*6777b538SAndroid Build Coastguard WorkerIn addition to the usual HTTP authentication methods, HTTPS proxies also
140*6777b538SAndroid Build Coastguard Workersupport client certificates.
141*6777b538SAndroid Build Coastguard Worker
142*6777b538SAndroid Build Coastguard WorkerHTTPS proxies using HTTP/2 can offer better performance in Chrome than a
143*6777b538SAndroid Build Coastguard Workerregular HTTP proxy due to higher connection limits (HTTP/1.1 proxies in Chrome
144*6777b538SAndroid Build Coastguard Workerare limited to 32 simultaneous connections across all domains).
145*6777b538SAndroid Build Coastguard Worker
146*6777b538SAndroid Build Coastguard WorkerChrome, Firefox, and Opera support HTTPS proxies; however, most older HTTP
147*6777b538SAndroid Build Coastguard Workerstacks do not.
148*6777b538SAndroid Build Coastguard Worker
149*6777b538SAndroid Build Coastguard WorkerSpecifying an HTTPS proxy is generally not possible through system proxy
150*6777b538SAndroid Build Coastguard Workersettings. Instead, one must use either a PAC script or a Chrome proxy setting
151*6777b538SAndroid Build Coastguard Worker(command line, extension, or policy).
152*6777b538SAndroid Build Coastguard Worker
153*6777b538SAndroid Build Coastguard WorkerSee the dev.chromium.org document on [secure web
154*6777b538SAndroid Build Coastguard Workerproxies](http://dev.chromium.org/developers/design-documents/secure-web-proxy)
155*6777b538SAndroid Build Coastguard Workerfor tips on how to run and test against an HTTPS proxy.
156*6777b538SAndroid Build Coastguard Worker
157*6777b538SAndroid Build Coastguard Worker### SOCKSv4 proxy scheme
158*6777b538SAndroid Build Coastguard Worker
159*6777b538SAndroid Build Coastguard Worker* Default port: 1080
160*6777b538SAndroid Build Coastguard Worker* Example identifiers (PAC): `SOCKS4 proxy:8080`, `SOCKS proxy:8080`
161*6777b538SAndroid Build Coastguard Worker* Example identifier (URI): `socks4://proxy:8080`
162*6777b538SAndroid Build Coastguard Worker
163*6777b538SAndroid Build Coastguard WorkerSOCKSv4 is a simple transport layer proxy that wraps a TCP socket. Its use
164*6777b538SAndroid Build Coastguard Workeris transparent to the rest of the protocol stack; after an initial
165*6777b538SAndroid Build Coastguard Workerhandshake when connecting the TCP socket (to the proxy), the rest of the
166*6777b538SAndroid Build Coastguard Workerloading stack is unchanged.
167*6777b538SAndroid Build Coastguard Worker
168*6777b538SAndroid Build Coastguard WorkerNo proxy authentication methods are supported for SOCKSv4.
169*6777b538SAndroid Build Coastguard Worker
170*6777b538SAndroid Build Coastguard WorkerWhen using a SOCKSv4 proxy, name resolution for target hosts is always done
171*6777b538SAndroid Build Coastguard Workerclient side, and moreover must resolve to an IPv4 address (SOCKSv4 encodes
172*6777b538SAndroid Build Coastguard Workertarget address as 4 octets, so IPv6 targets are not possible).
173*6777b538SAndroid Build Coastguard Worker
174*6777b538SAndroid Build Coastguard WorkerThere are extensions to SOCKSv4 that allow for proxy side name resolution, and
175*6777b538SAndroid Build Coastguard WorkerIPv6, namely SOCKSv4a. However Chrome does not allow configuring, or falling
176*6777b538SAndroid Build Coastguard Workerback to v4a.
177*6777b538SAndroid Build Coastguard Worker
178*6777b538SAndroid Build Coastguard WorkerA better alternative is to just use the newer version of the protocol, SOCKSv5
179*6777b538SAndroid Build Coastguard Worker(which is still 20+ years old).
180*6777b538SAndroid Build Coastguard Worker
181*6777b538SAndroid Build Coastguard Worker### SOCKSv5 proxy scheme
182*6777b538SAndroid Build Coastguard Worker
183*6777b538SAndroid Build Coastguard Worker* Default port: 1080
184*6777b538SAndroid Build Coastguard Worker* Example identifier (PAC): `SOCKS5 proxy:8080`
185*6777b538SAndroid Build Coastguard Worker* Example identifiers (URI): `socks://proxy:8080`, `socks5://proxy:8080`
186*6777b538SAndroid Build Coastguard Worker
187*6777b538SAndroid Build Coastguard Worker[SOCKSv5](https://tools.ietf.org/html/rfc1928) is a transport layer proxy that
188*6777b538SAndroid Build Coastguard Workerwraps a TCP socket, and allows for name resolution to be deferred to the proxy.
189*6777b538SAndroid Build Coastguard Worker
190*6777b538SAndroid Build Coastguard WorkerIn Chrome when a proxy's scheme is set to SOCKSv5, name resolution is always
191*6777b538SAndroid Build Coastguard Workerdone proxy side (even though the protocol allows for client side as well). In
192*6777b538SAndroid Build Coastguard WorkerFirefox client side vs proxy side name resolution can be configured with
193*6777b538SAndroid Build Coastguard Worker`network.proxy.socks_remote_dns`; Chrome has no equivalent option and will
194*6777b538SAndroid Build Coastguard Workeralways use proxy side resolution.
195*6777b538SAndroid Build Coastguard Worker
196*6777b538SAndroid Build Coastguard WorkerNo authentication methods are supported for SOCKSv5 in Chrome (although some do
197*6777b538SAndroid Build Coastguard Workerexist for the protocol).
198*6777b538SAndroid Build Coastguard Worker
199*6777b538SAndroid Build Coastguard WorkerA handy way to create a SOCKSv5 proxy is with `ssh -D`, which can be used to
200*6777b538SAndroid Build Coastguard Workertunnel web traffic to a remote host over SSH.
201*6777b538SAndroid Build Coastguard Worker
202*6777b538SAndroid Build Coastguard WorkerIn Chrome SOCKSv5 is only used to proxy TCP-based URL requests. It cannot be
203*6777b538SAndroid Build Coastguard Workerused to relay UDP traffic.
204*6777b538SAndroid Build Coastguard Worker
205*6777b538SAndroid Build Coastguard Worker### QUIC proxy scheme
206*6777b538SAndroid Build Coastguard Worker
207*6777b538SAndroid Build Coastguard Worker* Default (UDP) port: 443
208*6777b538SAndroid Build Coastguard Worker* Example identifier (PAC): `QUIC proxy:8080`
209*6777b538SAndroid Build Coastguard Worker* Example identifier (URI): `quic://proxy:8080`
210*6777b538SAndroid Build Coastguard Worker
211*6777b538SAndroid Build Coastguard WorkerA QUIC proxy uses QUIC (UDP) as the underlying transport, but otherwise
212*6777b538SAndroid Build Coastguard Workerbehaves as an HTTP proxy. It has similar properties to an [HTTPS
213*6777b538SAndroid Build Coastguard Workerproxy](#HTTPS-proxy-scheme), in that the connection to the proxy server
214*6777b538SAndroid Build Coastguard Workeris secure, and connection limits are less restrictive.
215*6777b538SAndroid Build Coastguard Worker
216*6777b538SAndroid Build Coastguard WorkerSupport for QUIC proxies in Chrome is currently experimental and not
217*6777b538SAndroid Build Coastguard Workerready for production use. In particular, sending https:// and wss://
218*6777b538SAndroid Build Coastguard WorkerURLs through a QUIC proxy is [disabled by
219*6777b538SAndroid Build Coastguard Workerdefault](https://bugs.chromium.org/p/chromium/issues/detail?id=969859).
220*6777b538SAndroid Build Coastguard Worker
221*6777b538SAndroid Build Coastguard WorkerAnother caveat is that QUIC does not currently support
222*6777b538SAndroid Build Coastguard Workerclient certificates since it does not use a TLS
223*6777b538SAndroid Build Coastguard Workerhandshake. This may change in future versions.
224*6777b538SAndroid Build Coastguard Worker
225*6777b538SAndroid Build Coastguard Worker## Manual proxy settings
226*6777b538SAndroid Build Coastguard Worker
227*6777b538SAndroid Build Coastguard WorkerThe simplest way to configure proxy resolution is by providing a static list of
228*6777b538SAndroid Build Coastguard Workerrules comprised of:
229*6777b538SAndroid Build Coastguard Worker
230*6777b538SAndroid Build Coastguard Worker1. A mapping of URL schemes to [proxy server identifiers](#Proxy-server-identifiers).
231*6777b538SAndroid Build Coastguard Worker2. A list of [proxy bypass rules](#Proxy-bypass-rules)
232*6777b538SAndroid Build Coastguard Worker
233*6777b538SAndroid Build Coastguard WorkerWe refer to this mode of configuration as "manual proxy settings".
234*6777b538SAndroid Build Coastguard Worker
235*6777b538SAndroid Build Coastguard WorkerManual proxy settings can succinctly describe setups like:
236*6777b538SAndroid Build Coastguard Worker
237*6777b538SAndroid Build Coastguard Worker* Use proxy `http://foo:8080` for all requests
238*6777b538SAndroid Build Coastguard Worker* Use proxy `http://foo:8080` for all requests except those to a `google.com`
239*6777b538SAndroid Build Coastguard Worker  subdomain.
240*6777b538SAndroid Build Coastguard Worker* Use proxy `http://foo:8080` for all `https://` requests, and proxy
241*6777b538SAndroid Build Coastguard Worker  `socsk5://mysocks:90` for everything else
242*6777b538SAndroid Build Coastguard Worker
243*6777b538SAndroid Build Coastguard WorkerAlthough manual proxy settings are a ubiquituous way to configure proxies
244*6777b538SAndroid Build Coastguard Workeracross platforms, there is no standard representation or feature set.
245*6777b538SAndroid Build Coastguard Worker
246*6777b538SAndroid Build Coastguard WorkerChrome's manual proxy settings most closely resembles that of WinInet. But it
247*6777b538SAndroid Build Coastguard Workeralso supports idioms from other platforms -- for instance KDE's notion of
248*6777b538SAndroid Build Coastguard Workerreversing the bypass list, or Gnome's interpretation of bypass patterns as
249*6777b538SAndroid Build Coastguard Workersuffix matches.
250*6777b538SAndroid Build Coastguard Worker
251*6777b538SAndroid Build Coastguard WorkerWhen defining manual proxy settings in Chrome, we specify three (possibly
252*6777b538SAndroid Build Coastguard Workerempty) lists of [proxy server identifiers](#Proxy-server-identifiers).
253*6777b538SAndroid Build Coastguard Worker
254*6777b538SAndroid Build Coastguard Worker  * proxies for HTTP - A list of proxy server identifiers to use for `http://`
255*6777b538SAndroid Build Coastguard Worker    requests, if non-empty.
256*6777b538SAndroid Build Coastguard Worker  * proxies for HTTPS - A list of proxy server identifiers to use for
257*6777b538SAndroid Build Coastguard Worker    `https://` requests, if non-empty.
258*6777b538SAndroid Build Coastguard Worker  * other proxies - A list of proxy server identifiers to use for everything
259*6777b538SAndroid Build Coastguard Worker    else (whatever isn't matched by the other two lists)
260*6777b538SAndroid Build Coastguard Worker
261*6777b538SAndroid Build Coastguard WorkerThere are a lot of ways to end up with manual proxy settings in Chrome
262*6777b538SAndroid Build Coastguard Worker(discussed in other sections).
263*6777b538SAndroid Build Coastguard Worker
264*6777b538SAndroid Build Coastguard WorkerThe following examples will use the command line method. Launching Chrome with
265*6777b538SAndroid Build Coastguard Worker`--proxy-server=XXX` (and optionally `--proxy-bypass-list=YYY`)
266*6777b538SAndroid Build Coastguard Worker
267*6777b538SAndroid Build Coastguard WorkerExample: To use proxy `http://foo:8080` for all requests we can launch
268*6777b538SAndroid Build Coastguard WorkerChrome with `--proxy-server="http://foo:8080"`. This translates to:
269*6777b538SAndroid Build Coastguard Worker
270*6777b538SAndroid Build Coastguard Worker  * proxies for HTTP - *empty*
271*6777b538SAndroid Build Coastguard Worker  * proxies for HTTPS - *empty*
272*6777b538SAndroid Build Coastguard Worker  * other proxies - `http://foo:8080`
273*6777b538SAndroid Build Coastguard Worker
274*6777b538SAndroid Build Coastguard WorkerWith the above configuration, if the proxy server was unreachable all requests
275*6777b538SAndroid Build Coastguard Workerwould fail with `ERR_PROXY_CONNECTION_FAILED`. To address this we could add a
276*6777b538SAndroid Build Coastguard Workerfallback to `DIRECT` by launching using
277*6777b538SAndroid Build Coastguard Worker`--proxy-server="http://foo:8080,direct://"` (note the comma separated list).
278*6777b538SAndroid Build Coastguard WorkerThis command line means:
279*6777b538SAndroid Build Coastguard Worker
280*6777b538SAndroid Build Coastguard Worker  * proxies for HTTP - *empty*
281*6777b538SAndroid Build Coastguard Worker  * proxies for HTTPS - *empty*
282*6777b538SAndroid Build Coastguard Worker  * other proxies - `http://foo:8080`, `direct://`
283*6777b538SAndroid Build Coastguard Worker
284*6777b538SAndroid Build Coastguard WorkerIf instead we wanted to proxy only `http://` URLs through the
285*6777b538SAndroid Build Coastguard WorkerHTTPS proxy `https://foo:443`, and have everything else use the SOCKSv5 proxy
286*6777b538SAndroid Build Coastguard Worker`socks5://mysocks:1080` we could launch Chrome with
287*6777b538SAndroid Build Coastguard Worker`--proxy-server="http=https://foo:443;socks=socks5://mysocks:1080"`. This now
288*6777b538SAndroid Build Coastguard Workerexpands to:
289*6777b538SAndroid Build Coastguard Worker
290*6777b538SAndroid Build Coastguard Worker  * proxies for HTTP - `https://foo:443`
291*6777b538SAndroid Build Coastguard Worker  * proxies for HTTPS - *empty*
292*6777b538SAndroid Build Coastguard Worker  * other proxies - `socks5://mysocks:1080`
293*6777b538SAndroid Build Coastguard Worker
294*6777b538SAndroid Build Coastguard WorkerThe command line above uses WinInet's proxy map format, with some additional
295*6777b538SAndroid Build Coastguard Workerfeatures:
296*6777b538SAndroid Build Coastguard Worker
297*6777b538SAndroid Build Coastguard Worker* Instead of naming proxy servers by just a hostname:port, you can use Chrome's
298*6777b538SAndroid Build Coastguard Worker  URI format for proxy server identifiers. In other words, you can prefix the
299*6777b538SAndroid Build Coastguard Worker  proxy scheme so it doesn't default to HTTP.
300*6777b538SAndroid Build Coastguard Worker* The `socks=` mapping is understood more broadly as "other proxies". The
301*6777b538SAndroid Build Coastguard Worker  subsequent proxy list can include proxies of any scheme, however if the
302*6777b538SAndroid Build Coastguard Worker  scheme is omitted it will be understood as SOCKSv4 rather than HTTP.
303*6777b538SAndroid Build Coastguard Worker
304*6777b538SAndroid Build Coastguard Worker### Mapping WebSockets URLs to a proxy
305*6777b538SAndroid Build Coastguard Worker
306*6777b538SAndroid Build Coastguard Worker[Manual proxy settings](#Manual-proxy-settings) don't have mappings for `ws://`
307*6777b538SAndroid Build Coastguard Workeror `wss://` URLs.
308*6777b538SAndroid Build Coastguard Worker
309*6777b538SAndroid Build Coastguard WorkerSelecting a proxy for these URL schemes is a bit different from other URL
310*6777b538SAndroid Build Coastguard Workerschemes. The algorithm that Chrome uses is:
311*6777b538SAndroid Build Coastguard Worker
312*6777b538SAndroid Build Coastguard Worker* If "other proxies" is non-empty use it
313*6777b538SAndroid Build Coastguard Worker* If "proxies for HTTPS" is non-empty use it
314*6777b538SAndroid Build Coastguard Worker* Otherwise use "proxies for HTTP"
315*6777b538SAndroid Build Coastguard Worker
316*6777b538SAndroid Build Coastguard WorkerThis is per the recommendation in section 4.1.3 of [RFC
317*6777b538SAndroid Build Coastguard Worker6455](https://tools.ietf.org/html/rfc6455).
318*6777b538SAndroid Build Coastguard Worker
319*6777b538SAndroid Build Coastguard WorkerIt is possible to route `ws://` and `wss://` separately using a PAC script.
320*6777b538SAndroid Build Coastguard Worker
321*6777b538SAndroid Build Coastguard Worker### Proxy credentials in manual proxy settings
322*6777b538SAndroid Build Coastguard Worker
323*6777b538SAndroid Build Coastguard WorkerMost platforms' [manual proxy settings](#Manual-proxy-settings) allow
324*6777b538SAndroid Build Coastguard Workerspecifying a cleartext username/password for proxy sign in. Chrome does not
325*6777b538SAndroid Build Coastguard Workerimplement this, and will not use any credentials embedded in the proxy
326*6777b538SAndroid Build Coastguard Workersettings.
327*6777b538SAndroid Build Coastguard Worker
328*6777b538SAndroid Build Coastguard WorkerProxy authentication will instead go through the ordinary flow to find
329*6777b538SAndroid Build Coastguard Workercredentials.
330*6777b538SAndroid Build Coastguard Worker
331*6777b538SAndroid Build Coastguard Worker## Proxy bypass rules
332*6777b538SAndroid Build Coastguard Worker
333*6777b538SAndroid Build Coastguard WorkerIn addition to specifying three lists of [proxy server
334*6777b538SAndroid Build Coastguard Workeridentifiers](#proxy-server-identifiers), Chrome's [manual proxy
335*6777b538SAndroid Build Coastguard Workersettings](#Manual-proxy-settings) lets you specify a list of "proxy bypass
336*6777b538SAndroid Build Coastguard Workerrules".
337*6777b538SAndroid Build Coastguard Worker
338*6777b538SAndroid Build Coastguard WorkerThis ruleset determines whether a given URL should skip use of a proxy all
339*6777b538SAndroid Build Coastguard Workertogether, even when a proxy is otherwise defined for it.
340*6777b538SAndroid Build Coastguard Worker
341*6777b538SAndroid Build Coastguard WorkerThis concept is also known by names like "exception list", "exclusion list" or
342*6777b538SAndroid Build Coastguard Worker"no proxy list".
343*6777b538SAndroid Build Coastguard Worker
344*6777b538SAndroid Build Coastguard WorkerProxy bypass rules can be written as an ordered list of strings. Ordering
345*6777b538SAndroid Build Coastguard Workergenerally doesn't matter, but may when using subtractive rules.
346*6777b538SAndroid Build Coastguard Worker
347*6777b538SAndroid Build Coastguard WorkerWhen manual proxy settings are specified from the command line, the
348*6777b538SAndroid Build Coastguard Worker`--proxy-bypass-list="RULES"` switch can be used, where `RULES` is a semicolon
349*6777b538SAndroid Build Coastguard Workeror comma separated list of bypass rules.
350*6777b538SAndroid Build Coastguard Worker
351*6777b538SAndroid Build Coastguard WorkerFollowing are the string constructions for the bypass rules that Chrome
352*6777b538SAndroid Build Coastguard Workersupports. They can be used when defining a Chrome manual proxy settings from
353*6777b538SAndroid Build Coastguard Workercommand line flags, extensions, or policy.
354*6777b538SAndroid Build Coastguard Worker
355*6777b538SAndroid Build Coastguard WorkerWhen using system proxy settings, one should use the platform's rule format and
356*6777b538SAndroid Build Coastguard Workernot Chrome's.
357*6777b538SAndroid Build Coastguard Worker
358*6777b538SAndroid Build Coastguard Worker### Bypass rule: Hostname
359*6777b538SAndroid Build Coastguard Worker
360*6777b538SAndroid Build Coastguard Worker```
361*6777b538SAndroid Build Coastguard Worker[ URL_SCHEME "://" ] HOSTNAME_PATTERN [ ":" <port> ]
362*6777b538SAndroid Build Coastguard Worker```
363*6777b538SAndroid Build Coastguard Worker
364*6777b538SAndroid Build Coastguard WorkerMatches a hostname using a wildcard pattern, and an optional scheme and port
365*6777b538SAndroid Build Coastguard Workerrestriction.
366*6777b538SAndroid Build Coastguard Worker
367*6777b538SAndroid Build Coastguard WorkerExamples:
368*6777b538SAndroid Build Coastguard Worker
369*6777b538SAndroid Build Coastguard Worker* `foobar.com` - Matches URL of any scheme and port, whose normalized host is
370*6777b538SAndroid Build Coastguard Worker  `foobar.com`
371*6777b538SAndroid Build Coastguard Worker* `*foobar.com` - Matches URL of any scheme and port, whose normalized host
372*6777b538SAndroid Build Coastguard Worker  ends with `foobar.com` (for instance `blahfoobar.com` and `foo.foobar.com`).
373*6777b538SAndroid Build Coastguard Worker* `*.org:443` - Matches URLs of any scheme, using port 443 and whose top level
374*6777b538SAndroid Build Coastguard Worker  domain is `.org`
375*6777b538SAndroid Build Coastguard Worker* `https://x.*.y.com:99` - Matches https:// URLs on port 99 whose normalized
376*6777b538SAndroid Build Coastguard Worker  hostname matches `x.*.y.com`
377*6777b538SAndroid Build Coastguard Worker
378*6777b538SAndroid Build Coastguard Worker### Bypass rule: Subdomain
379*6777b538SAndroid Build Coastguard Worker
380*6777b538SAndroid Build Coastguard Worker```
381*6777b538SAndroid Build Coastguard Worker[ URL_SCHEME "://" ] "." HOSTNAME_SUFFIX_PATTERN [ ":" PORT ]
382*6777b538SAndroid Build Coastguard Worker```
383*6777b538SAndroid Build Coastguard Worker
384*6777b538SAndroid Build Coastguard WorkerHostname patterns that start with a dot are special cased to mean a subdomain
385*6777b538SAndroid Build Coastguard Workermatches. `.foo.com` is effectively another way of writing `*.foo.com`.
386*6777b538SAndroid Build Coastguard Worker
387*6777b538SAndroid Build Coastguard WorkerExamples:
388*6777b538SAndroid Build Coastguard Worker
389*6777b538SAndroid Build Coastguard Worker* `.google.com` - Matches `calendar.google.com` and `foo.bar.google.com`, but
390*6777b538SAndroid Build Coastguard Worker  not `google.com`.
391*6777b538SAndroid Build Coastguard Worker* `http://.google.com` - Matches only http:// URLs that are a subdomain of `google.com`.
392*6777b538SAndroid Build Coastguard Worker
393*6777b538SAndroid Build Coastguard Worker### Bypass rule: IP literal
394*6777b538SAndroid Build Coastguard Worker
395*6777b538SAndroid Build Coastguard Worker```
396*6777b538SAndroid Build Coastguard Worker[ SCHEME "://" ] IP_LITERAL [ ":" PORT ]
397*6777b538SAndroid Build Coastguard Worker```
398*6777b538SAndroid Build Coastguard Worker
399*6777b538SAndroid Build Coastguard WorkerMatches URLs that are IP address literals, and optional scheme and port
400*6777b538SAndroid Build Coastguard Workerrestrictions. This is a special case of hostname matching that takes into
401*6777b538SAndroid Build Coastguard Workeraccount IP literal canonicalization. For example the rules `[0:0:0::1]` and
402*6777b538SAndroid Build Coastguard Worker`[::1]` are equivalent (both represent the same IPv6 address).
403*6777b538SAndroid Build Coastguard Worker
404*6777b538SAndroid Build Coastguard WorkerExamples:
405*6777b538SAndroid Build Coastguard Worker
406*6777b538SAndroid Build Coastguard Worker* `127.0.0.1`
407*6777b538SAndroid Build Coastguard Worker* `http://127.0.0.1`
408*6777b538SAndroid Build Coastguard Worker* `[::1]` - Matches any URL to the IPv6 loopback address.
409*6777b538SAndroid Build Coastguard Worker* `[0:0::1]` - Same as above
410*6777b538SAndroid Build Coastguard Worker* `http://[::1]:99` - Matches any http:// URL to the IPv6 loopback on port 99
411*6777b538SAndroid Build Coastguard Worker
412*6777b538SAndroid Build Coastguard Worker### Bypass rule: IPv4 address range
413*6777b538SAndroid Build Coastguard Worker
414*6777b538SAndroid Build Coastguard Worker```
415*6777b538SAndroid Build Coastguard WorkerIPV4_LITERAL "/" PREFIX_LENGTH_IN_BITS
416*6777b538SAndroid Build Coastguard Worker```
417*6777b538SAndroid Build Coastguard Worker
418*6777b538SAndroid Build Coastguard WorkerMatches any URL whose hostname is an IPv4 literal, and falls between the given
419*6777b538SAndroid Build Coastguard Workeraddress range.
420*6777b538SAndroid Build Coastguard Worker
421*6777b538SAndroid Build Coastguard WorkerNote this [only applies to URLs that are IP
422*6777b538SAndroid Build Coastguard Workerliterals](#Meaning-of-IP-address-range-bypass-rules).
423*6777b538SAndroid Build Coastguard Worker
424*6777b538SAndroid Build Coastguard WorkerExamples:
425*6777b538SAndroid Build Coastguard Worker
426*6777b538SAndroid Build Coastguard Worker* `192.168.1.1/16`
427*6777b538SAndroid Build Coastguard Worker
428*6777b538SAndroid Build Coastguard Worker### Bypass rule: IPv6 address range
429*6777b538SAndroid Build Coastguard Worker
430*6777b538SAndroid Build Coastguard Worker```
431*6777b538SAndroid Build Coastguard WorkerIPV6_LITERAL "/" PREFIX_LENGTH_IN_BITS
432*6777b538SAndroid Build Coastguard Worker```
433*6777b538SAndroid Build Coastguard Worker
434*6777b538SAndroid Build Coastguard WorkerMatches any URL that is an IPv6 literal that falls between the given range.
435*6777b538SAndroid Build Coastguard WorkerNote that IPv6 literals must *not* be bracketed.
436*6777b538SAndroid Build Coastguard Worker
437*6777b538SAndroid Build Coastguard WorkerNote this [only applies to URLs that are IP
438*6777b538SAndroid Build Coastguard Workerliterals](#Meaning-of-IP-address-range-bypass-rules).
439*6777b538SAndroid Build Coastguard Worker
440*6777b538SAndroid Build Coastguard WorkerExamples:
441*6777b538SAndroid Build Coastguard Worker
442*6777b538SAndroid Build Coastguard Worker* `fefe:13::abc/33`
443*6777b538SAndroid Build Coastguard Worker* `[fefe::]/40` -- WRONG! IPv6 literals must not be bracketed.
444*6777b538SAndroid Build Coastguard Worker
445*6777b538SAndroid Build Coastguard Worker### Bypass rule: Simple hostnames
446*6777b538SAndroid Build Coastguard Worker
447*6777b538SAndroid Build Coastguard Worker```
448*6777b538SAndroid Build Coastguard Worker<local>
449*6777b538SAndroid Build Coastguard Worker```
450*6777b538SAndroid Build Coastguard Worker
451*6777b538SAndroid Build Coastguard WorkerMatches hostnames without a period in them, and that are not IP literals. This
452*6777b538SAndroid Build Coastguard Workeris a naive string search -- meaning that periods appearing *anywhere* count
453*6777b538SAndroid Build Coastguard Worker(including trailing dots!).
454*6777b538SAndroid Build Coastguard Worker
455*6777b538SAndroid Build Coastguard WorkerThis rule corresponds to the "Exclude simple hostnames" checkbox on macOS and
456*6777b538SAndroid Build Coastguard Workerthe "Don't use proxy server for local (intranet) addresses" on Windows.
457*6777b538SAndroid Build Coastguard Worker
458*6777b538SAndroid Build Coastguard WorkerThe rule name comes from WinInet, and can easily be confused with the concept
459*6777b538SAndroid Build Coastguard Workerof localhost. However the two concepts are completely orthogonal. In practice
460*6777b538SAndroid Build Coastguard Workerone wouldn't add rules to bypass localhost, as it is [already done
461*6777b538SAndroid Build Coastguard Workerimplicitly](#Implicit-bypass-rules).
462*6777b538SAndroid Build Coastguard Worker
463*6777b538SAndroid Build Coastguard Worker### Bypass rule: Subtract implicit rules
464*6777b538SAndroid Build Coastguard Worker
465*6777b538SAndroid Build Coastguard Worker```
466*6777b538SAndroid Build Coastguard Worker<-loopback>
467*6777b538SAndroid Build Coastguard Worker```
468*6777b538SAndroid Build Coastguard Worker
469*6777b538SAndroid Build Coastguard Worker*Subtracts* the [implicit proxy bypass rules](#Implicit-bypass-rules)
470*6777b538SAndroid Build Coastguard Worker(localhost and link local addresses). This is generally only needed for test
471*6777b538SAndroid Build Coastguard Workersetups. Beware of the security implications to proxying localhost.
472*6777b538SAndroid Build Coastguard Worker
473*6777b538SAndroid Build Coastguard WorkerWhereas regular bypass rules instruct the browser about URLs that should *not*
474*6777b538SAndroid Build Coastguard Workeruse the proxy, this rule has the opposite effect and tells the browser to
475*6777b538SAndroid Build Coastguard Workerinstead *use* the proxy.
476*6777b538SAndroid Build Coastguard Worker
477*6777b538SAndroid Build Coastguard WorkerOrdering may matter when using a subtractive rule, as rules will be evaluated
478*6777b538SAndroid Build Coastguard Workerin a left-to-right order. `<-loopback>;127.0.0.1` has a subtly different effect
479*6777b538SAndroid Build Coastguard Workerthan `127.0.0.1;<-loopback>`.
480*6777b538SAndroid Build Coastguard Worker
481*6777b538SAndroid Build Coastguard Worker### Meaning of IP address range bypass rules
482*6777b538SAndroid Build Coastguard Worker
483*6777b538SAndroid Build Coastguard WorkerThe IP address range bypass rules in manual proxy settings applies only to URL
484*6777b538SAndroid Build Coastguard Workerliterals. This is not what one would intuitively expect.
485*6777b538SAndroid Build Coastguard Worker
486*6777b538SAndroid Build Coastguard WorkerExample:
487*6777b538SAndroid Build Coastguard Worker
488*6777b538SAndroid Build Coastguard WorkerSay we have have configured a proxy for all requests, but added a bypass rule
489*6777b538SAndroid Build Coastguard Workerfor `192.168.0.0.1/16`. If we now navigate to `http://foo` (which resolves
490*6777b538SAndroid Build Coastguard Workerto `192.168.1.5` in our setup) will the browser connect directly (bypass proxy)
491*6777b538SAndroid Build Coastguard Workerbecause we have indicated a bypass rule that includes this IP?
492*6777b538SAndroid Build Coastguard Worker
493*6777b538SAndroid Build Coastguard WorkerIt will go through the proxy.
494*6777b538SAndroid Build Coastguard Worker
495*6777b538SAndroid Build Coastguard WorkerThe bypass rule in this case is not applicable, since the browser never
496*6777b538SAndroid Build Coastguard Workeractually does a name resolution for `foo`. Proxy resolution happens before
497*6777b538SAndroid Build Coastguard Workername resolution, and depending on what proxy scheme is subsequently chosen,
498*6777b538SAndroid Build Coastguard Workerclient side name resolution may never be performed.
499*6777b538SAndroid Build Coastguard Worker
500*6777b538SAndroid Build Coastguard WorkerThe usefulness of IP range proxy bypass rules is rather limited, as they only
501*6777b538SAndroid Build Coastguard Workerapply to requests whose URL was explicitly an IP literal.
502*6777b538SAndroid Build Coastguard Worker
503*6777b538SAndroid Build Coastguard WorkerIf proxy decisions need to be made based on the resolved IP address(es) of a
504*6777b538SAndroid Build Coastguard WorkerURL's hostname, one must use a PAC script.
505*6777b538SAndroid Build Coastguard Worker
506*6777b538SAndroid Build Coastguard Worker## Implicit bypass rules
507*6777b538SAndroid Build Coastguard Worker
508*6777b538SAndroid Build Coastguard WorkerRequests to certain hosts will not be sent through a proxy, and will instead be
509*6777b538SAndroid Build Coastguard Workersent directly.
510*6777b538SAndroid Build Coastguard Worker
511*6777b538SAndroid Build Coastguard WorkerWe call these the _implicit bypass rules_. The implicit bypass rules match URLs
512*6777b538SAndroid Build Coastguard Workerwhose host portion is either a localhost name or a link-local IP literal.
513*6777b538SAndroid Build Coastguard WorkerEssentially it matches:
514*6777b538SAndroid Build Coastguard Worker
515*6777b538SAndroid Build Coastguard Worker```
516*6777b538SAndroid Build Coastguard Workerlocalhost
517*6777b538SAndroid Build Coastguard Worker*.localhost
518*6777b538SAndroid Build Coastguard Worker[::1]
519*6777b538SAndroid Build Coastguard Worker127.0.0.1/8
520*6777b538SAndroid Build Coastguard Worker169.254/16
521*6777b538SAndroid Build Coastguard Worker[FE80::]/10
522*6777b538SAndroid Build Coastguard Worker```
523*6777b538SAndroid Build Coastguard Worker
524*6777b538SAndroid Build Coastguard WorkerThe complete rules are slightly more complicated. For instance on
525*6777b538SAndroid Build Coastguard WorkerWindows we will also recognize `loopback`.
526*6777b538SAndroid Build Coastguard Worker
527*6777b538SAndroid Build Coastguard WorkerThis concept of implicit proxy bypass rules is consistent with the
528*6777b538SAndroid Build Coastguard Workerplatform-level proxy support on Windows and macOS (albeit with some differences
529*6777b538SAndroid Build Coastguard Workerdue to their implementation quirks - see compatibility notes in
530*6777b538SAndroid Build Coastguard Worker`net::ProxyBypassRules::MatchesImplicitRules`)
531*6777b538SAndroid Build Coastguard Worker
532*6777b538SAndroid Build Coastguard WorkerWhy apply implicit proxy bypass rules in the first place? Certainly there are
533*6777b538SAndroid Build Coastguard Workerconsiderations around ergonomics and user expectation, but the bigger problem
534*6777b538SAndroid Build Coastguard Workeris security. Since the web platform treats `localhost` as a secure origin, the
535*6777b538SAndroid Build Coastguard Workerability to proxy it grants extra powers. This is [especially
536*6777b538SAndroid Build Coastguard Workerproblematic](https://bugs.chromium.org/p/chromium/issues/detail?id=899126) when
537*6777b538SAndroid Build Coastguard Workerproxy settings are externally controllable, as when using PAC scripts.
538*6777b538SAndroid Build Coastguard Worker
539*6777b538SAndroid Build Coastguard WorkerHistorical support in Chrome:
540*6777b538SAndroid Build Coastguard Worker
541*6777b538SAndroid Build Coastguard Worker* Prior to M71 there were no implicit proxy bypass rules, except if using
542*6777b538SAndroid Build Coastguard Worker  [`--winhttp-proxy-resolver`](#winhttp_proxy_resolver-command-line-switch).
543*6777b538SAndroid Build Coastguard Worker* In M71 Chrome applied implicit proxy bypass rules to PAC scripts
544*6777b538SAndroid Build Coastguard Worker* In M72 Chrome generalized the implicit proxy bypass rules to manually
545*6777b538SAndroid Build Coastguard Worker  configured proxies
546*6777b538SAndroid Build Coastguard Worker
547*6777b538SAndroid Build Coastguard Worker### Overriding the implicit bypass rules
548*6777b538SAndroid Build Coastguard Worker
549*6777b538SAndroid Build Coastguard WorkerIf you want traffic to `localhost` to be sent through a proxy despite the
550*6777b538SAndroid Build Coastguard Workersecurity concerns, it can be done by adding the special proxy bypass rule
551*6777b538SAndroid Build Coastguard Worker`<-loopback>`. This has the effect of _subtracting_ the implicit rules.
552*6777b538SAndroid Build Coastguard Worker
553*6777b538SAndroid Build Coastguard WorkerFor instance, launch Chrome with the command line flag:
554*6777b538SAndroid Build Coastguard Worker
555*6777b538SAndroid Build Coastguard Worker```
556*6777b538SAndroid Build Coastguard Worker--proxy-bypass-list="<-loopback>"
557*6777b538SAndroid Build Coastguard Worker```
558*6777b538SAndroid Build Coastguard Worker
559*6777b538SAndroid Build Coastguard WorkerNote that there currently is no mechanism to disable the implicit proxy bypass
560*6777b538SAndroid Build Coastguard Workerrules when using a PAC script. Proxy bypass lists only apply to manual
561*6777b538SAndroid Build Coastguard Workersettings, so the technique above cannot be used to let PAC scripts decide the
562*6777b538SAndroid Build Coastguard Workerproxy for localhost URLs.
563*6777b538SAndroid Build Coastguard Worker
564*6777b538SAndroid Build Coastguard Worker## Evaluating proxy lists (proxy fallback)
565*6777b538SAndroid Build Coastguard Worker
566*6777b538SAndroid Build Coastguard WorkerProxy resolution results in a _list_ of [proxy server
567*6777b538SAndroid Build Coastguard Workeridentifiers](#Proxy-server-identifiers) to use for a
568*6777b538SAndroid Build Coastguard Workergiven request, not just a single proxy server identifier.
569*6777b538SAndroid Build Coastguard Worker
570*6777b538SAndroid Build Coastguard WorkerFor instance, consider this PAC script:
571*6777b538SAndroid Build Coastguard Worker
572*6777b538SAndroid Build Coastguard Worker```
573*6777b538SAndroid Build Coastguard Workerfunction FindProxyForURL(url, host) {
574*6777b538SAndroid Build Coastguard Worker    if (host == "www.example.com") {
575*6777b538SAndroid Build Coastguard Worker        return "PROXY proxy1; HTTPS proxy2; SOCKS5 proxy3";
576*6777b538SAndroid Build Coastguard Worker    }
577*6777b538SAndroid Build Coastguard Worker    return "DIRECT";
578*6777b538SAndroid Build Coastguard Worker}
579*6777b538SAndroid Build Coastguard Worker
580*6777b538SAndroid Build Coastguard Worker```
581*6777b538SAndroid Build Coastguard Worker
582*6777b538SAndroid Build Coastguard WorkerWhat proxy will Chrome use for connections to `www.example.com`, given that
583*6777b538SAndroid Build Coastguard Workerwe have a choice of three separate proxy server identifiers to choose from
584*6777b538SAndroid Build Coastguard Worker{`http://proxy1:80`, `https://proxy2:443`, `socks5://proxy3:1080`}?
585*6777b538SAndroid Build Coastguard Worker
586*6777b538SAndroid Build Coastguard WorkerInitially, Chrome will try the proxies in order. This means first attempting
587*6777b538SAndroid Build Coastguard Workerthe request through `http://proxy1:80`. If that "fails", the request is
588*6777b538SAndroid Build Coastguard Workernext attempted through `https://proxy2:443`. Lastly if that fails, the
589*6777b538SAndroid Build Coastguard Workerrequest is attempted through `socks5://proxy3:1080`.
590*6777b538SAndroid Build Coastguard Worker
591*6777b538SAndroid Build Coastguard WorkerThis process is referred to as _proxy fallback_. What constitutes a
592*6777b538SAndroid Build Coastguard Worker"failure" is described later.
593*6777b538SAndroid Build Coastguard Worker
594*6777b538SAndroid Build Coastguard WorkerProxy fallback is stateful. The actual order of proxy attempts made be Chrome
595*6777b538SAndroid Build Coastguard Workeris influenced by the past responsiveness of proxy servers.
596*6777b538SAndroid Build Coastguard Worker
597*6777b538SAndroid Build Coastguard WorkerLet's say we request `http://www.example.com/`. Per the PAC script this
598*6777b538SAndroid Build Coastguard Workerresolves to a list of three proxy server identifiers:
599*6777b538SAndroid Build Coastguard Worker
600*6777b538SAndroid Build Coastguard Worker{`http://proxy1:80`, `https://proxy2:443`, `socks5://proxy3:1080`}
601*6777b538SAndroid Build Coastguard Worker
602*6777b538SAndroid Build Coastguard WorkerChrome will first attempt to issue the request through these proxies in the
603*6777b538SAndroid Build Coastguard Workerleft-to-right order.
604*6777b538SAndroid Build Coastguard Worker
605*6777b538SAndroid Build Coastguard WorkerLet's say that the attempt through `http://proxy1:80` fails, but then the
606*6777b538SAndroid Build Coastguard Workerattempt through `https://proxy2:443` succeeds. Chrome will mark
607*6777b538SAndroid Build Coastguard Worker`http://proxy1:80` as _bad_ for the next 5 minutes. Being marked as _bad_
608*6777b538SAndroid Build Coastguard Workermeans that `http://proxy1:80` is de-prioritized with respect to
609*6777b538SAndroid Build Coastguard Workerother proxy server identifiers (including `direct://`) that are not marked as
610*6777b538SAndroid Build Coastguard Workerbad.
611*6777b538SAndroid Build Coastguard Worker
612*6777b538SAndroid Build Coastguard WorkerThat means the next time `http://www.example.com/` is requested, the effective
613*6777b538SAndroid Build Coastguard Workerorder for proxies to attempt will be:
614*6777b538SAndroid Build Coastguard Worker
615*6777b538SAndroid Build Coastguard Worker{`https://proxy2:443`, `socks5://proxy3:1080`, `http://proxy1:80`}
616*6777b538SAndroid Build Coastguard Worker
617*6777b538SAndroid Build Coastguard WorkerConceptually, _bad_ proxies are moved to the end of the list, rather than being
618*6777b538SAndroid Build Coastguard Workerremoved from consideration all together.
619*6777b538SAndroid Build Coastguard Worker
620*6777b538SAndroid Build Coastguard WorkerWhat constitutes a "failure" when it comes to triggering proxy fallback depends
621*6777b538SAndroid Build Coastguard Workeron the proxy type. Generally speaking, only connection level failures
622*6777b538SAndroid Build Coastguard Workerare deemed eligible for proxy fallback. This includes:
623*6777b538SAndroid Build Coastguard Worker
624*6777b538SAndroid Build Coastguard Worker* Failure resolving the proxy server's DNS
625*6777b538SAndroid Build Coastguard Worker* Failure connecting a TCP socket to the proxy server
626*6777b538SAndroid Build Coastguard Worker
627*6777b538SAndroid Build Coastguard Worker(There are some caveats for how HTTPS and QUIC proxies count failures for
628*6777b538SAndroid Build Coastguard Workerfallback)
629*6777b538SAndroid Build Coastguard Worker
630*6777b538SAndroid Build Coastguard WorkerPrior to M67, Chrome would consider failures establishing a
631*6777b538SAndroid Build Coastguard WorkerCONNECT tunnel as an error eligible for proxy fallback. This policy [resulted
632*6777b538SAndroid Build Coastguard Workerin problems](https://bugs.chromium.org/p/chromium/issues/detail?id=680837) for
633*6777b538SAndroid Build Coastguard Workerdeployments whose HTTP proxies intentionally failed certain https:// requests,
634*6777b538SAndroid Build Coastguard Workersince that necessitates inducing a failure during the CONNECT tunnel
635*6777b538SAndroid Build Coastguard Workerestablishment. The problem would occur when a working proxy fallback option
636*6777b538SAndroid Build Coastguard Workerlike DIRECT was given, since the failing proxy would then be marked as bad.
637*6777b538SAndroid Build Coastguard Worker
638*6777b538SAndroid Build Coastguard WorkerCurrently there are no options to configure proxy fallback (including disabling
639*6777b538SAndroid Build Coastguard Workerthe caching of bad proxies). Future versions of Chrome may [remove caching
640*6777b538SAndroid Build Coastguard Workerof bad proxies](https://bugs.chromium.org/p/chromium/issues/detail?id=936130)
641*6777b538SAndroid Build Coastguard Workerto make fallback predictable.
642*6777b538SAndroid Build Coastguard Worker
643*6777b538SAndroid Build Coastguard WorkerTo investigate issues relating to proxy fallback, one can [collect a NetLog
644*6777b538SAndroid Build Coastguard Workerdump using
645*6777b538SAndroid Build Coastguard Workerchrome://net-export/](https://dev.chromium.org/for-testers/providing-network-details).
646*6777b538SAndroid Build Coastguard WorkerThese logs can then be loaded with the [NetLog
647*6777b538SAndroid Build Coastguard Workerviewer](https://netlog-viewer.appspot.com/).
648*6777b538SAndroid Build Coastguard Worker
649*6777b538SAndroid Build Coastguard WorkerThere are a few things of interest in the logs:
650*6777b538SAndroid Build Coastguard Worker
651*6777b538SAndroid Build Coastguard Worker* The "Proxy" tab will show which proxies (if any) were marked as bad at the
652*6777b538SAndroid Build Coastguard Worker  time the capture ended.
653*6777b538SAndroid Build Coastguard Worker* The "Events" tab notes what the resolved proxy list was, and what the
654*6777b538SAndroid Build Coastguard Worker  re-ordered proxy list was after taking into account bad proxies.
655*6777b538SAndroid Build Coastguard Worker* The "Events" tab notes when a proxy is marked as bad and why (provided the
656*6777b538SAndroid Build Coastguard Worker  event occurred while capturing was enabled).
657*6777b538SAndroid Build Coastguard Worker
658*6777b538SAndroid Build Coastguard WorkerWhen debugging issues with bad proxies, it is also useful to reset Chrome's
659*6777b538SAndroid Build Coastguard Workercache of bad proxies. This can be done by clicking the "Clear bad proxies"
660*6777b538SAndroid Build Coastguard Workerbutton on
661*6777b538SAndroid Build Coastguard Worker[chrome://net-internals/#proxy](chrome://net-internals/#proxy). Note the UI
662*6777b538SAndroid Build Coastguard Workerwill not give feedback that the bad proxies were cleared, however capturing a
663*6777b538SAndroid Build Coastguard Workernew NetLog dump can confirm it was cleared.
664*6777b538SAndroid Build Coastguard Worker
665*6777b538SAndroid Build Coastguard Worker## Arguments passed to FindProxyForURL() in PAC scripts
666*6777b538SAndroid Build Coastguard Worker
667*6777b538SAndroid Build Coastguard WorkerPAC scripts in Chrome are expected to define a JavaScript function
668*6777b538SAndroid Build Coastguard Worker`FindProxyForURL`.
669*6777b538SAndroid Build Coastguard Worker
670*6777b538SAndroid Build Coastguard WorkerThe historical signature for this function is:
671*6777b538SAndroid Build Coastguard Worker
672*6777b538SAndroid Build Coastguard Worker```
673*6777b538SAndroid Build Coastguard Workerfunction FindProxyForURL(url, host) {
674*6777b538SAndroid Build Coastguard Worker  ...
675*6777b538SAndroid Build Coastguard Worker}
676*6777b538SAndroid Build Coastguard Worker```
677*6777b538SAndroid Build Coastguard Worker
678*6777b538SAndroid Build Coastguard WorkerScripts can expect to be called with string arguments `url` and `host` such
679*6777b538SAndroid Build Coastguard Workerthat:
680*6777b538SAndroid Build Coastguard Worker
681*6777b538SAndroid Build Coastguard Worker* `url` is a *sanitized* version of the request's URL
682*6777b538SAndroid Build Coastguard Worker* `host` is the unbracketed host portion of the origin.
683*6777b538SAndroid Build Coastguard Worker
684*6777b538SAndroid Build Coastguard WorkerSanitization of the URL means that the path, query, fragment, and identity
685*6777b538SAndroid Build Coastguard Workerportions of the URL are stripped. Effectively `url` will be
686*6777b538SAndroid Build Coastguard Workerlimited to a `scheme://host:port/` style URL
687*6777b538SAndroid Build Coastguard Worker
688*6777b538SAndroid Build Coastguard WorkerExamples of how `FindProxyForURL()` will be called:
689*6777b538SAndroid Build Coastguard Worker
690*6777b538SAndroid Build Coastguard Worker```
691*6777b538SAndroid Build Coastguard Worker// Actual URL:   https://www.google.com/Foo
692*6777b538SAndroid Build Coastguard WorkerFindProxyForURL('https://www.google.com/', 'www.google.com')
693*6777b538SAndroid Build Coastguard Worker
694*6777b538SAndroid Build Coastguard Worker// Actual URL:   https://[dead::beef]/foo?bar
695*6777b538SAndroid Build Coastguard WorkerFindProxyForURL('https://[dead::beef]/', 'dead::beef')
696*6777b538SAndroid Build Coastguard Worker
697*6777b538SAndroid Build Coastguard Worker// Actual URL:   https://www.example.com:8080#search
698*6777b538SAndroid Build Coastguard WorkerFindProxyForURL('https://www.example.com:8080/', 'example.com')
699*6777b538SAndroid Build Coastguard Worker
700*6777b538SAndroid Build Coastguard Worker// Actual URL:   https://username:[email protected]
701*6777b538SAndroid Build Coastguard WorkerFindProxyForURL('https://www.example.com/', 'example.com')
702*6777b538SAndroid Build Coastguard Worker```
703*6777b538SAndroid Build Coastguard Worker
704*6777b538SAndroid Build Coastguard WorkerStripping the path and query from the `url` is a departure from the original
705*6777b538SAndroid Build Coastguard WorkerNetscape implementation of PAC. It was introduced in Chrome 52 for [security
706*6777b538SAndroid Build Coastguard Workerreasons](https://bugs.chromium.org/p/chromium/issues/detail?id=593759).
707*6777b538SAndroid Build Coastguard Worker
708*6777b538SAndroid Build Coastguard WorkerThere is currently no option to turn off sanitization of URLs passed to PAC
709*6777b538SAndroid Build Coastguard Workerscripts (removed in Chrome 75).
710*6777b538SAndroid Build Coastguard Worker
711*6777b538SAndroid Build Coastguard WorkerThe sanitization of http:// URLs currently has a different policy, and does not
712*6777b538SAndroid Build Coastguard Workerstrip query and path portions of the URL. That said, users are advised not to
713*6777b538SAndroid Build Coastguard Workerdepend on reading the query/path portion of any URL
714*6777b538SAndroid Build Coastguard Workertype, since future versions of Chrome may [deprecate that
715*6777b538SAndroid Build Coastguard Workercapability](https://bugs.chromium.org/p/chromium/issues/detail?id=882536) in
716*6777b538SAndroid Build Coastguard Workerfavor of a consistent policy.
717*6777b538SAndroid Build Coastguard Worker
718*6777b538SAndroid Build Coastguard Worker## Resolving client's IP address within a PAC script using myIpAddress()
719*6777b538SAndroid Build Coastguard Worker
720*6777b538SAndroid Build Coastguard WorkerPAC scripts can invoke `myIpAddress()` to obtain the client's IP address. This
721*6777b538SAndroid Build Coastguard Workerfunction returns a single IP literal, or `"127.0.0.1"` on failure.
722*6777b538SAndroid Build Coastguard Worker
723*6777b538SAndroid Build Coastguard WorkerThis API is [inherently ambiguous when used on multi-homed
724*6777b538SAndroid Build Coastguard Workerhosts](#myIpAddress_myIpAddressEx_and-multi_homed-hosts), as such hosts can
725*6777b538SAndroid Build Coastguard Workerhave multiple IP addresses and yet the browser can pick just one to return.
726*6777b538SAndroid Build Coastguard Worker
727*6777b538SAndroid Build Coastguard WorkerChrome's algorithm for `myIpAddress()` favors returning the IP that would be
728*6777b538SAndroid Build Coastguard Workerused if we were to connect to the public internet, by executing the following
729*6777b538SAndroid Build Coastguard Workerordered steps and short-circuiting once the first candidate IP is found:
730*6777b538SAndroid Build Coastguard Worker
731*6777b538SAndroid Build Coastguard Worker1. Select the IP of an interface that can route to public Internet:
732*6777b538SAndroid Build Coastguard Worker    * Probe for route to `8.8.8.8`.
733*6777b538SAndroid Build Coastguard Worker    * Probe for route to `2001:4860:4860::8888`.
734*6777b538SAndroid Build Coastguard Worker2. Select an IP by doing a DNS resolve of the machine's hostname:
735*6777b538SAndroid Build Coastguard Worker    * Select the first IPv4 result if there is one.
736*6777b538SAndroid Build Coastguard Worker    * Select the first IP result if there is one.
737*6777b538SAndroid Build Coastguard Worker3. Select the IP of an interface that can route to private IP space:
738*6777b538SAndroid Build Coastguard Worker    * Probe for route to `10.0.0.0`.
739*6777b538SAndroid Build Coastguard Worker    * Probe for route to `172.16.0.0`.
740*6777b538SAndroid Build Coastguard Worker    * Probe for route to `192.168.0.0`.
741*6777b538SAndroid Build Coastguard Worker    * Probe for route to `FC00::`.
742*6777b538SAndroid Build Coastguard Worker
743*6777b538SAndroid Build Coastguard WorkerNote that when searching for candidate IP addresses, link-local and loopback
744*6777b538SAndroid Build Coastguard Workeraddresses are skipped over. Link-local or loopback address will only be returned as a
745*6777b538SAndroid Build Coastguard Workerlast resort when no other IP address was found by following these steps.
746*6777b538SAndroid Build Coastguard Worker
747*6777b538SAndroid Build Coastguard WorkerThis sequence of steps explicitly favors IPv4 over IPv6 results, to match
748*6777b538SAndroid Build Coastguard WorkerInternet Explorer's IPv6 support.
749*6777b538SAndroid Build Coastguard Worker
750*6777b538SAndroid Build Coastguard Worker*Historical note*: Prior to M72, Chrome's implementation of `myIpAddress()` was
751*6777b538SAndroid Build Coastguard Workereffectively just `getaddrinfo(gethostname)`. This is now step 2 of the heuristic.
752*6777b538SAndroid Build Coastguard Worker
753*6777b538SAndroid Build Coastguard Worker## Resolving client's IP address within a PAC script using myIpAddressEx()
754*6777b538SAndroid Build Coastguard Worker
755*6777b538SAndroid Build Coastguard WorkerChrome supports the [Microsoft PAC
756*6777b538SAndroid Build Coastguard Workerextension](https://docs.microsoft.com/en-us/windows/desktop/winhttp/myipaddressex)
757*6777b538SAndroid Build Coastguard Worker`myIpAddressEx()`.
758*6777b538SAndroid Build Coastguard Worker
759*6777b538SAndroid Build Coastguard WorkerThis is like `myIpAddress()`, but instead of returning a single IP address, it
760*6777b538SAndroid Build Coastguard Workercan return multiple IP addresses. It returns a string containing a semi-colon
761*6777b538SAndroid Build Coastguard Workerseparated list of addresses. On failure it returns an empty string to indicate
762*6777b538SAndroid Build Coastguard Workerno results (whereas `myIpAddress()` returns `127.0.0.1`).
763*6777b538SAndroid Build Coastguard Worker
764*6777b538SAndroid Build Coastguard WorkerThere are some differences with Chrome's implementation:
765*6777b538SAndroid Build Coastguard Worker
766*6777b538SAndroid Build Coastguard Worker* In Chrome the function is unconditionally defined, whereas in Internet
767*6777b538SAndroid Build Coastguard Worker  Explorer one must have used the `FindProxyForURLEx` entrypoint.
768*6777b538SAndroid Build Coastguard Worker* Chrome [does not necessarily enumerate all of the host's network
769*6777b538SAndroid Build Coastguard Worker  interfaces](#myIpAddress_myIpAddressEx_and-multi_homed-hosts)
770*6777b538SAndroid Build Coastguard Worker* Chrome does not return link-local or loopback addresses (except if no other
771*6777b538SAndroid Build Coastguard Worker  addresses were found).
772*6777b538SAndroid Build Coastguard Worker
773*6777b538SAndroid Build Coastguard WorkerThe algorithm that Chrome uses is nearly identical to that of `myIpAddress()`
774*6777b538SAndroid Build Coastguard Workerdescribed earlier, but in certain cases may return multiple IPs.
775*6777b538SAndroid Build Coastguard Worker
776*6777b538SAndroid Build Coastguard Worker1. Select all the IPs of interfaces that can route to public Internet:
777*6777b538SAndroid Build Coastguard Worker    * Probe for route to `8.8.8.8`.
778*6777b538SAndroid Build Coastguard Worker    * Probe for route to `2001:4860:4860::8888`.
779*6777b538SAndroid Build Coastguard Worker    * If any IPs were found, return them, and finish.
780*6777b538SAndroid Build Coastguard Worker2. Select an IP by doing a DNS resolve of the machine's hostname:
781*6777b538SAndroid Build Coastguard Worker    * If any IPs were found, return them, and finish.
782*6777b538SAndroid Build Coastguard Worker3. Select the IP of an interface that can route to private IP space:
783*6777b538SAndroid Build Coastguard Worker    * Probe for route to `10.0.0.0`.
784*6777b538SAndroid Build Coastguard Worker    * Probe for route to `172.16.0.0`.
785*6777b538SAndroid Build Coastguard Worker    * Probe for route to `192.168.0.0`.
786*6777b538SAndroid Build Coastguard Worker    * Probe for route to `FC00::`.
787*6777b538SAndroid Build Coastguard Worker    * If any IPs were found, return them, and finish.
788*6777b538SAndroid Build Coastguard Worker
789*6777b538SAndroid Build Coastguard WorkerNote that short-circuiting happens whenever steps 1-3 find a candidate IP. So
790*6777b538SAndroid Build Coastguard Workerfor example if at least one IP address was discovered by checking routes to
791*6777b538SAndroid Build Coastguard Workerpublic Internet, only those IPs will be returned, and steps 2-3 will not run.
792*6777b538SAndroid Build Coastguard Worker
793*6777b538SAndroid Build Coastguard Worker## myIpAddress() / myIpAddressEx() and multi-homed hosts
794*6777b538SAndroid Build Coastguard Worker
795*6777b538SAndroid Build Coastguard Worker`myIpAddress()` is a poor API for hosts that have multiple IP addresses, as it
796*6777b538SAndroid Build Coastguard Workercan only return a single IP, which may or may not be the one you wanted. Both
797*6777b538SAndroid Build Coastguard Worker`myIpAddress()` and `myIpAddressEx()` favor returning the IP for the interface
798*6777b538SAndroid Build Coastguard Workerthat would be used to route to the public internet.
799*6777b538SAndroid Build Coastguard Worker
800*6777b538SAndroid Build Coastguard WorkerAs an API, `myIpAddressEx()` offers more flexibility since it can return
801*6777b538SAndroid Build Coastguard Workermultiple IP addresses. However Chrome's implementation restricts which IPs a
802*6777b538SAndroid Build Coastguard WorkerPAC script can see [due to privacy
803*6777b538SAndroid Build Coastguard Workerconcerns](https://bugs.chromium.org/p/chromium/issues/detail?id=905366). So
804*6777b538SAndroid Build Coastguard Workerusing `myIpAddressEx()` is not as powerful as enumerating all the host's IPs,
805*6777b538SAndroid Build Coastguard Workerand may not address all use-cases.
806*6777b538SAndroid Build Coastguard Worker
807*6777b538SAndroid Build Coastguard WorkerA more reliable strategy for PAC scripts to check which network(s) a user is on
808*6777b538SAndroid Build Coastguard Workeris to probe test domains using `dnsResolve()` / `dnsResolveEx()`.
809*6777b538SAndroid Build Coastguard Worker
810*6777b538SAndroid Build Coastguard WorkerMoreover, note that Chrome does not support the Firefox-specific
811*6777b538SAndroid Build Coastguard Worker`pacUseMultihomedDNS` option, so adding that global to a PAC script has no
812*6777b538SAndroid Build Coastguard Workerspecial side-effect in Chrome. Whereas in Firefox it reconfigures
813*6777b538SAndroid Build Coastguard Worker`myIpAddress()` to be dependent on the target URL that `FindProxyForURL()` was
814*6777b538SAndroid Build Coastguard Workercalled with.
815*6777b538SAndroid Build Coastguard Worker
816*6777b538SAndroid Build Coastguard Worker## Android quirks
817*6777b538SAndroid Build Coastguard Worker
818*6777b538SAndroid Build Coastguard WorkerProxy resolving via PAC works differently on Android than other desktop Chrome
819*6777b538SAndroid Build Coastguard Workerplatforms:
820*6777b538SAndroid Build Coastguard Worker
821*6777b538SAndroid Build Coastguard Worker* Android Chrome uses the same Chromium PAC resolver, however does not run it
822*6777b538SAndroid Build Coastguard Worker  out-of-process as on Desktop Chrome. This architectural difference is
823*6777b538SAndroid Build Coastguard Worker  due to the higher process cost on Android, and means Android Chrome is more
824*6777b538SAndroid Build Coastguard Worker  susceptible to malicious PAC scripts. The other consequence is that Android
825*6777b538SAndroid Build Coastguard Worker  Chrome can have distinct regressions from Desktop Chrome as the service setup
826*6777b538SAndroid Build Coastguard Worker  is quite different (and most `browser_tests` are not run on Android either).
827*6777b538SAndroid Build Coastguard Worker
828*6777b538SAndroid Build Coastguard Worker* [WebView does not use Chrome's PAC
829*6777b538SAndroid Build Coastguard Worker  resolver](https://bugs.chromium.org/p/chromium/issues/detail?id=989667).
830*6777b538SAndroid Build Coastguard Worker  Instead Android WebView uses the Android system's PAC resolver, which is less
831*6777b538SAndroid Build Coastguard Worker  optimized and uses an old build of V8. When the system is configured to use
832*6777b538SAndroid Build Coastguard Worker  PAC, Android WebView's net code will see the proxy settings as being a
833*6777b538SAndroid Build Coastguard Worker  single HTTP proxy on `localhost`. The system localhost proxy will in turn
834*6777b538SAndroid Build Coastguard Worker  evaluate the PAC script and forward the HTTP request on to the resolved
835*6777b538SAndroid Build Coastguard Worker  proxy. This translation has a number of effects, including what proxy
836*6777b538SAndroid Build Coastguard Worker  schemes are supported, the maximum connection limits, how proxy fallback
837*6777b538SAndroid Build Coastguard Worker  works, and overall performance (the current Android PAC evaluator blocks on
838*6777b538SAndroid Build Coastguard Worker  DNS).
839*6777b538SAndroid Build Coastguard Worker
840*6777b538SAndroid Build Coastguard Worker* Android system log messages for `PacProcessor` are not related to Chrome or
841*6777b538SAndroid Build Coastguard Worker  its PAC evaluator. Rather, these are log messages generated by the Android
842*6777b538SAndroid Build Coastguard Worker  system's PAC implementation. This confusion can arise when users add
843*6777b538SAndroid Build Coastguard Worker  `alert()` to debug PAC script logic, and then refer to output in `logcat` to
844*6777b538SAndroid Build Coastguard Worker  try and diagnose a resolving issue in Android Chrome.
845*6777b538SAndroid Build Coastguard Worker
846*6777b538SAndroid Build Coastguard Worker## Downloading PAC scripts
847*6777b538SAndroid Build Coastguard Worker
848*6777b538SAndroid Build Coastguard WorkerWhen a network context is configured to use a PAC script, proxy resolution will
849*6777b538SAndroid Build Coastguard Workerstall while downloading the PAC script.
850*6777b538SAndroid Build Coastguard Worker
851*6777b538SAndroid Build Coastguard WorkerFetches for PAC URLs are initiated by the network stack, and behave differently
852*6777b538SAndroid Build Coastguard Workerfrom ordinary web visible requests:
853*6777b538SAndroid Build Coastguard Worker
854*6777b538SAndroid Build Coastguard Worker* Must complete within 30 seconds.
855*6777b538SAndroid Build Coastguard Worker* Must complete with an HTTP response code of exactly 200.
856*6777b538SAndroid Build Coastguard Worker* Must have an uncompressed body smaller than 1 MB.
857*6777b538SAndroid Build Coastguard Worker* Do not follow ordinary HTTP caching semantics.
858*6777b538SAndroid Build Coastguard Worker* Are never fetched through a proxy
859*6777b538SAndroid Build Coastguard Worker* Are not visible to the WebRequest extension API, or to service workers.
860*6777b538SAndroid Build Coastguard Worker* Do not support HTTP authentication (ambient authentication may work, but
861*6777b538SAndroid Build Coastguard Worker  cannot prompt UI for credentials).
862*6777b538SAndroid Build Coastguard Worker* Do not support client certificates (including `AutoSelectCertificateForUrls`)
863*6777b538SAndroid Build Coastguard Worker* Do not support auxiliary certificate network fetches (will only used cached
864*6777b538SAndroid Build Coastguard Worker  OCSP, AIA, and CRL responses during certificate verification).
865*6777b538SAndroid Build Coastguard Worker
866*6777b538SAndroid Build Coastguard Worker### Caching of successful PAC fetches
867*6777b538SAndroid Build Coastguard Worker
868*6777b538SAndroid Build Coastguard WorkerPAC URLs are always fetched from the network, and never from the HTTP cache.
869*6777b538SAndroid Build Coastguard WorkerAfter a PAC URL is successfully fetched, its contents (which are used to create
870*6777b538SAndroid Build Coastguard Workera long-lived Java Script context) will be assumed to be fresh until either:
871*6777b538SAndroid Build Coastguard Worker
872*6777b538SAndroid Build Coastguard Worker* The network changes (IP address changes, DNS configuration changes)
873*6777b538SAndroid Build Coastguard Worker* The response becomes older than 12 hours
874*6777b538SAndroid Build Coastguard Worker* A user explicitly invalidates PAC through `chrome://net-internals#proxy`
875*6777b538SAndroid Build Coastguard Worker
876*6777b538SAndroid Build Coastguard WorkerOnce considered stale, the PAC URL will be re-fetched the next time proxy
877*6777b538SAndroid Build Coastguard Workerresolution is requested.
878*6777b538SAndroid Build Coastguard Worker
879*6777b538SAndroid Build Coastguard Worker### Fallback for failed PAC fetches
880*6777b538SAndroid Build Coastguard Worker
881*6777b538SAndroid Build Coastguard WorkerWhen the proxy settings are configured to use a PAC URL, and that PAC URL
882*6777b538SAndroid Build Coastguard Workercannot be fetched, proxy resolution will fallback to the next option, which is
883*6777b538SAndroid Build Coastguard Workeroften `DIRECT`:
884*6777b538SAndroid Build Coastguard Worker
885*6777b538SAndroid Build Coastguard Worker* If using system proxy settings, and the platform supports fallback to manual
886*6777b538SAndroid Build Coastguard Worker  proxy settings (e.g. Windows), the specified manual proxy servers will be
887*6777b538SAndroid Build Coastguard Worker  used after the PAC fetch fails.
888*6777b538SAndroid Build Coastguard Worker* If using Chrome's proxy settings, and the PAC script was marked as
889*6777b538SAndroid Build Coastguard Worker  [mandatory](https://developer.chrome.com/extensions/proxy), fallback to
890*6777b538SAndroid Build Coastguard Worker  `DIRECT` is not permitted. Subsequent network requests will fail proxy
891*6777b538SAndroid Build Coastguard Worker  resolution and complete with `ERR_MANDATORY_PROXY_CONFIGURATION_FAILED`.
892*6777b538SAndroid Build Coastguard Worker* Otherwise proxy resolution will silently fall back to `DIRECT`.
893*6777b538SAndroid Build Coastguard Worker
894*6777b538SAndroid Build Coastguard Worker### Recovering from failed PAC fetches
895*6777b538SAndroid Build Coastguard Worker
896*6777b538SAndroid Build Coastguard WorkerWhen fetching an explicitly configured PAC URL fails, the browser will try to
897*6777b538SAndroid Build Coastguard Workerre-fetch it:
898*6777b538SAndroid Build Coastguard Worker
899*6777b538SAndroid Build Coastguard Worker* In exactly 8 seconds
900*6777b538SAndroid Build Coastguard Worker* 32 seconds after that
901*6777b538SAndroid Build Coastguard Worker* 2 minutes after that
902*6777b538SAndroid Build Coastguard Worker* Every 4 hours thereafter
903*6777b538SAndroid Build Coastguard Worker
904*6777b538SAndroid Build Coastguard WorkerThis background polling of the PAC URL is only initiated in response to an
905*6777b538SAndroid Build Coastguard Workerincoming proxy resolution request, so it will not trigger work when the browser
906*6777b538SAndroid Build Coastguard Workeris otherwise idle.
907*6777b538SAndroid Build Coastguard Worker
908*6777b538SAndroid Build Coastguard WorkerSimilarly to successful fetches, the PAC URL will be also be re-fetched
909*6777b538SAndroid Build Coastguard Workerwhenever the network changes, the proxy settings change, or it was manually
910*6777b538SAndroid Build Coastguard Workerinvalidated via `chrome://net-internals#proxy`.
911*6777b538SAndroid Build Coastguard Worker
912*6777b538SAndroid Build Coastguard Worker### Text encoding
913*6777b538SAndroid Build Coastguard Worker
914*6777b538SAndroid Build Coastguard WorkerNote that UTF-8 is *not* the default interpretation of PAC response bodies.
915*6777b538SAndroid Build Coastguard Worker
916*6777b538SAndroid Build Coastguard WorkerThe priority for encoding is determined in this order:
917*6777b538SAndroid Build Coastguard Worker
918*6777b538SAndroid Build Coastguard Worker1. The `charset` property of the HTTP response's `Content-Type`
919*6777b538SAndroid Build Coastguard Worker2. Any BOM at the start of response body
920*6777b538SAndroid Build Coastguard Worker3. Otherwise defaults to ISO-8859-1.
921*6777b538SAndroid Build Coastguard Worker
922*6777b538SAndroid Build Coastguard WorkerWhen setting the `Content-Type`, servers should prefer using a mime type of
923*6777b538SAndroid Build Coastguard Worker`application/x-ns-proxy-autoconfig` or `application/x-javascript-config`.
924*6777b538SAndroid Build Coastguard WorkerHowever in practice, Chrome does not enforce the mime type.
925*6777b538SAndroid Build Coastguard Worker
926*6777b538SAndroid Build Coastguard Worker## Capturing a Net Log for debugging proxy resolution issues
927*6777b538SAndroid Build Coastguard Worker
928*6777b538SAndroid Build Coastguard WorkerIssues in proxy resolution are best investigated using a Net Log.
929*6777b538SAndroid Build Coastguard Worker
930*6777b538SAndroid Build Coastguard WorkerA good starting point is to follow the [general instructions for
931*6777b538SAndroid Build Coastguard Workernet-export](https://www.chromium.org/for-testers/providing-network-details),
932*6777b538SAndroid Build Coastguard Worker*and while the Net Log is being captured perform these steps*:
933*6777b538SAndroid Build Coastguard Worker
934*6777b538SAndroid Build Coastguard Worker1. Reproduce the failure (ex: load a URL that fails)
935*6777b538SAndroid Build Coastguard Worker2. If you can reproduce a success, do so (ex: load a different URL that succeeds).
936*6777b538SAndroid Build Coastguard Worker3. In a new tab, navigate to `chrome://net-internals/#proxy` and click both
937*6777b538SAndroid Build Coastguard Worker   buttons ("Re-apply settings" and "Clear bad proxies").
938*6777b538SAndroid Build Coastguard Worker4. Repeat step (1)
939*6777b538SAndroid Build Coastguard Worker5. Stop the Net Log and save the file.
940*6777b538SAndroid Build Coastguard Worker
941*6777b538SAndroid Build Coastguard WorkerThe resulting Net Log should have enough information to diagnose common
942*6777b538SAndroid Build Coastguard Workerproblems. It can be attached to a bug report, or explored using the [Net Log
943*6777b538SAndroid Build Coastguard WorkerViewer](https://netlog-viewer.appspot.com/). See the next section for some tips
944*6777b538SAndroid Build Coastguard Workeron analyzing it.
945*6777b538SAndroid Build Coastguard Worker
946*6777b538SAndroid Build Coastguard Worker## Analyzing Net Logs for proxy issues
947*6777b538SAndroid Build Coastguard Worker
948*6777b538SAndroid Build Coastguard WorkerLoad saved Net Logs using [Net Log Viewer](https://netlog-viewer.appspot.com/).
949*6777b538SAndroid Build Coastguard Worker
950*6777b538SAndroid Build Coastguard Worker### Proxy overview tab
951*6777b538SAndroid Build Coastguard Worker
952*6777b538SAndroid Build Coastguard WorkerStart by getting a big-picture view of the proxy settings by clicking to the
953*6777b538SAndroid Build Coastguard Worker"Proxy" tab on the left. This summarizes the proxy settings at the time the
954*6777b538SAndroid Build Coastguard Worker_capture ended_.
955*6777b538SAndroid Build Coastguard Worker
956*6777b538SAndroid Build Coastguard Worker* Does the _original_ proxy settings match expectation?
957*6777b538SAndroid Build Coastguard Worker  The proxy settings might be coming from:
958*6777b538SAndroid Build Coastguard Worker  * Managed Chrome policy (chrome://policy)
959*6777b538SAndroid Build Coastguard Worker  * Command line flags (ex: `--proxy-server`)
960*6777b538SAndroid Build Coastguard Worker  * (per-profile) Chrome extensions (ex: [chrome.proxy](https://developer.chrome.com/extensions/proxy))
961*6777b538SAndroid Build Coastguard Worker  * (per-network) System proxy settings
962*6777b538SAndroid Build Coastguard Worker
963*6777b538SAndroid Build Coastguard Worker* Was [proxy autodetect (WPAD)](#Web-Proxy-Auto_Discovery-WPAD) specified? In
964*6777b538SAndroid Build Coastguard Worker  this case the final URL probed will be reflected by the difference between
965*6777b538SAndroid Build Coastguard Worker  the "Effective" and "Original" settings.
966*6777b538SAndroid Build Coastguard Worker
967*6777b538SAndroid Build Coastguard Worker* Internally, proxy settings are per-NetworkContext. The proxy
968*6777b538SAndroid Build Coastguard Worker  overview tab shows settings for a *particular* NetworkContext, namely the
969*6777b538SAndroid Build Coastguard Worker  one associated with the Profile used to navigate to `chrome://net-export`. For
970*6777b538SAndroid Build Coastguard Worker  instance if the net-export was initiated from an Incognito window, it may
971*6777b538SAndroid Build Coastguard Worker  show different proxy settings here than a net-export capture initiated by a
972*6777b538SAndroid Build Coastguard Worker  non-Incognito window. When the net-export was triggered from command line
973*6777b538SAndroid Build Coastguard Worker  (`--log-net-log`) no particular NetworkContext is associated with the
974*6777b538SAndroid Build Coastguard Worker  capture and hence no proxy settings will be shown in this overview.
975*6777b538SAndroid Build Coastguard Worker
976*6777b538SAndroid Build Coastguard Worker* Were any proxies marked as bad?
977*6777b538SAndroid Build Coastguard Worker
978*6777b538SAndroid Build Coastguard Worker### Import tab
979*6777b538SAndroid Build Coastguard Worker
980*6777b538SAndroid Build Coastguard WorkerSkim through the Import tab and look for relevant command line flags and active
981*6777b538SAndroid Build Coastguard Workerfield trials. A find-in-page for `proxy` is a good starting point. Be on the lookout for
982*6777b538SAndroid Build Coastguard Worker[`--winhttp-proxy-resolver`](#winhttp_proxy_resolver-command-line-switch) which
983*6777b538SAndroid Build Coastguard Workerhas [known problems](https://bugs.chromium.org/p/chromium/issues/detail?id=644030).
984*6777b538SAndroid Build Coastguard Worker
985*6777b538SAndroid Build Coastguard Worker### Events tab
986*6777b538SAndroid Build Coastguard Worker
987*6777b538SAndroid Build Coastguard WorkerTo deep dive into proxy resolution, switch to the Events tab.
988*6777b538SAndroid Build Coastguard Worker
989*6777b538SAndroid Build Coastguard WorkerYou can start by filtering on `type:URL_REQUEST` to see all the top level
990*6777b538SAndroid Build Coastguard Workerrequests, and then keep click through the dependency links to
991*6777b538SAndroid Build Coastguard Workertrace the proxy resolution steps and outcome.
992*6777b538SAndroid Build Coastguard Worker
993*6777b538SAndroid Build Coastguard WorkerThe most relevant events have either `PROXY_`, `PAC_`, or
994*6777b538SAndroid Build Coastguard Worker`WPAD_` in their names. You can also try filtering for each of those.
995*6777b538SAndroid Build Coastguard Worker
996*6777b538SAndroid Build Coastguard WorkerDocumentation on specific events is available in
997*6777b538SAndroid Build Coastguard Worker[net_log_event_type_list.h](https://chromium.googlesource.com/chromium/src/+/HEAD/net/log/net_log_event_type_list.h).
998*6777b538SAndroid Build Coastguard Worker
999*6777b538SAndroid Build Coastguard WorkerNetwork change events can also be key to understanding proxy issues. After
1000*6777b538SAndroid Build Coastguard Workerswitching networks (ex VPN), the effective proxy settings, as well as content
1001*6777b538SAndroid Build Coastguard Workerof any PAC scripts/auto-detect can change.
1002*6777b538SAndroid Build Coastguard Worker
1003*6777b538SAndroid Build Coastguard Worker## Web Proxy Auto-Discovery (WPAD)
1004*6777b538SAndroid Build Coastguard Worker
1005*6777b538SAndroid Build Coastguard WorkerWhen configured to use WPAD (aka "autotmaticaly detect proxy settings"), Chrome
1006*6777b538SAndroid Build Coastguard Workerwill prioritize:
1007*6777b538SAndroid Build Coastguard Worker
1008*6777b538SAndroid Build Coastguard Worker1. DHCP-based WPAD (option 252)
1009*6777b538SAndroid Build Coastguard Worker2. DNS-based WPAD
1010*6777b538SAndroid Build Coastguard Worker
1011*6777b538SAndroid Build Coastguard WorkerThese are tried in order, however DHCP-based WPAD is only supported for Chrome
1012*6777b538SAndroid Build Coastguard Workeron Windows and Chrome on Chrome OS.
1013*6777b538SAndroid Build Coastguard Worker
1014*6777b538SAndroid Build Coastguard WorkerWPAD is the system default for many home and Enterprise users.
1015*6777b538SAndroid Build Coastguard Worker
1016*6777b538SAndroid Build Coastguard Worker### Chrome on macOS support for DHCP-based WPAD
1017*6777b538SAndroid Build Coastguard Worker
1018*6777b538SAndroid Build Coastguard WorkerChrome on macOS does not support DHCP-based WPAD when configured to use
1019*6777b538SAndroid Build Coastguard Worker"autodetect".
1020*6777b538SAndroid Build Coastguard Worker
1021*6777b538SAndroid Build Coastguard WorkerHowever, macOS might perform DHCP-based WPAD and embed this discovered PAC URL
1022*6777b538SAndroid Build Coastguard Workeras part of the system proxy settings. So effectively when Chrome is configured
1023*6777b538SAndroid Build Coastguard Workerto "use system proxy settings" it may behave as if it supports DHCP-based WPAD.
1024*6777b538SAndroid Build Coastguard Worker
1025*6777b538SAndroid Build Coastguard Worker### Dangers of DNS-based WPAD and DNS search suffix list
1026*6777b538SAndroid Build Coastguard Worker
1027*6777b538SAndroid Build Coastguard WorkerDNS-based WPAD involves probing for the non-FQDN `wpad`. This means
1028*6777b538SAndroid Build Coastguard WorkerWPAD's performance and security is directly tied to the user's DNS search
1029*6777b538SAndroid Build Coastguard Workersuffix list.
1030*6777b538SAndroid Build Coastguard Worker
1031*6777b538SAndroid Build Coastguard WorkerWhen resolving `wpad`, the host's DNS resolver will complete the hostname using
1032*6777b538SAndroid Build Coastguard Workereach of the suffixes in the search list:
1033*6777b538SAndroid Build Coastguard Worker
1034*6777b538SAndroid Build Coastguard Worker1. If the suffix list is long this process can very slow, as it triggers a
1035*6777b538SAndroid Build Coastguard Worker   cascade of NXDOMAIN.
1036*6777b538SAndroid Build Coastguard Worker2. If the suffix list includes domains *outside of the administrative domain*,
1037*6777b538SAndroid Build Coastguard Worker   WPAD may select an attacker controlled PAC server, and can subsequently
1038*6777b538SAndroid Build Coastguard Worker   funnel the user's traffic through a proxy server of their choice. The
1039*6777b538SAndroid Build Coastguard Worker   evolution of TLDs further increases this risk, since what were previously
1040*6777b538SAndroid Build Coastguard Worker   private suffixes used by an enterprise can become publicly registerable.
1041*6777b538SAndroid Build Coastguard Worker   See also [WPAD Name Collision
1042*6777b538SAndroid Build Coastguard Worker   Vulnerability](https://www.us-cert.gov/ncas/alerts/TA16-144A)
1043*6777b538SAndroid Build Coastguard Worker
1044*6777b538SAndroid Build Coastguard Worker## --winhttp-proxy-resolver command line switch
1045*6777b538SAndroid Build Coastguard Worker
1046*6777b538SAndroid Build Coastguard WorkerPassing the `--winhttp-proxy-resolver` command line argument instructs Chrome
1047*6777b538SAndroid Build Coastguard Workerto use the system libraries for *one narrow part of proxy resolution*: evaluating
1048*6777b538SAndroid Build Coastguard Workera given PAC script.
1049*6777b538SAndroid Build Coastguard Worker
1050*6777b538SAndroid Build Coastguard WorkerUse of this flag is NOT a supported mode, and has [known
1051*6777b538SAndroid Build Coastguard Workerproblems](https://bugs.chromium.org/p/chromium/issues/detail?id=644030): It
1052*6777b538SAndroid Build Coastguard Workercan break Chrome extensions (`chrome.proxy` API), the interpretation of
1053*6777b538SAndroid Build Coastguard WorkerProxy policies, hurt performance, and doesn't ensure full fidelity
1054*6777b538SAndroid Build Coastguard Workerinterpretation of system proxy settings.
1055*6777b538SAndroid Build Coastguard Worker
1056*6777b538SAndroid Build Coastguard WorkerAnother oddity of this switch is that it actually gets interpreted with a
1057*6777b538SAndroid Build Coastguard Workersmilar meaning on other platforms (macOS), despite its Windows-specific naming.
1058*6777b538SAndroid Build Coastguard Worker
1059*6777b538SAndroid Build Coastguard WorkerThis flag was historically exposed for debugging, and to mitigate unresolved
1060*6777b538SAndroid Build Coastguard Workerpolicy differences in PAC execution. In the future this switch [will be
1061*6777b538SAndroid Build Coastguard Workerremoved](https://bugs.chromium.org/p/chromium/issues/detail?id=644030).
1062*6777b538SAndroid Build Coastguard Worker
1063*6777b538SAndroid Build Coastguard WorkerAlthough Chrome would like full fidelity with Windows proxy settings, there are
1064*6777b538SAndroid Build Coastguard Workerlimits to those integrations. Dependencies like NRPT for proxy
1065*6777b538SAndroid Build Coastguard Workerresolution necessitate using Windows proxy resolution libraries directly
1066*6777b538SAndroid Build Coastguard Workerinstead of Chrome's. We hope these less common use cases will be fully
1067*6777b538SAndroid Build Coastguard Workeraddressed by [this
1068*6777b538SAndroid Build Coastguard Workerfeature](https://bugs.chromium.org/p/chromium/issues/detail?id=1032820)
1069