2013-08-28 4 views
0

Вот простой сценарий, который я написал для ограничения загрузки для пользователей по одному (IE, если они загружают файл, тогда они не могут загрузить другой, пока не отменит текущую загрузку или не закончится).Почему этот скрипт загрузки PHP не работает?

ignore_user_abort(true); 

$local_file = $_GET['filename']; 
$download_file = explode("/", $local_file); 
$download_file = $download_file[count($download_file) -1]; 

// set the download rate limit (value is in kilobytes per second 
$download_rate = 100; 
if(file_exists($local_file) && is_file($local_file)) { 
    $ip = visitor_ip(); 
    if(!are_downloading($ip)) { 
     header('Cache-control: private'); 
     header('Content-Type: application/octet-stream'); 
     header('Content-Length: '.filesize($local_file)); 
     header('Content-Disposition: filename='.$download_file); 

     flush(); 

     $file = fopen($local_file, "r"); 
     log_downloader($ip); 

     while(!feof($file)) { 
      if (!connection_aborted()) { 
      // send the current file part to the browser 
      print fread($file, round($download_rate * 1024)); 
      // flush the content to the browser 
      flush(); 
      // sleep one second 
      sleep(1); 
     } else { 
      break; 
      } 
     } 

     clear_downloader($ip);  
     fclose($file); 
    } else { 
     die('<span style="color:#DDDDDD">Due to server limitations you may only download one file at a time. Please cancel or wait for your current download to finish before trying again. Click <a href="/simfiles">here</a> to return.</span>'); 
    } 
} else { 
    die('Error: The file '.$local_file.' does not exist!'); 
} 

function visitor_ip() { 
    if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) 
     $TheIp=$_SERVER['HTTP_X_FORWARDED_FOR']; 
    else $TheIp=$_SERVER['REMOTE_ADDR']; 

    return trim($TheIp); 
} 

function are_downloading($ip) { 
    $query = "select * from downloaders where ip_addr='$ip'"; 
    $result = mysql_query($query); 

    $num_rows = mysql_num_rows($result); 

    return $num_rows > 0; 
} 

function log_downloader($ip) { 
    $query = "insert into downloaders (ip_addr) values ('$ip')"; 
    $result = mysql_query($query); 
} 

function clear_downloader($ip) { 
    $query = "delete from downloaders where ip_addr='$ip'"; 
    $result = mysql_query($query); 
} 

Когда я проверить это, он отлично работает, но для многих людей, их IP никогда не будет очищен из базы данных - даже тогда, когда они закончили загрузку/отменила файл. Почему IP-адреса не удаляются?

+0

Это плохая идея из-за NAT. Я бы использовал их идентификатор сеанса PHP вместо своего IP, чтобы идентифицировать их, что гарантированно будет уникальным. – ChunkyBaconPlz

+0

Этот сценарий крайне небезопасен. Вы позволяете пользователям загружать все, что захотите, с вашего жесткого диска, включая исходный код для ваших приложений, возможно, пароли и т. Д. Вы также широко открыты для атак SQL-инъекций, поскольку вы доверяете заголовкам запросов для значений «HTTP_X_FORWARDED_FOR» а что нет, и ничего не избегать, прежде чем использовать его в базе данных. Используйте подготовленные/параметризованные запросы с PDO или аналогичные, чтобы избежать проблем с SQL-инъекциями, и проверяйте файлы, которые вы разрешаете пользователям загружать, чтобы убедиться, что они находятся в каталоге, который вы ожидаете. – Brad

+0

Есть еще кое-что, о чем вы говорили, это только часть сценария, вызывающая проблемы. –

ответ

1

Проблема заключалась в том, что с большими загрузками соединение MySQL ушло, мне просто пришлось снова подключиться к функции clear_downloader, и теперь он работает нормально.

Смежные вопросы