Virtual Hosting: PAC: Difference between revisions

From The Uniform Server Wiki
Jump to navigation Jump to search
(New page: <span id="top"></span> <div style="padding:0;margin:0; border-bottom:3px inset #000000"> {| | MPG UniCenter || Virtual Hosting: [[Virtual Hosting: Home | Ho...)
 
(Fix grammatical stuff and clarify meaning; Updated broken external link.)
 
(One intermediate revision by one other user not shown)
Line 18: Line 18:
'''PAC and Portability'''<br>'''Uniform Server 3.5-Apollo'''
'''PAC and Portability'''<br>'''Uniform Server 3.5-Apollo'''
|}
|}
On the previous page I covered name-based virtual hosting it uses the local machines Hosts file to resolve domain names. To run a portable development server you need to edit the new target PC’s Hosts file. This page looks at resolving this issue using a PAC file and a portable browser making the server completely portable.
On the previous page I covered name-based virtual hosting. It uses the local machine's Hosts file to resolve domain names. To run a portable development server you need to edit the new target PC’s Hosts file. This page looks at resolving this issue using a PAC file and a portable browser, making the server completely portable.


PAC allows you to simulate a DNS server locally one line per CNAME entry. Unlike the hosts file it is dynamic. PAC is a standard uses a single file and is supported by all new browsers.
PAC allows you to simulate a DNS server locally, with one line per CNAME entry. Unlike the hosts file it is dynamic. PAC is a standard, uses a single file and is supported by all new browsers.


Ever had problems testing sites with a mix of relative, root relative and absolute links ever wanted to test cross-site interlinking the following trio may be what you are looking for. Uniform Server, portable (Firefox or Opera) and PAC make an ideal test environment all on a USB memory stick.
Ever had problems testing sites with a mix of relative, root relative and absolute links? Ever wanted to test cross-site interlinking? The following trio may be what you are looking for. Uniform Server, portable (Firefox or Opera) and PAC make an ideal test environment, all on a USB memory stick.


In the light of issues raised overall Firefox portable is the best option.
In the light of issues raised overall, Firefox portable is the best option.


== Background ==
== Background ==
Testing multi-web sites is relatively easy; first create a virtual host section for each site in the Apache configuration file. Use the '''hosts''' file on your machine to resolve web site IP address that’s it finished. Suppose you do not have access to the host file what alternatives are there.
Testing multi-web sites is relatively easy. First create a virtual host section for each site in the Apache configuration file. Use the '''hosts''' file on your machine to resolve the web site names to IP address. That’s it; finished. Suppose you do not have access to the host file. What alternatives are there?


If you use only relative links on your site you can use the Apache alias and re-map however if your sites are using absolute or root relative links this method will fail.
If you use only relative links on your site, you can use the Apache alias and re-map. However if your sites are using absolute or root-relative links, this method will fail.


Not looking very good, what other methods are there for resolving IP addresses. A local DNS server would do nicely even allow you to enter MX records. That seems a bit of overkill, all we want to do is convince our browser to pick up pages from a different server masquerading as the real server enter the world of proxy servers.
So what other methods are there for resolving IP addresses? A local DNS server would do nicely, even allow you to enter MX records. That seems a bit of overkill, since all we want to do is convince our browser to pick up pages from a different server masquerading as the real server. Enter the world of proxy servers.


'''''[[#top | Top]]'''''
'''''[[#top | Top]]'''''
== PAC ==
== PAC ==
Web browsers can be configured to use a proxy server allowing the use of files or other resource available on a different server.
Web browsers can be configured to use a proxy server, allowing the use of files or other resources available on a different server.


This process is automated with a '''Proxy Auto-Configuration''' (PAC) file. Sounds complicated, not really the PAC file is a simple text file containing a few instructions.
This process is automated with a '''Proxy Auto-Configuration''' (PAC) file. Sounds complicated, but not really. The PAC file is a simple text file containing a few instructions.


Just tell your browser where to find it by setting the appropriate options. Your browser reads this file when it is re-started and whenever it needs to resolve an IP address.
Just tell your browser where to find it by setting the appropriate options. Your browser reads this file when it is re-started and whenever it needs to resolve an IP address.


Any special instruction are executed '''before''' your browser attempts to resolve an IP address this is why PAC is so powerful.
Any special instructions are executed '''before''' your browser attempts to resolve an IP address. This is why PAC is so powerful.


'''''[[#top | Top]]'''''
'''''[[#top | Top]]'''''
Line 48: Line 48:
|-
|-
|valign="top"|
|valign="top"|
The PAC file is a JavaScript consisting of single function. This function receives two parameters ('''url''' and '''host''').<br>Parameters are automatically provided by a browser.
The PAC file is a JavaScript consisting of a single function. This function receives two parameters ('''url''' and '''host''').<br>Parameters are automatically provided by a browser.




Line 64: Line 64:
|}
|}


