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の設定などは前回を参照してください。
※本記事内容の無断転載を禁じます。
ご連絡は以下アドレスまでお願いします★
Windowsのデスクトップ画面をそのまま配信するための下準備
WindowsでGPUの状態を確認するには(ASUS系監視ソフトの自動起動を停止する)
CORESERVER v1プランからさくらインターネットスタンダートプランへ引っ越しメモ
さくらインターネットでPython MecabをCGIから使う
さくらインターネットのPHPでAnalytics-G4 APIを使う
インクルードパスの調べ方
【Git】特定ファイルを除外する.gitignore
【Ubuntu/Debian】NVIDIA関係のドライバを自動アップデートさせない
【Python】Spacyを使用して文章から出発地と目的地を抜き出す
【Windows10】リモートデスクトップ間のコピー&ペーストができなくなった場合の対処法
Windows11+WSL2でUbuntuを使う【2】ブリッジ接続+固定IPの設定
Windows版Google Driveが使用中と言われアンインストールできない場合
VirtualBoxの仮想マシンをWindows起動時に自動起動し終了時に自動サスペンドする
【Apache】サーバーに同時接続可能なクライアント数を調整する
【C/C++】小数点以下の切り捨て・切り上げ・四捨五入
Googleファミリーリンクで子供の端末の現在地がエラーで取得できない場合
【Linux】iconv/libiconvをソースコードからインストール
Ubuntu Server 21.10でイーサリアムブロックチェーン【その5】