Optimizing performance with automatic proxy-configuration scripts (PAC)
Warning
The retired, out-of-support Internet Explorer 11 desktop application has been permanently disabled through a Microsoft Edge update on certain versions of Windows 10. For more information, see Internet Explorer 11 desktop app retirement FAQ.
This topic explains how to optimize the performance of an automatic proxy-configuration script (PAC file, also known as Wpad.dat). This document focuses on how to resolve issues with the intranet servers directly and external internal traffic through a proxy-server.
For more information about the functions that are used to evaluate an address (URL or hostname), see: Use proxy autoconfiguration (.pac) files with IEAK 11.
Note
The isInNet()
, isResolvable()
, and dnsResolve()
functions send queries to the DNS-subsystem. Therefore, you should avoid, or, at least, minimize the use of these functions.
Query for NetBIOS names
NetBIOS names (server names that contain no period) are used in the intranet only and are not routed through the proxy:
if (isPlainHostName(host))
return "DIRECT";
Query for internal DNS suffixes
Internally used DNS zones are typically routed directly. The easiest way to determine such hosts is by using the dnsDomainis
function:
if (dnsDomainIs(host, ".dns.company.com"))
return "DIRECT";
An alternative and faster method for the same result can be obtained by using ShExMatch()
. This function does a string compare. It returns the same result but adds an asterisk (*) as a wildcard character:
if (shExpMatch(host, "*.dns.company.com"))
return "DIRECT";
Query for IP ranges
If the IP address of the host belongs to the local intranet, regardless of the web server name, it should bypass the proxy in order to navigate directly.
If the IP address is entered directly into the address bar, you do not have to resolve it again. You can use the following code to check whether the host is already in the IP address format:
var isIpV4Addr = /^(\d+.){3}\d+$/;
ret = isIpV4Addr.test(host);
This code checks whether the variable host contains three numerals that are followed by a period and then followed by another numeral. The result is then passed to the variable return. The result is "true" for an IP and "false" otherwise.
In the following code snippet, the variable host IP contains the IP address for use in future checks:
var hostIP;
var isIpV4Addr = /^(\d+.){3}\d+$/;
if (isIpV4Addr.test(host))
hostIP = host;
else
hostIP = dnsResolve(host);
When a non-existing host is passed to the function (for example, the user entered something wrong in the address bar), the result in host IP might be zero. Any additional error handling will be done by the proxy:
if (hostIP==0)
return "PROXY myproxy:80";
Because we have the IP address of the host, the internal IP ranges have to be checked.
Whenever possible, use the shExpMatch
function instead of isInNet
. The following code snippets have identical results, although shExpMatch
runs faster:
if (isInNet(hostIP, "95.53.0.0", "255.255.0.0"))
return "DIRECT";
if (shExpMatch(hostIP, "95.53.*"))
return "DIRECT";
JavaScript is case-sensitive
The proxy script uses the JavaScript language. JavaScript is case-sensitive. Therefore, an if
clause that is uppercase will never become true, while other parameters use lowercase. Internet Explorer itself converts the variables host
and url
into lowercase before the FindProxyForURL
function is called.
This condition is not true for WinHTTP
. This is because WinHTTP
passes the host
and the url
directly to the function.
Therefore, the parameters that are checked within the PAC file should be converted within the PAC before they are evaluated:
host = host.toLowerCase();
Using IPv6
If you want to use and handle IPv6 addresses, Internet Explorer supports them because Internet Explorer is included in every currently supported Windows version (and in WinHTTP since Windows Vista). However, in this case, you have to use "Ex" functions (such as isInNetEx()
), as mentioned in the following article:
IPv6-Aware Proxy Helper API Definitions
For an example of myIpAddressEx
implementation, see "myIpAddress" function returns incorrect result in Internet Explorer 9.
Testing a PAC file
If the script contains any syntax error (for example, a missing ")" character in an if
statement), the script is not run. To minimize errors, consider using a script editor that runs syntax checking. By using Visual Studio, you can rename the extension of the PAC file to ".js" during editing, but rename it back to ".pac" before uploading it to the webserver.
Note
Starting in Windows 10, you can no longer use file-based PAC files. For more information, see the following articles:
Testing with Autoprox.exe
Sometimes, you have to test the PAC file even if you have no access to the website. To do this, you can use the Autoprox.exe command line tool.
If you open the tool within a command without using additional parameters, the following output with the help is returned:
C:\temp>autoprox
Help for AUTOPROX.EXE
Version : 2.44 (12/16/2019)
Usage : AUTOPROX -a (calling DetectAutoProxyUrl and saving wpad.dat file in temporary file if success)
Usage : AUTOPROX -n (calling DetectAutoProxyUrl with PROXY_AUTO_DETECT_TYPE_DNS_A only and saving wpad.dat file in temporary file if success)
Usage : AUTOPROX [-o] [-d] [-v] [-u:url] [-p:Path to autoproxy file] [-i:IP address]
-o: calls InternetInitializeAutoProxyDll with helper functions implemented in AUTOPROX
-i:IP Address: calls InternetInitializeAutoProxyDll with helper functions implemented in AUTOPROX and using provided IP Address
-v: verbose output for helper functions
For debugging: -d plus HKEY_CURRENT_USER\Software\Microsoft\Windows Script\Settings\JITDebug=1
AUTOPROX -u:url: calling DetectAutoProxyUrl and using autoproxy file to find the proxy for the url
AUTOPROX -u:url -p:path: using the autoproxy file/url from the path to find proxy for the url
Example: autoprox http://www.microsoft.com -> calling DetectAutoProxyUrl and using WPAD if found
Example: autoprox -o -u:http://www.microsoft.com -p:c:\inetpub\wwwroot\wpad.dat
Example: autoprox -u:http://www.microsoft.com -p:http://proxy/wpad.dat
Example: autoprox -d -u:http://www.microsoft.com -p:http://proxy/wpad.dat
Here is the output if it uses our sample:
C:\temp>autoprox -u:https://us.msn.com -p:c:\temp\sample.pac
Searching proxy for url : https://us.msn.com
Searching proxy using file : c:\temp\sample.pac
The Winsock 2.2 dll was found okay
Calling InternetInitializeAutoProxyDll with c:\temp\sample.pac
Calling InternetGetProxyInfo for url https://us.msn.com and host us.msn.com
Proxy returned for url https://us.msn.com is:
PROXY myproxy:80;
Error handling in Autoprox.exe
If the PAC file contains syntax errors, you receive the following message:
ERROR: InternetGetProxyInfo failed with error number 0x3eb 1003.
After you finish the local test, you should copy the PAC file to the web server on which it will be accessed through the HTTP protocol.
Example:
function FindProxyForURL(url, host) {
// NetBIOS-names
if (isPlainHostName(host))
return "DIRECT";
// change to lower case, if not already been done
host = host.toLowerCase();
// internal DNS-suffixes
if (shExpMatch(host, "*.corp.company.com") ||
shExpMatch(host, "*.dns.company.com"))
return "DIRECT";
// Save the IP-address to variable hostIP
var hostIP;
var isIpV4Addr = /^(\d+.){3}\d+$/;
if (isIpV4Addr.test(host))
hostIP = host;
else
hostIP = dnsResolve(host);
// IP could not be determined -> go to proxy
if (hostIP == 0)
return "PROXY myproxy:80";
// These 3 scopes are used only internally
if (shExpMatch(hostIP, "95.53.*") ||
shExpMatch(hostIP, "192.168.*") ||
shExpMatch(hostIP, "127.0.0.1"))
return "DIRECT";
// Eveything else goes through the proxy
return "PROXY myproxy:80;";
}
Third-party contact disclaimer
Microsoft provides third-party contact information to help you find additional information about this topic. This contact information may change without notice. Microsoft does not guarantee the accuracy of third-party contact information.