Logo address

Pegasus httpd 2.2 仕様書

目次

更新: 2006/07/30

Pegasus 2.2 で導入された新しい内容

ダイジェスト認証のサポート

ブラウザ側のダイジェスト認証のサポートが整ってきたようなので Pegasus 2.2 でもダイジェスト認証をサポートしました。
ダイジェスト認証については RFC2617.txt
を参照してください。

日本語のファイル名に対応

漢字や仮名などのファイル名が使えるようになりました。これに関する RFC は比較的新しく2005年の RFC3987なのでブラウザ側の対応が遅れています。

日本語のファイル名へ対応への対応問題は意外とややこしい問題を含んでおり、多分、Pegasus 2.2 はバグを含んでいるでしょう。

Pegasus 2.1 から 2.2 への変更

/sys/lib/httpd.conf

# allowbasic		0	# 1: allow basic authentication
を追加しました。これは 2.1 版までの Pegasus との互換性のための設定で、
	allowbasic	1
にしたときには、ベーシック認証も許可します。allowbasic を httpd.conf で指定しないときには 0 が想定され、ベーシック認証は行われません。

/usr/web/etc/nonce

ダイジェスト認証をしっかり行うためには反射攻撃(リプレイアタック)を防ぐ必要があり、そのためにディレクトリ
	/usr/web/etc/nonce
が使われています。(ダイジェスト認証はサーバモードでのみサポートされています)
このディレクトリはユーザ web から読み書き実行を可能にしておいてください。
以下は筆者の例です。
term% pwd
/usr/web/etc
term% ls -l
d-rwxrwx--- M 8 arisawa web       0 Jul 15 21:55 nonce

$web/etc/passwd

$web はサービスルートです。サービスルートとは CGI のアクセス空間のルートで、例えばシステムユーザの場合であれば
	/usr/alice/web
を意味します。
$web/etc/passwd はパスワードによってアクセス制限を掛けます。この内容は例えば次のようなものです。
#       old format is
#               user key path
#       the key is produced by
#               echo -n 'password' | md5sum
#       for example
#               echo -n 'black cat' | md5sum
#
#       new format is
#               user key path realm
#       the key is produced by
#               echo -n 'user:realm:password' | md5sum
#       for example
#               echo -n 'arisawa:/private:black cat' | md5sum
#
arisawa c05f2777ab3d9488d07d0e3f8e38c79a        /me
arisawa a7f0bde701b79510db88dfa4ae0295cd        /private /private
ベーシック認証とダイジェスト認証では書き方が異なります。3個のフィールドで構成されているのが旧版の形式でベーシック認証だけをサポートします。4個のフィールドで構成されているのが新しい形式でダイジェスト認証とベーシック認証をサポートします。httpd.conf の allowbasic が 0 であればベーシック認証は行われません。

この内容は

旧版のベーシック認証では簡単のため「認証レルム名=保護されるバス名」となっていました。
認証キーは MD5SUM を使って作ります。作り方はコメントに書かれている通りです。ここではパスワードが「black cat」の例を載せています。

$web/doc/~

Pegasus ではシステムユーザ(例えば alice)のドキュメント空間は
	/usr/alice/web/doc/
をルートとしています。以下 host をホストのドメイン名とします。ブラウザによる
	http://host/~alice/foo
のリクエストによって
	/usr/alice/web/doc/foo
の内容がブラウザに渡されます。(但し foo がファイルの場合)
bob を実ホストの管理者としましょう。bob は
	/usr/bob/www/doc/
を bob が公開する host のドキュメントルートとします。
さて旧版の Pegasus では alice のサービス空間と実ホストのサービス空間は完全に分離されていました。この事が Pegasus の高レベルのセキュリティの源泉であり、それに基づくユーザレベルの CGI プログラムの自由を保証しているわけです。しかしちょっとした不便さが残りました。bob はシステムユーザに共通して利用できるようなファイルのサービスができません。
そこで新版ではディレクトリ
	/usr/bob/www/doc/~/
に bob が置いたファイルは alice のサービス空間から参照可能にしました。これらは
	/usr/alice/web/doc/~/
の中に見えます。

実はこの仕組みを考えたのは favicon.ico 対策からでした。Safari などのブラウザはしっつこく favicon.ico を

	http://host/favicon.ico
からゲットしようとします。これが存在しない旨のメッセージをブラウザに渡し続けても、何回も何回も新しい頁をダウンロードするたびに favicon.ico のゲットを試みるのです。
これが通常のサーバに対してであれば大きな問題は発生しないのですが、Pegasus では問題です。http://host/favicon.ico は bob の空間にあるので alice の
	http://host/~alice/foo/
