wizdLiveにphp-cgiのPOSTを実行させるのにかなり試行錯誤しました。
はまった点は以下の2点です。
・php-cgiはセキュリティの観点から単純に呼び出した時にはセキュリティ警告を出して終了する。これを回避するにはREDIRECT_STATUSを設定しなければならない。
・POSTデータを取得するには、CONTENT_TYPEにapplication/x-www-form-urlencodedを設定しなければならない。
これを探すのにTCPDUMPなどで内容を色々見ました。
Windows上では、Microsoft Network Monitorが非常に便利でした。これはマイクロソフト謹製のTCPダンププログラムで、WireSharkとかより使い方が楽。
NewCaptureをクリックして新しいキャプチャを開きます。次にDisplay Filter欄にhttpと入力、Applyをクリック。これでhttpプロトコルのみキャプチャされます。
あとはファイルメニューからCapture->Startするだけです。
俺のようなお子様仕様な人には最適です。
linux側はtcpdumpを使います。今回はportが8000に決まっているので、スーパーユーザで
tcpdump -x port 8000
と入力します。
PHP-Attempt-Once-Again-to-Fix-CGI-Bug-PHP-5-4-3-and-5-3-13-Released
あとはネット情報を調べまくりました。日本語にはわりと低レベルな疑問とか無いんですね。地味なコードは知恵袋とか見ても少ないです。残念。
結果からいうと下のコードでPOSTできました。
#include
#include
#include
main()
{
int outfd[2];
int infd[2];
int oldstdin, oldstdout;
pipe(outfd); // 親プロセスから書き込むパイプ
pipe(infd); // 親プロセスが読み込むパイプ
//子プロセス
if(!fork())
{
close(0);
close(1);
dup2(outfd[0], 0); // 標準入力を親からのパイプに接続
dup2(infd[1],1); // 標準出力を親へのパイプに接続
setenv("REDIRECT_STATUS","1",1); //PHP-CGIを動作させるためのセキュリティ回避
setenv("CONTENT_LENGTH", "5", 1); //読み込みサイズ
setenv("REQUEST_METHOD", "POST", 1);
setenv("SCRIPT_FILENAME", "/var/www/html/test.php", 1);
setenv("CONTENT_TYPE", "application/x-www-form-urlencoded", 1);
//setenv("CONTENT_TYPE", "text/html", 1); //これでは動作しない
execl("/usr/bin/php-cgi","/usr/bin/php-cgi", NULL);
}
//親プロセス
else
{
char output[1000];
close(outfd[0]); // 読み込み側は子プロセスで使うのでクローズ
write(outfd[1],"s=444", 5); // 子プロセスに書き込み
close(outfd[1]);
close(infd[1]);
output[read(infd[0],output,1000)] = 0; // 子プロセスから読み取り
printf("%s", output);
}
}
結果は
X-Powered-By: PHP/5.3.3
Content-type: text/html
array(1) {
["s"]=>
string(3) "444"
}
となります。
バージョンはPHP/5.3.3 CentOS release 6.4 (Final)です。
この結果はシングルタスクのメディアサーバwizdLiveに反映されています。wizdLiveはメディアサーバwizdを延々と修正したものです。シングルタスク版は現状ではまあ動きだしたかな?というところです。詳細はgithubで。
Copyright(c) 2015 Birdland Ltd. All Rights Reserved.