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.cpp | GitHub 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¶m2=value2' http://localhost:80/form.cgi Hello World! Access Counter : 2 POST Parameter String : param1=value1¶m2=value2
無事パラメータを取得し出力できている。GETもやってみる。
curl 'http://localhost:80/form.cgi?param1=value1¶m2=value2' Hello World! Access Counter : 3 GET Parameter String : param1=value1¶m2=value2
Cサンプルのソースを改造したのみなので、その他nginxの設定などは前回を参照してください。
※本記事内容の無断転載を禁じます。
ご連絡は以下アドレスまでお願いします★
☆ServerNote.NETショッピング↓
ShoppingNote / Amazon.co.jp
☆お仲間ブログ↓
一人社長の不動産業務日誌
TSUKUMOのマルチGPUパソコンWA9J-X211/XTにUbuntu Server 22.04とCOEIROINK Engineを導入する
Python venv(仮想環境作成)でError: Command returned non-zero exit status 1のエラー対処法
【Ubuntu】プロジェクトごとに複数のPythonバージョンを使い分ける
【PHP】フォーム入力を受け取り出力する
【Ubuntu】aptでインストールしたapache2にソースコンパイルしたphpをマルチスレッドモードで組み込む
【PHP】HTMLファイルを読み込んで文字列変換して出力する
TSUKUMOのマルチGPUパソコンWA9J-X211/XTにUbuntu Server 22.04とVOICEVOX Engineを導入する
【VOICEBOX Engine】403 Forbidden Origin not allowedの対処法
【Python urllib】Proxy URL had no scheme, should start with http:// or https://の対処法
進研ゼミチャレンジタッチをAndroid端末化する
Windows版Google Driveが使用中と言われアンインストールできない場合
Googleファミリーリンクで子供の端末の現在地がエラーで取得できない場合
【C/C++】小数点以下の切り捨て・切り上げ・四捨五入
Androidホームで左にスワイプすると出てくるニュース共を一切表示させない方法
Windows11+WSL2でUbuntuを使う【2】ブリッジ接続+固定IPの設定
【Apache】サーバーに同時接続可能なクライアント数を調整する
Googleスプレッドシートを編集したら自動で更新日時を入れる
【Javascript】JSON配列内にある特定要素の取得法【Node.js】