さて、WEBのプログラムを書くのはいろいろ勉強になります。
本格的にWEBをやるならJavaかPHPなどがいいと思います。
ここでは、C++でWEBプログラミングをすることで遊んでみましょう!
まずは、HTTP通信とは? を読んでヘッダ部とデータ部の知識を身につけましょう!
ここでは、GETのデータとPOSTのデータを取得してみます。
1つのプログラムで両方ともに対応するように書きますので見にくいところもあるかもしれませんが
気張っていきましょう
【準備】
AN HTTPDをインストールしてください。
(IISなどでもよいです。)
【サンプル】
#include <cstdlib>
#include <iostream>
#include <string>
#include "boost/shared_array.hpp"
using namespace std;
using namespace boost;
//postデータを取得する
const bool getPostedData(string& data)
{
//環境変数から送られたデータサイズを取得する
char* str = getenv("CONTENT_LENGTH");
if(str == NULL) return false;
int length = atol(str) + 1;
//もし、サイズが大きすぎるときはエラー
if(length > 1000000) return false;
//POSTデータを取得する
shared_array<char> tmp(new char[length]);
cin.get(tmp.get(), length);
if(!cin) return false;
data = tmp.get();
return true;
};
int main(int argc, char *argv[])
{
char* str;
//ヘッダ部を出力します。
cout << "Content-type: text/html\n\n";
//メソッド(GETなのかPOSTなのか)を取得する
str = getenv("REQUEST_METHOD");
if(str == NULL) return EXIT_FAILURE;
string method = str;
//データを出力します。メソッドで処理を分けています。
string data;
if(method == "GET"){
str = getenv("QUERY_STRING");
if(str == NULL) return EXIT_FAILURE;
data = str;
}else{
if(!getPostedData(data)) return EXIT_FAILURE;
}
//データを出力します
cout << "<html><head>" << method << ":" << data << "</head><body>\n";
//system("PAUSE");
return EXIT_SUCCESS;
}
【サンプルHTML】
test.htmlというファイル名で、「C:\httpd\cgi-bin\test」などに保存してください。
<html>
<body>
<form method="post" action="http://localhost/cgi-bin/test/post.exe
">
<input name="address" ><br>
<input name="age" ><br>
<input type="submit" >
</form>
</body>
</html>
※サンプルをコンパイルしたexeは、「C:\httpd\cgi-bin\test\post.exe」などに保存してください。
【説明】
httpd.exeを起動してください。
GETを試したい場合:以下にアクセスしてください。
http://localhost/cgi-bin/test/post.exe?name=nana&age=17
POSTを試したい場合:以下にアクセスしてください。
http://localhost/cgi-bin/test/test.html
ボタンを押すとPOSTします。
<ヘッダの出力>
main()の中で以下のテキストを出力しています。
cout << "Content-type: text/html\n\n";
これは、HTTPのヘッダ部の出力です。
最後に改行を2回出力してます。
これが「ヘッダ部はここで終了!」というしるしです。
HTTP通信とは? では様々なヘッダをサンプルで記述しましたが、必要なものだけ書けば大丈夫。
つまり簡易なものなら、ヘッダ部は上記1行だけでも十分なんです。
ちなみに意味は、「送信しようとしているのは(バイナリではなく)テキストで、HTML形式です」ということを
示しています。
<IEから受信したヘッダ部の情報の取得>
ヘッダ部の情報を取得するには、getenv()を使用します。
また、引数で渡す文字列は決まっています。
ここで使用したものは以下のとおりです。
REQUEST_METHOD・・・GETかPOSTかの情報を取得します
CONTENT_LENGTH・・・POSTのとき、データ部の長さ(バイト数)を取得します。
QUERY_STRING・・・GETのとき、データ部の文字列を取得します。
もし、値が無い場合getenv()はNULLを返します。
これは注意点です。
ちなみに、CONTENT_LENGTHで得られる長さと実際のデータ部の長さが違っても通信のどこかで
エラーになってくれません。
ですので、そのようなチェックはプログラム側の責任で行わないといけません。
<GETデータの取得>
環境変数のQUERY_STRING から取得すればいいです!
<POSTデータの取得>
getPostedData()関数を見てください。
cinから取得していますね。
実は標準入力から取得するので、GETとやり方が違います。
でも、それほど難しくないですよね?
最後に取得したデータをcoutを使ってそのまま出力しています。
そんなに難しくないですよね?
【補足】
データは何も加工せずにそのまま出力しています。
「それが何か?」って思わないでください。
本当はこれでは処理が足りません。
HTTP通信とは?で書きましたが、データはエスケープされます。
ですので、元に戻すアンエスケープをしてあげないといけません。
これについてはまた次の記事で書こうと思います。
参考:
・windowsでWEBをするには? セキュアC/C++