function send_bits($File_Name, $MIME) { $File_Size = filesize($File_Name); $File = fopen($File_Name, "rb"); $File_Ranges = null; if ($_SERVER['REQUEST_METHOD'] == 'GET' && isset($_SERVER['HTTP_RANGE']) && ($File_Range = stristr(trim($_SERVER['HTTP_RANGE']), 'bytes='))) { $File_Range = substr($File_Range, 6); $Boundary = 'sdfjasjbc3hd84hr9ajdh20d'; $File_Ranges = explode(',', $File_Range); } if ($File_Ranges && count($File_Ranges)) { header("HTTP/1.1 206 Partial content"); header("Accept-Ranges: bytes"); if (count($File_Ranges) > 1) { $content_length = 0; foreach ($File_Ranges as $File_Range) { set_index($File_Range, $File_Size, $Index_First, $Index_Last); $content_length += strlen("\r\n--{$Boundary}\r\n"); $content_length += strlen("Content-type: {$MIME}\r\n"); $content_length += strlen("Content-range: bytes {$Index_First}-{$Index_Last}/{$File_Size}\r\n\r\n"); $content_length += $Index_Last - $Index_First + 1; } $content_length += strlen("\r\n--{$boundary}--\r\n"); header("Content-Length: {$content_length}"); header("Content-Type: multipart/x-byteranges; boundary={$boundary}"); foreach ($File_Ranges as $File_Range) { set_index($File_Range, $File_Size, $Index_First, $Index_Last); echo "\r\n--{$boundary}\r\n"; echo "Content-type: {$MIME}\r\n"; echo "Content-range: bytes {$Index_First}-{$Index_Last}/{$File_Size}\r\n\r\n"; fseek($File, $Index_First); buffered_read($File, $Index_Last - $Index_First + 1); } echo "\r\n--{$boundary}--\r\n"; } else { $File_Range = $File_Ranges[0]; set_index($File_Range, $File_Size, $Index_First, $Index_Last); header("Content-Length: " . ($Index_Last - $Index_First + 1)); header("Content-Range: bytes {$Index_First}-{$Index_Last}/{$File_Size}"); header("Content-Type: {$MIME}"); fseek($File, $Index_First); buffered_read($File, $Index_Last - $Index_First + 1); } } else { header("Accept-Ranges: bytes"); header("Content-Length: {$File_Size}"); header("Content-Type: {$MIME}"); readfile($File_Name); } fclose($File); }
function byteserve($filename, $mimeType = 'application/pdf') { /* Byteserves the file $filename. When there is a request for a single range, the content is transmitted with a Content-Range header, and a Content-Length header showing the number of bytes actually transferred. When there is a request for multiple ranges, these are transmitted as a multipart message. The multipart media type used for this purpose is "multipart/byteranges". */ $filesize = filesize($filename); $file = fopen($filename, "rb"); $ranges = NULL; if ($_SERVER['REQUEST_METHOD'] == 'GET' && isset($_SERVER['HTTP_RANGE']) && ($range = stristr(trim($_SERVER['HTTP_RANGE']), 'bytes='))) { $range = substr($range, 6); $boundary = 'g45d64df96bmdf4sdgh45hf5'; //set a random boundary $ranges = explode(',', $range); } if ($ranges && count($ranges)) { header("HTTP/1.1 206 Partial content"); header("Accept-Ranges: bytes"); if (count($ranges) > 1) { /* More than one range is requested. */ //compute content length $content_length = 0; foreach ($ranges as $range) { set_range($range, $filesize, $first, $last); $content_length += strlen("\r\n--{$boundary}\r\n"); $content_length += strlen("Content-type: " . $mimeType . "\r\n"); $content_length += strlen("Content-range: bytes {$first}-{$last}/{$filesize}\r\n\r\n"); $content_length += $last - $first + 1; } $content_length += strlen("\r\n--{$boundary}--\r\n"); //output headers header("Content-Length: {$content_length}"); //see http://httpd.apache.org/docs/misc/known_client_problems.html for an discussion of x-byteranges vs. byteranges header("Content-Type: multipart/x-byteranges; boundary={$boundary}"); //output the content foreach ($ranges as $range) { set_range($range, $filesize, $first, $last); echo "\r\n--{$boundary}\r\n"; echo "Content-type: " . $mimeType . "\r\n"; echo "Content-range: bytes {$first}-{$last}/{$filesize}\r\n\r\n"; fseek($file, $first); buffered_read($file, $last - $first + 1); } echo "\r\n--{$boundary}--\r\n"; } else { /* A single range is requested. */ $range = $ranges[0]; set_range($range, $filesize, $first, $last); header("Content-Length: " . ($last - $first + 1)); header("Content-Range: bytes {$first}-{$last}/{$filesize}"); header("Content-Type: " . $mimeType); fseek($file, $first); buffered_read($file, $last - $first + 1); } } else { //no byteserving while (ob_get_level()) { ob_end_clean(); } header("Accept-Ranges: bytes"); header("Content-Length: {$filesize}"); header("Content-Type: " . $mimeType); ob_end_flush(); readfile($filename); } fclose($file); }
function byteserve($filename) { /* Byteserves the file $filename. When there is a request for a single range, the content is transmitted with a Content-Range header, and a Content-Length header showing the number of bytes actually transferred. When there is a request for multiple ranges, these are transmitted as a multipart message. The multipart media type used for this purpose is "multipart/byteranges". */ global $MAX_FILE_SIZE; $filesize = filesize($filename); $ranges = NULL; if ($_SERVER['REQUEST_METHOD'] == 'GET' && isset($_SERVER['HTTP_RANGE']) && ($range = stristr(trim($_SERVER['HTTP_RANGE']), 'bytes='))) { $range = substr($range, 6); $ranges = explode(',', $range); } //If we don't find it in the header, check the query parameter if ($range == NULL && $ranges == NULL) { $strfirst = $_GET['start']; $last = $_GET['end']; $hasQueryStart = $strfirst != NULL; if ($hasQueryStart) { $first = (int) $strfirst; $last = (int) $last; } } if ($ranges && count($ranges) || $hasQueryStart) { header("HTTP/1.1 206 Partial content", True, 206); header("Accept-Ranges: bytes"); if (count($ranges) > 1) { //unsatisfiable range header("HTTP/1.1 501 Do not support multiple ranges", True, 501); } else { //A single range is requested. $range = $ranges[0]; if ($hasQueryStart) { //Nothing to do, $first and last already set } else { set_range($range, $filesize, $first, $last); } header("Content-Length: " . ($last - $first + 1)); $contRange = "Content-Range: bytes {$first}-{$last}/{$filesize}"; //log_message($contRange); header($contRange); $file = fopen($filename, "rb"); fseek($file, $first); buffered_read($file, $last - $first + 1, 1024); fclose($file); } } else { $isHead = $_SERVER['REQUEST_METHOD'] == 'HEAD'; header("Accept-Ranges: bytes"); header("Content-Length: {$filesize}"); if (!$isHead) { readfile($filename); } } }