【问题标题】:Adding a .zip file to the body of an LWP::UserAgent POST request将 .zip 文件添加到 LWP::UserAgent POST 请求的正文
【发布时间】:2023-03-26 11:15:01
【问题描述】:

我相信我有一个一般的 Perl 问题,而不是 LWP::UserAgent 问题......但是它有点复杂。

任务是编写一个执行SWORD 存款的测试脚本。 我首先编写代码来创建测试,以证明事情有效,然后添加 Test::More 包装器以使其成为测试。

背景

SWORD 存款只是一个带有一堆已定义标头的 http post 请求,而主体的内容就是要摄取的东西。这一切都很好,我可以通过 CURL 执行操作,并且我已经编写了脚本来执行此操作....但是在更大的应用程序环境中(将是 EPrints。)

代码

我相信,当我尝试将文件的内容附加到磁盘上时,我的问题就出现了。

#!/home/cpan/bin/perl
use strict;
use warnings;

use LWP::UserAgent;
##use WWW::Mechanize;
use File::Slurp;
use MIME::Base64;

my $auth     = 'username:password';
my $domain   = 'devel.example.com';

my $ua = LWP::UserAgent->new();

my $basedir = "./test_files";

my $package  = 'http://opendepot.org/europePMC/2.0';
my $filename = "$basedir/PMC165035.zip";
my $mime     = 'application/zip';
print "filename: $filename\n";
my $deposit_url = $domain . '/sword-app/deposit/archive';

my $file = read_file( $filename, { binmode => ':raw' } );

# Set up the SWORD deposit
my $autho = "Basic " . MIME::Base64::encode( $auth, '' );

my %headers = (
  'X-Packaging'         => $package,
  'X-No-Op'             => 'false',
  'X-Verbose'           => 'true',
  'Content-Disposition' => "filename=$filename",
  'Content-Type'        => $mime,
  'User-Agent'          => 'Broker Test Harness',
  'Authorization'       => $autho,
); 
my $r = $ua->post( $deposit_url, %headers, Content => $file );

# DEBUG TEST
write_file('foo.zip', $file);

my $ret = $r->decoded_content;
print "Content: $ret\n";
if ( $r->is_success ) { print "Deposited $package successfully" }

什么有效,什么无效

这段代码几乎是直接从我的工作代码中提取的——唯一的区别是工作代码通过 EPrints 中的对象调用获取 $file 的内容。

我知道该文件存在于磁盘上,如果我在打印的文件名上添加ls -l,我可以看到该文件,并且它是可读的

在上面的代码中,有一行 write_file('foo.zip', $file); - 写入了一个文件,unzip -l foo.zip 高兴地告诉我其中有 3 个文件。

print "Content: $ret\n"; 行应该打印一个 atom 响应 - 对我来说,它什么也没打印.... Access 日志报告错误 500,但错误日志中有 diddly-squat。

帮助

我需要知道的是如何将 .zip 文件的实际内容放入 LWP::UserAgent 发布请求的 content 部分...

(我将花很多时间不尝试深入研究 EPrints,跟踪错误 500 的来源,以及为什么日志文件中没有出现任何内容......但这可能要归结为发布的内容有问题

【问题讨论】:

  • $deposit_url开头没有协议(http://)
  • 您还需要binmode => ':raw' 来调用write_file
  • 最好使用unzip -t foo.zip来验证你的zip文件。或者,如果您只是将一个 zip 文件复制到另一个,那么为什么不使用 `File::Copy?

标签: perl lwp-useragent


【解决方案1】:

解决方案在于了解 LWP POST 正在做什么。

my $filename = "$basedir/PMC165035.zip";
my $file = read_file( $filename, { binmode => ':raw' } );
my %headers = (
  'X-Packaging'         => $package,
  'X-No-Op'             => 'false',
  'X-Verbose'           => 'true',
  'Content-Disposition' => "filename=$filename",
  'Content-Type'        => $mime,
  'User-Agent'          => 'Broker Test Harness',
  'Authorization'       => $autho,
); 

通过将$filename 设置为类似于/home/services/foo/testing/test_files/PMC165035.zip 并将这个(完整)文件名传递给服务器example.com,所有工作都可以工作。

问题是服务器正在寻找一个文件名,而不是一个带路径的文件名......所以当服务通过将 content 转储到其临时上传中来处理文件时location,然后找~~~temp_location/home/services/foo/testing/test_files/PMC165035.zip,找不到!

解决办法是读入文件,但要确保headers中给出的文件名只是文件名,而不是with-a-path

【讨论】:

    猜你喜欢
    • 2013-10-09
    • 1970-01-01
    • 2010-09-09
    • 1970-01-01
    • 1970-01-01
    • 2011-03-05
    • 1970-01-01
    • 2019-02-09
    • 1970-01-01
    相关资源
    最近更新 更多