2011/05/11

c++でcgi ー POSTメソッドでデータを受け取る

HTMLのformからPOSTメソッドでデータを取得してみます。


・HTML

<!DOCTYPE html>
<html>
  <head>
 <meta charset="UTF-8">
  </head>

<body>
 <form action="cgiへのパス" method="post">
   <textarea name="test1"></textarea>
   <textarea name="test2"></textarea>
          <input type="submit" value="送信">
 </form>
</body>
</html>
form内にテキストエリアが2つ(nameは"test1"と"test2")あり、8行目で呼び出すCGIへのパスとPOSTメソッドを指定しています。


・C++
#include <iostream>
#include <string>

#include <stdlib.h> // getenv

using namespace std;


//! 文字列から値に変換します。
template < typename T > T convert( const std::string & str )
{
 std::istringstream istream( str );
 T type = 0;

 if ( !str.empty())
 {
  istream >> type;
 }
 return type;
};

int main()
{
 // 環境変数[REQUEST_METHOD]に送信されたメソッド[GET/POST]が入ります。
 std::string request_method = getenv( "REQUEST_METHOD" ); 
 if ( request_method != "POST" )
 {
  cout << "REQUEST_METHOD : " << request_method << endl;
  return 0;
 }

 // 送信されたサイズを取得します。
 std::string lengthStr = getenv( "CONTENT_LENGTH" );
 unsigned long length  = convert< unsigned long >( lengthStr );
 if ( length > ( 1024 * 1024 /* 1M byte*/))
 {
  cout << "CONTENT_LENGTH : " << lengthStr << endl;
  return 0;
 }

 // 送信されたデータを保存する文字列のメモリを確保します。
 char * tmpBuf = new char[ length + 1 ];
 if ( !tmpBuf )
 {
  cout << "Allocate is failed." << endl;
  return 0;
 }

 // 標準入力からPOSTされたデータを取得します。
 if ( fread( tmpBuf, 1, length, stdin ) != length )
 {
  cout << "fread is failed." << endl;
  return 0;
 }
 tmpBuf[ length ] = '\0';

 // HTMLを出力します。
 cout << "Content-Type: text/html" << endl << endl;

 cout << "<html>" << endl;
 cout << "<head><title>test</title></head>" << endl;
 cout << "<body>" << endl;
 cout << tmpBuf << "<br>" << endl;

 cout << "</body>" << endl;
 cout << "</html>" << endl;
 return 0;
}

9行目から20行目までは、文字列から数値に変換する関数です。
送信されたサイズを数値に変換するのに使用しています。

25行目で環境変数[REQUEST_METHOD]からGET/POSTのどちらのメソッドかを取得しています。

32~39行目までは環境変数[CONTENT_LENGTH]から送信されたサイズを文字列で取得した後、数値に変換しています。

42行目で、送信されたデータを保存する文字列のメモリを確保し、
50行目でfreadを使用して送信されたデータを確保したメモリに書き込んでいます。

57行目移行は、送信されたデータをHTMLとして書き出しています。


GETメソッドと同様、送信されたデータはURLエンコードされnameと内容が[=]で結ばれ、各項目が[&]で結ばれます。

最初の テキストエリア(test1)に[123]、次のテキストエリア(test2)に[test]を入力した時は、
送信される文字列は[test1=123&test2=test]になります。

実際に使用する時は、文字列をURLデコードし文字列を[&]と[=]で区切る必要があります。

0 コメント:

コメントを投稿

 
Design by Free WordPress Themes | Bloggerized by Lasantha - Premium Blogger Themes | Blogger Templates