ちょっと変わった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等の便利な関数がないので面倒
  • サーバー依存のコードになる(その分早いのかもしれませんが)

C言語CGIライブラリ

http://www.mysticwall.com/software/cockatrice/