社内SEの徒然なる日記

proxy.pac(プロキシパック)対応 No.9 pac作成(基本)

■ 部品作り

過去8回に渡る記事により、ようやく準備が整いました。

後は、FindProxyFor関数で受取った引数の内容から、直接接続させたいURL(又はホスト名)だった場合は、"DIRECT"を返却し、それ以外の場合は、プロキシサーバーを経由させれば良いわけです。

当然、書き方はいくつか存在するので、ここから具体的に事例を書いていきます。

なお、プロキシサーバーのIPアドレスは192.168.1.100、ポート番号は80だったとします。

■ shExpMatch関数(特定の文字を含むサイト)

仮に、グループウェアサーバーのIPアドレスが192.168.1.20だったとして、このサーバーには直接接続したいとした場合、こう書くことが出来ます。

function FindProxyForURL(url, host) {

// 192.168.1.20で始まるurlは直接接続
if (shExpMatch(url, "http://192.168.1.20*")) {
return "DIRECT";
}

// 上記以外の場合は、プロキシサーバーを使用する
return "PROXY 192.168.1.100:80";
}


初登場の、shExpMatch関数を使用しました。
この関数は、第一引数の値が、第二引数のパターンに一致しているかを判断することが出来ます。

出来ますっていうか、参考にしたサイトに、そのように書いていました。
パターン、っていうのが、具体的にどのように記述すれば良いのか分らなかったのですが、「*(アスタリスク)は、0以上の文字を表す」って事は間違いないようです。

上の例では、urlが「http://192.168.1.20」で始まる場合は、直接接続になります。

実際には、ホスト名を使用した指定も必要だと思います。
IPアドレス「192.168.1.20」のホスト名が「GROUPSV」だとすると、こうなります。

function FindProxyForURL(url, host) {

// グループウェアは直接接続
if (shExpMatch(url, "http://GROUPSV*") ||
shExpMatch(url, "http://192.168.1.20*")) {
return "DIRECT";
}

// 上記以外の場合は、プロキシサーバーを使用する
return "PROXY 192.168.1.100:80";
}


■ isPlainHostName関数(ローカル端末との切り分け)

上では、shExpMatch関数を使用して、特定のアドレスは直接接続としました。
しかし、たいていの場合は、自社内のシステムについては直接接続で良いはずです。

それを実現するのが、isPlainHostName関数になります。
この関数は、引数として受けたホスト名を受取り、ローカル端末なら真(True)、違うなら偽(False)を返却します。

function FindProxyForURL(url, host) {

// ドメインが無い場合はダイレクト
if (isPlainHostName(host)) {
return "DIRECT";
}

// 上記以外の場合は、プロキシサーバーを使用する
return "PROXY 192.168.1.100:80";
}


この、isPlainHostNameって関数。何を持って真偽を判断しているのかと思ったのですが、単純に引数にピリオドを含むかどうかを見てるだけなようです。

例えば、先ほどのグループウェアに「http://GROUPSV/"」とアクセスした場合、引数hostの値は「GROUPSV」です。ピリオドを含まないので、ローカル端末、つまり真(True)を返却します。

次に、「http://192.168.1.20/」とアクセスします。アクセスする場所は同じでも、引数hostの値は「192.168.1.20」になります。
ピリオドを含むので、ローカル端末ではない、として偽(False)が返却されます。

社内のシステムには、必ずホスト名を使用してアクセスするって決まりを徹底出来るなら、これは有効ですね。なにせ、名前解決さえしっかりすれば、proxy.pacの修正をしなくても良いわけですから。

■ myIpAddress関数(自端末の状態で切り分け)

ここまでは、接続先によって処理を分ける例ですが、時には接続する端末によって動作を変更する事もあると思います。

そこで役に立つのが、自身のIPアドレスを返却するmyIpAddress関数です。

自端末のIPアドレスが「10.1.10.1」の場合、プロキシサーバーに接続しないとすると、こうなります。

function FindProxyForURL(url, host) {

if (myIpAddress() == "10.1.10.1") {
return "DIRECT";
} else {
return "PROXY 192.168.1.100:80";
}

return "DIRECT";
}


実際には、複数のプロキシサーバーがある時に、端末によって使うプロキシサーバーを切り分けるような時に使用すると思います。

myIpAddress関数と、shExpMatch関数を駆使すれば、いろいろと判断できますね。
例えば、こんな感じですか。

var myIp = myIpAddress();
if (shExpMatch(myIp, "10.1.10.*")) {
return "PROXY 192.168.1.100:80";
} else {
return "PROXY 192.168.1.200:80";
}


■ substring関数(プロトコルによる切り分け)

そもそも、インターネットへの接続のためにプロキシサーバーを使う訳ですから、使用しているプロトコルがインターネット関係の場合のみ、プロキシサーバーを使えば良いわけです。
発想としては、自社内のシステムは直接接続するっていうisPlainHostName関数と同じものですね。

面白い関数があるって訳ではなく、substring関数(文字列から指定した位置にある文字列を取得する関数)を使って力ずくで何とかします。

function FindProxyForURL(url, host) {

// プロトコルがhttp、ftp、httpsの場合はプロキシを使用
if (url.substring(0,5) == "http:" ||
url.substring(0,6) == "https:" ||
url.substring(0,4) == "ftp:") {
return "PROXY 192.168.1.100:80";
}

return "DIRECT";
}


substring関数は、開始インデックスと終了インデックス-1の範囲で文字を取得します。
ネットのプロトコルは、先頭に記述されているので、先頭から該当するプロトコルの分だけ引数urlから取得して、判定すればよいわけです。

おそらく、http、https、ftpの3つを指定しておけば、まず問題なく動作すると思います。

■ 後書き

おそらく、今回紹介した関数を組み合わせるだけで、上手く動くプロキシパックが作れると思います。

私の場合、isPlainHostName関数、shExpMatch関数、の順に実行して該当したら直接接続。それを突破したら、substring関数で指定したプロトコルだったらプロキシサーバーを使用。判定できなかった場合は、直接接続って感じで作っています。

今回は紹介しなかったのですが、DNSを使用して名前解決できたら云々っていう類の関数も存在します。しますが、使わない方が良いし、使う場合も最小限に留めた方が良いと思います。

本音では使っても問題は無いと思うのですが、若干ですが通信や処理の負荷が増大するのは確かです。ならば、あえて使う理由は無いかなと。

機能としては面白いので、次回はそのあたりの関数で遊んでみます。


前回:proxy.pac(プロキシパック)対応 No.8 pac作成(デバッグ)
次回:proxy.pac(プロキシパック)対応 No.10 pac作成(DNS)

投稿記事の一覧:http://harikofu.web.fc2.com/

--- blog end ---

スポンサードリンク

PageTop

コメント


管理者にだけ表示を許可する