説明
download
パッケージ
ChangeLog
リポジトリ
試してみる
- 適当にパッケージを取得して./configure; makeしておく。
- cd srcしておく。
- djbのtcpserverが有るなら、
env - PATH="$PATH" tcpserver -v -c 8 -h -R 0 8888 \
gosh tcpcgi-kickstart.scm
とかやってから(このコンソールにはログが表示されます)、ブラウザで
http://127.0.0.1:8888/
にアクセスする。
- または、
env - PATH="$PATH" gosh tcpcgi-server-kickstart.scm
で、自前のtcp socketで待ち受ける。
-
http://127.0.0.1:8888/wiliki
にアクセスすると、wilikiも動作確認可能(/tmpにデータベースを作るので、試した後は掃除が必要。
- 気に入ったなら、make install。
- インストールしたものの「やっぱりこんなの使えない」と思うなら、make uninstallで削除可能。
- インストールだけなら
gauche-package install --clean \
http://legacy.tir.jp/tcpcgi-0.4.4.2.tgz
一発で完了。
benchmark
少し古い版での測定結果。そのうち、また測定する予定(未定)。
自作自演FAQ
- メタ変数が環境変数に設定されていない
gaucheref:cgi-metavariables経由でメタ変数を取得する事。
- メタ変数がcgi-metavariablesに設定されていない事がある
以下のどちらか。
- メタ変数はクライアントからのアクセスがあった時に設定されるので、初期化時には設定されていない。初期化時にもメタ変数が必要な場合はdelayを使う(サンプルスクリプトのwiliki部分を参考の事)。
- apacheで設定される一部のメタ変数は、tcpcgiには実装されていない(それでも、CGI/1.1は満たしてはいる筈)。
- 能書きに書いてある仕様が実装されてない
以下の機能は、まだ未実装。
- ファイルのLast Modified, Not Modified, Partial Content, 等々
- ディレクトリインデックス
- リダイレクトを簡単に設定できるようにする
- 認証モジュール
- HTTP/1.1の基本的な部分は満たしている(つもり)だが、リクエストのエラー判定部分が甘い
- サイズ的なDoSに対する防衛設定はまだ
- エラードキュメントのhtmlが少ししか無い
- test caseが全然書けてない
- スレッドを利用するcgiを使いたい
今のところ、タイムアウト判定にSIGALRMを使用しているので、スレッドを使う場合は、タイムアウト時に発生するSIGALRMに注意する事。
- 高速動作させたい
keepalive-timeoutを大きくして、前にsquid等の、persistent connectionに対応したreverse proxyを設置する。apache:mod_proxyはpersistent connectionに対応していないようなので、まず速度は出ない。
- SSLを使いたい
前にsquidを置き、squidにSSLをかけさせる。または、google:ucspi-sslを使う。
- 「tcpcgi」よりも「pipecgi」の方が正しい名前では?
その通り。だけどもう遅い。
実装しない機能
- apacheのServerAlias。
- 別名で同一コンテンツにアクセスできるのは混乱の元。
- 代わりに、ServerRedirectとでも言うべき機能を用意した。
- CGI/1.1には無い、apache固有のメタ変数の一部。
- ip/port baseのvirtual host。
根本的な制約
- 並列動作性を得る為に、単一プロセスとしての動作を諦めている為、lisp machine的な、プロセス内での動的なサーバのパラメータ変更は出来ない(変更自体は可能だが、行っても他の兄弟プロセスに伝播しないので役に立たない)。
- scoreboardファイルまたは共有メモリ的な何かを使えば、一応可能。
今後の予定とか
基本的には、ソースを「ToDo」で検索すると見付かる。
- ファイル表示モジュールの高機能化。
- squidの代わりとなるproxyを自前(gauche)で用意する。
- 認証モジュールの作成。
- test caseのコンプリート。
- WiLiKi:Gauche:Packagesに載せてもらう。
- fastcgi?のserverとして動作する機能を追加。
- 実行させるcgiは、起動スクリプトに含めるのではなく、別ファイルにする。
バグとか
ありましたら、この辺に適当に書いておいて下さい。
- squidとの相性の問題か、リダイレクト時に、persistent connectionが切れてしまうようだ。詳細不明。(2005/10/01 03:46:48 JST)
- この時、tcpcgiのログには、間に'empty_request が記録されている。
- 調べてみたところ、squidが、何らかの理由で、明示的に接続を切っているようだ。しかし、tcpcgi側は、接続を切られる毎に、再起動するので、リダイレクトを多用するcgi等では、速度が異様に遅くなってしまう……。
- 分かった。302でのlocation時に、content-bodyとして、リダイレクト先の書かれたhtmlを表示させているが、それのContent-Lengthが不明なので、どこまででコンテンツの終わりかが分からない為に、persistent connectionを切っているようだ。
- apacheでは、Transfer-Encoding: chunkedで送っているので、途中で終わりを指定できる為、persistent connectionを維持できている。
- つまり、Transfer-Encoding: chunkedに対応する必要がある。
- tcpcgiは諦めて、lighttpdにでも移行した方がいい気がしてきた……。
- 更に調べたところ、squidは、そもそも、Transfer-Encoding: chunkedには対応していない事が分かった。
- 原因は、tcpcgiが、location時に、誤って、Content-Length: 0を送っていたバグだった。
- 今考えると、大元の原因は、rfc的に、POST後は一旦persistent connectionを切るのが正しい挙動で、squidはその通りに動いていただけだった。
- しかし、これ関連で色々バグ出しできたので、よしとする。
- 不正なリクエストの判定が甘い。(2005/10/01 04:08:57 JST)
- 以下のようなリクエストは、400で弾いていいと思う。
- REQUEST_METHODがGETやPOST等の通常のものでない
- 現状は、ABCとか適当なものでも、そのままファイルを出力しようとしたり、cgi-thunkを呼び出したりしている(特に、gaucheのwww.cgiのcgi-mainが、methodを判定できずにエラーを出してしまうので、対策が必要)。
- OPTIONSとか来たら、501でも返すようにする事。
- HTTP/0.9形式の、ファイル名だけのリクエスト(のように解釈可能な、空白を含まない(バイナリ?)文字列)
- 今は、何故か、内部で、Unknown REQUEST_METHODエラーが出ている。おそらく、何故か、cgi-parse-parameter等を実行してしまっている。
- スラッシュで始まっていないなら、問答無用でエラーにしてもいいと思う。
- 同様に、cesで日本語変換できないバイナリ文字列が来た時も、エラーにする事。
- ces変換可能なバイナリ文字列は、それらしく扱う事……。
実際に使ってみて感じた問題点
- 設置がかなり面倒。
- 単体で使う分には、それほど面倒でもないが、本格的にtcpserver+squidの構成にしようとすると、結構な量の設定ファイルや起動スクリプト等を書かなくてはならない。セキュリティ向上の為に、権限を分割したりすると、更に面倒。
- 更に、エラー発生時のテンプレートや、エラー通知の仕組みを用意するなら、より一層面倒。
- tcpcgiの起動スクリプトの評価/実行時にエラーがあった際に、アクセスが全滅する。
- 現在は、tcpcgiの起動スクリプト内に、各cgiの本体を含める形式にしている為、どれかのcgiにsyntax/readエラーが起こると、全滅してしまう。これはまずい。
- 矢張り、各cgiは、少なくとも、ファイルを分ける必要がある。
- インタラクティブ開発が微妙に困難。
- tcpcgiは、起動スクリプト内に各cgiの本体を含む為、コードを書き換えた際に、tcpcgiの再起動が必要となる。
- コンテンツの増加に対応しづらい
- 普通、ウェブページはどんどん増殖する。
- cgi等の動的コンテンツも、新しく作ったら追加させたい。
- しかし、現状では、動的コンテンツを増やす事に毎回、起動スクリプトの修正が必要になってしまう。
- 元々は、単機能な、cgi専用のhttpdとして作ったものの、やっぱり、httpdとして使うなら、楽に更新できる仕組みが必要だと実感。
- やっぱり、SIGALRMを使うのは、微妙。
- しかし、HTTPリクエストの途中で詰まった場合に備えてタイムアウトさせる、他の方法が思い付かない。スレッド使う?
上記の問題点を踏まえて、次のバージョンを作るなら?
- 設置が面倒なのは、諦める。
- 起動スクリプトや設定ファイルのサンプルを含めて、お茶を濁す。
- httpdとcgiスクリプトの分離は必須。
- 分離させる事で、評価の遅延実行が可能となり、エラーで死ににくくなる。
- 代わりに、cgiスクリプトは毎回評価されてしまう事になる?
- この場合、結局、fcgi等の実装が必要になる???
- 現状の起動スクリプト方式なら、各cgi毎の微妙な設定が楽に行えるというメリットもあるが、これも諦めるのか?
- 分離する事で、以下の機能が使いにくくなる。
- nphスクリプトかどうかの判定
- 各種のリダイレクト設定
- zopeのように、httpd自体に、コンテンツマネージャ的機能を含める?
- きっちりと実装する気力はない……。
- しかし、簡単なものは、用意したい気もする。
- apacheでいう.htaccess的ファイルによる動作設定を可能にしたい
あとがき
- WiLiKi:Gauche:RemoteSlideで利用してもらいました。
- これを見て思い出したのは、元々に想定していた用途は、組み込みの管理画面(要するに、よくあるルータの管理画面とか、ゲームとかの設定ツールとか)に使う為のhttpdを目的として作っていたという事。このWiLiKi:Gauche:RemoteSlideでの使い方は、結構それに近いような気がする。
- しかし、作っている最中に時間が経ち、その当初の利用目的の方がどっかに行ってしまった。
- 更に、折角だからという事で、ここ(e.tir.jp)のウェブサーバに利用してみる事にしたら、前述の「実際に使ってみて感じた問題点」の項目が非常に多い事に気付いた。こういう点では、既存のhttpdには全然敵わないという結論となった。
- 今後の開発について。
- tcpcgiをこれ以上発展させても、どうにも既存のhttpdに勝てるような気がしないし、cmsサーバとかを実現するならKahuaをベースにした方がずっと良いように思えるので、tcpcgiとしての開発はこれ以上進める気はありません。が、こういうGauche用ウェブ用途モジュールの開発は色々と続ける予定。
- とりあえず次は、とある用途に必要な為、とあるperl用コマンドのGauche用cloneを作成予定。
最終更新 : 2012/01/04 05:54:00 JST