Virtual Hosting: PAC: Difference between revisions
(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 | 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 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 | 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 | 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 | Top]]''''' | '''''[[#top | Top]]''''' | ||
== PAC == | == PAC == | ||
Web browsers can be configured to use a proxy server allowing the use of files or other | 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 | 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 | 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> | {| | ||
*'''host''' | |- | ||
*'''ret''' | |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:''' | |||
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. | |||
|} | |||
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: [http://www.returnproxy.com/proxypac/static/netscape-proxy-format.html Navigator Proxy Auto-Config File Format]. | |||
'''''[[#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''' | ||
| | | | ||
any string to be compared for example the URL or the hostname. | |||
|- | |- | ||
| | | | ||
'''shexp''' | :*'''shexp''' | ||
| | | | ||
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 | 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 ( | 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 | 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 | 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 | 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 == | ||
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 | == 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 | '''''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 | 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
Virtual Hosting: Home | Name based | PAC | Browsers and PAC | Making it portable | Issues |
PAC and Portability |
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.
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.
PAC file
The PAC file is a JavaScript consisting of a single function. This function receives two parameters (url and host).
|
|
|
The full URL being accessed e.g.: http://wiki.uniformserver.com/index.php/Main_Page |
|
The hostname extracted from the URL. It is the string between :// and the first : or / after that e.g. |
|
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.
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)
|
any string to be compared for example the URL or the hostname. |
|
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.
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) |
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.
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)
|
is the hostname from the URL e.g http://wiki.uniformserver.com/index.php/Main_Page |
|
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 ""; } |
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 ""; } |
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.
Ric |