php文件下载:奇怪的http头文件 [英] php file download: strange http header

查看:154
本文介绍了php文件下载:奇怪的http头文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在建立这个php脚本,显示给定文件夹的子文件夹和文件。文件应该被下载。

i'm builing this php script which displays a given folder 's children folders and files. Files ought to be downloaded.

为了尽可能公开尽可能少的信息,目录中的每个项目都是一个包含html标记的提交按钮的表单。发送方法是POST。

In order to disclose as little information as possible, each item in the directory is a form with a submit button that contains the html markup. The send method is POST.

如果我点击一个目录,它会打开该目录并显示内容。
如果我点击一个文件,它显示一个下载提示,文件下载就好了。
但是点击之后,我会看到这样的事情:

IF i click on a directory, it opens that directory and displays the content just fine. If i click on a file, it shows a download prompt and the file downloads just fine. But the click after that, i get to see such thing:

0 65535 f
0000000000 65535 f
0000000000 65535 f
0000000000 65535 f
0000000000 65535 f
0000000000 65535 f
0000000000 65535 f
0000000000 65535 f
0000000000 65535 f
0000000000 65535 f
0000000000 65535 f
0000000000 65535 f
0000000000 65535 f
0000000000 65535 f
trailer
<</Size 34>>
startxref
116
%%EOF
HTTP/1.1 200 OK
Date: Mon, 31 Aug 2009 21:01:36 GMT
Server: Apache
X-Powered-By: PHP/5.2.5
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Keep-Alive: timeout=15, max=93
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html

2822
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

,并列出显示页面的其余html代码源。

and the rest of the html code source of the display page is listed.

这里发生了什么?

更新:我的强制下载代码:

UPDATE: my "force download" code:

function offerToDownloadFile($filename, $access_type='url') {


// converting url to local path so Apache can find the file.
// force download:
// required for IE, otherwise Content-disposition is ignored
    if (ini_get('zlib.output_compression'))
        ini_set('zlib.output_compression', 'Off');

    if($access_type === 'url') {
    // access type is via the file 's url
        $parsed_url = parse_url($filename);
        $fileinfo = pathinfo($filename);
        $parsed_url['extension'] = $fileinfo['extension'];
        $parsed_url['filename'] = $fileinfo['basename'];

        $parsed_url['localpath'] = LOCALROOT . $parsed_url['path'];
    }
    else {
    // access type is the local file path
        $fileinfo = pathinfo($filename);
        $parsed_url['localpath'] = $filename;
        $parsed_url['filename'] = basename($filename);
        $parsed_url['extension'] = $fileinfo['extension'];
    }


    // just in case there is a double slash created when joining document_root and path
    $parsed_url['localpath'] = preg_replace('/\/\//', '/', $parsed_url['localpath']);

    if (!file_exists($parsed_url['localpath'])) {
        die('File not found: ' . $parsed_url['localpath']);
    }
    $allowed_ext = array('ics','pdf', 'png', 'jpg', 'jpeg', 'zip', 'doc', 'xls', 'gif', 'exe', 'ppt');
    if (!in_array($parsed_url['extension'], $allowed_ext)) {
        die('This file type is forbidden.');
    }

    switch ($parsed_url['extension']) {
        case "ics": $ctype="text/calendar";
            break;
        case "pdf": $ctype = "application/pdf";
            break;
        case "exe": $ctype = "application/octet-stream";
            break;
        case "zip": $ctype = "application/zip";
            break;
        case "doc": $ctype = "application/msword";
            break;
        case "xls": $ctype = "application/vnd.ms-excel";
            break;
        case "ppt": $ctype = "application/vnd.ms-powerpoint";
            break;
        case "gif": $ctype = "image/gif";
            break;
        case "png": $ctype = "image/png";
            break;
        case "jpeg":
        case "jpg": $ctype = "image/jpg";
            break;
        default: $ctype = "application/force-download";
    }
    header("Pragma: public"); // required
    header("Expires: 0");
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header("Cache-Control: private", false); // required for certain browsers
    header("Content-Type: $ctype");
    header("Content-Disposition: attachment; filename=\"" . $parsed_url['filename'] . "\";");
    header("Content-Transfer-Encoding: binary");
    header("Content-Length: " . filesize($parsed_url['localpath']));
    readfile($parsed_url['localpath']);
    clearstatcache();
    exit();

}


推荐答案

看起来你的文件下载脚本可能设置错误的Content-Length,以便文件的最后几个字节可以溢出到下一个请求中,导致所有的破坏方式。

By the looks of it your file download script may be setting the wrong Content-Length, so that the last few bytes of the file can spill over into the next request, causing all manners of brokenness.

您正在使用什么Web服务器和操作系统,以及如何调用PHP?因为如果是Windows,我怀疑你的PHP安装可能以某种方式写入stdout作为文本而不是二进制流。这将导致每个\\\
字节转换为\r\\\
序列,这可能会使大多数二进制文件不可读,以及使响应主体比Content-Length头部长一点。 / p>

What web server and OS are you using, and how are you invoking PHP? Because if it's Windows I'd have a suspicion that your PHP installation may somehow be writing to stdout as a text instead of a binary stream. This would cause each \n byte to be converted to a \r\n sequence, which would probably make most binary files unreadable as well as making the response body a bit longer than the Content-Length header said it was.


$ parsed_url ['localpath'] = LOCALROOT。 $ parsed_url ['path'];

$parsed_url['localpath'] = LOCALROOT . $parsed_url['path'];

这似乎相当危险。我希望$ filename被检查和验证到其生命的一寸之内,然后再尝试这样的事情。 (文件名验证是欺骗性的)。

That seems rather dangerous. I would hope $filename were checked and validated to within an inch of its life before trying anything like that. (Filename validation is deceptively hard.)

这篇关于php文件下载:奇怪的http头文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