function send_file_to_client($real_filename, $filename, $disposition = null, $send_name = false, $delete = false) { if (!file_exists($real_filename)) { return false; } $content_type = get_mime_type($filename); if ($content_type == 'text/html') { $charset = '; charset=' . html_charset($real_filename); } elseif ($content_type == 'text/plain') { $charset = '; charset=' . text_charset($real_filename); } else { $charset = ''; } if ($send_name) { if (preg_match('/[^\\x20-\\x7E]/', $filename) and strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false) { $filename = urlencode($filename); } // Add quotes to filename if it contains spaces if (strpos($filename, ' ') !== false) { $filename = '"' . $filename . '"'; } $filenameattr = '; filename=' . $filename; if (!isset($disposition)) { $disposition = 'attachment'; } } else { $filenameattr = ''; } header("Content-type: {$content_type}{$charset}"); if (isset($disposition)) { header("Content-Disposition: {$disposition}{$filenameattr}"); } header('Pragma:'); header('Cache-Control: public'); header('Content-length: ' . filesize($real_filename)); $mtime = filemtime($real_filename); $mdate = gmdate('D, d M Y H:i:s', $mtime); $etag = md5($real_filename . $mdate . $filename . filesize($real_filename)); header('Last-Modified: ' . $mdate . ' GMT'); header("Etag: {$etag}"); if (array_key_exists('HTTP_IF_MODIFIED_SINCE', $_SERVER) and strtotime(preg_replace('/;.*$/', '', $_SERVER['HTTP_IF_MODIFIED_SINCE'])) >= $mtime or array_key_exists('HTTP_IF_NONE_MATCH', $_SERVER) and trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag) { header("HTTP/1.0 304 Not Modified"); } else { stop_output_buffering(); if ($delete) { register_shutdown_function('unlink', $real_filename); } readfile($real_filename); } return true; }
function send_file_to_client($real_filename, $filename, $disposition = null, $send_name = false, $delete = false) { if (!file_exists($real_filename)) { return false; } $content_type = get_mime_type($filename); if ($content_type == 'text/html') { $charset = '; charset=' . html_charset($real_filename); } elseif ($content_type == 'text/plain') { $charset = '; charset=' . text_charset($real_filename); } else { $charset = ''; } if ($send_name) { if (preg_match('/[^\\x20-\\x7E]/', $filename) and strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false) { $filename = urlencode($filename); } // Add quotes to filename if it contains spaces if (strpos($filename, ' ') !== false) { $filename = '"' . $filename . '"'; } $filenameattr = '; filename=' . $filename; if (!isset($disposition)) { $disposition = 'attachment'; } } else { $filenameattr = ''; } header("Content-type: {$content_type}{$charset}"); if (isset($disposition)) { header("Content-Disposition: {$disposition}{$filenameattr}"); } header('Pragma:'); header('Cache-Control: public'); $mtime = filemtime($real_filename); $mdate = gmdate('D, d M Y H:i:s', $mtime); $etag = md5($real_filename . $mdate . $filename . filesize($real_filename)); header('Last-Modified: ' . $mdate . ' GMT'); header("Etag: {$etag}"); if (array_key_exists('HTTP_IF_MODIFIED_SINCE', $_SERVER) and strtotime(preg_replace('/;.*$/', '', $_SERVER['HTTP_IF_MODIFIED_SINCE'])) >= $mtime or array_key_exists('HTTP_IF_NONE_MATCH', $_SERVER) and trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag) { header("HTTP/1.0 304 Not Modified"); } else { if ($delete) { register_shutdown_function('unlink', $real_filename); } $size = filesize($real_filename); if (isset($_SERVER['HTTP_RANGE'])) { // error_log('http range ON: ' . $_SERVER['HTTP_RANGE']); // debug output in apache error.log // Parse the range header to get the byte offset $ranges = array_map('intval', explode('-', substr($_SERVER['HTTP_RANGE'], 6))); if (!$ranges[1]) { // Second number missing, return from byte $range[0] to end $start = $ranges[0]; $end = $size - 1; } else { // Both numbers present, return specific range $start = $ranges[0]; $end = $ranges[1]; } $length = $end - $start + 1; // Send the appropriate headers header('HTTP/1.1 206 Partial Content'); header('Accept-Ranges: bytes'); header('Content-Length: ' . $length); header(sprintf('Content-Range: bytes %d-%d/%d', $start, $end, $size)); $f = fopen($real_filename, 'rb'); // Open the file in binary mode $chunkSize = 8192; // The size of each chunk to output fseek($f, $start); // Seek to the requested start range stop_output_buffering(); while ($length) { // Read in blocks of chunksize so we don't chew up memory on the server $read = $length > $chunkSize ? $chunkSize : $length; $length -= $read; echo fread($f, $read); } fclose($f); } else { // error_log('http range OFF'); // debug output in apache error.log header('Content-length: ' . $size); stop_output_buffering(); readfile($real_filename); } } return true; }