Jump to content


Photo
* * * * - 1 votes

PAC (Proxy Auto Configuration) File


  • Please log in to reply
6 replies to this topic

#1 wildweaselmi

wildweaselmi

    Administrator

  • Moderators
  • 1,126 posts

Posted 24 January 2010 - 03:17 PM

So what is a PAC file?
A PAC file contains some JavaScript code that lets your browser know what route is has to take to connect to different sites on the Internet. For most home users, the browser normally connects directly to a web site. However, it's also possible to have the browser connect to a "proxy" computer that gets the web content and passes it back to your browser. If you connect through a proxy, the proxy can act as an intelligent "man in the middle", blocking pornography and viruses. Sounds great, huh? What's the catch? Well, the companies that control proxy servers usually charge you money to use those proxy servers. That takes all the fun out of it...
Wikipedia PAC file definition

How to create/edit a PAC file?
Utilize a plain-text editor like notepad in Windows or TextEdit in Mac. Here's a few (tame) lines from the PAC file:

BadURL_Parts[i++] = "sex";
BadURL_Parts[i++] = "porn";
BadURL_Parts[i++] = "bitch";

You probably have no problem figuring out how to modify those words to suit your own needs.

Where does the proxy.pac file get installed?
If placed locally then most people who discuss PAC files are kind of vague about where to put them or what to name them. I'm going to be specific. The PAC file should be named "proxy" with no file extension and it should be in the same folder as your "hosts" file. Why? This puts it in a folder normally reserved for system files (which is good, because this is a system file), the lack of a file extension makes it look like all the other files there (so it won't attract attention), and the lack of a file extension makes it difficult for kids to open. The folder we are discussing is located here:
XP C:\Windows\system32\drivers\etc\ 
2000  C:\WINNT\system32\drivers\etc\ 
98/ME  C:\Windows\

If using your browser config then in the Internet Explorer menu, select "Tools", then "Internet Options", then go to the "Connections" tab. Click the "Settings..." or "LAN Settings..." button depending on whether you have broadband or a dialup connection. If you aren't sure, you can do both.

Check the "Use automatic configuration script" box and enter the location of your PAC file. You must use the "file://" protocol when specifying your file location. It's a little awkward to type in because all the slashes go the "wrong way", but when you get done, you should have something like this:
XP  file://C:/Windows/system32/drivers/etc/proxy 
2000  file://C:/WINNT/system32/drivers/etc/proxy 
98/ME  file://C:/Windows/proxy

Setup a dummy proxy server to test
The only reason you may need to do this is if you use this pac file solution on something other than IE, FireFox, or Mozilla. If you do, and if that other application seems to hang, you may need to get a real proxy server. Another reason to set up a dummy server is if you don't like to see error messages in your web pages! The simplest proxy server is "Homer".
The great thing about Homer is that it returns a blank image to replace the ad or porn image that might have originally displayed. This stops the error from being displayed and gives you "nothing" in return. It also has a log to show you what URLs are being blocked.
Attached File  Homer.zip   281.23KB   17 downloads

Attached File  pactester-pacparser-1.0.8-1.0.4-win32.zip   446.21KB   16 downloads
Usage:  ./pactester <-p pacfile> <-u url> [-h host] [-c client_ip]
        ./pactester <-p pacfile> <-f urlslist> [-c client_ip]

Options:
  -p pacfile: PAC file to test
  -u url: URL to test
  -h host: Host part of the URL
  -c client_ip: client IP address (defaults to IP address of the machine on which script is running)
  -f urlslist: a file containing list of URLs to be tested.

Example:
  ./pactester -p wpad.dat -u http://www.google.com
  ./pactester -p wpad.dat -u http://www.google.com -c 192.168.1.105
  ./pactester -p wpad.dat -f url_list

Below is a very simple example of a PAC file. Use notepad or your preferred text editor to create the file, and save it as proxy.pac.
function FindProxyForURL(url, host)
{
  //set the ip address of the proxy into a variable named proxy
  var proxy = "PROXY 192.168.250.1:8080";

  return proxy;
}
This very simple example of a PAC file will just re-direct traffic out through a proxy server running at 192.168.250.1 on port 8080. This of course is a very simple example but it should work. To test the PAC file drop it onto one of your internal web servers, and point your browser's automatic config file at the URL, e.g.

http://webserver1/proxy.pac

Once you have set this, as long as the IP and port in the PAC file match yours, you should start using the logic contained in this file. How to distribute the PAC file to clients is discussed later in the article.

