Eu tenho um problema muito chato, enquanto os PDFs que estou tentando baixar do site ficam corrompidos. Eles são gerados bem (eu posso ver que se eu baixá-lo via SFTP da pasta temp eles são colocados).
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;
}
O código Perl é bastante simples (não vou me incomodar em colocar o código de geração de PDF também, pois isso está funcionando bem);
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;
}
}
Então, basicamente, o nginx passa a requisição para o Apache2.4, então o Perl roda e cria o PDF. O script então passa o PDF de volta para eles.
[Tue Apr 25 13:41:36.810922 2017] [:error] [pid 2901] :Apache2 IO write: (104) Connection reset by peer at /home/fatpeter/web/site.com/cgi-bin/hotels/invoices.cgi line 285
A linha 285 é o loop while () { }
:
while (read($file, my $chunk, 4096)) {
Não sei por que ele seria interrompido antes de ser baixado. Alguma ideia? Para que vale a pena, o arquivo de teste que estou usando está em 363 KB (372.596 bytes), então não é exatamente enorme! Minhas configurações de proxy no arquivo principal nginx.conf são:
proxy_redirect off; proxy_set_header Host $ host; proxy_set_header X-Real-IP $ remote_addr; proxy_set_header X-Forwarded-For $ proxy_add_x_forwarded_for; proxy_pass_header Set-Cookie; proxy_connect_timeout 90; proxy_send_timeout 90; proxy_read_timeout 90; proxy_buffers 32 4k;
Isso é o que o script está enviando como cabeçalhos:
Content-type: application/pdf
Content-Disposition: attachment; filename="foo.pdf"; size=372596
Content-Length: 372596
UPDATE: Curiosamente, agora recebo esta mensagem de erro no Firefox quando faço o download:
C:\Users\Andy\AppData\Local\Temp\Jy4tj5pr.pdf.part could not be saved, because the source file could not be read.
Try again later, or contact the server administrator.
Eu também agora recebo isso no log de acesso:
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"
UPDATE 3: OK, estou chegando um pouco mais perto daqui. O problema parece ser com o "chunking" no script:
while (read($file, my $chunk, 4096)) {
Se eu mudar isso para, por exemplo:
while (read($file, my $chunk, 409600)) {
(maior que o tamanho do arquivo em questão), FUNCIONA ! O problema com isso, porém, é o que eu faço com arquivos maiores?
Então aqui está o código de trabalho:
{
local $\;
while (read($file, my $chunk, -s $filepath)) {
print $chunk;
}
}
Eu simplesmente não gosto da ideia de não ser capaz de mandar de volta em blocos. Existe alguma desvantagem em fazer isso dessa maneira?
Tags nginx perl apache-2.4