Proxy Autoconfigの記述方法
ネットスケープではProxy サーバの選択を柔軟に行うため、Javaスクリプトを使ってProxyサーバの選択ルールを記述することができます。
FindProxyForURL(url, host)
このルールは、設定ファイルの形でサーバかローカルへ置く必要があり、次の関数を定義することによって、サーバのアクセス方法を制御します。
FindProxyForURL(url, host);
url アクセスするサーバのフルURL
(protocol://hostname:port/patdname?search)host URLから得られるホスト名(hostnameのみ) FindProxyForURL()関数は、ルールの評価結果を次の文字列で返します。
direct Proxyサーバを使用せず、直接接続する proxy host:port 指定されたProxyサーバが使用する socks host:port 指定されたSocksサーバが使用する 上記は以下のように「;"」で結果を続けることができます。もし複数設定されていれば、ブラウザ(閲覧ソフト)はProxy接続が確立するまで、左の設定順で接続が試みられます。
接続が試みられる順番 → proxy proxy1.yok.com; proxy proxy2.yok.comブラウザは前回応答がなかったProxyサーバへ30分後、自動的に再接続を行い、確立できない場合はさらに1時間後、再び接続します。こうして30分毎に再接続が続けられます。すべてのProxyサーバはダウンしていて、directが指定されていない場合、ブラウザはProxyを一時的に無視して、直接接続を試みるかどうかをユーザ(読者)へ尋ねます。これは20分毎の繰り返しです。たとえば、
- proxy proxy1.yok.com:8080; proxy proxy2.yok.com:8000
- proxy1:8080が主サーバで、ダウンもしくは接続できない場合、主サーバが再接続できるまでproxy2:8000が使用されます。
- proxy proxy1.yok.com:8080; proxy proxy2.yok.com:8000; direct
- 上記と同じで、両方のサーバがダウンしていた場合、直接接続を試みます。
(最初の例では、両方のサーバがダウンしていた場合、直接接続するかどうかを尋ねられます)
- proxy proxy1.yok.com; socks socks.yok.com:1080
- 主Proxyサーバがダウンしていた場合、Socksサーバを使用します。
設定ファイルの置き方
まず、サーバ側で後述のJavaScript関数を使い、「xxxx.pac」という名で設定ファイルを作成します。この設定ファイルはMIMEタイプ「application/x-ns-proxy-autoconfig」で送り込み、NCSA httpdサーバの場合、mime.typeへ以下の行を書き込みます。
application/x-ns-proxy-autoconfig pacブラウザ側では、「Network Preferences」の「Proxy」ウィンドウの「Automatic Proxy Configuraion」を選択します。Location(URL)へは、先程のProxy設定ファイルのURLを書き込み、 Reloadボタンを押して設定をロードすると完了です。
クラアイント側に置く場合、「Automatic Proxy Configuraion」のLocation(URL)へProxy設定ファイルのURL("file:/pathname/proxy.pac")を書き込み、Reloadボタンを押して設定をロードすると完了です。
設定ファイルの記述方法
設定ファイルは、ある条件の時にクライアントが直接接続を行うか、どのProxyサーバ、Socksサーバを選択するかを記述していきます。ファイルの基本的なパターンは次のとおりです。
function FindProxyForURL(url, host) { if 条件 return directまたはproxyまたはsocks else if 条件 return directまたはproxyまたはsocks : : else return directまたはproxyまたはsocks }JavaScript関数
ホスト名関連関数
ユティリティ関数
URL/ホスト名関連関数
時刻関連関数
ProxyConfig.bindings
これらの関数の詳細は以下のとおりです。
host: URLから得られるホスト名(ポート番号は除く)ホスト名にはドメイン名がない場合、真を返します
- isPlainHostName("www")なら真
- isPlainHostName("www.yok.com")なら偽
host: URLから得られるホスト名
domain: 評価するドメイン名ホストのドメイン名が一致している場合、真を返します。
- dnsDomainIs("www.yok.com", ".yok.com")なら真
- dnsDomainIs("www", ".yok.com")なら偽
- dnsDomainIs("www.yoc.com", ".yok.com")なら偽
localHostOrDomainIs(host, hostdom)
host: URLから得られるホスト名
domain: 評価するFully Qualifiedホスト名ホスト名が確実に指定されたホスト名に一致している場合、または、ホスト名にドメイン名部がない場合、真を返します。
- localHostOrDomainIs("www.yok.com", "www.yok.com")なら真(完全に一致)
- localHostOrDomainIs("www", "www.yok.com")なら真(ホスト名が一致、ドメイン名は指定なし)
- localHostOrDomainIs("www.yoc.com", "www.yok.com")なら偽(ドメイン名が不一致)
- localHostOrDomainIs("home.yok.com", "www.yok.com")なら真(ホスト名が不一致)
host: URLから得られるホスト名ホスト名がDNS的に解決できる場合、真を返します。
- isResolvable("www.yok.com")なら真(DNS的に解決できれば)
- isResolvable("bogus.domain.yokbar")なら偽
host: DNS的ホスト名、IPアドレス
pattern: IPアドレス・パターン
mask: 一致するアドレス範囲を決定するためのマスクビットホストのIPアドレスが指定されたIPアドレスパターンと一致する場合、真を返します。
- isInNet(207.218.88.2, "207.218.88.2", "255.255.255.255")なら真(完全に一致)
- isInNet(207.218.*.*, "207.218.88.2", "255.255.255.255")なら真
host: 解決するホスト名与えられたDNSホスト名のIPアドレスを返します。
- dnsResolve("w3.lainet.com")なら"207.218.88.2"
ブラウザが動作しているホストのIPアドレスを返します。
- myIpAddress()なら"207.218.88.2"
host: URLから得られるホスト名ホスト名のDNSドメインレベルの数(ドット数)を返します。
- dnsDomainLevels("www")なら0
- dnsDomainLevels("www.yok.com")なら3
str: 比較したい任意の文字列(たとえばURL、ホスト名など)
shexp: 比較するシェル表現(メタキャラクタ)文字列が指定されたシェル表現と一致する場合、真を返します(パターンはシェル表現で、正規表現ではありません)。
- shExpMatch("http://www.yok.com/people/taro/index.html", "*/taro/*")なら真
- shExpMatch("http://www.yok.com/people/taro/index.html", "*/tato/*")なら偽
wd1, wd2: sun(日曜日)、mon(月曜日)、tue(火曜日)、wed(水曜日)、
thu(木曜日)、fri(金曜日)、sat(土曜日)gmt: gmt、またはなし 第1パラメータ(wd1)は必須ですが、第2、第3パラメータは指定しなくても構いません。第1パラメータのみの場合、指定したローカルタイムでの曜日の時間を返し、第2パラメータが"gmt"の場合、グリニッジ標準時間(GMTタイム)での曜日の時間を返します。
また、第2パラメータが曜日の場合、第2パラメータと第2パラメータの間は真を返します。
- weekdayRange("sat")なら土曜日のローカル時間
- weekdayRange("sat", "gmt")なら土曜日のグリニッジ標準時間
- weekdayRange("mon", "fri")ならローカルタイムで月曜日から金曜日までは真
- weekdayRange("mon", "fri", "gmt")ならグリニッジ標準時間で月曜日から金曜日までは真
- weekdayRange("fri", "mon")なら金曜日から翌週月曜日までは真
day: 1〜31(日付) month: jan(1月)、feb(2月)、mar(3月)、apr(4月)、mai(5月)、jun(6月)、
jul(7月)、aug(8月)、sep(9月)、oct(10月)、nov(11月)、dec(12月)year: 西暦(たとえば1996) gmt: あればグリニッジ標準時間、なければローカルタイム(JST) 年月日のパラメータが1つの場合、それと一致する日は真を返し、2つ以上の場合、その範囲内の日であれば真を返します。
- dateRange(1)ならローカルタイムで1日は真
- dateRange(1, "gmt")ならグリニッジ標準時間で1日は真
- dateRange(1, 15)なら1日〜15日は真
- dateRange(24, "dec")なら12月24日は真
- dateRange(24, "dec", 1996)なら1996年12月24日は真
- dateRange("jan", "mar")なら1月1日〜3月31日は真
- dateRange(1, "jun", 15, "aug")なら6月1日〜8月15日は真
- dateRange(1, "jun", 1996, 15, "aug", 1996)なら1996年6月1日〜1996年8月15日は真
- dateRange("oct", 1996, "mar", 2000)なら1996年10月〜2000年3月は真
- dateRange(1996)なら1996年は真
- dateRange(1996, 2000)なら1996年〜2000年は真
hour: 0〜23(時間)
min: 0〜59(分)
sec: 0〜59(秒)
gmt: あればグリニッジ標準時間、なければローカルタイム(JST)指定された時間または時間の範囲であれば真を返します。
- timeRange(12)なら午後0時〜午後0時59分は真
- timeRange(12, 13)なら午後0時〜午後1時は真
- timeRange(12, "gmt")ならグリニッジ標準時間で午後0時〜午後0時59分は真
- timeRange(9, 17)なら午前9時〜午後5時は真
- timeRange(8, 30, 17, 00)なら午前8時半〜午後5時は真
- timeRange(0, 0, 0, 0, 0, 30)なら午前0時0分0秒から30秒後までは真
例1
この例はアクセスしたいWWWサーバのホスト名がhostかhost.yok.comかhost.yuk.comであれば直接接続を行ない、それ以外はProxyサーバproxy.yok.comポー ト番号8080を使用します。そして、Proxyサーバがダウンしている時は直接WWWサーバに接続します。
function FindProxyForURL(url, host) { if (isPlainHostName(host) || dnsDomainIs(host, ".yok.com") || dnsDomainIs(host, ".yuk.com")) return "direct"; else return "proxy proxy.yok.com:8080; direct"; }例2
この例はアクセスしたいWWWサーバのホストhostがDNS解決できれば直接接続し、できなければProxyサーバを使用します。function FindProxyForURL(url, host) { if (isResolvable(host)) return "direct"; else return "proxy proxy.yok.com:8080"; }次の場合はDNSが動いていない時も有効です。
function FindProxyForURL(url, host) { if (isPlainHostName(host) || dnsDomainIs(host, ".yok.com") || isResolvable(host)) return "direct"; else return "proxy proxy.yok.com:8080"; }例3
この例はWWWサーバホストが202.218.*.* にあれば直接接続し、なければProxyサーバを使用します。
function FindProxyForURL(url, host) { if (isInNet(host, "202.218.0.0", "255.255.0.0")) return "direct"; else return "proxy proxy.yok.com:8080"; }次の場合はDNSが動いていない時も有効です。
function FindProxyForURL(url, host) { if (isPlainHostName(host) || dnsDomainIs(host, ".yok.com") || isInNet(host, "202.218.0.0", "255.255.0.0")) return "direct"; else return "proxy proxy.yok.com:8080"; }例4
これは目的によってProxyサーバを分けて使用する例です。
Proxyサーバ アクセスしたいWWWサーバのホスト proxy1 .jpドメイン proxy2 .comドメイン proxy3 他 proxy4 バックアップ "+" は Javaスクリプトの演算子で、文字列をコンカチネートします。
function FindProxyForURL(url, host) { if (isPlainHostName(host) || dnsDomainIs(host, ".yok.com")) return "direct"; else if (shExpMatch(host, "*.jp")) return "proxy proxy1.yok.com:8080; " + "proxy proxy4.yok.com:8080"; else if (shExpMatch(host, "*.com")) return "proxy proxy2.yok.com:8080; " + "proxy proxy4.yok.com:8080"; else return "proxy proxy3.yok.com:8080; " + "proxy proxy4.yok.com:8080"; }例5
これはWWWクライアントホストに応じてProxyサーバを変える例です。WWWクライアントホストが202.218.1.* にあれば、Proxyサーバ"proxy1.yok.com:8080"を利用し、202.218.2.* にあれば、Proxyサーバ"proxy2.yok.com:8080"を利用し、それ以外の場合は直接接続します。
function FindProxyForURL(url, host) { if (isInNet(myIpAddress(), "202.218.1.0", "255.255.255.0")) return "proxy proxy1.yok.com:8080"; else if (isInNet(myIpAddress(), "202.218.2.0", "255.255.255.0")) return "proxy proxy2.yok.com:8080"; else return "direct"; }例6
これはJavaスクリプトのsubstring()メソッドを使い、プロトコル別のProxyサーバを選択する例です。
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"; } }shExpMatch()関数を使って作成することもできます。
... if (shExpMatch(url, "http:*")) { return "proxy http-proxy.mydomain.com:8080; } ...ヒント
設定ファイルは CGI スクリプトの出力を利用すると、より便利になるでしょう。
isInNet()、isResolvable()、dnsResove()関数はDNS機能が必要です。そのため、DNSサーバへ接続できないとProxyサーバが利用できなくなってしまいます。たとえば自分のホストがDNSサーバになったり、ProxyサーバをDNSサーバにできれば、2つのサーバを気にしなくてもよいと思います。
参考文献
http://home.netscape.com/eng/mozilla/2.0/relnotes/demo/proxy-live.html