[Apache+PHP] проблема с докачкой

Andbar

Есть скрипт, осуществляющих докачку (скрипт вызывается через mod_rewrite данные о файле на который передаются через сессию.
//error_reporting(0);
set_time_limit(100);
@ini_set('implicit_flush','1');
function Er($n){@header('HTTP/1.1 '.$n);die;}
session_name('ses');
session_start;
header('Expires:');//!
header('Cache-Control:');
header('Pragma:');
$file = $_SESSION['file'];
$size = $_SESSION['size'];
if(!is_readable($file Er(404);
if(filesize($file)!=$size) Er(409);
if(isset($_SERVER['HTTP_RANGE']{
if(strncasecmp('bytes=',$_SERVER['HTTP_RANGE'],6 Er(416);
list($start,$end) = explode('-',substr($_SERVER['HTTP_RANGE'],6;
if($start=='' or $start==='0')$start = 0;
elseif(!($start = intval($start Er(400);
if($end=='')$end = $size-1;
elseif(!($end = intval($end Er(400);
if($start==0 and $end==size-1){
header('HTTP/1.1 200');
} else {
if($start>$end or $end>=$size) Er(416);
header('HTTP/1.1 206');
header('Content-Range: bytes '.$start.'-'.$end.'/'.$size);
}
} else {
$start = 0;
$end = $size-1;
header('HTTP/1.1 200');
}
$len = $end-$start+1;
header('Last-Modified: '.gmdate('D, d M Y H:i:s',filemtime($file.' GMT');
header('ETag: "'.$_SESSION['etag'].'"');
header('Accept-Ranges: bytes');
header('Content-Length: '.$len);
header('Content-Type: '.$_SESSION['type']);
$file = fopen($file,'r');
fseek($file,$start,SEEK_SET);
while($len>0):
set_time_limit(20);
flock($file,LOCK_SH+LOCK_NB);
echo fread($file,min(2048,$len;
flock($file,LOCK_UN);//!
$len -= 2048;
sleep(0);
endwhile;
fclose($file);
Закачка происходит только в один поток (изредка - второй работает, но есть подозрение, что при этом первый приостанавливается остальные передают заголовки, но даунлоад-менеджер (FlashGet) никаких данных не получает. Если убрать set_time_limit, то два из четырёх потоков вылетают по "Maximum execution time of 30 seconds exceeded" на строках, отмеченных коментарием "!" (запускал закачку несколько раз - ошибки одни и те же).
Что я неправильно делаю?

Andbar

Похоже сессии виноваты.
session_write_close; перед циклом чтения/вывода помогло.

vlfdimir58

cпасибо тебе! Аналогичная проблема была!
Сучьи сессии
Session data is usually stored after your script terminated without the need to call session_write_close but as session data is locked to prevent concurrent writes only one script may operate on a session at any time. When using framesets together with sessions you will experience the frames loading one by one due to this locking. You can reduce the time needed to load all the frames by ending the session as soon as all changes to session variables are done.
Оставить комментарий
Имя или ник:
Комментарий: