2

私はperl上にfastcgiを備えたlighttpdサーバーを持っています。Lighttpd 構成:

server.modules = (
        "mod_access",
        "mod_alias",
        "mod_compress",
        "mod_redirect",
        "mod_rewrite",
        "mod_accesslog",
)

server.document-root        = "/var/www"
server.upload-dirs          = ( "/var/cache/lighttpd/uploads" )
server.errorlog             = "/var/log/lighttpd/error.log"
server.pid-file             = "/var/run/lighttpd.pid"
server.username             = "www-data"
server.groupname            = "www-data"

server.max-keep-alive-requests = 10
server.max-keep-alive-idle = 5
#server.max-fds = 10240
server.max-connections = 8192

index-file.names            = ( "index.php", "index.html",
                                "index.htm", "default.htm",
                                "index.lighttpd.html" )

url.access-deny             = ( "~", ".inc" )

static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )

dir-listing.encoding        = "utf-8"
server.dir-listing          = "disable"

compress.cache-dir          = "/var/cache/lighttpd/compress/"
compress.filetype           = ( "application/x-javascript", "text/css", "text/html", "text/plain" )

include_shell "/usr/share/lighttpd/create-mime.assign.pl"
include_shell "/usr/share/lighttpd/include-conf-enabled.pl"

$HTTP["host"] =~ "(^|\.)hostname\.net$" {
    server.document-root = "/var/www/hostname.net"
    url.rewrite-once = (     
        "^/index.php" => "/index.pl",
    )
}

高速 CGI が有効になっています。ここで構成fcgi.server:

fastcgi.server += ( ".pl" =>
        ((
                "socket" => "/tmp/perl.socket" + var.PID,
                "bin-path" => "/usr/bin/dispatch.fcgi",
                "docroot" => "/var/www/hostname.net",
                "check-local"     => "disable",
        ))
)

ディスパッチ.fcgi:

use strict;
use CGI::Fast;
use Embed::Persistent; {
    my $p = Embed::Persistent->new();
    while (new CGI::Fast) {

        my $filename = $ENV{SCRIPT_FILENAME};
        my $package  = $p->valid_package_name($filename);
        my $mtime;

        if ($p->cached($filename, $package, \$mtime)) {

            eval {$package->handler;};
        }
        else {

            $p->eval_file($ENV{SCRIPT_FILENAME});
        }
    }
}

そして、これが私のスクリプトです(編集後):

use strict;
use warnings;

use CGI;
my $q = new CGI;

open my $fh, '>', "/var/www/hostname.net/payload.body" or die "Can't open payload.body: $!";
{
 local $/;
 print $fh $q->param('arg1');
}
close $fh;

print $q->header;
print $q->param('arg1');

リクエストを送信:

wget --post-data="arg1=dfsdfasf&arg2=sdfasfdsdf" http://hostname.net/test.pl --save-headers --quiet -O -

payload.body は空です (ただし、変更の時間は更新されます)。ダンプは次のとおりです。

HTTP/1.0 200 OK
Content-Type: text/html; charset=ISO-8859-1
Content-Length: 0
Connection: keep-alive
Date: Fri, 05 Oct 2012 12:23:07 GMT
Server: lighttpd/1.4.28

それで全部です。

この方法で POST パラメータを取得しようとしましたが、クエリが空になります。私はこのように試しました:

use Data::Dumper;
my $request;
use FCGI;
my $env;
my $q = FCGI::Request();
$env = $q->GetEnvironment();
my $buffer = "data\n";

if ( $ENV{'REQUEST_METHOD'} eq "POST" ){

    read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
}
else {

    print ("some error");
};

print("Content-type: text/plain\r\n\r\n", Dumper($buffer),"\n");

リクエストから POST パラメーターを取得する必要があります (バイナリ投稿データ)。

手伝って頂けますか?多分私は間違った方法でポストパラメータを取りますか?

どうもありがとう!

4

1 に答える 1

2

open説明した

最初のスクリプトが機能しない理由は次のとおりです。

open FH, "<payload.body";
#         ^---

perl はopenBourne Shell から構文を借用しています。

手段 読み取り
手段 書き込み
>>手段 追加
+<手段 読み取りと書き込み

いくつかのベスト プラクティスに従うと、openステートメントは次のようになります。

open my $fh, '>', "payload.body" or die "Can't open payload.body: $!";

Perl に助けてもらう

実際、あなたはread-onlyprintのファイルハンドルにしようとしていました。ただし、Perl は、この問題や、遭遇する可能性のある他の多くの問題について警告することができます。スクリプトの一番上 (実際にはすべてのスクリプト)。モジュールを使用すると、より適切なエラー メッセージを発行できます。サーバーでは、これらの警告は通常ログに記録されますが、そこにあるものは見つける価値があることに注意してください。use strictuse warningsCarp

Dumper

このData::Dumperモジュールは Perl データ構造を受け取り、それらを実行可能な Perl コードに変換します。これはデバッグには最適で、シリアル化には問題ないこともありますが、文字列やスカラーを単に出力するのには適していません。含まれているすべてのデータは、有効な Perl であるために引用されますが、これは望ましくありません。

その他の小片

readターゲット変数を最初 (インデックス 0) から埋め始めます。4 番目の引数 (例: -1) にオフセットを指定して、読み取っているデータを追加します。

binmode2 番目の引数がない場合は、Windows でのみ有効です。Windows では、\n論理改行を使用できます (例: " \r\n")。\015\012ネットワークでバイト値を使用します。

2 番目の例では、 の文字で上書き$bufferします。デバッグ目的で、このコンテンツの長さも出力したい場合があります。$ENV{CONTENT_LENGTH}STDIN

FCGI::Request()リクエストオブジェクトを返します。ドキュメントAcceptには、おそらくループ内で、各リクエストを行う必要があると記載されています。成功した場合、メソッドは値を返しAcceptます。>= 0

于 2012-10-05T10:33:59.643 に答える