|
ふと思ったのですが、CGIへPOSTメソッドでデータを送信した時に そのCGIでデータを受け無い時(readしない場合)って、そのデータは どうなるのでしょう? CGIで、最近流行りのバッファーオーバーフロー対策?として、POST データサイズを予め調べてから、read で読み込むようにしようと 考えましたが、このような場合は、サーバーOS/ソフト側でバッファ に一旦溜まるのでしょうか? それとも、CGIが受け取らない限りOS/ソフト側でデータそのものを 受け取らないのでしょうか? 試しに自環境にあるApacheに、アップロード機能付きの掲示板CGIを 使って約80Mbを送信してみましたが、cgi-lib.pl のエラー?でCGIは 停止したらしく、ps コマンドを見ると、zonbi となっていたため、 httpdがタイムアウト処理?をして切断された結果(だと思う)、ブラウザに 「cgi-lib.pl: Request to receive toomuch data: 84400432 bytes」と 表示され切断されたように見えました。 そして、その状態まで送信は止まらずにブラウザは送信を続けていました。 top や free で送信中のメモリの状態を観察していても変化がなかった 事から、CGIが受け取らないと捨てられてしまうようにも見えますが、 ちゃんと試験が出来ていたのか、自信が無いので正確な所は不明です。 結局、CGIでPOSTデータを受け取らなくても(プロセスが死んでいた為) ブラウザ自身は送信を続けていたので、どの時点で(OSかApache)データ を破棄しているのかは判断できませんでした。 そもそもCGI側でオーバーフローを気にしなくても良いならば、それでいい のですが、どうも動作が判りません。 #それとも実装依存なのかな? |
|
>>2110 /tk > 余計なような足りないような… 確かに。補足どうもです。 >>2112 moz > 質問するかもしれませんので、そのときは、どうか > よろしくお願いします。 ぜひ回答する側にもまわって下さい :-) >>2113 スナフキン > そのCGIでデータを受け無い時(readしない場合)って、そのデータは > どうなるのでしょう? 実装依存です。TCP 的に言えば、相手側がプロセスが read してくれないと相 手側の OS のバッファにたまります。それがいっぱいになったら書き込み側が ブロックします。つまり print SOCKET "...."; を実行したままずっと止まってしまうということです。 ちゃんと調べたわけではありませんが、一般的にPOST データを全部受け取っ て CGI に渡す web サーバが 多いような印象を受けます。あくまで印象なの で、試したわけではありません。 もし int sock; bind(...); listen(...); sock = accept(...); ... ヘッダ読み込み ... if ( fork() == 0 ){ char *args[]={"/home/user/public_html/cgi-bin/foo.cgi", NULL}; dup2(sock, 0); execvp("cgi", args); } else { int status; wait(&status); } のように、直接ソケットを CGI プロセスの標準入力に渡すような 実装ならば、CGI プロセスが read しないと書き込み側がブロック するわけですね。 apache の実装がどうなっているかわかったら僕にも教えて下さい。 |
|
>>2114 68user なんかいろいろとアレなので、書き直し。 int sock; int pipes[2]; bind(...); listen(...); sock = accept(...); ... ヘッダ読み込み ... pipe(pipes); if ( fork() == 0 ){ char *args[]={"cgi", NULL}; dup2(sock, 0); dup2(pipes[1], 1); execvp("/home/user/public_html/cgi-bin/foo.cgi", args); } else { char buf[256]; int len; int status; while ( len=read(pipes[0], buf, sizeof(buf) ){ write(sock, buf, len); } wait(&status); } ソケットのデータを CGI プロセスの標準入力に渡し、 CGI プロセスの標準出力を受け取り、そのままブラウザに 返す web サーバもどきです。 |
|
こんにちは。又お邪魔させてもらいました(^^;) この前はありがとうございます。うまくできました\(^o^)/ 今回は、Perl/Tkなんですがアドバイスよろしくお願いします。m(__)m リストはこんな感じなんですが・・・ use Tk; $mw = MainWindow->new; $mw->title("gifgraph"); $can = $mw->Canvas(-width=400, |
|
すみません↓ tabで形をそろえようとしたら送信のところにいっちゃってenterおしちゃいました(^^;; ヒヤアセ で、リストは use Tk; $mw = MainWindow->new; $mw->title("gifgraph"); $can = $mw->Canvas(-width=>400, -height=>300) -pack(); for(;;){ $gif = $mw->Photo(-format=>'gif', -file=>"graph.gif"); $can->createImage(200,150,-image=>$gif); $mw->after(4000); } 画像が更新されるのでfor文で何度も画像を読みこませたいんですが、ウィジェットすら開かないんです。for文をはずせば今ある画像が表示されるんですが、なぜなんでしょうか? |
|
>>2117 CCIE Perl/Tk は久しくやってないので忘れてしまいましたが、 $can->createImage(200,150,-image=>$gif); $mw->after(4000, \&change_image); MailLoop; exit; sub change_image { $gif が変わっていたら $can をいじる } じゃないですかね。 |