にアクセスしたついでに favicon.ico をとってくると言う訳にはいかないのです。一旦接続が切られ、bob の空間に再接続されます(もちろん自動的に)。このことは認証を伴っている場合にさらに非効率なやりとりになっていきます。

CGI ツールの変更と追加

webm

これはブラウザを通じてサーバ上に自由にファイルやディレクトリを作成するためのツールですが内容的な変更を伴っています。
変更を行った理由は OSX/Safari の問題です。

URI シンタックスの変遷

Pegasus は
	scheme://host:port/path;params?query
の形の URI をサポートしています。この形式は HTTP 1.1 を定めた RFC2068で規定されている
	net_path       = "//" net_loc [ abs_path ]
	abs_path       = "/" rel_path
	rel_path       = [ path ] [ ";" params ] [ "?" query ]
	params         = param *( ";" param )
	param          = *( pchar | "/" )
に沿ったものです。

RFC1630 (1994)

	表題: Universal Resource Identifiers in WWW

RFC1738 (1994)

	表題: Uniform Resource Locators (URL)

ここでは HTTP で使用されている URL のシンタックスを次のように説明しています。

httpurl        = "http://" hostport [ "/" hpath [ "?" search ]]
hpath          = hsegment *[ "/" hsegment ]
hsegment       = *[ uchar | ";" | ":" | "@" | "&" | "=" ]
search         = *[ uchar | ";" | ":" | "@" | "&" | "=" ]

safe           = "$" | "-" | "_" | "." | "+"
extra          = "!" | "*" | "'" | "(" | ")" | ","
unreserved     = alpha | digit | safe | extra
uchar          = unreserved | escape
これを見る限りセミコロンはパス名の一部と変わらない。
セミコロンを使用する例として ftp プロトコルが挙げられている。
ftpurl         = "ftp://" login [ "/" fpath [ ";type=" ftptype ]]
ftptype        = "A" | "I" | "D" | "a" | "i" | "d"
ここで ftptype の "a" は ascii を、"i" は image を、"d" は directory listing を意味しており、これらはファイルの型情報である。(大文字で指定しても構わない)
つまり ";" 以下の情報はファイルアクセスに必要な付加情報であり、パス名の一部ではない。

RFC1808 (1995)

	表題: Relative Uniform Resource Locators

Base:

?y         = <URL:http://a/b/c/d;p?y>
g?y        = <URL:http://a/b/c/g?y>
;x         = <URL:http://a/b/c/d;x>
g;x        = <URL:http://a/b/c/g;x>

RFC1945 (1996)

	表題: Hypertext Transfer Protocol -- HTTP/1.0
ここでは URI が Uniform Resource Identifier として説明されている。
URIs have been known by many names: WWW addresses, Universal Document
Identifiers, Universal Resource Identifiers [2], and finally the
combination of Uniform Resource Locators (URL) [4] and Names (URN)
[16]. As far as HTTP is concerned, Uniform Resource Identifiers are
simply formatted strings which identify--via name, location, or any
other characteristic--a network resource.

URI のシンタックスは
URI            = ( absoluteURI | relativeURI ) [ "#" fragment ]
absoluteURI    = scheme ":" *( uchar | reserved )
relativeURI    = net_path | abs_path | rel_path
net_path       = "//" net_loc [ abs_path ]
abs_path       = "/" rel_path
rel_path       = [ path ] [ ";" params ] [ "?" query ]
path           = fsegment *( "/" segment )
fsegment       = 1*pchar
segment        = *pchar
params         = param *( ";" param )
param          = *( pchar | "/" )
scheme         = 1*( ALPHA | DIGIT | "+" | "-" | "." )
net_loc        = *( pchar | ";" | "?" )
query          = *( uchar | reserved )
fragment       = *( uchar | reserved )
pchar          = uchar | ":" | "@" | "&" | "=" | "+"
uchar          = unreserved | escape
unreserved     = ALPHA | DIGIT | safe | extra | national
escape         = "%" HEX HEX
reserved       = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+"
extra          = "!" | "*" | "'" | "(" | ")" | ","
safe           = "$" | "-" | "_" | "."
unsafe         = CTL | SP | <"> | "#" | "%" | "<" | ">"
national       = <any OCTET excluding ALPHA, DIGIT,
                 reserved, extra, safe, and unsafe>

For definitive information on URL syntax and semantics, see RFC 1738
[4] and RFC 1808 [9]. The BNF above includes national characters not
allowed in valid URLs as specified by RFC 1738, since HTTP servers
are not restricted in the set of unreserved characters allowed to
represent the rel_path part of addresses, and HTTP proxies may
receive requests for URIs not defined by RFC 1738.

