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);
}
Exemple #2
0
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);
}
Exemple #3
0
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);
        }
    }
}