【问题标题】:Upload to webserver Perl both Ends上传到网络服务器 Perl 两端
【发布时间】:2013-10-22 16:52:51
【问题描述】:

我有两个 Linux 机器。一个很远。我为我遥远的 Linux 机器提供计算服务 使用 LAMP(Linux Apache Mysql Perl)服务器。有一天,我认为有一个脚本可以轻松地将文件从那里传输到这里会很好(我远方的员工不懂计算机)。认为通过 CGI 上传文件很容易。鉴于服务器是 https:,我可以免费获得加密。这几天一直在和它打架,没有任何效果。我在网上找到的示例不起作用。所涉及的软件包的文档太模糊了。

服务器端:

#!/usr/bin/perl -wT
use strict;
use CGI;
use CGI::Carp qw ( fatalsToBrowser );
use File::Basename;
use Sys::Syslog;
use Data::Dumper;

$CGI::POST_MAX = 1024 * 5000;
$CGI::DISABLE_UPLOADS = 0;


my $safe_filename_characters = "a-zA-Z0-9_.-";
my $upload_dir = "/var/my_safe_dir_writable_by_user_nobody";
my $query = new CGI;

#my $filename = $query->param( 'upload' );
my $filename = $query->param( 'filename' );
openlog( 'bare_upchuck.cgi','nodelay,pid','local1' );

if ( !$filename )
    {
    print $query->header ( );
    syslog( 'debug', "No filename!" );
    exit;
    }

# remove any absolute directories
my ( $name, $path, $extension ) = fileparse ( $filename, '..*' );
$filename = $name . $extension;

# remove any spaces.
$filename =~ tr/ /_/;

# remove any unsafe characters
$filename =~ s/[^$safe_filename_characters]//g;

# untaint the filename, taking only safe characters.
if ( $filename =~ /^([$safe_filename_characters]+)$/ )
    {
    $filename = $1;
    }
else
    {
    die "Filename contains invalid characters";
    }

syslog( 'debug', "now filename is $filename" );
syslog( 'debug', CGI::Dump() );

my $upload_filehandle = $query->upload($filename );

if( !defined $upload_filehandle )
    {
    syslog ( 'debug', "upload_filehandle is undefined!" );
    }
else
    {
    syslog ( 'debug', "upload_filehandle is $upload_filehandle" );
    }
open( UPLOADFILE, ">$upload_dir/$filename" ) or die "$!";
binmode UPLOADFILE;

while( <$upload_filehandle> )
    {
    print UPLOADFILE;
    }
close UPLOADFILE;

客户端:

#!/usr/bin/perl -d
use HTTP::Request::Common;
use LWP::UserAgent;
use CGI qw(:standard);
use strict;
use warnings;

my $file;
my $result;
my $message;
my $filePath = '/where_files_to_upload_are';

$file = $filePath . '/' . "stuff.pdf";  #tryit

my $ua = LWP::UserAgent->new;
my $req = $ua->request( POST 'https://www.jm-properties.com/jt5/upchuck/bare_upchuck.cgi',
      Content_Type => 'form-data',
      Content => [ Content_Type => "application/pdf",
                   filename => "stuff.pdf",
                   Upload => ["$file" ]
                 ]
);

print "\nRESPONSE -- \n" . $req->as_string;

print $req->content;
# Check the outcome of the response
if ($req->is_success)
    {
    print $req->content;
    }
else
    {
    print "\n in else not success\n";
    }

...服务器端主要使用 CGI.pm,客户端 - LWP::UserAgent。发生的事情是文件似乎没有传输。服务器端因未定义的 $upload_filehandle 而失败。在客户端执行 strace 显示文件正在被打开和读取。

服务器可以看到文件名,并且成功地清除了文件名。但是那里似乎没有实际的文件(在服务器中)。也许去过那里并做过那件事的人可以看到明显的东西?这几天我一直在用头撞墙,开始疼了:)。

可能的问题可能包括客户端上用于设置上传的 Perl 数据结构。此外 - 将错误的文件名传输到服务器,因此 $query->upload() 调用失败。但我真的不知道。我什至不知道如何接近 故障排除。由于服务器端脚本是 CGI,我不能真正使用 Perl 调试器。我在客户端尝试了调试器,这似乎在做一些明智的事情。它确实到达了 HTTP::Common::Request::Post,正如我所说,strace 验证文件是否正在被打开和读取。 我在 Web 上找到的此类示例已经很老了,而且 API 已经漂移....

提前致谢,

【问题讨论】:

  • rsync 可能更简单,因为您想传输文件并在两个盒子上都拥有 shell 访问权限
  • 真的,scprsync 有什么问题?那些也免费为您提供加密。
  • 老实说,可能没什么。我只是没想到这些。

标签: perl file-upload cgi multipartform-data


【解决方案1】:

好的,这就是我所做的。我并没有真正让它发挥作用,但我取得了实质性进展,正如这里有人建议的那样,我转向了另一种技术。

为了将问题分解,我编写了一个假的“网络服务器”,它位于端口 8080 上,除了将传入的网络请求输出到 STDOUT 之外什么也没做。然后我将它们通过管道传输到一个文件中。

每个表单都尝试不同的上传脚本。其中之一是假服务器。 通过从浏览器上传到假服务器,我捕获了一个完整的转储文件 文件上传的样子。

然后我在远程机器上运行我的 perl 脚本,试图上传到服务器,并捕获了我上传错误的样子的转储。

问题一目了然,我能够在客户端使用脚本以获得合理的输出。

但是,尽我所能,我无法让 CGI.pm 在服务器上接受该输出。我用头撞墙好几天。它会得到文件名,但是为内部生成的临时文件打开文件句柄的魔法是返回 undef。

然后,我用 PHP 重新编码了服务器端(我知道大概是 squat )并在 15 分钟内让它工作。

我希望这可以减轻其他人的痛苦。 CGI.pm 上传工具的文档记录不完善且损坏。

我尝试在此处插入我的代码,但没有时间或力量在每行之前手动插入 4 个空格。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-19
    • 2011-12-26
    • 2011-02-23
    • 2012-08-12
    • 2017-04-05
    • 2012-05-02
    • 2013-03-11
    相关资源
    最近更新 更多