scgiとfcgiって、fcgiの方が多機能だけど、リクエスト時の動きは一緒と思ってたのだが、結構違った。
paster create -t paste_deploy で作成されるサンプルアプリケーションで、PATH_INFOを調べてみた結果です。
fcgiの場合
/a にマウント
http://localhost/a
- PATH_INFO
- ''
- SCIPT_NAME
- '/a'
http://localhost/a/b
- PATH_INFO
- '/b'
- SCIPT_NAME
- '/a'
/ にマウント
http://localhost/
- PATH_INFO
- ''
- SCIPT_NAME
- '/'
http://localhost/a
- PATH_INFO
- ''
- SCIPT_NAME
- '/a'
scgiの場合
/a にマウント
http://localhost/a
- PATH_INFO
- '/a'
- SCIPT_NAME
- ''
http://localhost/a/b
- PATH_INFO
- '/a/b'
- SCIPT_NAME
- ''
/ にマウント
http://localhost/
- PATH_INFO
- '/'
- SCIPT_NAME
- ''
http://localhost/a
- PATH_INFO
- '/a'
- SCIPT_NAME
- ''
と、PATH_INFOとSCRIPT_NAMEの分け方が逆。
fcgiは全部SCRIPT_NAME側に振られるけど、scgiはPATH_INFOに振ってくる。
ただし、scgiの場合はscriptNameを設定できるわけで、scriptName=/a で、/a にマウントした場合が以下
http://localhost/a
- PATH_INFO
- ''
- SCIPT_NAME
- '/a'
http://localhost/a/b
- PATH_INFO
- '/b'
- SCIPT_NAME
- '/a'
これはfcgiで、/a にマウントした場合と同じ振るまいをする。
scgiを使う場合はscriptNameのデフォルトが''なので、/a にマウントした場合は、pasteの設定でも/aをscriptNameにしないとだめ。
ところで、fcgiで/ にマウントした場合の挙動が非常に気になる。
すべて、SCRIPT_NAMEになってしまうのはいかがなものか。
scgiの挙動の方が正しく思える。
SCRIPT_NAMEは実体までのパスで、PATH_INFOはそれ以降の仮想的なパスという意味合いを持つ。
とすれば、同じWSGIアプリケーションに対するリクエストで、SCRIPT_NAMEが変わってしまうのは納得がいかない。
というか、WSGIで使われているディスパッチャはたいていPATH_INFOをみているわけで、うまく動かない。
Djangoでも、lightyの/にfcgiでマウントするとうまく動かなくなるという話を聞いているが、おそらくこれ原因じゃないだろうか。
/にマウントした場合、REQUEST_URIを使ってしのいでいるらしいが、おそらくSCRIPT_NAMEを使っても同様の動作となるだろう。
正しく動かすには、scgiでマウントさせるのが良さそうだ。
実際、Pylonsでも試してみたが、fcgiで/にマウントすると、うまく動かず、scgiに変更したら正常に動作した。
|