▼Apache 1.X と 2.0 の違い▼

2.0.35 (2002/04) が 「正式」リリースされてみんなが飛び付いている ようですが、設定ファイルなんかは 1.3 と微妙に互換性がありません。 凝った設定をしているとハマります。

でも将来、移行の苦労をしたくないなら今のうちにスムーズに移行できる書き方 をしてたほうがいいかも。

一応 Upgrading to 2.0 from 1.3 (docs/manual/upgrading.html) という文書もソースについてきますが、あまりきっちり書かれているわけでは ありません (というか不足だと思ったらcontribするのが正しい態度)

$Id: httpd2.html,v 1.15 2002-08-03 03:34:11+09 kabe Exp $


mod_alias と mod_userdir は原則併用不可

ってもなんのことやらという感じですが、 Apache 1.x で使われていた

・特定の人だけ ~/public_html/ ではない
	UserDir	public_html
	Alias   /~except         /home/except/share/htdocs
・~/public_html/cgi-bin/ を特殊扱いする (一般的)
	UserDir	public_html
	ScriptAlias /~cgiuser/cgi-bin  /home/cgiuser/public_html/cgi-bin
というのは、Apache 2.0 ではうまくいきません

UserDir は mod_userdir, ScriptAliasやAliasは mod_alias が担当しますが、 この2つでは mod_userdir の方が強く、UserDir が当たると mod_alias の処理は行われません。ので、

となるので、要注意です。

▽対策

いろいろな方法はありますが、「正しい」方法はたぶん

	## for 1.X & 2.0
	UserDir public_html
	## 特定の人だけ mod_userdir処理を解除する
	UserDir disable except
	Alias   /~except         /home/except/share/htdocs
	## ScriptAlias の副作用でではなく、まじめにハンドラを設定する
	<Directory /home/cgiuser/public_html/cgi-bin>
		Options +ExecCGI
		SetHandler cgi-script
	</Directory>

この書き方は Apache 1.X でも有効。


AddTypeの副作用はなくなる

SSIとCGIが影響を受ける場合があります。

NCSA系では、 ディレクトリ毎ではなく、ファイルの拡張子で SSI や CGI を起動するために

	AddType application/x-httpd-cgi .cgi
	AddType text/x-server-parsed-html .shtml
なんて設定がありますが、Apache 2.0 では「CGI/SSIを起動する」という 副作用がなくなり、単に Content-Type が設定されるだけになります。 (ファイル丸見え。)

Apache 2.0 ではこういった 古くさいNCSAイズムの排除を推し進めているので 要注意。

▽対策

◇ *.cgi を CGIスクリプトとする

	## for 1.X & 2.0
	<Files *.cgi>
		SetHandler cgi-script
	</Files>
該当する <Directory> なり .htaccess なりには当然 Options +ExecCGI が有効になっている必要があります。この書き方は Apache 1.X でも有効。

AddType application/x-httpd-cgi .cgi もまだ有効ではありますが、 擬似的な MIMEタイプ であるのは確かなので今後どうなるかはわかりません。 (MIMEタイプ とハンドラは本来別モノなので)

現実問題として、いきなりx-http-cgiを廃止してしまうと 穴があいても気づかない管理者が大量発生するでしょうから、 廃止されるのはずーーーっと先だと思われますが

◇ *.shtml を SSIで処理する

SSI処理のための INCLUDE フィルタを 出力フィルタ (output filter) として挿入します。

	## for 2.0
	<Files *.shtml>
	## これがないと text/plain のままになる
		ForceType text/html
		SetOutputFilter INCLUDES
	</Files>

2.0.25以降の mod_mimeには、拡張子ベースで追加する AddOutputFilter てのも新設されていて、1.X っぽい書き方もできます。

	## for 2.0.25-
	AddOutputFilter INCLUDES shtml
AddOutputFilterとSetOutputFilter両方を指定した場合の フィルタ実行順が マニュアルを見てもわからんのですが、 ソースを読んだ限りでは AddOutputFilter→SetOutputFilterの 順のようです。 SetOutputFilter は core なので常に使えますが、 AddOutputFilter は mod_mime なのでそういう関係になるのかも。
マニュアルには載ってないのですが、2.0.33 以降には core moduleに AddOutputFilterByType filter mime/type てのがあります。(directory, .htaccess範囲で使用可) 何に使うんだろ。いじらないほうがいいかも? cf.dev@apache [1] [2]

Apache 1.3 での"AddType text/x-server-parsed-html .shtml" の副作用を 明示的に書き下すと

	## for 1.X
	<Files *.shtml>
		ForceType text/html
		SetHandler server-parsed
	</Files>
こう書いておけば 2.0 への移行が少し楽になります。

ただしserver-parsedハンドラは2.0にはありません、 ので 2.0 では思いっ切りエラーになります。 SSI の実装方法が違うためなのですが、移行期間中は 1.X と 2.0 の両方を使うこともあります。 <IfDefine> なんかで切り替えられれば .htaccess が共用できていいのですが、 ぬあんと切り替え方法は用意されてません。 しょうがないので

	## for 1.X & 2.0
	<Files *.shtml>
	  ForceType text/html
	  <IfModule mod_cgid.c>
	    SetOutputFilter INCLUDES
	  </IfModule>
	  <IfModule !mod_cgid.c>
	    SetHandler server-parsed
	  </IfModule>
	</Files>
