php dosyası indir: garip http başlık

2 Cevap php

Ben belirli bir klasör 'çocukları dosya ve klasörleri görüntüler bu php script builing ediyorum. Dosyaları indirdiğiniz olmalı.

Mümkün olduğunca az bilgi ifşa etmek amacıyla, dizindeki her öğe html biçimlendirme içeren bir Gönder düğmesi ile bir şeklidir. Send yöntemi 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">

ve ekran sayfanın html kod kaynağının kalanı listelenir.

Burada neler oluyor?

GÜNCELLEME: my "force indir" kodu:

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();

}

2 Cevap

Dosyanın son birkaç bayt parçalanmışlığın tüm görgü neden, sonraki isteği üzerine dökmek böylece bunun görünüyor tarafından dosya indirme komut, yanlış Content-Length ayarı olabilir.

Ne web sunucusu ve işletim sistemi kullanıyorsanız, ve nasıl PHP çağırıyoruz? Windows eğer ben senin PHP kurulum şekilde yerine ikili bir akış bir metin olarak stdout yazılı olabilir bir şüphe olurdu çünkü. Bu, her \ n byte muhtemelen okunamayan çoğu ikili dosyaları yapmak gibi biraz daha uzun Content-Length üstbilgisi daha tepki organı olacak bir \ r \ n dizisi, dönüştürülebilir neden olur olduğunu söyledi.

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

Bu oldukça tehlikeli görünüyor. Ben $ dosya böyle bir şey denemeden önce ömrünün bir inç içinde kontrol ve valide edildi umuyoruz. (Dosya adı doğrulama aldatıcı zordur.)

Ben tüm çöp orada ne olduğunu anlayamadı, ama bunu önlemek için, size aracılığıyla dosyayı gönderdikten sonra, çağrı die().