質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
Perl

Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

CGI

CGI(Common Gateway Interface)とは、Webサーバー上でユーザプログラム動作させる仕組みのこと。また、動かす前提のプログラムをCGIと呼ぶこともあります。HTMLなどの静的な情報に限らず、プログラムの処理結果をベースにした動的情報の提供が可能です。

POST

POSTはHTTPプロトコルのリクエストメソッドです。ファイルをアップロードしたときや入力フォームが送信されたときなど、クライアントがデータをサーバに送る際に利用されます。

Q&A

2回答

4552閲覧

POST送信でCGI(Perl)にアクセスしてSTDINを読まないと502エラー

harutann

総合スコア4

Perl

Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

CGI

CGI(Common Gateway Interface)とは、Webサーバー上でユーザプログラム動作させる仕組みのこと。また、動かす前提のプログラムをCGIと呼ぶこともあります。HTMLなどの静的な情報に限らず、プログラムの処理結果をベースにした動的情報の提供が可能です。

POST

POSTはHTTPプロトコルのリクエストメソッドです。ファイルをアップロードしたときや入力フォームが送信されたときなど、クライアントがデータをサーバに送る際に利用されます。

0グッド

0クリップ

投稿2020/07/06 02:22

新しいサーバに変更したところ、今まで体験した事の無いエラーをCGIが出すようになりました。今まではPerl5.08や5.10などを使っていました。

Perl5.26で@INCからカレントディレクトリが削除された事によるエラーはすぐ把握して対処しましたが、それとは違う問題です。

具体的には、下記のCGIにPOST送信でアクセスすると502エラーになります。

###↓POST送信でアクセスすると502エラーになる

perl

1#!/usr/bin/perl 2 3print "Content-type: text/html\n\n"; 4print "Hello";

GET送信や直接アクセスする分にはもちろん「Hello」と表示されます。

Perl歴20年ですが、Perlのバージョンが変わってこんな超初歩のCGIがエラーを出した事、そして、その原因に何時間も費やした事に多大なショックを受けています。

原因を特定して下記の記述なら問題無い事が判明しました。

###↓POST送信でアクセスしても502エラーにならない

perl

1#!/usr/bin/perl 2 3$a = <STDIN>; 4 5print "Content-type: text/html\n\n"; 6print "Hello";

恐らく、STDIN(POST送信されてきたデータ)を読み込んで、STDINの中身が消えてしまえば502エラーにならないのでしょう。こんなもので特定に半日も費やした苛立ちが半端ないです。

いつから、何故、このような訳の分からない仕様になったのでしょうか。正気の沙汰を疑うような誰得?で無価値な制限に思えるのですが、私が何か見落としているのでしょうか。

■502エラーになるサーバ
CentOS8 Perl 5.26 Apache 2.4.37
CentOS7 Perl 5.16 Apache 2.4.06

■502エラーにならないサーバ
CentOS6 Perl 5.10 Apache 2.2.15
CentOS5 Perl 5.08 割愛

恐らく、5.10~5.16の何処かで仕様が変更になったのでしょうか。しかし、perldoc.jp でperl5.10~5.26までSTDIN関連の変更を確認しましたが、該当するような記述は見受けられませんでした。

Perl5.16の「Content-Length が設定されていないとき、もはや STDIN から 読み込まなくなりました」は別問題ですし…。
まさか、サイレント修正なんて事も無いでしょうし…。

この件について何かご存知の方がいらっしゃいましたら、いつから、何故、このような仕様になったのかお教え頂けませんでしょうか。納得できる理由が無いと、20年間愛し続けたPerlの事をディスってしまいそうです…。

「POST送信でSTDIN読まないのってどうなん?」とかの煽りは抜きでお願いします。(STDIN読むまでも無くexitしたい時だってあるのです…。アクセス規制とかね)

Perlの事なので気長に回答をお待ちしています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

CHERRY

2020/07/06 03:28

Apache 2.2 と 2.4 の違いもありますね。 こちらは調べてみたのでしょうか?
ryochin

2020/07/06 04:41

Apache のエラーログ等になにか残っているかどうかも気になりますね。
hope_mucci

2020/07/06 13:12

docker official のapacheイメージで質問と同様のことを試してみましたが正常に動作しました。 ・Debian GNU/Linux 10 (buster) ・ perl 5, version 28, subversion 1 (v5.28.1) ・Apache/2.4.43 (Unix) CentOS 7|8以外で動かしてみたらどうでしょう?
guest

回答2

0