もっとも、2.0 でmod_cgidがいつも使われてるわけでもないので 確実ではない。サイト毎で細工する余裕があるなら httpd 起動時に -D オプションを渡して <IfDefine> で切り替えた方が いいでしょう。
2.0.25 以降では、なんか SetHandler server-parsed も使えるように なっているようです(本当に「わかりやすい」のか?)

Portは廃止

2.0.26で Port port# は削られました。 基本的に Port は NCSA との上位互換のために用意されていて、 近代 Apacheで Listen やバーチャルホストを使う設定では何かと 混乱の元になっていたものです。

今後は Listen だけを使います。 普通は単に Listen 80 とでも書いておけば 大抵のサイトでは大丈夫ですが、

80番以外で動かしているなら ServerNameも ServerName www.my.site:port# とポート番号を明示しておきましょう。 エラーメッセージの at www.my.site Port num や、CGIの SERVER_PORT 環境変数がここから採られるので、 設定しとかないと CGIから自分自身を指し返せなくなったりします。


日本語でないYO

デフォルトの設定ファイル (httpd-std.conf) には

	AddDefaultCharset ISO-8859-1
てのが仕込まれていて、文字コード指定のない文書には 自動的に Content-Type: text/html; charset=ISO-8859-1 がつきます

が日本人が書くHTMLファイルは大抵 8859-1 ではないので、 この行は削るなりしておかないとハマります。

MultiViewsを標準使用していて、ファイル名をいつも hogehoge.html.ja.jis とかにしている人であれば AddDefaultCharset はそのままでもいいですが

ただしプロトコル的には「指定がなければ ISO-8859-1」が正しいので、 いつまでもブラウザ側の自動コード判別に頼っていないよーに。 (オマエモナ−)

CERT Advisory が出ているとかで「危ないから切るな」と言う人がいますが、 ちゃんとわかった上で危ないと言ってるのはどのくらいいるのか…
単なる静的文書を置いているだけであれば危険は極小です


出力フィルタ

出力フィルタという概念は Apache 2.0 で導入されました。 Apache 1.3 では SSIはハンドラとして実装されていましたが、

	*.shtml
	  ↓
	server-parsedハンドラ → 出力
Apache 2.0 では SSI はフィルタとして実装され、*.shtml を読むのは 通常ファイルを読むためにも使われているデフォルトハンドラになります。
	*.shtml
	  ↓
	デフォルトハンドラ → INCLUDESフィルタ → (その他のフィルタ) → 出力

デフォルトでは以下の出力フィルタが使われます。

これらはハードコーディングされていてユーザーでは変えられないし、 下手に変えてはいけません。 これらのフィルタにデータを流し込むハンドラが、 通常ファイルではデフォルトハンドラ(特に名前がない)、 CGI では cgi-script ハンドラとなります。 SetOutputFilter を指定すると、ハンドラの直後、フィルタの最前列に 指定したフィルタが挿入されます。

今のところ、ユーザーが指定できる出力フィルタとしては INCLUDES (SSI, mod_include) と DEFLATE (deflate/gzip, mod_deflate) しか用意されてませんが、 2.0 が広く使われるようになれば perlやPHPなフィルタも開発されるでしょう。 2.0 がなかなかαにさえならなかったのは、この SSIフィルタがガン だったようです。 実際このフィルタの実装はあんまりきれいではなく、よくこんなんで動いているなと 驚嘆するような複雑な処理をしています。

CGIがハンドラでSSIがフィルタなので、(意味があるかどうかはともかく) CGIの出力をSSIで加工することもできます。

cgidて何よ

マニュアルを読もう。

…まだ日本語版はないのね

CGIゲートウェイを起動するためにプロセスを fork() で分身させるのは、 特にメモリ大食いの 2.0 では高価な処理になります。 threaded/worker/perchildなマルチスレッドMPMでは、 プロセス内に複数の処理が詰め込まれているのでさらに負荷が高い。

ので、まだ軽くてヒープが小さいうちに専用のプロセスを作っておき、 ゲートウェイのfork()→exec()はこれに担当させます。 このプロセスが cgid。 本処理用の各プロセス・スレッドとは名前つきパイプ (Scriptsock) で通信します。

	root 11989 /opt/APSFhttpd/bin/httpd	主制御 (SIGHUPとかはここへ)
	www   9898  /opt/APSFhttpd/bin/httpd	cgid
	www   9899  /opt/APSFhttpd/bin/httpd	本処理プロセス1
	www   9900  /opt/APSFhttpd/bin/httpd	本処理プロセス2

マルチスレッドMPMでは(--disable-cgid とか指定しなければ) cgidが組み込まれます。が、 (FreeBSDのスレッドがへたれているという理由で) 2.0.23 以降では 何も指定せず configure った場合は 1.3 と同様の シングルスレッド型のprefork MPM が選択されるので cgid も使われません。


かべ@sra-tohoku.co.jp
2.0a4 (2000/06) から使ってきた人間からするとイマサラ飛ビ付イテモナ と思うことはある