nginx proxy_pass,传回时会损坏 pdf 文件吗?

nginx proxy_pass,传回时会损坏 pdf 文件吗?

我有一个非常恼人的问题,我试图从网站下载的 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;
    }
}

我只是不喜欢不能以块的形式发送回去的想法。这样做有什么缺点吗?

相关内容