Проблемы с сервером защиты файлов - readfile (); - PullRequest
0 голосов
/ 09 февраля 2011

Я написал следующий скрипт для во избежание предоставления защищенных файлов пользователям, вошедшим в мое веб-приложение.

Это хорошо работает с небольшими файлами ... но на некоторых платформах, таких какiPad, Android, Internet Explorer и иногда Safari. Я получаю файл , иногда (примерно 50%), который обслуживается частично ... как остановка соединения в середине передачи.

Я использую Apache2.2 / PHP 5.3 на Ubuntu Server 10.04.

Кто-нибудь может подсказать, как его улучшить?Спасибо.

<?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');
}

1 Ответ

0 голосов
/ 09 февраля 2011

Theres проблема с этой строкой:

$type = exec('file -bi ' . escapeshellarg($file) );

На сервере Ubuntu 9.10 возвращаемое значение команды оболочки:

image/jpeg; charset=binary

Так что ваш чек должен проваливаться всегда. Вам нужно изменить команду на:

$type = exec('file --mime-type -b ' . escapeshellarg($file) );

Что должно дать вам:

image/jpeg

Кроме того, лучше всего проверять вызовы API с помощью curl вместо браузера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...