使用Perl CGI脚本无法正常上载文件

时间:2017-07-08 12:30:02

标签: perl file-upload hyperlink upload cgi

以下代码没有任何语法错误,但仍然无法正常工作。我可以使用服务器IP(如100.100.100.100)进行$ Domain以及应该为$ directory指定的路径(i是指添加serverip或域名?请帮忙

#!/usr/bin/perl
use CGI;
$CGI::POST_MAX= 100 * 1024;
$CGI::DISABLE_UPLOADS=0;
$Referer = $ENV{HTTP_REFERER};
$Domain = "xxx.com";
$cgi = new CGI;
$file=$cgi->upload('text');
print $cgi->header,
$cgi->start_html
(
        -title=>'CGI.pm File Upload'
);
print <<EOF;
<form action="" method="post" enctype="multipart/form-data">
<input type="file" name="text" size=60><br>
<input type="submit" value="Upload">
</form>
EOF
if($file)
{
        if($Referer =~ "$Domain")
        {
                $directory="var/www/cgi-bin/uploads";
                open UPLOAD, ">$directory$file";
                binmode UPLOAD;
                while(<$file>) {print UPLOAD;}
                close UPLOAD;
        }
}
$cgi->end_html;
exit;

1 个答案:

答案 0 :(得分:1)

您似乎需要再次阅读the documentation on file upload basics。他们的示例代码是:

use autodie;

# undef may be returned if it's not a valid file handle
if ( my $io_handle = $q->upload('field_name') ) {
    open ( my $out_file,'>>','/usr/local/web/users/feedback' );
    while ( my $bytesread = $io_handle->read($buffer,1024) ) {
        print $out_file $buffer;
    }
}

您的代码存在一些风格差异,但需要注意的是,当您的代码运行此行时:

$file=$cgi->upload('text');

然后$file包含一个打开的文件句柄。它不包含文件名。这意味着代码的这些行中至少有三个错误:

$directory="var/www/cgi-bin/uploads";
open UPLOAD, ">$directory$file";
  1. 您在$directory中存储的值几乎肯定会以/开头(因此它是/var/www/cgi-bin/uploads)。
  2. 您还需要/$directory之间的其他$file(否则,它将包含/var/www/cgi-bin/uploadsmyfile.dat)。
  3. 您需要致电$cgi->param('text')以获取正在上传的文件的名称。
  4. 这就是阻止你的程序工作的原因。代码的上传部分应如下所示:

    my $filename = $cgi->param('text');
    my $fh       = $cgi->upload('text');
    
    my $directory = '/var/www/cgi-bin/uploads';
    
    open my $upload_fh, '>', "$directory/$filename"
      or die "Can't open '$directory/$filename': $!";
    
    print $upload_fh $_ while <$fh>;
    

    请注意,我在这里做了一些风格改进:

    1. 使用{-1}}
    2. 的3参数版本
    3. 使用词汇文件句柄
    4. 检查open()调用是否成功,并在程序失败时使用有用的错误消息将其杀死
    5. 总而言之,您似乎已经从大约二十年过时的资源中学习了CGI编程。你的代码看起来像是从20世纪90年代开始的。

      其他一些提示:

      1. 始终open()use strict
      2. 间接对象表示法(use warnings)可能非常混乱。请改用new CGI
      3. 我们已经知道,自上一个千禧年结束以来,CGI.pm中的HTML生成功能是一个糟糕的主意。请不要使用它们。 Perl提供了许多优秀的模板解决方案。
      4. 2017年编写CGI计划是一个糟糕的主意。请查看CGI::Alternatives,了解Modern Perl Web开发工具。