Five PAC file bugs that fail quietly
A PAC file is a small JavaScript function with no error messages. These five mistakes produce the wrong routing without any warning, and each has a quick check.
A proxy auto-config file is one JavaScript function, FindProxyForURL. The browser calls it for every request and does what it returns. If the logic is wrong, nothing reports an error. Traffic simply goes the wrong way. These are the five bugs worth checking first.
1. A return above the bypass
function FindProxyForURL(url, host) {
return "PROXY ${GATEWAY}:80";
if (dnsDomainIs(host, ".corp.local")) return "DIRECT";
}
A return ends the function. The bypass on the next line is never reached, so intranet sites are sent to the proxy and fail. Bypass checks go first, the proxy return goes last.
2. Matching with the wrong case
if (shExpMatch(host, "*.Corp.Local")) return "DIRECT";
shExpMatch is case-sensitive and browsers pass the host in lower case. Write patterns in lower case, and add host = host.toLowerCase(); as the first line so the rest of the file can rely on it.
3. Logic that depends on where the user is
Branches such as isInNet(myIpAddress(), "10.20.0.0", "255.255.0.0") send one office somewhere different. They also explain the classic report: "it works everywhere except one site". When a single location fails with a shared PAC file, compare that location's subnets with these branches before looking anywhere else.
4. Functions that look names up
isInNet(host, …) and dnsResolve(host) make the browser resolve the name, and the browser waits while that happens. Repeating the call on several lines repeats the wait. Names that only resolve internally can stall for seconds when the user is outside.
Do the cheap text checks first. If an address check is still needed, resolve once and reuse the result:
var ip = dnsResolve(host);
if (ip && (isInNet(ip, "10.0.0.0", "255.0.0.0") ||
isInNet(ip, "192.168.0.0", "255.255.0.0"))) return "DIRECT";
5. No decision about failure
return "PROXY ${GATEWAY}:80; PROXY ${SECONDARY_GATEWAY}:80; DIRECT";
Entries are tried from left to right. With DIRECT at the end, browsing continues unprotected if both proxies are unreachable. Without it, browsing stops. Neither is wrong, but it should be a decision. A PAC file that fails open by accident is a hole nobody knows about.
A file that avoids all five
function FindProxyForURL(url, host) {
host = host.toLowerCase();
if (isPlainHostName(host)) return "DIRECT";
if (dnsDomainIs(host, ".corp.local")) return "DIRECT";
return "PROXY ${GATEWAY}:80; PROXY ${SECONDARY_GATEWAY}:80; DIRECT";
}