If that is working, you can now build more into the file to control what happens to certain sites and subnets.

One of the most useful things you can do is send different subnets through different proxies. This is very good for multiple sites that each have their own Internet connection.

To do this we use a simple if statement to test for the client's IP address, and then set the proxy server based on what is returned, like this:

// Test for entire subnets
// if (isInNet(myIpAddress(), "192.168.250.0", "255.255.255.0"))
// proxy = "PROXY 192.168.250.1:8080";

This statement uses the function IsInNet to determine whether or not the client's IP address matches the one you specify. In the above code if you are any client on the 192.168.0.0 subnet, the function will return true and set the proxy variable to be 192.168.250.1:8080.

You can also use a similar block of code to send individual clients to a certain proxy instead of the entire subnet. This could be useful if certain people are heavy Internet users and have a dedicated proxy.

// Test for individual clients
if (isInNet(myIpAddress(), "192.168.250.25", "255.255.255.255"))
  proxy = "PROXY 192.168.250.242:8080";

Of course if you want to use this on certain clients, they will have to have a static IP address.

Directing Traffic based on URL

Next we will test for a certain site URL, and if we find the user wants to access that URL we will send them down yet another proxy.

if (url.substring(0, 24) == "http://www.microsoft.com")
  proxy = "PROXY 192.168.250.242:8080";

This function tests the URL string passed into the PAC file for the website address. The 0, 24 parameters tell the function to start at position 0 from the left hand side of the string, and count 24 characters. If the string matches the function returns true and the proxy variable is set.

As we are using the Substring function, we can not only test for a specific web site, but specific protocols as well. For instance you might want all of your FTP traffic to go out over a different link from your normal HTTP and HTTPS traffic.

if (url.substring(0, 4) == "ftp:")
  proxy = "PROXY 192.168.250.241:8080";
Now that we have got this far, we are almost ready to send the user to the correct proxy. The only thing we have not done yet is make sure that, if they are trying to access a site on your internal network, they go directly and do not use the proxy. This is done like so:

if (isInNet(host, "192.168.0.0", "255.255.0.0"))
  {
    return "DIRECT";
  }
else {
    return proxy;
  }
The first part of the IF statement is the IsInNet function again, this time on the IP address of the destination passed into the PAC file. If it is in the IP scope specified, then the user is sent directly to the site. At this point the logic of the PAC file concludes and the user is sent to the site.

If the IF statement returns false, then the user is sent to the proxy server that is currently held in the proxy variable.

Put it all Together
Now that we have all the building blocks, we can create our PAC file. If we wish, we can also set it up so that, instead of using the IP address of the proxy, it points to a DNS entry. This is useful if you have backup proxies. In that case, if the main one goes offline you can change the DNS entry to the backup and the clients will be re-directed, without you having to alter the PAC file. We use this in our final completed example.

function FindProxyForURL(url, host)
{
  //Set a default proxy if non are returned below
  var proxy = "PROXY 192.168.0.244:8080";
 
  // Test for Prestons subnets
  if (isInNet(myIpAddress(), "192.168.1.0", "255.255.255.0"))
    proxy = "PROXY proxy_preston:8080";
  if (isInNet(myIpAddress(), "192.168.2.0", "255.255.255.0"))
    proxy = "PROXY proxy_preston:8080";
 
  // Test for Londons subnets
  if (isInNet(myIpAddress(), "192.168.3.0", "255.255.255.0"))
    proxy = "PROXY proxy_blackpool:8080";
  if (isInNet(myIpAddress(), "192.168.4.0", "255.255.255.0"))
    proxy = "PROXY proxy_blackpool:8080";
 
  //Now direct the user out through the proxy if not internal site
  if (isInNet(host, "192.168.0.0", "255.255.0.0"))
  {
    return "DIRECT";
  }
  else if (url.substring(0, 24) == "http://www.microsoft.com")
  {
    return "PROXY 159.180.13.52:3128";
  }
  else if (url.substring(0, 5) == "http:")
  {
    return proxy;
  }
  else if (url.substring(0, 4) == "ftp:")
  {
    return proxy;
  }
}

Now that you have your PAC file, you need to get your users to start using it. There are a couple of ways you can accomplish this, apart from the obvious one of getting them to do it themselves.

Please note that all the options discussed below are for use with Internet Explorer; they won't affect FireFox, Opera, Safari etc. If you have any way of setting up these browsers send them to me and I'll attach them as a comment to this article.

