我有一个非常恼人的问题,我试图从网站下载的 PDF 却损坏了。它们生成得很好(我可以看到,如果我通过 SFTP 从它们所在的临时文件夹下载它)。
location ~ \.cgi$ {
#try_files $uri =404;
gzip off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8181;
}
Perl 代码非常简单(我不会费心放入 PDF 生成代码,因为它运行良好);
my $filepath = qq|/home/fatpeter/web/site.com/cgi-bin/hotels/admin/tmp_pdf/| . CORE::time() . q|.pdf|;
$pdf->to_file($filepath);
$file_name =~ s/\-/_/sig;
my $size = -s $filepath;
my $file = \do { local *FH; *FH };
open $file, "<$filepath" or die "Unable to open file '$filepath': $!";
binmode $file;
binmode STDOUT;
print $IN->header($IN->file_headers(
filename => $file_name,
mimetype => 'application/pdf',
inline => 0,
size => $size
));
{
local $\;
while (read($file, my $chunk, 4096)) {
print $chunk;
}
}
因此,基本上 nginx 将请求传递给 Apache2.4,然后 Perl 运行并创建 PDF。然后脚本将 PDF 传回给他们。
[2017 年 4 月 25 日星期二 13:41:36.810922] [:错误] [pid 2901]:Apache2 IO 写入:(104)对等方在 /home/fatpeter/web/site.com/cgi-bin/hotels/invoices.cgi 第 285 行重置连接
第 285 行是while () { }
循环:
while (read($file, my $chunk, 4096)) {
我不明白为什么它会在下载前将其切断。有什么想法吗?不管怎么说,我使用的测试文件是 363 KB(372,596 字节),所以不算很大!我的主代理设置nginx.conf文件是:
proxy_redirect 关闭;proxy_set_header 主机 $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_pass_header 设置 Cookie;proxy_connect_timeout 90;proxy_send_timeout 90;proxy_read_timeout 90;proxy_buffers 32 4k;
这是脚本作为标题发送的内容:
Content-type: application/pdf
Content-Disposition: attachment; filename="foo.pdf"; size=372596
Content-Length: 372596
更新:有趣的是,我现在在 Firefox 中下载时收到此错误消息:
无法保存 C:\Users\Andy\AppData\Local\Temp\Jy4tj5pr.pdf.part,因为无法读取源文件。
请稍后重试,或联系服务器管理员。
我现在也在访问日志中看到此信息:
127.0.0.1 - - [25/Apr/2017:15:29:38 +0000] "GET /cgi-bin/hotels/invoices.cgi?action=download;id=60d90acf677e9c81;invoice=1055;t=french HTTP/1.0" 200 372861 "https://www.example.com/cgi-bin/hotels/invoices.cgi?t=french" "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0"
81.174.134.133 - - [25/Apr/2017:15:29:38 +0000] "GET /cgi-bin/hotels/invoices.cgi?action=download;id=60d90acf677e9c81;invoice=1055;t=french HTTP/2.0" 200 372616 "https://www.example.com/cgi-bin/hotels/invoices.cgi?t=french" "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0"
更新 3:好的,我在这里更接近了。问题似乎出在脚本中的“分块”上:
while (read($file, my $chunk, 4096)) {
如果我将其更改为,例如:
while (read($file, my $chunk, 409600)) {
(大于相关文件大小),它作品!但是问题是,我该如何处理更大的文件?
以下是工作代码:
{
local $\;
while (read($file, my $chunk, -s $filepath)) {
print $chunk;
}
}
我只是不喜欢不能以块的形式发送回去的想法。这样做有什么缺点吗?