*'''url''' <nowiki>----</nowiki>The full URL being accessed.
{|
*'''host''' <nowiki>----</nowiki>The hostname extracted from the URL. It is the string between '''://''' and the first ''':''' or '''/''' after that. ''Note'': The port number is not included. If required can be extracted from the URL.
|-
*'''ret''' <nowiki>----</nowiki>The return value a string describing the configuration.
|valign="top"|
*'''url'''
|
The full URL being accessed e.g.: '''<nowiki>http://wiki.uniformserver.com/index.php/Main_Page</nowiki>'''
|-
|valign="top"|
*'''host'''
|
The hostname extracted from the URL. It is the string between '''://''' and the first ''':''' or '''/''' after that e.g.<br><nowiki>http://</nowiki>'''wiki.uniformserver.com/index.php'''/Main_Page<br>
''Note 1'': The port number is not included. If required, it can be extracted from the URL.
|-
|valign="top"|
*'''ret'''
|The return value is a string describing the configuration.
|}


'''Return Value:'''


'''Return Value:<br>'''The JavaScript function must return a single string if the string is null, no proxies shall be used. The string can contain any of the following blocks, separated by a semicolon:
The JavaScript function must return a single string. If the string is null, no proxies will be used. The string can contain any of the following blocks, separated by a semicolon:
{|cellpadding="6"
|-
|'''DIRECT'''||Connections should be made directly, without any proxies.
|-
|'''PROXY host;port'''||The specified proxy should be used. '''''It's this return value we are interested in'''''
|-
|'''SOCKS host;port'''||The specified SOCKS server should be used.
|}


'''DIRECT''' <nowiki>----</nowiki> Connections should be made directly, without any proxies.<br>
There are a number of predefined functions you can use. We are interested in only two: '''shExpMatch''' and '''dnsDomainIs'''.
'''PROXY host;port''' <nowiki>----</nowiki> The specified proxy should be used.<br>
'''SOCKS host;port''' <nowiki>----</nowiki> The specified SOCKS server should be used.


