2011/05/11

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

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


・HTML

  1. <!DOCTYPE html>  
  2. <html>  
  3.   <head>  
  4.  <meta charset="UTF-8">  
  5.   </head>  
  6.   
  7. <body>  
  8.  <form action="cgiへのパス" method="post">  
  9.    <textarea name="test1"></textarea>  
  10.    <textarea name="test2"></textarea>  
  11.           <input type="submit" value="送信">  
  12.  </form>  
  13. </body>  
  14. </html>  
form内にテキストエリアが2つ(nameは"test1"と"test2")あり、8行目で呼び出すCGIへのパスとPOSTメソッドを指定しています。


・C++
  1. #include <iostream>  
  2. #include <string>  
  3.   
  4. #include <stdlib.h> // getenv  
  5.   
  6. using namespace std;  
  7.   
  8.   
  9. //! 文字列から値に変換します。  
  10. template < typename T > T convert( const std::string & str )  
  11. {  
  12.  std::istringstream istream( str );  
  13.  T type = 0;  
  14.   
  15.  if ( !str.empty())  
  16.  {  
  17.   istream >> type;  
  18.  }  
  19.  return type;  
  20. };  
  21.   
  22. int main()  
  23. {  
  24.  // 環境変数[REQUEST_METHOD]に送信されたメソッド[GET/POST]が入ります。  
  25.  std::string request_method = getenv( "REQUEST_METHOD" );   
  26.  if ( request_method != "POST" )  
  27.  {  
  28.   cout << "REQUEST_METHOD : " << request_method << endl;  
  29.   return 0;  
  30.  }  
  31.   
  32.  // 送信されたサイズを取得します。  
  33.  std::string lengthStr = getenv( "CONTENT_LENGTH" );  
  34.  unsigned long length  = convert< unsigned long >( lengthStr );  
  35.  if ( length > ( 1024 * 1024 /* 1M byte*/))  
  36.  {  
  37.   cout << "CONTENT_LENGTH : " << lengthStr << endl;  
  38.   return 0;  
  39.  }  
  40.   
  41.  // 送信されたデータを保存する文字列のメモリを確保します。  
  42.  char * tmpBuf = new char[ length + 1 ];  
  43.  if ( !tmpBuf )  
  44.  {  
  45.   cout << "Allocate is failed." << endl;  
  46.   return 0;  
  47.  }  
  48.   
  49.  // 標準入力からPOSTされたデータを取得します。  
  50.  if ( fread( tmpBuf, 1, length, stdin ) != length )  
  51.  {  
  52.   cout << "fread is failed." << endl;  
  53.   return 0;  
  54.  }  
  55.  tmpBuf[ length ] = '\0';  
  56.   
  57.  // HTMLを出力します。  
  58.  cout << "Content-Type: text/html" << endl << endl;  
  59.   
  60.  cout << "<html>" << endl;  
  61.  cout << "<head><title>test</title></head>" << endl;  
  62.  cout << "<body>" << endl;  
  63.  cout << tmpBuf << "<br>" << endl;  
  64.   
  65.  cout << "</body>" << endl;  
  66.  cout << "</html>" << endl;  
  67.  return 0;  
  68. }  

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デコードし文字列を[&]と[=]で区切る必要があります。

1 コメント:

匿名 さんのコメント...

All Your favorite online casino games - 벳썸 바카라사이트 바카라사이트 bet365 bet365 31BEST Casino Games Online for Real Money | 났체크 먹튀

コメントを投稿

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