2010年1月16日土曜日

InfernoのHTTPでCGIを書く

InfernoのHTTPでCGIを作成する方法が分かりました。

・HTTPサーバーの起動

svc/httpd/httpd

オプションは
-D デバッグログを出す
-p ポート

・まずは普通のウェブページの表示方法

/services/httpd/rootというディレクトリの下に
htmlソースを置くとアクセスできる。
index.htmlというファイルを置くと、

http://host/index.htmlまたはhttp://host/ でアクセス可能。

サブディレクトリを作ってもOK。

・CGIのサンプル

CGIはhttp://host/magic というパスでアクセスする。
まずはhttp://host/magic/echo
とアクセスしてみる。
すると、なにやら情報が表示される。
これはファイルシステム上の/dis/svc/httpd/echo.disに当たる。
LimboでかかれたCGIファイルで、ソースは/appl/svc/httpdの下にecho.bがある。
これを真似して、例えば同じ場所にtest.disを置くと、
http://host/magic/test
でアクセスできる。

詳細はecho.bをみると大体わかるが、
通常のシェルコマンドと書き方がちょっと違う。

覚えきれるものでもないので、雛形にしてしまうのがよいか。


implement test;

include "sys.m";
sys: Sys;
include "draw.m";

include "bufio.m";
include "cache.m";
include "contents.m";
include "httpd.m";
Private_info: import Httpd;
include "cgiparse.m";
cgiparse: CgiParse;

test: module {
init: fn(g: ref Private_info,
req: Httpd->Request);
};

init(g: ref Private_info,
req: Httpd->Request)
{
sys = load Sys Sys->PATH;
cgiparse = load CgiParse CgiParse->PATH;
if(cgiparse == nil){
return;
}
cgidata := cgiparse->cgiparse(g, req);
bufio := g.bufio;
Iobuf: import bufio;

# Send header
g.bout.puts(cgidata.httphd);

# Send body
g.bout.puts("<head><title>test</title></head><body>test</body>\r\n");

g.bout.flush();
}


リクエストデータはcgiparseの結果に格納され、
method, uri, headerなどのメンバーで参照できて便利。
フォームデータはformでアクセス出来るのでこれでCGIが実現できるはず。
これはtag, valのペアのリストになっているのでhd, tlメソッドで
簡単に取り出せる。

(tag, val) = hd cgidata.form;
cgidata.form = tl cgidata.form;

のループでOK。

cgidataに関してはcgiparse.mを見ると良い。
関係ないけどacme(エディタ)でimport "cgiparse.m";の所で右クリックすると
ヘッダファイルにジャンプしてくれるので実に便利。

・その他

認証には対応していないように見える。

情報があんまり無いので、結局ソースコードから追った。
時間かかった〜。

0 件のコメント:

コメントを投稿