Hacking the Registry

The IE home page is just a simple setting in the registry. It is specific for each user profile on the machine and lives in

HKCUSoftwareMicrosoftWindowsCurrentVersionInternet SettingsAutoConfigURL

So if you use VBS login scripts you could have a function in them that writes down your config file, something like this:

'Create shell objext
Set objwsh = WScript.CreateObject("WScript.Shell")
 
'Assign the PAC file
Const PROXY_LOC = "http://webserver1/proxy.pac"
 
objwsh.RegWrite "HKCUSoftwareMicrosoftWindowsCurrentVersionInternet SettingsAutoConfigURL", PROXY_LOC, "REG_SZ"

Using a Group Policy

If you are running in an active directory domain, this is probably the best way to control it. By using this method you can not only set the location of the PAC file, but disable the option in Internet Explorer so that the user can't go in and change it.

Open up (or create) a Policy file that will hold the settings for your users. The options you need are all in the USER section under Windows Settings/Internet Explorer Maintenance/Connection. To use your PAC file, open up the Automatic Browser Configuration option.

In here tick the Enable Automatic Configuration box, and then in the bottom text area named Auto-proxy URL, put the address of your PAC file in. For example, http://webserver1/proxy.pac.

You can also set a time in minutes that will reload the PAC file. If you leave this blank the PAC file is just re-read every time you reload the browser.

Going Forward

As the language of the PAC file is JavaScript-based, there are a lot more functions you could build into it, such as re-directing the user to one site if they try to visit a page they shouldn't be visiting. There are also various other options for distributing the PAC file. One of the most interesting is using DNS and DHCP to implement the Web Proxy Autodiscovery (WPAD) protocol.

#2 wildweaselmi

wildweaselmi

    Administrator

  • Moderators
  • 1,126 posts

Posted 24 January 2010 - 06:58 PM

A great free java script editor is attached
Attached File  freejse.zip   6.54MB   12 downloads

Or you can use the very nice UltraEdit program but it cost $50 so the free version is okay for me.
Attached File  ue_english.zip   15.28MB   4 downloads

Beyond a java script editor you should utilize a text compare tool to validate your changes are the only items that have changed. I have tried the free ExamDiff version
Attached File  edpro50.zip   5.71MB   1 downloads

Or if you liked the UltraEdit program, they also provide a compare tool which works very well

#3 wildweaselmi

wildweaselmi

    Administrator

  • Moderators
  • 1,126 posts

Posted 25 January 2010 - 09:06 PM

Debugging a pac file

http://support.microsoft.com/kb/274356

Or

JSLint. http://www.jslint.com/

#4 wildweaselmi

wildweaselmi

    Administrator

  • Moderators
  • 1,126 posts

Posted 25 January 2010 - 09:16 PM

The pac file itself have a few predefined functions and variables exposed, here are the most useful ones:

  • host – host being connected to.
  • url – address to be retrieved.
  • myIpAddress() – returns the IP address (in integer-dot format) of the network adapter that have the highest priority on the host, that the browser is running on.
  • isInNet(host, network, subnet) – determines if the given host resides on the specified network.
  • dnsDomainIs(host, dns-suffix) – attempts to decide if host belongs to domain.
  • isPlainHostName(host) - returns true if host doesn’t contain any dots.


#5 wildweaselmi

wildweaselmi

    Administrator

  • Moderators
  • 1,126 posts

Posted 25 January 2010 - 09:20 PM

Below is a sample proxy.pac file

// ********************************************************************
// template.txt: Version 3.1
// slight edits for clarity
//
// Proxy Auto-Config (PAC) template file for web browser and roaming
// users. Follow the instruction through this configuration file to
// update for your specific environment.
//
// Notes:
// - "host" refers to the host portion of the URL being requested (i.e.
//	everything after the :// at the beginning of the URL up to the
//	first colon (<img src='http://community.mywiseguys.com/public/style_emoticons/<#EMO_DIR#>/smile.gif' class='bbc_emoticon' alt=':)' /> or slash (/) (e.g. www.example.com).
// - "url" refers to the entire URL being requested. This includes
//	the protocol and file (e.g. http://www.example.com/index.html).
// - Microsoft IE processes the PAC file once per hostname and caches
//	the result. You cannot have different behaviour for the same
//	hostname (e.g. http://www.example.com/index.html must be
//	directed to the same proxy as http://www.example.com/foo.html).
// - isInNet will perform a DNS lookup for non IP addresses. Ensure the
//	host is a raw IP before using this function.
// - For debugging, set the debug variable to true.
// ********************************************************************