There are a number of predefined functions that can be used within the main function for example isInNet, dnsDomainIs and shExpMatch just to mention a few.
If these do not suit your needs, you can easily find more information on the Internet. This is worth a read, and the site has more PAC info: [http://www.returnproxy.com/proxypac/static/netscape-proxy-format.html Navigator Proxy Auto-Config File Format].
You can look these up on the Internet to find out what they do we are interest in only shExpMatch serves our requirement nicely.


'''''[[#top | Top]]'''''
'''''[[#top | Top]]'''''
== Compare function ==
== Compare function ==
This function compares two strings I think the only special character it accepts is the wildcard character * (matches one or more characters) not a limitation probably makes it easier to use. The function has this format:
This function compares two strings. I think the only special character it accepts is the wildcard character * (matches one or more characters). It's not a limitation and probably makes it easier to use. The function has this format:


'''shExpMatch(str, shexp)'''
'''shExpMatch(str, shexp)'''


{|
{| cellpadding="4" cellspacing="0"
|-
|-
|
|
'''str'''
:*'''str'''
|<nowiki>----</nowiki> any string to be compared for example the URL or the hostname.
|
any string to be compared for example the URL or the hostname.
|-
|-
|
|
'''shexp'''
:*'''shexp'''
|<nowiki>----</nowiki> the expression to compare against can use the wildcard character.
|
the expression to compare against can use the wildcard character.
|}
|}
The function returns true if the string matches the specified expression.
The function returns true if the string matches the specified expression.


Line 101: Line 125:
shExpMatch("<nowiki>http://home.unicenter.com/site2/index.html</nowiki>", "*site1*") is false.
shExpMatch("<nowiki>http://home.unicenter.com/site2/index.html</nowiki>", "*site1*") is false.


The above is just an example, replace the fixed string with a variable such as the url for example:
The above is just an example. Replace the fixed string with a variable such as the url, for example:


(shExpMatch('''url''', "*site1*");
(shExpMatch('''url''', "*site1*");


Any url passed to the above function containing the string site1 (anywhere) will produce true hence can be can be filtered out using an '''if''' statement.
Any url passed to the above function containing the string site1 ('''anywhere''') will produce true.


The result can be filtered using an '''if''' statement. If true do something else continue onto the next line of code.
{| cellpadding="4" cellspacing="1" style="background:#000000;"
{| cellpadding="4" cellspacing="1" style="background:#000000;"
|- style="background:#e8e8e8;"
|- style="background:#e8e8e8;"
Line 115: Line 140:
|}
|}


The url our browser is looking for can be found on the proxy server '''127.0.0.1''' (that's our local test server)
When the comparison is true, the something to do is to return an IP address of a proxy server. The url our browser was looking for can be found on the proxy server '''127.0.0.1''' (that's our local test server). It's this return value that resolves the IP address hence the browser is happy and fetches the information.
Its this return value that resolves the IP address hence the browser is happy and fetches the information.


'''''[[#top | Top]]'''''
'''''[[#top | Top]]'''''
== Complete PAC file ==
== Complete PAC file ==
Add this filter to the PAC function and we have our very own DNS resolver, with the ability to define any CNAME that we wish.
Add this filter to the PAC function and we have our very own DNS resolver, with the ability to define any CNAME that we wish.
Line 134: Line 159:
|}
|}


'''''Note'':''' If a match is not found the function returns a null value. This means the poor old browser needs to do a little more work to resolve the IP address. It checks the hosts file then any local DNS server, as a last resort puts a request onto the Internet to a DNS server.
'''''Note'':''' If a match is not found the function returns a null value. This means the poor old browser needs to do a little more work to resolve the IP address. It checks the hosts file, then any local DNS server, and as a last resort puts a request onto the Internet to a DNS server.


'''''[[#top | Top]]'''''
'''''[[#top | Top]]'''''
Line 144: Line 169:
*127.0.0.1    www.'''ric.com'''
*127.0.0.1    www.'''ric.com'''


With a PAC file specific strings can be targetted, we are interested in is resolving domain names not what is typed into a browser. I have highlighted in bold these domain names. There are only two domains to resolve '''mine.nu''' and '''ric.com''' hence our PAC file requires two lines as follows:
With a PAC file, specific strings can be targeted. We are interested in resolving domain names and not what is typed into a browser. I have highlighted in bold these domain names. There are only two domains to resolve: '''mine.nu''' and '''ric.com''' hence our PAC file requires only two lines as follows:


{| cellpadding="4" cellspacing="1" style="background:#000000;"
{| cellpadding="4" cellspacing="1" style="background:#000000;"
Line 154: Line 179:
function FindProxyForURL(url, host)
function FindProxyForURL(url, host)
{
{
   if (shExpMatch(url,"*mine.nu*")) return "PROXY 127.0.0.1";
   if (shExpMatch(url,"*.mine.nu/*")) return "PROXY 127.0.0.1";
   if (shExpMatch(url,"*ric.com*")) return "PROXY 127.0.0.1";
   if (shExpMatch(url,"*.ric.com/*")) return "PROXY 127.0.0.1";
  return "";
}
</pre>
|}
 
=== Alternative function ===
If you do not like using wild cards, you can use the function dnsDomainIs to directly target a domain name.
 
'''dnsDomainIs(host, domain)'''
 
{| cellpadding="4" cellspacing="0"
|-
|
:*host
|
is the hostname from the URL e.g http://'''wiki.uniformserver.com'''/index.php/Main_Page
|-
|
:*'''domain'''
|
is the domain name to test the hostname against e.g. '''.uniformserver.com'''
|}
 
Returns true if the domain of hostname matches.
 
{| cellpadding="4" cellspacing="1" style="background:#000000;"
|- style="background:#e8e8e8;"
!test1.pac File
|- style="background:#f5f5f5;"
|
<pre style="border:none">
function FindProxyForURL(url, host)
{
  if (dnsDomainIs(host,".mine.nu")) return "PROXY 127.0.0.1";
  if (dnsDomainIs(host,".ric.com")) return "PROXY 127.0.0.1";
   return "";
   return "";
}  
}  
Line 162: Line 222:


'''''[[#top | Top]]'''''
'''''[[#top | Top]]'''''
== Mimic Hosts file ==
== Mimic Hosts file ==
If you do not like using wild cards you can mimic the host file as follows:
You can mimic the host file as follows:


{| cellpadding="4" cellspacing="1" style="background:#000000;"
{| cellpadding="4" cellspacing="1" style="background:#000000;"
Line 173: Line 234:
function FindProxyForURL(url, host)
function FindProxyForURL(url, host)
{
{
   if (shExpMatch(url,"www.my_site1.fredtest.mine.nu")) return "PROXY 127.0.0.1";
   if (shExpMatch(url,"http://www.my_site1.fredtest.mine.nu/*")) return "PROXY 127.0.0.1";
   if (shExpMatch(url,"www.my_site2.fredtest.mine.nu")) return "PROXY 127.0.0.1";
   if (shExpMatch(url,"http://www.my_site2.fredtest.mine.nu/*")) return "PROXY 127.0.0.1";
   if (shExpMatch(url,"www.ric.com")) return "PROXY 127.0.0.1";
   if (shExpMatch(url,"http://www.ric.com/*")) return "PROXY 127.0.0.1";
   return "";
   return "";
}  
}  
Line 182: Line 243:


'''''[[#top | Top]]'''''
'''''[[#top | Top]]'''''
== Feedback from forum (27-6-07) ==
 
This was posted by '''figment88''' and provides another interesting way to use a PAC file; you can read the full post here [http://forum.uniformserver.com/index.php?showtopic=1216 Uniform Forum]. All I have done is a cut and past job.
== Feedback from the forum (27-6-07) ==
This was posted by '''figment88''' and provides another interesting way to use a PAC file; you can read the full post here [http://forum.uniformserver.com/index.php?showtopic=1216 Uniform Forum]. All I have done is cut and paste to here.


I wanted to add an extra tip on top of the UniCenter tutorial. The tutorial shows you how to setup a proxy file so you can have name based virtual hosts without modifying the current computer's HOST file. The examples in the tutorial require you to modify your proxy file (*.pac) to add a line for every new virtual host. In addition, the examples use wildcard matching, so if you name your local site "example" and the real site is "example.com" the browser might not let you load both.
I wanted to add an extra tip on top of the UniCenter tutorial. The tutorial shows you how to setup a proxy file so you can have name based virtual hosts without modifying the current computer's HOST file. The examples in the tutorial require you to modify your proxy file (*.pac) to add a line for every new virtual host. In addition, the examples use wildcard matching, so if you name your local site "example" and the real site is "example.com" the browser might not let you load both.
Line 209: Line 271:
site2 is site2.com
site2 is site2.com
----
----
'''''Comment'':''' My original pact file contained wildcard matching not intentional since I specially wanted to target each site and prevent my browser looking on the Internet. I have included both versions for completness. In contrast figment88 wants to view his development site locally and the published version hence his neat solution.
'''''Comment'':''' My original pac file contained wildcard matching, not intentional since I especially wanted to target each site and prevent my browser looking on the Internet. I have included both versions for completeness. In contrast figment88 wants to view his development site locally and the published version hence his neat solution.


== Summary ==
== Summary ==
The above was just a quick introduction to the PAC file; it is much more powerful and worth further investigation search the Internet for more information. I have only covered what we need for our purpose. The '''test.pac''' file is about as complex as it gets.
The above was just a quick introduction to the PAC file; it is much more powerful and worth further investigation. Search the Internet for more information. I have only covered what we need for our purpose. The '''test.pac''' file is about as complex as it gets.


On the next page I show how to [[Virtual Hosting: Browsers and PAC | plumb the PAC]] file into your browser.  
On the next page I show how to [[Virtual Hosting: Browsers and PAC | plumb the PAC]] file into your browser.  

Latest revision as of 02:34, 10 January 2010

MPG UniCenter

Virtual Hosting: Home | Name based | PAC | Browsers and PAC | Making it portable | Issues

PAC and Portability
Uniform Server 3.5-Apollo

On the previous page I covered name-based virtual hosting. It uses the local machine's Hosts file to resolve domain names. To run a portable development server you need to edit the new target PC’s Hosts file. This page looks at resolving this issue using a PAC file and a portable browser, making the server completely portable.

PAC allows you to simulate a DNS server locally, with one line per CNAME entry. Unlike the hosts file it is dynamic. PAC is a standard, uses a single file and is supported by all new browsers.

Ever had problems testing sites with a mix of relative, root relative and absolute links? Ever wanted to test cross-site interlinking? The following trio may be what you are looking for. Uniform Server, portable (Firefox or Opera) and PAC make an ideal test environment, all on a USB memory stick.

In the light of issues raised overall, Firefox portable is the best option.

Background

Testing multi-web sites is relatively easy. First create a virtual host section for each site in the Apache configuration file. Use the hosts file on your machine to resolve the web site names to IP address. That’s it; finished. Suppose you do not have access to the host file. What alternatives are there?

If you use only relative links on your site, you can use the Apache alias and re-map. However if your sites are using absolute or root-relative links, this method will fail.

So what other methods are there for resolving IP addresses? A local DNS server would do nicely, even allow you to enter MX records. That seems a bit of overkill, since all we want to do is convince our browser to pick up pages from a different server masquerading as the real server. Enter the world of proxy servers.

Top

PAC

Web browsers can be configured to use a proxy server, allowing the use of files or other resources available on a different server.

This process is automated with a Proxy Auto-Configuration (PAC) file. Sounds complicated, but not really. The PAC file is a simple text file containing a few instructions.

Just tell your browser where to find it by setting the appropriate options. Your browser reads this file when it is re-started and whenever it needs to resolve an IP address.

Any special instructions are executed before your browser attempts to resolve an IP address. This is why PAC is so powerful.

Top

PAC file

The PAC file is a JavaScript consisting of a single function. This function receives two parameters (url and host).
Parameters are automatically provided by a browser.


Your browser calls the function using the following line: ret = FindProxyForURL(url, host);

PAC File
function FindProxyForURL(url, host)

{
  ...
}

  • url

The full URL being accessed e.g.: http://wiki.uniformserver.com/index.php/Main_Page

  • host

The hostname extracted from the URL. It is the string between :// and the first : or / after that e.g.
http://wiki.uniformserver.com/index.php/Main_Page
Note 1: The port number is not included. If required, it can be extracted from the URL.

  • ret
The return value is a string describing the configuration.

Return Value:

The JavaScript function must return a single string. If the string is null, no proxies will be used. The string can contain any of the following blocks, separated by a semicolon:

DIRECT Connections should be made directly, without any proxies.
PROXY host;port The specified proxy should be used. It's this return value we are interested in
SOCKS host;port The specified SOCKS server should be used.

There are a number of predefined functions you can use. We are interested in only two: shExpMatch and dnsDomainIs.

If these do not suit your needs, you can easily find more information on the Internet. This is worth a read, and the site has more PAC info: Navigator Proxy Auto-Config File Format.

Top

Compare function

This function compares two strings. I think the only special character it accepts is the wildcard character * (matches one or more characters). It's not a limitation and probably makes it easier to use. The function has this format:

shExpMatch(str, shexp)

  • str

any string to be compared for example the URL or the hostname.

  • shexp

the expression to compare against can use the wildcard character.

The function returns true if the string matches the specified expression.

Examples:

shExpMatch("http://home.unicenter.com/site1/index.html", "*site1*") is true.
shExpMatch("http://home.unicenter.com/site2/index.html", "*site1*") is false.

The above is just an example. Replace the fixed string with a variable such as the url, for example:

(shExpMatch(url, "*site1*");

Any url passed to the above function containing the string site1 (anywhere) will produce true.

The result can be filtered using an if statement. If true do something else continue onto the next line of code.

Filter

if (shExpMatch(url,"*site1*")) return "PROXY 127.0.0.1";

When the comparison is true, the something to do is to return an IP address of a proxy server. The url our browser was looking for can be found on the proxy server 127.0.0.1 (that's our local test server). It's this return value that resolves the IP address hence the browser is happy and fetches the information.

Top

Complete PAC file

Add this filter to the PAC function and we have our very own DNS resolver, with the ability to define any CNAME that we wish.

test.pac File

function FindProxyForURL(url, host)
{
  if (shExpMatch(url,"*site1*")) return "PROXY 127.0.0.1";
  return "";
}

Note: If a match is not found the function returns a null value. This means the poor old browser needs to do a little more work to resolve the IP address. It checks the hosts file, then any local DNS server, and as a last resort puts a request onto the Internet to a DNS server.

Top

PAC and Hosts file

From the previous page we have the following entries in the Hosts file:

  • 127.0.0.1 www.my_site1.fredtest.mine.nu
  • 127.0.0.1 www.my_site2.fredtest.mine.nu
  • 127.0.0.1 www.ric.com

With a PAC file, specific strings can be targeted. We are interested in resolving domain names and not what is typed into a browser. I have highlighted in bold these domain names. There are only two domains to resolve: mine.nu and ric.com hence our PAC file requires only two lines as follows:

test.pac File
function FindProxyForURL(url, host)
{
  if (shExpMatch(url,"*.mine.nu/*")) return "PROXY 127.0.0.1";
  if (shExpMatch(url,"*.ric.com/*")) return "PROXY 127.0.0.1";
  return "";
} 

Alternative function

If you do not like using wild cards, you can use the function dnsDomainIs to directly target a domain name.

dnsDomainIs(host, domain)

  • host

is the hostname from the URL e.g http://wiki.uniformserver.com/index.php/Main_Page

  • domain

is the domain name to test the hostname against e.g. .uniformserver.com

Returns true if the domain of hostname matches.

test1.pac File
function FindProxyForURL(url, host)
{
  if (dnsDomainIs(host,".mine.nu")) return "PROXY 127.0.0.1";
  if (dnsDomainIs(host,".ric.com")) return "PROXY 127.0.0.1";
  return "";
} 

Top

Mimic Hosts file

You can mimic the host file as follows:

test2.pac File
function FindProxyForURL(url, host)
{
  if (shExpMatch(url,"http://www.my_site1.fredtest.mine.nu/*")) return "PROXY 127.0.0.1";
  if (shExpMatch(url,"http://www.my_site2.fredtest.mine.nu/*")) return "PROXY 127.0.0.1";
  if (shExpMatch(url,"http://www.ric.com/*")) return "PROXY 127.0.0.1";
  return "";
} 

Top

Feedback from the forum (27-6-07)

This was posted by figment88 and provides another interesting way to use a PAC file; you can read the full post here Uniform Forum. All I have done is cut and paste to here.

I wanted to add an extra tip on top of the UniCenter tutorial. The tutorial shows you how to setup a proxy file so you can have name based virtual hosts without modifying the current computer's HOST file. The examples in the tutorial require you to modify your proxy file (*.pac) to add a line for every new virtual host. In addition, the examples use wildcard matching, so if you name your local site "example" and the real site is "example.com" the browser might not let you load both.

I made a simple proxy file that solves both these issues

figment88.pac
function FindProxyForURL(url, host) {

if(isPlainHostName(host)) return "PROXY 127.0.0.1";

return "DIRECT";
} 

The isPlainHostName looks for hosts that have a dot. So, I always name my local version of a website as a single word; e.g,

site1 is site1.com
site2 is site2.com


Comment: My original pac file contained wildcard matching, not intentional since I especially wanted to target each site and prevent my browser looking on the Internet. I have included both versions for completeness. In contrast figment88 wants to view his development site locally and the published version hence his neat solution.

Summary

The above was just a quick introduction to the PAC file; it is much more powerful and worth further investigation. Search the Internet for more information. I have only covered what we need for our purpose. The test.pac file is about as complex as it gets.

On the next page I show how to plumb the PAC file into your browser.

Top


Ric