回答では無いですが、
CentOS8 Perl 5.26 Apache 2.4.37 でやってみました。
・フォームを作ってブラウザから呼ぶと、「接続がリセットされました」の画面
curl -X POST -d AAAA http://~~だと、「curl: (52) Empty reply from server
・いずれの場合にもaccess_log には200で記録される。レスポンス長は-
とやや症状が違いますが、Helloは返りません。

accesslog

1~~ "POST /foo.cgi HTTP/1.1" 200 - ~~

perlをshやrubyに変えてみると現象が出ないので、Perlの問題なのでしょうね。
perlをshに変えても同様の現象なので、Apacheの問題と思われます。
rubyは、Helloは返りますが、perlと同様にエラーログにはAH00574: ap_content_length_filter: apr_bucket_read() failed, が記録されます。

エラーメッセージでぐぐると、下記の情報がありますが、「読め」と言うことだけですね。
3.28 CGIプログラム実行許可の設定

投稿2020/07/06 13:51

編集2020/07/07 13:21
otn

総合スコア84786

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hope_mucci

2020/07/06 14:06

同様の環境(ただしDockerイメージ)で同様にテストしてみましたが手前の環境ではちゃんとhelloが返ります。 ・CentOS8.2.2004(core) Perl5.26.3 Apache 2.4.37 どこに相違があるのでしょうか。httpd.conf?
otn

2020/07/06 14:14

httpd.confは、 cgiを実行できるようにする2箇所の変更のみです。 AddHandler cgi-script .cgi Options ExecCGI FollowSymLinks Includes
hope_mucci

2020/07/07 11:13

私はインストール時のhttpd.confのままでテストしています。
otn

2020/07/07 11:28

それでCGI動いたんですね。
hope_mucci

2020/07/07 11:36

/cgi-bin/で動かす限りでは問題ないようです。
otn

2020/07/07 11:52

なるほど。ただ、結果は同じです。 ボディでデータ投げてますか?
hope_mucci

2020/07/07 13:18

投げてます。otnさんと同様の方法です。 詳しく回答書きましたのでご覧ください。
guest

0

完全な回答ではないですがCentOS8.2.2004(core) Perl5.26.3 Apache 2.4.37 で検証した結果をお知らせします。

officealのCentOS8のdockerイメージに、上記apacheとperlをインストールしただけの環境です。
http.confも修正していません。

質問のコードをcurlにてアクセスした結果です。レスポンスヘッダも表示しています。

[root@b92bfaa43d61 cgi-bin]# curl -D - -X POST -d xxxx http://localhost/cgi-bin/demo.cgi HTTP/1.1 200 OK Date: Tue, 07 Jul 2020 13:02:01 GMT Server: Apache/2.4.37 (centos) Transfer-Encoding: chunked Content-Type: text/html; charset=UTF-8 curl: (18) transfer closed with outstanding read data remaining Hello[root@b92bfaa43d61 cgi-bin]#

ステータスは200。Helloが表示されるまで5秒ほどかかっています。
warningを読むと、POSTで送ったデータが読まれないうちに接続が切断されたよ、ということで。
ブラウザからフォームを作って呼び出しても同様です。Helloは表示されるがサーバから切断されるまで5.01sかかっています。
サーバ側で処理完了してからkeep-aliveぶんの時間コネクションが維持され、その後切断されているから以上のような現象が起こるのではないか?と考えられます。

シェルスクリプトでも同様に試してみました。

sh

1#!/bin/bash 2# demo.sh 3 4echo Content-type: text/html 5echo 6echo Hello
[root@b92bfaa43d61 cgi-bin]# curl -D - -X POST -d xxxx http://localhost/cgi-bin/demo.sh HTTP/1.1 200 OK Date: Tue, 07 Jul 2020 13:08:57 GMT Server: Apache/2.4.37 (centos) Transfer-Encoding: chunked Content-Type: text/html; charset=UTF-8 Hello curl: (18) transfer closed with outstanding read data remaining

(改行有無の違いはあれど)結果は同じでした。

まとめ

質問者さんの環境では、クライアントからサーバへのPOSTデータ受信が完了していない段階でサーバ側の処理が終了すると502が返る何等かの設定がhttpサーバ~ゲートウェイの間に入っているのではないかと考えられます。少なくともまっさらなapacheには入っていない模様です。
あと、Perlが悪いわけじゃない、ということも補記します。

(STDIN読むまでも無くexitしたい時だってあるのです…。アクセス規制とかね)

という用途だったら特に気にすることもないと思いますが(どうせ蹴るだけだし)・・・どうでしょう。

投稿2020/07/07 13:17

hope_mucci

総合スコア4447

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問