Apache 2.0.54で mod_perlを導入したところ、通常のCGIとしては正しく動いていたものが動かなくなりました。error_logには Premature end of script headers が出ます。mod_perl を Loadしなければ正しく動くので、改行コードがどうとかそういうよくある問題ではないです。また httpd.confでは

PerlOptions +ParseHeaders としています。
mod_perlは経験がないため、どのようなデバッグ方法があるかわかりません。誰か教えてください。

回答の条件
  • URL必須
  • 1人2回まで
  • 登録:
  • 終了:--
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答6件)

id:redcherry No.1

回答回数135ベストアンサー獲得回数0

ポイント50pt

Apache2.0.X+mod_perlで Premature end of script headers が出た場合の解決方法がいくつか載ってます。


最初のURLにある1番

#! /usr/bin/perl --

 を付けるとなぜか直る。


2番目のURLにある4番

httpd.confを確認


2番目のURLにある5番

ディレクトリのパーミッション

 なんと!777 だと動かない!!

 755 などにして試してみる。


などが怪しそうですね。

http://xiaoxia.exblog.jp/m2004-09-01/#1078664

女プログラマってどうよ?:2004年09月

id:tebukuro

ありがとうございます。いずれも試したけどダメでした。。

2005/09/27 15:56:14
id:ootatmt No.2

回答回数1307ベストアンサー獲得回数65

URLのページの以下の部分を参考に httpd.cong を変更してみてはどうでしょうか。


3. Apache (httpd.conf) の設定

id:tebukuro

そんなgoogleで上位に出てくるようなページは当然チェック済みです。

2005/09/27 16:28:05
id:asakura-t No.3

回答回数151ベストアンサー獲得回数2

ポイント50pt

 httpd.confのPerlOptions以外の設定がどうなっているかにもよるのですが、例えば下記のような設定ではいかがでしょうか?


----

PerlModule ModPerl::Registry

<Location /perl>

SetHandler perl-script

PerlResponseHandler ModPerl::Registry

Options +ExecCGI

</Location>

id:tebukuro

それって標準的な設定ですよね。。すみませんがあまり参考になりません。

Premature end of ... ってことは、スクリプトがヘッダを吐く際に想定外のものがhttpdに渡っていると思うのですが、非mod_perl下では何も出ないし、当然shell上で実行しても想定どおり Content-Type: 等のヘッダが出ます。mod_perl上で動作している時に、スクリプトが何を吐いているかを知る方法を教えてください。

2005/09/27 17:46:14
id:asakura-t No.4

回答回数151ベストアンサー獲得回数2

http://perl.apache.org/docs/2.0/api/ModPerl/Registry.html#Debugg...

mod_perl: ModPerl::Registry - Run unaltered CGI scripts persistently under mod_perl

 失礼しました。

(サンプルのスクリプトが動いているのかどうかすら分からなかったものですから)


 参考URLにあるデバッグオプションを設定してはいかがでしょうか。

 あるいはModPerl::Registryを継承したデバッグ用のハンドラを書くのが良いかと思います。

id:tebukuro

うーんちょっとよくわかりませんでしたが、ありがとうございます。

2005/09/28 10:31:40
id:redcherry No.5

回答回数135ベストアンサー獲得回数0

英語ですが、mod_perlによるデバッグトレースを表示させる方法です。

要約すると


perl Makefile.PL PERL_TRACE=1 でmod_perlをリコンパイルする


環境変数MOD_PERL_TRACEを適切に設定する。たとえばhttpd.confにて

PerlSetEnv MOD_PERL_TRACE all とかシェルから

export MOD_PERL_TRACE=all とか

setenv MOD_PERL_TRACE all など


httpdをデバッグモードで動かす。たとえば

./httpd -X


そうするとhttpdを起動したターミナルにデバッグトレースが出てきます。

それを追っていけば何かわかるかもしれません。


あと、これは設定の点で気になった部分なんですが、shell上で動かしたらContent-Type:~が出るということですが、httpd.confにてPerlSendHeader Onになってますよね?

老婆心ながら、少々気になったもので。

「当然チェック済み」であるならば、失礼をどうかお許しくださいませ。