RFC2068 (1997)

表題: Hypertext Transfer Protocol -- HTTP/1.1
RFC2068 に述べられている URI シンタックスは RFC1945 と完全に同じ

RFC2396 (1998)

	表題: Uniform Resource Identifiers (URI): Generic Syntax
RFC2396 では URI を "Uniform Resource Identifier"
URL を "Uniform Resource Locator"
URN を"Uniform Resource Name"

o A URI is a sequence of characters, which is not always
represented as a sequence of octets.

o A URI may be transcribed from a non-network source, and thus
should consist of characters that are most likely to be able to
be typed into a computer, within the constraints imposed by
keyboards (and related input devices) across languages and
locales.

o A URI often needs to be remembered by people, and it is easier
for people to remember a URI when it consists of meaningful
components.


URI の一般的なシンタックスを議論している RFC2396 になると param の現れる場所が増えており

	net_path      = "//" authority [ abs_path ]
	abs_path      = "/"  path_segments
	path_segments = segment *( "/" segment )
	segment       = *pchar *( ";" param )
	param         = *pchar
	pchar         = unreserved | escaped |
			":" | "@" | "&" | "=" | "+" | "$" | ","
のようになっています。一見すると param が強化されたように見えますが、このシンタックスを見れば分かるようにセミコロンは segment (ファイルやディレクトリ)の名前の中に任意の数だけ埋め込めるようになっており、事実上名前の一部のように見えます。

RFC2616 (1999)

	表題: Hypertext Transfer Protocol -- HTTP/1.1
さらに RFC2068 の改訂版である RFC2616 になると
	http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]]
のように URI の構成要素としての params の概念は姿を消してしまいます。

RFC3986 (2005)

RFC3986でもセミコロンは RFC2616 と同様の扱いを受けていますが、RFC3986 に載っている relative reference の例がもっと具体的にセミコロンの位置づけを示しています。この例ではブラウザが
	http://a/b/c/d;p?q
にアクセスしたときに得られるドキュメント中の relative reference の例が多数例示されており、その中に
	?y		=	http://a/b/c/d;p?y

	;x		=	http://a/b/c/;x
があります。この例に依ると明らかに ";x" は "?y" のような振る舞いをしない。つまり<a href=";x">がドキュメントの中にあれば、それは "?y" の例から期待される
	http://a/b/c/d;x
ではなく
	http://a/b/c/;x
を意味すると。ここで提示されている例に依るとセミコロンはパス名の一部であるかのように振る舞うと解釈すれば理解できます。

Blacklist

Pegasus 2.0 では過度のアクセスがあったクライアントのIPを /sys/log/blacklist に登録し、pegasus が再起動されるまでアクセスを拒否していたのですが Pegasus 2.1 ではこの仕様を改め、3分間のアクセス停止にしました。この時間は
	/sys/lib/http.conf
lockouttime で調整できます。
以下はこのファイルの内容の一部です。
...
# maxconnect      30      # max connections by a single remote IP
# obstime               3       # observation time to detect burst access (in unit of sec)
# maxaccess     20      # allowed max access in obstime
# lockouttime   180     # lockouttime for maxconnect and maxaccess  (in unit of
...
/sys/log/blacklist にはこれまでどおり、過度のアクセスがあったクライアントのIPの記録が残されます。

mon の実行方法が変わりました。

Pegasus 2.1 では サーバモードでのユーザ web のパスワードを必要としません。
詳しくは monを見てください。

証明書(certificate)

Pegasus 2.0 の頃に比べて https に必要な「証明書(certificate)」作成の環境が変化したので解説します。
-a: cert.html 「証明書(certificate)」の作成

MP3 と MP4

MP3 と MP4 のストリーミングサーバとして働くように手を加えました。
/sys/lib/mimetype に以下のようにデータを追加してください。
.mp3            audio           mpeg           -        y      # Kenar
.mp4            video           mp4            -        y      # Kenar
"# Kenar" は僕のコメントですから記入する必要はありません。

僕の家庭内のLAN環境では問題なく動作しますが、大学と僕の家では途切れ途切れです。また、普通のパソコンをストリーミングサーバにして多人数のアクセスを許した場合にはサーバが保たないと思います。

ソースファイル

Pegasus 2.1 のソースファイルは
http://plan9.aichi-u.ac.jp/netlib/
に置かれています。

ファイル構成のサンプル

Pegasus 2.1 のファイル構成のサンプル
http://plan9.aichi-u.ac.jp/pegasus/man-2.1/example/
に置かれています。この内容は Pegasus 2.0 のものと基本的に変わりません。