Kenji Arisawa
E-mail: arisawa@aichi-u.ac.jp
Aichi University
Kurozasa 370, Miyoshi-cho
Aichi, Japan

2002/03/19
Powered by Pegasus

実行ハンドラ

実行ハンドラと言うのは多分 Pegasus 独自の機能で、特定のパスパターンのファイルに対して、それを処理するプログラムをユーザが指定あるいは組み込める機能です。 Pegasus ではこれを、CGI プログラムの定義や SSI (server side include) の機能の実現、さらにある特定のディレクトリに対して index.html が存在しない場合にファイルの一覧を表示する機能の実現のために使用されています。

■ 設定の方法

サービス空間の中の /etc/handler に、パスパターンとコマンドを結びつける行を書く。筆者のサーバ(http://plan9.aichi-u.ac.jp)のファイルの内容は次のようなものです。
    # path      mimetype    ramfs    execpath arg ...
    /netlib/*/index.html text/html 0 /bin/ftp2html
    *.http         -         0       $target
    *.html      text/html    1       $target
    *.dx_html   text/html    0       /bin/dx
この表は、パスパターン(第1項)によって、そのファイルを処理するプログラム(第4項)と処理の方法(第2項と第3項)を表しています。パスパターンの比較は上の行から行われ、マッチすればそこで終ります。第5項目以降でプログラムの引数を指定する事もできます。

パスパターンの指定において `/' は基本的に他の文字と同じ扱いですが(従ってシェルのパスパターンの扱いと同じではありません)、1つの例外があります。

	/netlib/*/index.html
のように、/*/ のパターンは / にマッチすると言うルールが追加されています。(このルールは Pegasus が ftp ディレクトリを扱うのに都合の良い様にできている訳です。)

第2項は HTTP ヘッダの ContentType を表しています。これが `-' の場合にはプログラムは HTTP ヘッダを自ら出力する必要があります。

第3項はプログラムの実行に伴って ramfs がサービスされるか否かを表しています。

第4項は実行プログラムが指定されます。第4項以降に現れる $target はリクエストされたドキュメントの絶対パスを表しています。第4項が $target になっていると言う事は、要求されたドキュメントが実行プログラムである事を意味しています。

第5項目以降に実行プログラムの引数を書くことができます。引数の最後が $target で終る場合には、$target を省略できます。

なおこの例に現れた /bin/ftp2html はftp のディレクトリを 扱うために筆者が使用しているツールです。他のサーバでは、index.html がない場合にディレクトリの内容を表示するオプションがあったりしますが、それと類似の機能を持っていますが、それだけではなく README があった場合にはそれも表示するとか、INDEX があった場合には、ディレクトリの内容ではなく INDEX の内容を気のきいたやり方で表示するとかします。
また/bin/dx は筆者が作成して使用している SSI の機能を実行する(もっと一般的な、そしてシンプルな)ツールです。

■ CGI との関係

Pegasus 1.0 では、いわゆる CGI ファイルは実行ハンドラの単なる1つの形式として扱われています。

Pegasus 1.0 では 「CGI」と言う用語は意味を失っているのですが、慣用的にハンドラの意味でこの言葉の使用を継続する事にします。

■ URI との関係

HTTP/1.0 及び HTTP/1.1 では URI のドキュメントへのパスに続いて paramquery を書くことができます。即ち、次の様になっています。
	path;params?query
	params = param[;params]
Web のサーバは(伝統的には) param を無視し、query をデコードして CGI に引数として渡している様です。Pegasus はこの伝統的な方式を改め、 param を実行ハンドラに引数として渡すべき部分であると認め、他方 query に関してはサーバは解釈に関与しないことにしました。(query の値は単に環境変数として実行ハンドラに渡る。)

■ CGI の名前空間(ハンドラの名前空間)

CGI プログラム(ハンドラ)が見る名前空間は、サービス空間の中でのファイル
	/etc/namespace.cgi
で再編成できます。
このファイルが存在しない場合、あるいは存在しても再編成をしていない場合には、CGI プログラムが見る名前空間はサービス空間と同じです。

■ CGI の環境変数(ハンドラの環境変数)

Pegasus は多数の環境変数を持っていますが、しかしながら現在の版では多くはま だ確定してはいません。確定的なのは以下に掲げる少数の環境変数だけです。
	GATEWAY_INTERFACE
	SERVER_NAME
	SERVER_PORT
	SERVER_SOFTWARE
	SERVER_PROTOCOL
	REQUEST_METHOD
	REMOTE_ADDR
	QUERY_STRING
	HTTP_HEADER
	HTTP_HOST
	HTTP_REFERER
	HTTP_USER_AGENT
	home		# /doc
	query		# QUERY_STRING に同じ
	target		# 要求されたドキュメントの(サービス空間での)パス
	name		# taget の basename
	cputype		# 386
	objtype		# 386
	date		# 'Mon, 04 Mar 2002 07:32:40 GMT' のような時刻

他の環境変数は将来廃止されるかも知れないし、また名称が変更されるかも知れま せん。

■ POST データのハンドリング

POST データは一旦サーバ(Pegasus)がクライアントから受け取ります。(その際に実際に受け取ったデータ量と Content-Length の整合性がチェックされます。)
次にサーバ(Pegasus)はこの POST データを CGI の標準入力に渡します。(従って POST データのパーサは Content-Length を調べる必要は無いはずです。)

■ CGI timeout(ハンドラのタイムアウト)

問題のある CGI がいつまでもデータの到来を待っているのを防ぐためにタイムアウトが定義されています。この時間は httpd のオプションで指定できます。暗黙の値は 5 秒です。