我将以下脚本编写为避免将受保护文件暴露给在我的Web应用程序中登录的用户。
这适用于小文件...但在某些平台上,例如iPad,Android,Internet Explorer以及有时Safari我有时会有时(约50%)文件服务...就像在trasfer中间的连接停止一样。
我在Ubuntu Server 10.04上运行Apache2.2 / PHP 5.3。
有谁能建议如何改进它? 感谢。
<?php
// my bootstrap with env vars
// some includes ..
if(! @constant('APP_BASE_PATH') ) { header('HTTP/1.1 502 Bad Gateway'); die(''); }
// allowed types
$allowed_types = array( 'application/pdf', 'image/png', 'image/jpeg' );
// my custom function to check login
if( isUserLogged($_SESSION) )
{
// if file exist
if(! is_file( $file ) )
{ header('HTTP/1.1 400 Bad Request'); die('unable to find target file'); }
// if is permitted
$type = exec('file -bi ' . escapeshellarg($file) );
if(! in_array( $type, $allowed_types ) )
{ header('HTTP/1.1 400 Bad Request'); die(''); }
// lenght calc
$content_lenght = intval( sprintf( "%u", filesize( $file ) ) );
// last modify
$last_modified = gmdate('D, d M Y H:i:s', filemtime( $file ) ) . ' GMT';
// generating l'etags
$stat = stat($file);
$etag = sprintf( '"%x-%x-%s"' , $stat['ino'] , $stat['size'] , base_convert( str_pad( $stat['mtime'], 16, '0' ) , 10 , 16 ) );
// disable gzip compression
@apache_setenv ( 'no-gzip', 1 );
@ini_set ( 'zlib.output_compression', 0 );
ini_set( 'display_error', 0);
header ( 'HTTP/1.1 200 OK' );
header ( 'Content-Type: ' . $type );
header ( 'Content-Length: ' . $content_lenght );
header ( 'Etag: ' . $etag );
header ( 'Last-Modified: ' . $last_modified );
// if that's a PDF, try to force
if( strpos($type, 'application/pdf') !== FALSE ) {
header ( 'Content-Description: File Transfer' );
header ( 'Content-disposition: attachment; filename=' . basename ( $file ) );
header ( 'Content-Transfer-Encoding: binary');
}
// serve file
readfile ( $file );
} else {
header('HTTP/1.1 401 Unauthorized');
}
答案 0 :(得分:0)
这条线存在问题:
$type = exec('file -bi ' . escapeshellarg($file) );
在Ubuntu 9.10服务器上,shell命令的返回值为:
image/jpeg; charset=binary
所以你的支票总是会失败。您需要将命令更改为:
$type = exec('file --mime-type -b ' . escapeshellarg($file) );
哪个应该给你:
image/jpeg
此外,最好通过curl而不是浏览器来测试您的API调用。