Debugging Squid PAC on Chrome
I’m tearing my hair out trying to get our Squid proxy to play nice with
WebSockets, so one of the things I decided to try was to use a PAC file
to get browsers to skip the proxy for websocket URLs. Should be easy
right? The URL for Ripple’s websocket server, for example, happens to be
wss://s2.ripple.com:51233/
So a proxy.pac should be quite trivial, no?
if (shExpMatch(url, "wss://*")) {
return "DIRECT";
}
(Note that in the above example, only “secure” websockets will be skipped as non-SSL websockets use the ws:// scheme)
The problem is it doesn’t fucking work. It’s also non-trivial to
diagnose any problems with a PAC file on Chrome, but I figured out a
nifty little trick. First, embed a Javascript alert()
in the PAC:
if (shExpMatch(url, "wss://*")) {
alert(url);
return "DIRECT";
}
Now if you open up
chrome://net-internals/proxy-service#events
in another tab and reload your page, you’ll see in the event log that
the alert is indeed showing up (filter by PAC_JAVASCRIPT_ALERT
to thin
out the herd a bit). It seems as though this is getting fired, so what’s
going on?
If I move the alert(url);
outside of the if block, then check the
logs, it appears upon a cursory check that Chrome evaluates the proxy
once for the wss:// URL, and then, because WebSockets are HTTP[S] at
their core, does it again for an https:// version of the URL.
t=1368594864610 [st=0] PAC_JAVASCRIPT_ALERT
--> message = "wss://s2.ripple.com:51233/"
t=1368594864610 [st=0] PAC_JAVASCRIPT_ALERT
--> message = "https://s2.ripple.com:51233/"
Obviously, the second attempt at working out which proxy to use is the one that has control, so it fails to avoid the proxy for wss:// connections after all.
I can specify a list of websockets in the PAC file and Chrome behaves as expected, but I don’t particularly want to add a new websocket URL to the PAC every time something breaks (particularly because there appears to be no sure-fire way to reload the PAC).
Clearly this is going to take some more diagnosing.
Update: Filtering the event log by wss:// and then inspecting
individual SOCKET_STREAM events, you can see all the alert()
s in one
convenient place.
Update #2: I tried on IRC, and posted in the Chrome Product Forums, both to no avail at this time. :(