2010/08/14

HTTPDのプロキシサーバ機能

NILScriptのHTTPDには、プロキシサーバとして動作してブラウザからのリクエストに応答し、コンテンツを書き換えたりするという機能も用意されています。
プロキシ機能を使用するには、HTTPD初期化時の引数オブジェクトに、以下のようなメンバを指定します。
後は、ブラウザで「プロキシ自動設定スクリプト」などの欄に「http://localhost/__proxy__/conf.pac」を指定すれば、「useProxy」の条件に一致し「noProxy」に一致しないURLへのアクセス時に、NILScriptのHTTPDのプロキシ機能を経由してアクセスされます。
実際の例はNILScriptに同梱の「sample\HTTPD.ng」を参照してください。また、メソッドなどの詳細はNILScriptに同梱の「doc\HTTPD.txt」で説明されています。
 useProxy:"http://",
 noProxy:"http://localhost/",
 proxyRequest:function(c){
  println(c.method+' '+c.url);
  if(c.url.host=='lukewarm.s151.xrea.com'){
   c.addScripts(function(){
    TestPlugin.serverSideTest(['proxy @ '+location.href])
   });
   if(c.url.path.match(/\.png$/)){
    c.cache=Main.scriptDirectory.directory('cache');
   }
  }
 },
 proxyResponse:function(c,r){
  if((c.url.host=='lukewarm.s151.xrea.com')
      &&(c.url.path.match(/\.dat$/))){
   r.lines.invoke('split',/<>/).addIndex()
    .execute(function([i,[name,mail,date,message,title]]){
    if(i==0){
     c.beginHTML(title);
    }
    c.write('<h3>'+(i+1)+': '+name+'('+mail+') - '+date
      +'</h3><p>'+message+'</p>');
   });
   c.endHTML();
  }
 },
プロキシとしての動作を指定しているのは、「proxyRequest」と「proxyResponse」の2つのメンバです。

proxyRequestの関数は、プロキシのリクエストを受取った時点で呼ばれます。
第1引数には通常のコンテンツ生成関数と同じようにConnectionオブジェクトが与えられ、その機能でリクエスト情報の取得やレスポンスの送信などを行えます。
また、HTML中に任意のスクリプトを挿入する「c.addScript()」や、テキストやHTMLノードに対するフィルタリングを行うメソッド群など、プロキシハンドラ専用の機能もいくつか用意されています。
addScript()で埋め込めるスクリプトでは、HTTPD上に定義したサーバ側関数なども利用できます。

「c.cache=」のようにすれば、レスポンスボディを保存するキャッシュファイルを指定できます。この場合、キャッシュファイルがあれば本来のリクエストを行わずにそれを返し、無ければ受信しながらキャッシュファイルとして保存するという動作になります。
また、「c.error(404)」のようにして、本来のリクエストを行わずにエラーを返したり、「c.write()」などで自前のコンテンツに差し替えてしまうことも可能です。

proxyRequestの中で送信が行われなかった場合、リクエストに従ってアクセスを行いレスポンスヘッダの取得までが行われ、proxyResponseで指定した関数が呼ばれます。
この時、第1引数にはConnectionオブジェクトが、第2引数にはリクエストにしたがって行ったHTTPリクエストのResponseオブジェクトが与えられます。Responseオブジェクトの機能の詳細については、「doc\HTTP.ng」の方で説明されています。

ここでは、レスポンスヘッダを書き換えたり、エラー時に代替コンテンツを生成して返すなどの処理を行うといいでしょう。
また、第2引数のレスポンスオブジェクトからレスポンスボディを読み込んで、そこから抜き出した情報を元にレスポンスを生成することも出来ます。


プロキシ機能を利用すれば、ブラウザを問わずに利用できる様々なブラウジング補助機能を実現できます。
ただし、ブラウザの設定を変更してプロキシを設定しなければならないという難点があるので、できるだけ通常のコンテンツ生成関数を利用した方がいいかもしれません。
例えば、あるWeb掲示板の表示を見やすくする機能を作りたい場合は、ページを取得して見易いHTMLに加工して返すというコンテンツ生成関数をHTTPD上のURLに割り当て、プロキシ機能では掲示板のURLから用意したURLへのリダイレクトのみを行うようにしておくのです。
こうすれば、プロキシ機能を利用できなくても、HTTPD上のURLへ直接アクセスすれば、用意された機能を利用できます。

0 件のコメント:

コメントを投稿