2

Apache で mod_perl 経由で perl スクリプトを実行しています。パラメータを安らかな方法で解析しようとしています(別名GET www.domain.com/rest.pl/Object/ID)。

次のように ID を指定すると、期待どおりに結果として GET www.domain.com/rest.pl/Object/1234オブジェクトが返されます。1234

ただし、このように不正なハッキングされた URL を指定すると、GET www.domain.com/rest.pl/Object/123object も返されます1234

この質問の問題が発生していると確信しているので、メソッドをパッケージ化し、パッケージのコア スクリプトから呼び出しました。その後も、スレッドが一見キャッシュされたデータを返しているのが見えます。

前述の記事の推奨事項の 1 つは、に置き換えるmyことourです。私たちののものを読んでの私の印象は、それourがグローバルであり、myローカルであるということでした. 私の仮定は、ローカル変数が毎回再初期化されるということです。とはいえ、以下のコード例のように、変数を毎回新しい値でリセットしています。

Apache Perl 構成は次のように設定されています。

PerlModule ModPerl::Registry

<Directory /var/www/html/perl/>
   SetHandler perl-script
   PerlHandler ModPerl::Registry
   Options +ExecCGI
</Directory>

直接呼び出される perl スクリプトを次に示します。

#!/usr/bin/perl -w
use strict;
use warnings;
use Rest;

Rest::init();

これが私のパッケージRestです。このファイルには、残りのリクエストを処理するためのさまざまな関数が含まれています。

#!/usr/bin/perl -w

package Rest;

use strict;
# Other useful packages declared here.

our @EXPORT = qw( init );

our $q = CGI->new;

sub GET($$) {
    my ($path, $code) = @_;
    return unless $q->request_method eq 'GET' or $q->request_method eq 'HEAD';
    return unless $q->path_info =~ $path;
    $code->();
    exit;
}

sub init()
{
eval {
        GET qr{^/ZonesByCustomer/(.+)$} => sub {
            Rest::Zone->ZonesByCustomer($1);
        }
    }
}

# packages must return 1
1;

補足として、このステートメントがどのように機能するか、またはコマンドevalによってどの文字列が解析されるかを完全には理解していません。qrこのスクリプトは、perl を使用して REST ベースの Web サービスをセットアップするためのこの例から大部分を抜粋したものです。その魔法の変数から引き出されているので$_はないかと思いますが、そうであるかどうか、または何を入力しているのかはわかりません(明らかにクエリ文字列またはURLですが、その一部にすぎないようです?)。

ここに私のパッケージRest::Zoneがあり、これには関数アクションの肉が含まれます。データが機能しているため、データの操作方法の詳細を省略し、これを抽象的なスタブとして残します。主な問題は、パラメーターがこの関数に渡されるか、関数の出力にあるようです。

#!/usr/bin/perl -w

package Rest::Zone;

sub ZonesByCustomer($)
{
    my ($className, $ObjectID) = @_;

    my $q = CGI->new;
    print $q->header(-status=>200, -type=>'text/xml',expires => 'now', -Cache_control => 'no-cache', -Pragma => 'no-cache');
    my $objectXML = "<xml><object>" . $ObjectID . "</object></xml>";
    print $objectXML;
}

# packages must return 1
1;

ここで何が起こっているのですか?古い値やキャッシュされた値を取得し続けるのはなぜですか?

4

2 に答える 2

3

これを試してください:

my $q = CGI->new; 
print $q->header(-status => 200,
                 -type => 'text/xml',
                 -Cache_control => 'no-cache, no-store, must-revalidate'); 

my $ID = $q->path_info();
$ID =~ s/^.*\/(.*)$/$1/;

my $objectXML = "<xml><object>$ID</object></xml>"; 

print $objectXML; 
于 2012-06-15T22:17:45.000 に答える
3

グローバル CGI オブジェクトを使用しないでください。

package Rest;

...

#our $q = CGI->new; 
# Remove that, it is only going to be executed once when the pacakge is loaded (use'd)

sub GET($$) {
    my ($path, $code) = @_;
    my $q = CGI->new; # Add this line (you can call CGI->new multiple times)
    return unless $q->request_method eq 'GET' or $q->request_method eq 'HEAD';
    return unless $q->path_info =~ $path;
    $code->();
    exit;
}

グローバルのままにして、ourリクエストごとに更新できます。init() はリクエストごとに呼び出されるため、そこに配置します。

package Rest;
our $q;
...
sub GET ....
...
sub init
{
  $q = CGI->new;
  eval ...
  ...
}
于 2012-06-19T15:48:14.567 に答える