function FindProxyForURL(url, host)
{
	var debug = true;
	var direct = "DIRECT";

	// Proxy addresses by region.
	var proxy1_eu = "PROXY proxy1.eu.webscanningservice.com:3128";
	var proxy1_us = "PROXY proxy1.us.webscanningservice.com:3128";
	var proxy2_us = "PROXY proxy2.us.webscanningservice.com:3128";
	var proxy1_ap = "PROXY proxy1.ap.webscanningservice.com:3128";
	var proxy1_hk = "PROXY proxy1.hk.webscanningservice.com:3128";

	// *****************************************************************
	// Proxy address for roaming users, specify the appropriate region
	// *****************************************************************
	var roaming1_eu = "PROXY roaming1.eu.webscanningservice.com:80";
	var roaming1_us = "PROXY roaming1.us.webscanningservice.com:80";
	var roaming2_us = "PROXY roaming2.us.webscanningservice.com:80";
	var roaming1_ap = "PROXY roaming1.ap.webscanningservice.com:80";
	var roaming = roaming1_eu;

	// *****************************************************************
	// Specify your CSP address if applicable, one line for each
	// distinct company subnet.
	// *****************************************************************
	var site1 = "PROXY 192.168.2.10:3128";
	var site3 = "PROXY 192.168.105.20:3128";
	var site2 = "PROXY 192.168.1.3:8080";

	// Source IP address.
	var myIp = myIpAddress();
	var anet = "255.0.0.0"
	var bnet = "255.255.0.0"
	var cnet = "255.255.255.0"	

	// If the host is this computer, connect directly
	if ((host == "localhost") ||
		 (host == "localhost.localdomain") ||
		 (host == "127.0.0.1"))
	{
		if (debug) alert("PAC: DIRECT: localhost: " + host);
		return direct;
	}

	// If host name is local (i.e. contains no dots), connect directly.
	if (isPlainHostName(host))
	{
		if (debug) alert("PAC: DIRECT: plain host: " + host);
		return direct;
	}

	// If host name is part of the IANA private IP address ranges, connect
	// directly.
	if (/^\d+\.\d+\.\d+\.\d+$/.test(host) &&
			(isInNet(host, "10.0.0.0", anet) ||
			 isInNet(host, "169.0.0.0", anet) ||
			 isInNet(host, "172.16.0.0", "255.240.0.0") ||
			 isInNet(host, "192.168.0.0", bnet)))
	{
		if (debug) alert("PAC: DIRECT: IANA private network: " + host);
		return direct;
	}

	// *****************************************************************
	// Specify remote URLs that are trusted and don't require proxying
	// and should be bypassed when roaming.
	// *****************************************************************
	if (shExpMatch(host, "*.download.microsoft.com") ||
		 shExpMatch(host, "*.windowsupdate.com") ||
		 shExpMatch(host, "*.windowsupdate.microsoft.com") ||
		 shExpMatch(host, "windowsupdate.microsoft.com") ||
		 shExpMatch(host, "*.update.microsoft.com") ||
		 shExpMatch(host, "update.microsoft.com"))
	{
		if (debug) alert("PAC: BYPASS: Windows Update: " + host);
		roaming = direct;
	}

	// *****************************************************************
	// Specify VPN ranges, one line for each VPN range.
	// When using a VPN, proxying is done through roaming proxy.
	// *****************************************************************
	// if (isInNet(myIp, "<VPN IP 1>", "<VPN Mask>" )) { if(debug) alert("PAC: ROAMING: VPN1: " + host); return roaming; }
	// if (isInNet(myIp, "<VPN IP 2>", "<VPN Mask>" )) { if(debug) alert("PAC: ROAMING: VPN1: " + host); return roaming; }

	// *****************************************************************
	// Specify local FQDNs which do not require proxying, one line per
	// expression. Shell expression patterns can be used.
	// *****************************************************************
	// if (shExpMatch(host, "<Local FQDN 1>")) { if(debug) alert("PAC: ROAMING: Local FQDN 1: " + host); return direct; }
	// if (shExpMatch(host, "<Local FQDN 2>")) { if(debug) alert("PAC: ROAMING: Local FQDN 1: " + host); return direct; }

	// *****************************************************************
	// Specify company subnet source IP address ranges which require
	// proxying, one line per expression. Specify adequate proxy region
	// or CSP address for each range.
	// *****************************************************************
	// if (isInNet(myIp, "<Subnet IP 1>", "<Subnet Mask>")) { if(debug) alert("PAC: ROAMING: Subnet 1: " + host); return <proxy_region1>; }
	if (isInNet(myIp,"192.168.2.0",	cnet)) 				{if(debug) alert("PAC: proxy site 1: " + host); 			return site1; }
	if (isInNet(myIp,"192.168.112.0",	cnet)) 				{if(debug) alert("PAC: site without local proxy: " + host); 		return roaming;}
	if (isInNet(myIp,"192.168.104.0",	cnet)) 				{if(debug) alert("PAC: proxy site2: " + host);	 		return site2; }
	if (isInNet(myIp,"192.168.105.0",	cnet)) 				{if(debug) alert("PAC: proxy site3: " + host); 				return site3; }

	// When outside company subnet, connect to roaming proxy.
	if (debug && roaming != direct) alert("PAC: ROAMING: Default: " + host);
	return roaming;
}
Attached File  proxypacfiletest.txt   6.07KB   6 downloads