id:tebukuro

商用UNIXでバイナリで提供されているmod_perlを使っているので、再コンパイルはむずかしいです。 -Xオプションもよくわかりませんでした。

PerlSendHeader On は、PerlOptions +ParseHeaders が相当していると思います。

が、

偶然、うまく動くようになりました!

$|++;

print ”Content-type: text/html¥n”;

print ”Pragma: no-cache¥n”;

print ”Cache-control: no-cache¥n¥n”;

としていたのですが、$|への代入を、ヘッダ出力の後に

もってくると正しく動作するようになりました。

これはこれで謎なのですが、あらためて質問してみます。

ありがとうございました。

2005/09/28 17:05:33
id:ootatmt No.6

回答回数1307ベストアンサー獲得回数65

> そんなgoogleで上位に出てくるようなページは当然チェック済みです。


チェックしてるけど間違ってるんじゃないの?

id:tebukuro

残念でした。0ポイント。

2005/09/28 17:05:57
  • id:ootatmt
    残念でした。

    何が残念なの?
    違うところで悩んでた人が残念なんだね。
  • id:tebukuro
    Re:残念でした。

    >何が残念なの?
    >違うところで悩んでた人が残念なんだね。

    ということにしたいのですね。
  • id:redcherry
    $|が原因?

    http://perl.apache.org/docs/2.0/user/coding/coding.html#Request_localized_Globals
    にも確かに「取り扱いに注意しろ」って書いてありますね。そして
    http://perl.apache.org/docs/2.0/user/coding/coding.html#Generating_HTTP_Response_Headers
    には

    For example this code won’t work:

    local $| = 1;
    print ”Content-type: text/html¥n”;
    print ”My-Header: SomeValue¥n”;
    print ”¥n”;

    Having a true $| causes the first print() call to flush its data immediately, which is sent to the internal HTTP header parser, which will fail since it won’t see the terminating ”¥n¥n”. One solution is to make sure that STDOUT won’t flush immediately, like so:

    local $| = 0;
    print ”Content-type: text/html¥n”;
    print ”My-Header: SomeValue¥n”;
    print ”¥n”;

    Notice that we local()ize that change, so it won’t affect any other code.

    はっきりと「このコードは動きません」って書いてありますもんね。
    こういうのって知ってないとわかんないですよね。

    ---

    > 商用UNIXでバイナリで提供されているmod_perlを使っているので、再コンパイルはむずかしいです。
    元々のコンパイルスイッチがデバッグトレース有りになってたかもしれないので、環境変数を変えてテストしてみる価値はあったと思いますよ。
    奥の手は勝手にコンパイルモジュールを作ってデバッグテスト時に入れ替えちゃう事ですが。
    テスト終了したら、また元に戻せばいいだけですし。

    > -Xオプションもよくわかりませんでした。
    http://httpd.apache.org/docs/2.0/programs/httpd.html
    Apacheの本体はhttpdというプログラムファイルで、これがプロセスとして(通常は)バックグラウンドで稼動しています。
    -X オプションは「デバッグモード」でhttpdを走らせるという起動オプションで、起動させたshell terminal上にログを吐き出しながらフォアグラウンドで稼動します。
    停止させるときはCtrl-Cです。
    当然このオプションを使う場合には、バックグラウンドで稼動しているプロセスを停止させなければなりません。

    他の人が一斉に開発に使用しているApacheを停止させるのはあまりいいアイデアではないかもしれませんね。
    まあ、プロジェクト担当で権限の高い人だけが出来る荒業かもしれませんので、本当に困った場合にはリーダーなどに相談してみる必要があるでしょう。
    これはmod_perlのモジュール入れ替えについても同様の事が言えると思います。

    もしくは、Linuxでもいいから簡易なテスト環境を構築しておくというのも手ではあります。

    とまあ、話がそれて来たのでこのへんで。

    とりあえず問題解決してよかったですね。
  • id:tebukuro
    Re:$|が原因?

    ありがとうございます、大変参考になりました。
    mod_perl化でよくある落とし穴、みたいなページは
    いくつか見たつもりですが、これは見かけなかった気がします。
    どうもありがとうございました。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません