나는 주어진 폴더의 하위 폴더와 파일을 표시하는이 PHP 스크립트를 작성하고 있습니다. 파일을 다운로드해야합니다.PHP 파일 다운로드 : 이상한 http 헤더
가능한 한 적은 정보를 공개하기 위해 디렉토리의 각 항목은 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();
}
웹 서버 + 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 두 번째 발언에 대해서는 이전에 file_exist()가 있는지 확인합니다. 충분하지 않아? – pixeline
... filesize()를 호출하는 줄을 주석 처리하는 것으로 문제가 해결됩니다. 그게 될 수 있을까? – pixeline
Content-Length를 생략하면 아파치가 길이를 자동으로 처리하게됩니다 (대개 청크 응답으로 출력을 래핑함으로써). 그러면 자동으로 길이가 올바르게됩니다. 문제는 \ n -> \ r \ n 문제가 아니라면 (왜 유닉스 서버를 사용한다면 그렇게 될 수 없다), 길이 헤더가 틀린 이유이다. 어떤 이유로 filesize()가 FALSE를 반환 할 수 있습니까? – bobince