#6 wildweaselmi

wildweaselmi

    Administrator

  • Moderators
  • 1,126 posts

Posted 26 January 2010 - 07:55 AM

Predefined Functions and Environment for the JavaScript Function
Hostname based conditions:

isPlainHostName()
dnsDomainIs()
localHostOrDomainIs()
isResolvable()
isInNet()
Related utility functions:

dnsResolve()
myIpAddress()
dnsDomainLevels()
URL/hostname based conditions:

shExpMatch()
Time based conditions:

weekdayRange()
dateRange()
timeRange()
There is one associative array already defined (because a JavaScript currently cannot define them on its own):

ProxyConfig.bindings

--------------------------------------------------------------------------------

isPlainHostName(host)
host
the hostname from the URL (excluding port number).
True iff there is no domain name in the hostname (no dots).
Examples:
isPlainHostName("www")
is true.
isPlainHostName("www.netscape.com")
is false.




--------------------------------------------------------------------------------

dnsDomainIs(host, domain)
host
is the hostname from the URL.
domain
is the domain name to test the hostname against.
Returns true iff the domain of hostname matches.
Examples:
dnsDomainIs("www.netscape.com", ".netscape.com")
is true.
dnsDomainIs("www", ".netscape.com")
is false.
dnsDomainIs("www.mcom.com", ".netscape.com")
is false.




--------------------------------------------------------------------------------

localHostOrDomainIs(host, hostdom)
host
the hostname from the URL.
hostdom
fully qualified hostname to match against.
Is true if the hostname matches exactly the specified hostname, or if there is no domain name part in the hostname, but the unqualified hostname matches.
Examples:
localHostOrDomainIs("www.netscape.com", "www.netscape.com")
is true (exact match).
localHostOrDomainIs("www", "www.netscape.com")
is true (hostname match, domain not specified).
localHostOrDomainIs("www.mcom.com", "www.netscape.com")
is false (domain name mismatch).
localHostOrDomainIs("home.netscape.com", "www.netscape.com")
is false (hostname mismatch).




--------------------------------------------------------------------------------

isResolvable(host)
host
is the hostname from the URL.
Tries to resolve the hostname. Returns true if succeeds.
Examples:
isResolvable("www.netscape.com")
is true (unless DNS fails to resolve it due to a firewall or some other reason).
isResolvable("bogus.domain.foobar")
is false.




--------------------------------------------------------------------------------

isInNet(host, pattern, mask)
host
a DNS hostname, or IP address. If a hostname is passed, it will be resoved into an IP address by this function.
pattern
an IP address pattern in the dot-separated format
mask
mask for the IP address pattern informing which parts of the IP address should be matched against. 0 means ignore, 255 means match.
True iff the IP address of the host matches the specified IP address pattern.
Pattern and mask specification is done the same way as for SOCKS configuration.

Examples:
isInNet(host, "198.95.249.79", "255.255.255.255")
is true iff the IP address of host matches exactly 198.95.249.79.
isInNet(host, "198.95.0.0", "255.255.0.0")
is true iff the IP address of the host matches 198.95.*.*.




--------------------------------------------------------------------------------

dnsResolve(host)
host
hostname to resolve
Resolves the given DNS hostname into an IP address, and returns it in the dot separated format as a string.
Example:
dnsResolve("home.netscape.com")
returns the string "198.95.249.79".

--------------------------------------------------------------------------------

