D言語で、CGIを作成する場合のノウハウをここでは紹介します。ここで書く内容のデバッグは ローカルサーバ上では正しく動作することを確認した上で行ってください。最初から作り始めたものを使って、無限ループなどさせてしまっては、サーバー管理者に怒られてしまいますから。(^^;
win版では正しく動作するのに、freebsdではcoreを出力して死んでしまう場合があります。 そういった場合にはprintfで細かく何処まで通っているか見ようと思っても、何も出力されずに困ってしまいます。そこで、logファイルにlog出力する関数を利用すると便利です。
import std.file; void log(char[] str){ append("log.txt",str~"\n"); }
使い方
log("debug1"); log("debug2"); log("debug3");
出力例(log.txt)
debug1 debug2
このファイルをftpでダウンロードしてみると、debug1とdebug2は動いていて、debug2とdebug3の間で死んでいることがわかります。
CGI では、 CGI の処理が始まる前に CGI 失敗することがあります。スクリプト言語などでは /usr/bin/perl などのパスが間違っているというものが典型でしょうか。 D などのコンパイル言語でもコンパイルした環境と実行環境で共有オブジェクトのバージョンが異なる、転送に失敗してファイルが破損している、などの場合に起こり得ます。この場合のエラーメッセージはもちろんブラウザには表示されず、プログラムが起動していないため上記方法でもログを残すことはできず、 Apache のログでも Premature end of script headers というほとんど意味の無い情報しか得られません。
このため、とりあえず転送したコマンドが実行可能なものであるかを確認するために、他の CGI からチェックしたいコマンドを実行してエラーメッセージを確認するという方法が考えられます。例えば以下のようなものを作れば良いでしょう。(もちろんこの CGI のパーミッションなどは絶対に間違えないこと。泥沼に行けます)
#!/bin/sh echo Content-Type: text/html echo cd dumncgi_dir ./dumncgi.cgi 2>&1
このようなスクリプトを毎回転送するのは面倒なので、 dumncgi.cgi の部分を可変にして入力フォームから受けとることも考えられます。そのようなスクリプトは他の人に実行されると非常に危険なので BASIC認証やクライアント認証をかけた場所に配置するべきです。