アプリケーション開発ポータルサイト
ServerNote.NET
Amazon.co.jpでPC関連商品タイムセール開催中!
カテゴリー【C/C++Amazon/AWSnginx
【FastCGI/libfcgi】C/C++API/FCGI_fread/FCGI_stdinを使ってPOSTフォームパラメータを取得する
POSTED BY
2023-10-25

Amazon Linux2でC/C++バイナリのFastCGIを作成しnginx経由でアクセスの続きです。

このときのCサンプルではCGIパラメータの収受に対応してませんでしたが、FCGI_APIを通じて、GET/POSTいずれのフォームデータにもアクセスできるよう改造しました。

libfcgiのC言語APIであるFCGI_を使ってフォームデータを取得するやりかたがWebで全く見つからなかったため、

https://github.com/toshic/libfcgi/blob/master/include/fcgi_stdio.h

を直接見てみたところ、POSTフォームを受け取る標準入力はstdinに代えてFCGI_stdinとすればよく、freadはFCGI_freadとすればよい。大きなデータを出力して返すならFCGI_printfに代えてFCGI_fwriteにFCGI_stdoutを指定すればよい。

それらをすべて使ってフォームデータ受け取り・内容出力をしてみたサンプルソースが以下。

C/C++fcgi_form.cppGitHub Source
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include "fcgi_config.h"
#include "fcgi_stdio.h"

int main (void) {
  uint32_t access_counter = 0;

  while (FCGI_Accept() >= 0) {

    FCGI_printf("Content-type: text/plain\r\n"
    "\r\n"
    "Hello World! Access Counter : %ld\n",
    ++access_counter);

    char *ptr,*mem = NULL; size_t len = 0,frn;

    if( (ptr = getenv( "QUERY_STRING" )) != NULL && (len = strlen( ptr )) > 0 ){
      FCGI_printf("GET Parameter String :\n");
      mem = strdup( ptr );
    }
    else if( (ptr = getenv( "CONTENT_LENGTH" )) != NULL && (len = atoi( ptr )) > 0 ){
      FCGI_printf("POST Parameter String :\n");
      if( (mem = (char*)malloc( len + 1 )) != NULL ){
        frn = FCGI_fread( mem,len,1,FCGI_stdin );
        mem[len] = '\0';
      }
    }

    if (mem) {
      FCGI_fwrite( mem,len,1,FCGI_stdout );
      FCGI_printf("\n");
      free(mem);
    }
  }

  return 0;
}

前回のアクセスカウンタ出力に加え、環境変数QUERY_STRINGに中身があればGETリクエストなのでそのまま出力、CONTENT_LENGTHが1以上ならPOSTリクエストなので、疑似標準入力FCGI_stdinからFCGI_freadで取得。出力はFCGI_stdoutにFCGI_fwriteしている。

コンパイル・リンク

g++ -o form.fcgi fcgi_form.cpp -lfcgi

実行バイナリファイルform.fcgiが出来上がる。場所は/home/ec2-user以下にできたものとする。

FastCGIデーモンプロセスとして起動

前回と同様UNIXドメインソケット接続で待ち受ける。

ps aux | grep fcgi # すでに立ち上がっていないか確認,あったらkillしておく

cgi-fcgi -connect /home/ec2-user/form.sock /home/ec2-user/form.fcgi

Content-type: text/plain

Hello World! Access Counter : 1

フォームパラメータつき実行テスト

curlを使う。POSTフォームのテスト

curl -XPOST --data 'param1=value1&param2=value2' http://localhost:80/form.cgi

Hello World! Access Counter : 2
POST Parameter String :
param1=value1&param2=value2

無事パラメータを取得し出力できている。GETもやってみる。

curl 'http://localhost:80/form.cgi?param1=value1&param2=value2'

Hello World! Access Counter : 3
GET Parameter String :
param1=value1&param2=value2

Cサンプルのソースを改造したのみなので、その他nginxの設定などは前回を参照してください。

※本記事は当サイト管理人の個人的な備忘録です。本記事の参照又は付随ソースコード利用後にいかなる損害が発生しても当サイト及び管理人は一切責任を負いません。
※本記事内容の無断転載を禁じます。
【WEBMASTER/管理人】
自営業プログラマーです。お仕事ください!
ご連絡は以下アドレスまでお願いします★

☆ServerNote.NETショッピング↓
ShoppingNote / Amazon.co.jp
☆お仲間ブログ↓
一人社長の不動産業務日誌
【キーワード検索】