myIpAddress()
Returns the IP address of the host that the Navigator is running on, as a string in the dot-separated integer format.
Example:
myIpAddress()
would return the string "198.95.249.79" if you were running the Navigator on that host.

--------------------------------------------------------------------------------

dnsDomainLevels(host)
host
is the hostname from the URL.
Returns the number (integer) of DNS domain levels (number of dots) in the hostname.
Examples:
dnsDomainLevels("www")
returns 0.
dnsDomainLevels("www.netscape.com")
returns 2.




--------------------------------------------------------------------------------

shExpMatch(str, shexp)
str
is any string to compare (e.g. the URL, or the hostname).
shexp
is a shell expression to compare against.
Returns true if the string matches the specified shell expression.
Actually, currently the patterns are shell expressions, not regular expressions.

Examples:
shExpMatch("http://home.netscape...ari/index.html", "*/ari/*")
is true.
shExpMatch("http://home.netscape...lli/index.html", "*/ari/*")
is false.




--------------------------------------------------------------------------------

weekdayRange(wd1, wd2, gmt)
wd1
and
wd2
are one of the weekday strings:
SUN MON TUE WED THU FRI SAT

gmt
is either the string: GMT or is left out.



Only the first parameter is mandatory. Either the second, the third, or both may be left out.
If only one parameter is present, the function yeilds a true value on the weekday that the parameter represents. If the string "GMT" is specified as a second parameter, times are taken to be in GMT, otherwise in local timezone.

If both wd1 and wd1 are defined, the condition is true if the current weekday is in between those two weekdays. Bounds are inclusive. If the "GMT" parameter is specified, times are taken to be in GMT, otherwise the local timezone is used.

Examples:
weekdayRange("MON", "FRI")
true Monday trhough Friday (local timezone).
weekdayRange("MON", "FRI", "GMT")
same as above, but GMT timezone.
weekdayRange("SAT")
true on Saturdays local time.
weekdayRange("SAT", "GMT")
true on Saturdays GMT time.
weekdayRange("FRI", "MON")
true Friday through Monday (note, order does matter!).




--------------------------------------------------------------------------------

dateRange(day)
dateRange(day1, day2)
dateRange(mon)
dateRange(month1, month2)
dateRange(year)
dateRange(year1, year2)
dateRange(day1, month1, day2, month2)
dateRange(month1, year1, month2, year2)
dateRange(day1, month1, year1, day2, month2, year2)
dateRange(day1, month1, year1, day2, month2, year2, gmt)
day
is the day of month between 1 and 31 (as an integer).
month
is one of the month strings:
JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC

year
is the full year number, for example 1995 (but not 95). Integer.
gmt
is either the string "GMT", which makes time comparison occur in GMT timezone; if left unspecified, times are taken to be in the local timezone.


Even though the above examples don't show, the "GMT" parameter can be specified in any of the 9 different call profiles, always as the last parameter.



If only a single value is specified (from each category: day, month, year), the function returns a true value only on days that match that specification. If both values are specified, the result is true between those times, including bounds.
Examples:
dateRange(1)
true on the first day of each month, local timezone.
dateRange(1, "GMT")
true on the first day of each month, GMT timezone.
dateRange(1, 15)
true on the first half of each month.
dateRange(24, "DEC")
true on 24th of December each year.
dateRange(24, "DEC", 1995)
true on 24th of December, 1995.
dateRange("JAN", "MAR")
true on the first quarter of the year.
dateRange(1, "JUN", 15, "AUG")
true from June 1st until August 15th, each year (including June 1st and August 15th).
dateRange(1, "JUN", 15, 1995, "AUG", 1995)
true from June 1st, 1995, until August 15th, same year.
dateRange("OCT", 1995, "MAR", 1996)
true from October 1995 until March 1996 (including the entire month of October 1995 and March 1996).
dateRange(1995)
true during the entire year 1995.
dateRange(1995, 1997)
true from beginning of year 1995 until the end of year 1997.




--------------------------------------------------------------------------------

timeRange(hour)
timeRange(hour1, hour2)
timeRange(hour1, min1, hour2, min2)
timeRange(hour1, min1, sec1, hour2, min2, sec2)
timeRange(hour1, min1, sec1, hour2, min2, sec2, gmt)
hour
is the hour from 0 to 23. (0 is midnight, 23 is 11 pm.)
min
minutes from 0 to 59.
sec
seconds from 0 to 59.
gmt
either the string "GMT" for GMT timezone, or not specified, for local timezone. Again, even though the above list doesn't show it, this parameter may be present in each of the different parameter profiles, always as the last parameter.



