読者です 読者をやめる 読者になる 読者になる

きくらげ観察日記

好きなことを、適当に。

CGIの仕様

Others Gauche

とある理由からGaucheCGIとかいう謎なことをしなければならなくなったので、ここにメモしておきます。

  1. メソッドは環境変数REQUEST_METHODに保存される。
  2. GETパラメータは環境変数QUERY_STRING、POSTのボディは標準入力。ただし、GET/POSTパラメータはGaucheではcgi-mainの引数の引数に渡される
  3. GETパラメータがhoge=fugaという形式ではない場合、コマンドライン引数にそのまま渡される
  4. 標準出力がヘッダ以降のレスポンスになる
  5. ヘッダにStatus: x があると、レスポンスのステータスコードがxにする。Gaucheでは(cgi-headers :status x)でできる。

試しに以下のようなプログラムを書いてみました。

#!/usr/bin/env gosh
;; example.scm

(use www.cgi)
(use text.html-lite)

(define (main args)
  (cgi-main
   (^(params)
     (list
      (cgi-header :status 404)
      (html-doctype)
      (html:html
       (html:head
        (html:title "Not Found"))
       (html:body
        (html:h1 "404 Not Found")
        (html:div
         "method: " (sys-getenv "REQUEST_METHOD"))
        (html:div
         "params: " (x->string params))
        (html:div
         "args: " (x->string args))
        ))))))

うまく行けば404が返ってきて、パラメータやらメソッドやらが表示されるはずです。

$ # 404が返ってくるはず
$ curl http://localhost/example.scm -o /dev/null -w '%{http_code}' -s
404
$ curl http://localhost/example.scm?hoge=fuga
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
       "http://www.w3.org/TR/html4/strict.dtd">
<html><head><title>Not Found</title
></head
><body><h1>404 Not Found</h1
><div>method: GET</div
><div>params: ((hoge fuga))</div
><div>args: (/var/www/example.scm)</div
></body
></html
>
$ # コマンドライン引数にfoobarが渡される
$ curl http://localhost/example.scm?foobar
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
       "http://www.w3.org/TR/html4/strict.dtd">
<html><head><title>Not Found</title
></head
><body><h1>404 Not Found</h1
><div>method: GET</div
><div>params: ((foobar #t))</div
><div>args: (/var/www/example.scm foobar)</div
></body
></html
>
$ curl -X POST -d bar=baz http://localhost/example.scm
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
       "http://www.w3.org/TR/html4/strict.dtd">
<html><head><title>Not Found</title
></head
><body><h1>404 Not Found</h1
><div>method: POST</div
><div>params: ((bar baz))</div
><div>args: (/var/www/example.scm)</div
></body
></html
>
$ # POSTのときはquery stringはparamsに渡されない
$ curl -X POST -d bar=baz http://localhost/example.scm?hoge=fuga
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
       "http://www.w3.org/TR/html4/strict.dtd">
<html><head><title>Not Found</title
></head
><body><h1>404 Not Found</h1
><div>method: POST</div
><div>params: ((bar baz))</div
><div>args: (/var/www/example.scm)</div
></body
></html
>
$ # でもコマンドライン引数には与えられる
$ curl -X POST -d bar=baz http://localhost/example.scm?hoge
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
       "http://www.w3.org/TR/html4/strict.dtd">
<html><head><title>Not Found</title
></head
><body><h1>404 Not Found</h1
><div>method: POST</div
><div>params: ((bar baz))</div
><div>args: (/var/www/example.scm hoge)</div
></body
></html
>