为什么我的.zip文件在HTTP文件上传后损坏了?

时间:2009-09-18 12:57:31

标签: perl http zip file-upload

我正在尝试使用CGI脚本接受并保存使用HTTP POST发送zip文件的程序中的文件。

在HTTP标头的MIME部分中,它看起来像这样:

Content-Disposition: form-data; name="el_upload_file_0"; filename="BugReport.zip";\r\n
Content-Type: application/octet-stream\r\n\r\n

在我的CGI代码中,我正在使用它:

 use CGI;
 use strict;
 my $cgi = CGI->new;
 my $upload_file = $cgi->upload('el_upload_file_0');
 my $time = time;

 my $filename = "/tmp/$time.zip";
 open TMP, ">$filename";
 binmode TMP;
 while (<$upload_file>) {
    print TMP $_;
 }
 close TMP;

不断保存的文件以某种方式损坏并且不是有效的zip文件。 HTTP请求是由C#应用程序发送的,它可能正在发送损坏的zip文件,但我对此表示怀疑。我有什么办法可以进一步排除故障吗?

3 个答案:

答案 0 :(得分:5)

你正在逐行读取.zip文件,这是一个很大的错误。毕竟,行仅与文本文件相关。

一次性阅读整个内容,或者如果必须,请以合理大小的块进行。在这个例子中,它是以1024字节的块读取的,但是你可以轻松地使用更大的值,例如16MB(1 <24)或任何看似合适的值:

my $data;
while (read($upload_file, $data, 1024))
{
  print TMP, $data;
}

答案 1 :(得分:3)

您上传的文件与最终保存的文件之间有什么区别?查看每个的十六进制转储。

我知道这听起来很愚蠢,但只是尝试将您尝试上传的文件复制到服务器而不使用CGI脚本。你还能在那里解压吗?同样,您是否可以从服务器获取上传的文件,将其复制回客户端计算机并将其解压缩到那里?

HTTP标头的其余部分是什么样的?你在改变字符集或其他什么吗?

我不怀疑文件翻译有问题,因为CGI应该已经为你设置了。所以,一旦有人说“应该”,你必须仔细检查:)。 CGI.pm中有一行可以自动检测需要binmode的系统,因此我认为您不需要在$upload_file上进行检测。但是,也许CGI.pm对你说错了:

 $needs_binmode = $OS=~/^(WINDOWS|DOS|OS2|MSWin|CYGWIN|NETWARE)/;

您可以尝试将变量设置为true,以确保:

 use CGI;
 $CGI::needs_binmode = 1;

答案 2 :(得分:0)

标题中的“\ r \ n”可能是一个线索。输出文件是否包含“\ r \ n”序列?你能/你应该在binmode文件句柄上做$upload_file吗?