True during (or between) the specified time(s).
Examples:
timerange(12)
true from noon to 1pm.
timerange(12, 13)
same as above.
timerange(12, "GMT")
true from noon to 1pm, in GMT timezone.
timerange(9, 17)
true from 9am to 5pm.
timerange(8, 30, 17, 00)
true from 8:30am to 5:00pm.
timerange(0, 0, 0, 0, 0, 30)
true between midnight and 30 seconds past midnight.




--------------------------------------------------------------------------------

Example #1: Use proxy for everything except local hosts
This would work in Netscape's environment. All hosts which aren't fully qualified, or the ones that are in local domain, will be connected to directly. Everything else will go through w3proxy:8080. If the proxy goes down, connections become automatically direct.
function FindProxyForURL(url, host)
{
if (isPlainHostName(host) ||
dnsDomainIs(host, ".netscape.com"))
return "DIRECT";
else
return "PROXY w3proxy.netscape.com:8080; DIRECT";
}

Note: This is the simplest and most efficient autoconfig file for cases where there's only one proxy.
--------------------------------------------------------------------------------

Example #1b: As above, but use proxy for local servers which are outside the firewall
If there are hosts (such as the main Web server) that belong to the local domain but are outside the firewall, and are only reachable through the proxy server, those exceptions can be handled using the localHostOrDomainIs() function:
function FindProxyForURL(url, host)
{
if ((isPlainHostName(host) ||
dnsDomainIs(host, ".netscape.com")) &&
!localHostOrDomainIs(host, "www.netscape.com") &&
!localHostOrDoaminIs(host, "merchant.netscape.com"))

return "DIRECT";
else
return "PROXY w3proxy.netscape.com:8080; DIRECT";
}

The above will use the proxy for everything else except local hosts in the netscape.com domain, with the further exception that hosts www.netscape.com and merchant.netscape.com will go through the proxy.
Note the order of the above exceptions for efficiency: localHostOrDomainIs() functions only get executed for URLs that are in local domain, not for every URL. Be careful to note the parentheses around the or expression before the and expression to achieve the abovementioned efficient behaviour.


--------------------------------------------------------------------------------

Example #2: Use proxy only if cannot resolve host
This example would work in an environment where internal DNS is set up so that it can only resolve internal host names, and the goal is to use a proxy only for hosts which aren't resolvable:
function FindProxyForURL(url, host)
{
if (isResolvable(host))
return "DIRECT";
else
return "PROXY proxy.mydomain.com:8080";
}

The above requires consulting the DNS every time; it can be grouped smartly with other rules so that DNS is consulted only if other rules do not yield a result:
function FindProxyForURL(url, host)
{
if (isPlainHostName(host) ||
dnsDomainIs(host, ".mydomain.com") ||
isResolvable(host))
return "DIRECT";
else
return "PROXY proxy.mydomain.com:8080";
}


--------------------------------------------------------------------------------

Example #3: Subnet based decisions
In this example all the hosts in a given subnet are connected to directly, others through the proxy.
function FindProxyForURL(url, host)
{
if (isInNet(host, "198.95.0.0", "255.255.0.0"))
return "DIRECT";
else
return "PROXY proxy.mydomain.com:8080";
}

Again, use of DNS in the above can be minimized by adding redundant rules in the beginning:
function FindProxyForURL(url, host)
{
if (isPlainHostName(host) ||
dnsDomainIs(host, ".mydomain.com") ||
isInNet(host, "198.95.0.0", "255.255.0.0"))
return "DIRECT";
else
return "PROXY proxy.mydomain.com:8080";
}


--------------------------------------------------------------------------------

Example #4: Load balancing/routing based on URL patterns
This example is more sophisticated. There are four (4) proxy servers; one of them is a hot stand-by for all of the other ones, so if any of the remaining three goes down, the fourth one will take over.
Furthermore, the three remaining proxy servers share the load based on URL patterns, which makes their caching more effective (there is only one copy of any document on the three servers -- as opposed to one copy on each of them). The load is distributed like this:

Proxy Purpose
#1 .com domain
#2 .edu domain
#3 all other domains
#4 hot stand-by

