2009-08-31 9 views
0

私は特定のフォルダの子フォルダとファイルを表示するこのphpスクリプトをビルドしています。ファイルをダウンロードする必要があります。phpファイルのダウンロード:strange http header

可能な限り情報を開示しないために、ディレクトリ内の各項目は、HTMLマークアップを含む送信ボタン付きのフォームです。 sendメソッドはPOSTです。

私がディレクトリをクリックすると、そのディレクトリが開き、コンテンツがうまく表示されます。 ファイルをクリックするとダウンロードプロンプトが表示され、ファイルは正常にダウンロードされます。

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コードのソースの残りの部分が表示されている: はしかし、クリック、その後、私はそのようなことを見ることが。

ここでは何が起こっていますか?

UPDATE:私の「力のダウンロード」コード:

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

ファイルのダウンロードスクリプトが間違ったContent-Lengthを設定している可能性があります。そのため、ファイルの最後の数バイトが次の要求に流出して破損してしまう可能性があります。

どのWebサーバーとOSを使用していますか、どのようにPHPを起動していますか? Windowsの場合は、PHPのインストールがバイナリストリームの代わりにテキストとしてstdoutに何らかの形で書き込まれている可能性があるという疑いがあるからです。これは、各\ nバイトが\ r \ nシーケンスに変換される原因になり、ほとんどのバイナリファイルが読み込み不能になるだけでなく、レスポンスボディがContent-Lengthヘッダより少し長くなります。

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

これはかなり危険です。私は$ filenameがそのようなものを試す前に、その人生の1インチ以内にチェックされ検証されることを願っています。 (ファイル名の検証は信じられないほど難しいです。)

+0

ウェブサーバ+ OS: サーバ:Apache/2.0.63(Unix)mod_ssl/2.0.63 OpenSSL/0.9.8e-fips-rhel5 mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635 PHP/5.2.8 X-Powered -By:PHP/5.2.8 あなたの2番目の発言については、以前にfile_exist()がチェックされています。十分ではありませんか? – pixeline

+0

...それは問題を解決するfilesize()を呼び出す行をコメントアウトしているようです。それはそれかもしれませんか? – pixeline

+0

Content-Lengthを省略すると、Apacheは長さを自動的に処理します(通常、チャンクレスで出力をラップすることによって)。自動的に長さが正しく取得されます。問題は、長さヘッダが\ n - > \ r \ nの問題ではない場合に、長さヘッダが間違っている理由です(Unixサーバを使用している場合はそうではありません)。何らかの理由でfilesize()がFALSEを返す可能性がありますか? – bobince

-1

私はすべてのゴミが何であるかを伝えることができませんでしたが、あなたは、die()を呼び出してファイルを送信した後、それを避けるために。

+0

私はすでにそれを持っています、残念なことに。 – pixeline

関連する問題