php - Troubles with file protector server - readfile(); -
i wrote following script avoid exposing protected files users logged in web application.
this works small files... on platforms, such ipad, android, internet explorer , safari sometimes (about 50% times) file served partially... connection stop in middle of trasfer.
i'm running apache2.2/php 5.3 on ubuntu server 10.04.
can suggest how improve it? thanks.
<?php // bootstrap env vars // 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' ); // custom function check login if( isuserlogged($_session) ) { // if file exist if(! is_file( $file ) ) { header('http/1.1 400 bad request'); die('unable find target file'); } // if 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 pdf, try 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'); }
theres problem line:
$type = exec('file -bi ' . escapeshellarg($file) );
on ubuntu 9.10 server, return value of shell command is:
image/jpeg; charset=binary
so check should fail always. need change command to:
$type = exec('file --mime-type -b ' . escapeshellarg($file) );
which should give you:
image/jpeg
also, best test api calls via curl instead of browser.
Comments
Post a Comment