All local accesses are desired to be direct. All proxy servers run on the port 8080 (they wouldn't need to). Note how strings can be concatenated by the + operator in JavaScript.

function FindProxyForURL(url, host)
{
if (isPlainHostName(host) || dnsDomainIs(host, ".mydomain.com"))
return "DIRECT";
else if (shExpMatch(host, "*.com"))
return "PROXY proxy1.mydomain.com:8080; " +
"PROXY proxy4.mydomain.com:8080";
else if (shExpMatch(host, "*.edu"))
return "PROXY proxy2.mydomain.com:8080; " +
"PROXY proxy4.mydomain.com:8080";
else
return "PROXY proxy3.mydomain.com:8080; " +
"PROXY proxy4.mydomain.com:8080";
}


--------------------------------------------------------------------------------

Example #5: Setting a proxy for a specific protocol
Most of the standard JavaScript functionality is available for use in the FindProxyForURL() function. As an example, to set different proxies based on the protocol, the substring() function can be used:
function FindProxyForURL(url, host)
{
if (url.substring(0, 5) == "http:") {

return "PROXY http-proxy.mydomain.com:8080";
}
else if (url.substring(0, 4) == "ftp:") {

return "PROXY ftp-proxy.mydomain.com:8080";
}
else if (url.substring(0, 7) == "gopher:") {

return "PROXY gopher-proxy.mydomain.com:8080";
}
else if (url.substring(0, 6) == "https:" ||
url.substring(0, 6) == "snews:") {

return "PROXY security-proxy.mydomain.com:8080";
}
else {

return "DIRECT";
}
}

Note: The same can be accomplished using the shExpMatch() function described earlier; for example:
...
if (shExpMatch(url, "http:*")) {
return "PROXY http-proxy.mydomain.com:8080;
}
...

#7 shadowmac

shadowmac

    Member

  • Members
  • 119 posts

Posted 30 June 2011 - 01:53 PM

Here is an example of our employee.pac file
/* 
 * Proxy autoconfig file 
 * 
 * $Revision: 5.02 $
 * $Date: 2011/05/01
 * $Author: Joe Smith 810 555 5555
 * $Source: /usr/local/repository/gwh/src/pac/proxy.pac,v $ 
 * $Employee Proxy File $
 */ 

var hash = 0;
//var index = myIpAddress().lastIndexOf(".") + 1;

//                alert("Use of COMPANY computing and network resources is subject to monitoring,\nand anyone using those resources expressly consents to such monitoring\nand recording.  All internet use through the COMPANY infrastructure is also\nsubject to monitoring and recording.  Abuse of COMPANY computing and\nnetwork resources, or internet services is subject to disciplinary\naction, and if criminal activity is detected, activity records may be\nprovided to law enforcement."); 

	alert("COMPANY LLC owns or controls these computing and network resources including internet access.  \nAs such, use is subject to monitoring and recording.\n \n			Anyone using these COMPANY resources expressly\n			consents to such monitoring and recording. \n \nAbuse of COMPANY computing resources, network resources or internet access is subject to disciplinary action,\n and if criminal activity is detected, activity records may be provided to law enforcement.\nUsers of COMPANY resources must adhere to the COMPANY Acceptable Use Policy available on COMPANY Website URL."); 


function FindProxyForURL(url, host)
{
   if (isPlainHostName(host))
   {
       return "DIRECT";
   }

   // Direct connections to local domains
   else if ((dnsDomainIs(host, ".mycompany.com") ||
       dnsDomainIs(host, ".ibm.mycompany.com") ||
       dnsDomainIs(host, "www-sit1.lansite.biz") ||
       dnsDomainIs(host, "199.181.218.35") ||
       shExpMatch(host, "10.*.*.*") ||
       shExpMatch(host, "130.178.*.*")) &&
   // force to else condition -- these need to go through the Netcache servers
       (!localHostOrDomainIs(host, "www.mycompany.com") &&
       !localHostOrDomainIs(host, "www.mycompany.net") &&
       !dnsDomainIs(host, ".xweb.hello.com")))

   {

       return "DIRECT";

   }

   else 
     { 

        myiparray = myIpAddress().split(".");
 

            hash = (myiparray[3] % 2); 
            if (hash == 0) 
                return "PROXY 10.60.0.15:80; PROXY 10.60.0.16:80"; 
            else if (hash == 1) 
                return "PROXY  10.60.0.15:80; PROXY 10.60.0.16:80"; 
          /*To deal with -1 due to some old Windows machine bug*/ 
            else 
                return "PROXY  10.60.0.16:80; PROXY 10.60.0.15:80"; 
  

    } 

}






Similar Topics Collapse

  Topic Forum Started By Stats Last Post Info