ちょっと変わったCGI
CGIというとRubyやらPerlやらで書く人が多いと思いますが、CやC++でも書けるようです。
hello.cppを次のように作ります。文字コードはEUCにしておいてください。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
class Page {
protected:
char title[256];
public:
Page() {}
virtual ~Page() {}
virtual void printHeader() {
printf("Content-type: text/plain;charset=x-euc-jp\n\n");
printf("<html><head><title>%s</title></head><doby>\n", this->title);
}
virtual void printBody() = 0;
virtual void printFooter() {
printf("</doby></html>\n");
}
virtual void printHTML() {
printHeader();
printBody();
printFooter();
}
};
class Test : public Page {
public:
Test() {
strncpy(this->title, "てすとです。", 256);
}
virtual ~Test() {}
virtual void printBody() {
fprintf(stderr, "%s:%s:%d\n", __FILE__, __FUNCTION__, __LINE__);
printf("<form action=\"./hello.cgi\" method=\"get\">\n");
printf("名前:<input type=\"text\" name=\"name\"><br>\n");
printf("ファイル:<input type=\"file\" name=\"file\"><br>\n");
printf("<input type=\"submit\"><br>\n");
printf("</form>\n");
printf("<h3>環境変数</h3>\n");
static char* params[9] = {
"CONTENT_LENGTH",
"SERVER_NAME",
"HTTP_HOST",
"HTTP_REFERER",
"HTTP_USER_AGENT",
"PATH",
"SCRIPT_NAME",
"REMOTE_ADDR",
"REMOTE_HOST",
};
for (int i = 0; i < 9; i++) {
printf("%s=%s<br>\n", params[i], getenv(params[i]));
}
printf("<h3>GETパラメータ</h3>\n");
printf("%s\n", getenv("QUERY_STRING"));
}
};
int main(int argc, char** argv) {
Test* test = new Test();
test->printHTML();
delete(test);
}サーバー上で以下のようにコンパイルします。
g++ -o hello.cgi hello.cpp
問題点は以下のとおりでしょうか。
- GETパラメータの解析が面倒
- POSTパラメータの解析が面倒
- DB等との接続が面倒
- grep等の便利な関数がないので面倒
- サーバー依存のコードになる(その分早いのかもしれませんが)