Perl脚本似乎正在缓存?

Perl脚本似乎正在缓存?,perl,mod-perl,Perl,Mod Perl,我正在使用Apache通过mod_perl运行一个perl脚本。我试图以restful方式解析参数(akaGET www.domain.com/rest.pl/Object/ID) 如果我像这样指定ID:GET www.domain.com/rest.pl/Object/1234我将按预期结果返回Object1234 但是,如果我指定了一个不正确的被黑客攻击的url,比如获取www.domain.com/rest.pl/Object/123,我还将获取Object1234 我非常确定中的问题正在

我正在使用Apache通过mod_perl运行一个perl脚本。我试图以restful方式解析参数(aka
GET www.domain.com/rest.pl/Object/ID

如果我像这样指定ID:
GET www.domain.com/rest.pl/Object/1234
我将按预期结果返回Object
1234

但是,如果我指定了一个不正确的被黑客攻击的url,比如
获取www.domain.com/rest.pl/Object/123
,我还将获取Object
1234

我非常确定中的问题正在发生,所以我打包了我的方法,并从包外的核心脚本调用它。即使在那之后,我仍然看到线程返回看似缓存的数据

上述文章中的建议之一是将
my
替换为
our
。阅读vs给我的印象是,
我们的
是全球的,
我的
是本地的。我的假设是,每次都会重新初始化局部变量。也就是说,在下面的代码示例中,我每次都用新值重置变量

Apache Perl配置设置如下:

PerlModule ModPerl::Registry

<Directory /var/www/html/perl/>
   SetHandler perl-script
   PerlHandler ModPerl::Registry
   Options +ExecCGI
</Directory>
这是我的软件包
Rest
。该文件包含处理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服务的过程中获取的。我怀疑它是从神奇的
$\ucode>变量中提取出来的,但我不确定它是否是,或者它填充了什么(很明显是查询字符串或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;
#/usr/bin/perl-w
包休息区;
按客户划分的分区(美元)
{
我的($className,$ObjectID)=@;
my$q=CGI->新建;
打印$q->header(-status=>200,-type=>'text/xml',expires=>'now',-Cache\u control=>'no Cache',-Pragma=>'no Cache');
my$objectXML=“”.$ObjectID。“”;
打印$objectXML;
}
#包裹必须返回1
1.
这是怎么回事?为什么我总是得到过时或缓存的值?

试试这个:

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; 
my$q=CGI->new;
打印$q->标题(-status=>200,
-类型=>'text/xml',
-Cache_control=>“无缓存,无存储,必须重新验证”);
my$ID=$q->path_info();
$ID=~s/^.*\/(.*)$/$1/;
my$objectXML=“$ID”;
打印$objectXML;

不要使用全局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;
}
您可以将其保留为
我们的
全局文件,并在每次请求时刷新它。由于每个请求都会调用init(),因此请将其放在那里:

package Rest;
our $q;
...
sub GET ....
...
sub init
{
  $q = CGI->new;
  eval ...
  ...
}

我想知道更多,但如果您将其更改为POST请求,它是否仍然缓存?请提供一个和您的mod_perl配置,以便我们可以实际执行您至少犯了一个基本的缓存错误(
Pragma
是一个请求指令),因此您似乎只是从某个地方装载了大量的代码,而不了解它的功能和工作方式。检查您的假设。您在代码中的什么位置获取pathinfo并将其放入正文?您的代码示例以静态方式输出
“1234”
。你是说“代码”吗$q->路径信息。“
?@daxim,我刚刚更新了代码示例以使其更加完整。我不相信该页面实际上是在缓存,我相信它与我引用的非常相似。我在为mod_perl配置寻找什么?这是apacheconf文件吗?或者它有自己单独的conf文件吗?@DondiMichaelStroma我更新了代码示例,以便更全面地显示路径信息的来源。同意,这应该可以。我认为Ben应该扔掉他的代码,使用一个框架,比如(从简单到复杂)Dancer、Mojolicous或Catalyst,或者使用Router::simple。我没有忘记这一点,我只是在接下来的几天里观察,以确保奇怪的行为似乎已经停止。
package Rest;
our $q;
...
sub GET ....
...
sub init
{
  $q = CGI->new;
  eval ...
  ...
}