currently using a simple php image proxy to load external images to ensure they don't mess with SSL. The problem is, on my live site they only seem to get stored in the memory cache and not the disk cache, so as soon as you close the tab/browser they get downloaded again.
Here's the code:
session_cache_limiter('public');
if (isset($_GET['url']))
{
header('Cache-control: max-age='.(60*60*24*365));
header('Expires: '.gmdate(DATE_RFC1123,time()+60*60*24*365));
header('Last-Modified: '.gmdate(DATE_RFC1123,filemtime($_GET['url'])));
define("APP_ROOT", dirname(dirname(__FILE__)));
require APP_ROOT . "/includes/bootstrap.php";
$url_check = parse_url($_GET['url']);
if (isset($url_check['scheme']) && ($url_check['scheme'] == 'http' || $url_check['scheme'] == 'https'))
{
$image_raw = core::file_get_contents_curl($_GET['url']);
$new_image = imagecreatefromstring($image_raw);
if ($new_image !== false)
{
$image_info = getimagesizefromstring($image_raw);
$image_type = $image_info['mime'];
if (stripos($image_type, 'image/') !== false)
{
header('Content-Type: '.$image_type);
imagepng($new_image);
imagedestroy($new_image);
}
}
}
else
{
echo 'Not a valid image url!';
}
}
Related
I have a php script that allows users to download large files. The script works well except for files of over around 500mb. Everytime I try to download a file that is 664mb the download stops at about 460mb ( around 15-17 mins). There is no error. What can I do? I
suspect the script is timing out but I can't see why. I've spent days trying to get it to work and just can't make any progress. Any thoughts or suggestions would be great. I'm using a hosted server so cannot try modx_sendfile sadly. I'm using php 7.0.25
$db = new mysqli($dbHost, $dbUsername, $dbPassword, $dbName);
ob_start() or die('Cannot start output buffering');
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
$strDownloadFolder = "files/";
//- turn off compression on the server
//#apache_setenv('no-gzip', 1);
#ini_set('zlib.output_compression', 'Off');
//Download a file more than once
$boolAllowMultipleDownload = 2;
if(!empty($_GET['key'])){
//check the DB for the key
$sql = "SELECT * FROM downloads WHERE downloadkey = '".mysqli_real_escape_string($db,$_GET['key'])."' LIMIT 1";
$resCheck=mysqli_query($db, $sql);
$arrCheck = mysqli_fetch_array($resCheck); //Create array from first result
if(!empty($arrCheck['file'])){
//check that the download time hasnt expired
if($arrCheck['expires']>=time()){
if(!$arrCheck['downloads'] OR $boolAllowMultipleDownload){
//everything is ok -let the user download it
$strDownload = $strDownloadFolder.$arrCheck['file'];
if(file_exists($strDownload)){
$file_path = $arrCheck['file'];
$path_parts = pathinfo($file_path);
$file_name = $path_parts['basename'];
$file_ext = $path_parts['extension'];
$file_path = 'files/' . $file_name;
// allow a file to be streamed instead of sent as an attachment
$is_attachment = isset($_REQUEST['stream']) ? false : true;
// make sure the file exists
if (is_file($file_path))
{
$file_size = filesize($file_path);
$file = #fopen($file_path,"rb");
if ($file)
{
// set the headers, prevent caching
header("Pragma: public");
header("Expires: -1");
header("Cache-Control: public, must-revalidate, post-check=0, pre-check=0");
header("Content-Disposition: attachment; filename=\"$file_name\"");
// set appropriate headers for attachment or streamed file
if ($is_attachment) {
header("Content-Disposition: attachment; filename=\"$file_name\"");
}
else {
header('Content-Disposition: inline;');
header('Content-Transfer-Encoding: binary');
}
// set the mime type based on extension, add yours if needed.
$ctype_default = "application/octet-stream";
$content_types = array(
"exe" => "application/octet-stream",
"zip" => "application/zip",
"mp3" => "audio/mpeg",
"mpg" => "video/mpeg",
"avi" => "video/x-msvideo",
);
$ctype = isset($content_types[$file_ext]) ? $content_types[$file_ext] : $ctype_default;
header("Content-Type: " . $ctype);
//check if http_range is sent by browser (or download manager)
if(isset($_SERVER['HTTP_RANGE']))
{
list($size_unit, $range_orig) = explode('=', $_SERVER['HTTP_RANGE'], 2);
if ($size_unit == 'bytes')
{
list($range, $extra_ranges) = explode(',', $range_orig, 2);
}
else
{
$range = '';
header('HTTP/1.1 416 Requested Range Not Satisfiable');
exit;
}
}
else
{
$range = '';
}
//figure out download piece from range (if set)
list($seek_start, $seek_end) = explode('-', $range, 2);
//set start and end based on range (if set), else set defaults
//also check for invalid ranges.
$seek_end = (empty($seek_end)) ? ($file_size - 1) : min(abs(intval($seek_end)),($file_size - 1));
$seek_start = (empty($seek_start) || $seek_end < abs(intval($seek_start))) ? 0 : max(abs(intval($seek_start)),0);
//Only send partial content header if downloading a piece of the file (IE workaround)
if ($seek_start > 0 || $seek_end < ($file_size - 1))
{
header('HTTP/1.1 206 Partial Content');
header('Content-Range: bytes '.$seek_start.'-'.$seek_end.'/'.$file_size);
header('Content-Length: '.($seek_end - $seek_start + 1));
}
else
header("Content-Length: $file_size");
header('Accept-Ranges: bytes');
set_time_limit(0);
fseek($file, $seek_start);
while(!feof($file))
{
print(#fread($file, 1024*8));
ob_flush();
flush();
if (connection_status()!=0)
{
#fclose($file);
exit;
}
}
// file save was a success
#fclose($file);
exit;
}
else
{
// file couldn't be opened
header("HTTP/1.0 500 Internal Server Error");
exit;
}
}
else
{
// file does not exist
header("HTTP/1.0 404 Not Found");
exit;
}
}else{
echo "We couldn't find the file to download.";
}
}else{
//this file has already been downloaded and multiple downloads are not allowed
echo "This file has already been downloaded.";
}
}else{
//this download has passed its expiry date
echo "This download has expired.";
}
}else{
//the download key given didnt match anything in the DB
echo "No file was found to download.";
}
}else{
//No download key wa provided to this script
echo "No download key was provided. Please return to the previous page and try again.";
}
A much simpler piece of code that still throws up the same problem (but works with smaller files) mkaes me think it is a hosting / php.ini issue although I don't know why.
<?php
$local_file = 'my_big_file.zip';
$download_file = 'my_big_file.zip';
// set the download rate limit (=> 20,5 kb/s)
if(file_exists($local_file) && is_file($local_file))
{
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");
while(!feof($file))
{
// send the current file part to the browser
print fread($file, round(1024 * 1024));
// flush the content to the browser
flush();
// sleep one second
sleep(1);
}
fclose($file);}
else {
die('Error: The file '.$local_file.' does not exist!');
}
?>
This script stops downloading after about 17 minutes.
Below is my code which I tried but there is showing some warning errors:
Warning: getimagesize(C:\xampp\tmp\php2F0B.tmp): failed to open stream: No such file or directory in C:\xampp\htdocs\maahima\admin\uploadBulkImages.php on line 55
Warning: imagejpeg() expects parameter 1 to be resource, string given in C:\xampp\htdocs\maahima\admin\uploadBulkImages.php on line 66
I want the code to insert images in folder in bulk with compressed image.
<?php
if(isset($_FILES['file']['tmp_name'])){
$pro_image = $_FILES['file']['tmp_name'];
$no_of_file = count($_FILES['file']['tmp_name']);
$name = ''; $type = ''; $size = ''; $error = '';
for($i=0;$i < $no_of_file;$i++){
if(! is_uploaded_file($_FILES['file']['tmp_name'][$i])){
header("location:add_products.php?error=er8r5r");
}
else{
if(move_uploaded_file($_FILES['file']['tmp_name'][$i],"../products/".$_FILES['file']['name'][$i])){
if ($_FILES["file"]["error"][$i] > 0) {
$error = $_FILES["file"]["error"];
}
else {
$image="";
$error = "Uploaded image should be jpg or gif or png";
$url = '../smallSize-Image/'.$_FILES['file']['name'][$i];
echo $url;
$source_url=$_FILES["file"]["tmp_name"][$i];
$destination_url=$url;
$quality=12;
$info = getimagesize($source_url);
if ($info['mime'] == 'image/jpeg')
$image = imagecreatefromjpeg($source_url);
elseif ($info['mime'] == 'image/gif')
$image = imagecreatefromgif($source_url);
elseif ($info['mime'] == 'image/png')
$image = imagecreatefrompng($source_url);
imagejpeg($image, $destination_url, $quality);
return $destination_url;
$buffer = file_get_contents($url);
/* Force download dialog... */
//header("Content-Type: application/force-download");
//header("Content-Type: application/octet-stream");
//header("Content-Type: application/download");
// header("location:add_products.php?succcess=s8sc5s");
/* Don't allow caching... */
// header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
/* Set data type, size and filename */
//header("Content-Type: application/octet-stream");
//header("Content-Length: " . strlen($buffer));
//header("Content-Disposition: attachment; filename=$url");
/* Send our file... */
echo $buffer;
}
}
else{
header("location:add_products.php?error=er8r5r");
}
}
}
}
else{
}
?>
Your script has a lot of illogical features. If you are going to redirect, you need to exit. You should not have a return in the middle of the script, that is somewhat random (probably this is unfinished script and it's inside another function/method?). Here are some things I would do if I were to do this.
If you don't already have a config that has some absolute defines, I would create one and include it on every initial load page at the top.
This is tested and works, provided it's implemented correctly and as demonstrated. Use some of it, bits of it, or none of it, but it does work:
/config.php
<?php
define('DS',DIRECTORY_SEPARATOR);
define('ROOT_DIR',__DIR__);
define('UPLOAD_DIR',ROOT_DIR.DS.'uploads'.DS.'images');
define('THUMB_DIR',ROOT_DIR.DS.'uploads'.DS.'thumbs');
define('VENDOR_DIR',ROOT_DIR.DS.'vendors');
I would consider making some quick functions, in this case a class/method system to complete some simple tasks.
/vendors/Files.php
class Files
{
/*
** #description This will turn a numbered $_FILES array to a normal one
*/
public static function normalize($key = 'file')
{
foreach($_FILES[$key]['tmp_name'] as $fKey => $value) {
$FILES[] = array(
'tmp_name'=>$_FILES[$key]['tmp_name'][$fKey],
'name'=>$_FILES[$key]['name'][$fKey],
'error'=>$_FILES[$key]['error'][$fKey],
'size'=>$_FILES[$key]['size'][$fKey],
'type'=>$_FILES[$key]['type'][$fKey]
);
}
return $FILES;
}
/*
** #description I would contain this step into an editable method for
** ease of use and reuse.
*/
public static function compress($path, $dest, $quality = 12)
{
$info = getimagesize($path);
if($info['mime'] == 'image/jpeg')
$image = imagecreatefromjpeg($path);
elseif($info['mime'] == 'image/gif')
$image = imagecreatefromgif($path);
elseif($info['mime'] == 'image/png')
$image = imagecreatefrompng($path);
imagejpeg($image,$dest,$quality);
}
}
Put it all together, in this case I would maybe throw exceptions and save errors to a session. Loop through them on the add_products.php page.
# Add our config
include(__DIR__.DIRECTORY_SEPARATOR.'config.php');
# Add our file handler class (spl_autoload_register() is a better option)
include(VENDOR_DIR.DS.'Files.php');
# Observe for file upload
if(!empty($_FILES['file']['tmp_name'])){
# Use our handy convert method
$FILES = Files::normalize();
# Try here
try {
# Loop through our normalized file array
foreach($FILES as $i => $file){
# Throw error exception here
if(!is_uploaded_file($file['tmp_name']))
throw new Exception('File is not an uploaded document.');
# I like to add a create directory line or two to cover all bases
if(!is_dir(UPLOAD_DIR)) {
if(!mkdir(UPLOAD_DIR,0755,true))
throw new Exception('Upload folder could not be created.');
}
# Ditto
if(!is_dir(THUMB_DIR)) {
if(!mkdir(THUMB_DIR,0755,true))
throw new Exception('Thumb folder could not be created.');
}
# Create an absolute path for the full size upload
$path = UPLOAD_DIR.DS.$file['name'];
# If no errors and file is moved properly, compress and save thumb
if(($file["error"]) == 0 && move_uploaded_file($file['tmp_name'],$path))
# Create a thumbnail from/after the file you moved, not the temp file
Files::compress($path,THUMB_DIR.DS.$file['name']);
# Throw error on fail
else
throw new Exception('An unknown upload error occurred.');
}
}
# Catch, assign, redirect
catch (Exception $e) {
$_SESSION['errors'][] = $e->getMessage();
header("location: add_products.php?error=er8r5r");
exit;
}
}
I tried to use the code provided by SmartFile download provided in the internet. In the code I check the file name with the login id to avoid the user providing a different file name directly in the URL. (As he can easily guess because the First part of File name is the from login id)
. I check this in the code whether it is equal then it allows for pdf download else displays access violation.
Every thing fine so far. But after downloading I get the message that the file is corrupt or the file has been damaged(it was sent as email attachment and not correctly decoded).
I could not figure out where the problem lies. Any help appreciated. Thanks
<?php
session_start();
include_once('header.php');
if(!$_SESSION['username'])
{
header("Location: index.php");//redirect to login page to secure the welcome page without login access.
}
else
{
$user = $_SESSION['username'];
// Allow direct file download (hotlinking)?
// Empty - allow hotlinking
// If set to nonempty value (Example: example.com) will only allow downloads when referrer contains this text
define('ALLOWED_REFERRER', '');
// Download folder, i.e. folder where you keep all files for download.
// MUST end with slash (i.e. "/" )
define('BASE_DIR','../../downloads/');
// log downloads? true/false
define('LOG_DOWNLOADS',true);
// log file name
define('LOG_FILE','downloads.log');
// Allowed extensions list in format 'extension' => 'mime type'
// If myme type is set to empty string then script will try to detect mime type
// itself, which would only work if you have Mimetype or Fileinfo extensions
// installed on server.
$allowed_ext = array (
// documents
'pdf' => 'application/pdf'
);
####################################################################
### DO NOT CHANGE BELOW
####################################################################
// If hotlinking not allowed then make hackers think there are some server problems
if (ALLOWED_REFERRER !== ''
&& (!isset($_SERVER['HTTP_REFERER']) || strpos(strtoupper($_SERVER['HTTP_REFERER']),strtoupper(ALLOWED_REFERRER)) === false)
) {
die("Internal server error. Please contact system administrator.");
}
// Make sure program execution doesn't time out
// Set maximum script execution time in seconds (0 means no limit)
//set_time_limit(0);
if (!isset($_GET['f']) || empty($_GET['f'])) {
die("Please specify file name for download.");
}
// Nullbyte hack fix
if (strpos($_GET['f'], "\0") !== FALSE) die('');
// Get real file name.
// Remove any path info to avoid hacking by adding relative path, etc.
$fname = basename($_GET['f']);
if ($fname == $user."IN".".pdf")
{
// Check if the file exists
// Check in subfolders too
function find_file ($dirname, $fname, &$file_path) {
$dir = opendir($dirname);
while ($file = readdir($dir)) {
if (empty($file_path) && $file != '.' && $file != '..') {
if (is_dir($dirname.'/'.$file)) {
find_file($dirname.'/'.$file, $fname, $file_path);
}
else {
if (file_exists($dirname.'/'.$fname)) {
$file_path = $dirname.'/'.$fname;
return;
}
}
}
}
} // find_file
// get full file path (including subfolders)
$file_path = '';
find_file(BASE_DIR, $fname, $file_path);
if (!is_file($file_path)) {
die("File does not exist. Make sure you specified correct file name.");
}
// file size in bytes
$fsize = filesize($file_path);
// file extension
$fext = strtolower(substr(strrchr($fname,"."),1));
// check if allowed extension
if (!array_key_exists($fext, $allowed_ext)) {
die("Not allowed file type.");
}
// get mime type
if ($allowed_ext[$fext] == '') {
$mtype = '';
// mime type is not set, get from server settings
if (function_exists('mime_content_type')) {
$mtype = mime_content_type($file_path);
}
else if (function_exists('finfo_file')) {
$finfo = finfo_open(FILEINFO_MIME); // return mime type
$mtype = finfo_file($finfo, $file_path);
finfo_close($finfo);
}
if ($mtype == '') {
$mtype = "application/force-download";
}
}
else {
// get mime type defined by admin
$mtype = $allowed_ext[$fext];
}
// Browser will try to save file with this filename, regardless original filename.
// You can override it if needed.
if (!isset($_GET['fc']) || empty($_GET['fc'])) {
$asfname = $fname;
}
else {
// remove some bad chars
$asfname = str_replace(array('"',"'",'\\','/'), '', $_GET['fc']);
if ($asfname === '') $asfname = 'NoName';
}
// set headers
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Type: $mtype");
header("Content-Disposition: attachment; filename=\"$asfname\"");
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . $fsize);
// download
// #readfile($file_path);
$file = #fopen($file_path,"rb");
if ($file) {
while(!feof($file)) {
print(#fread($file, 1024*8));
flush();
if (connection_status()!=0) {
#fclose($file);
die();
}
}
#fclose($file);
}
// log downloads
if (!LOG_DOWNLOADS) die();
$f = #fopen(LOG_FILE, 'a+');
if ($f) {
#fputs($f, date("m.d.Y g:ia")." ".$_SERVER['REMOTE_ADDR']." ".$fname."\n");
#fclose($f);
}
}
else
{
echo '<script type="text/javascript">alert("Access Violation !")header("Location: index.php");</script>';
}
}
?>
Output buffer should be cleaned before sending any header or the file will become corrupt. ob_end_clean() should take care of it.
I created a code to backup an entire website & automatically download it on a single click. Here is what my code looks like:
if (file_exists("file.zip")) {
unlink("file.zip");
}
$folder_array = array();
$file_array = array();
function listFolderFiles($dir){
global $folder_array;
global $file_array;
$ffs = scandir($dir);
foreach($ffs as $ff){
if ($ff != '.' && $ff != '..') {
if (is_dir($dir.'/'.$ff)) {
$new_item = "$dir/$ff";
$new_item = str_replace('..//','',$new_item);
if ($new_item !== "stats") {
array_push($folder_array, $new_item);
listFolderFiles($dir.'/'.$ff);
}
}
else {
$new_item = "$dir/$ff";
$new_item = str_replace('..//','',$new_item);
if (($new_item !== "stats/logs") && ($new_item !== "stats/")) {
array_push($file_array, $new_item);
}
}
}
}
}
listFolderFiles('../');
$zip = new ZipArchive;
if ($zip->open('file.zip', true ? ZIPARCHIVE::OVERWRITE:ZIPARCHIVE::CREATE) === TRUE) {
foreach($folder_array as $folder) {
$zip->addEmptyDir($folder);
}
foreach($file_array as $key => $file) {
$file_path = "../$file";
$zip->addFile($file_path, $file);
}
}
$zip->close();
$file = "file.zip";
chmod("$file", 0700);
header("Content-type: application/zip");
header("Content-Disposition: attachment; filename=". $file);
readfile($file);
Now this code was working good for awhile, but it seems today it doesn't want to work. The thing is, it's not a PHP script error. I've checked my error logs and nothing is showing up. It appears to be a browser error, but each browser displays a different message:
Chrome says "This webpage is not available"
Firefox says "The connection was reset"
Internet Explorer says "This page can't be displayed"
Even though these errors come up, the ZIP file is still being created and I can download it from the server.
Here is a list of things I've tried after extensive research:
1) I removed the code to have the ZIP file download automatically (all code written after I close the ZIP file). Still get the browser errors.
2) I read that it's possible too many files are getting opened and its going over my limit. I added to the code to close and reopen the ZIP file after every 200 files. Still didn't work.
3) I limited the amount of files to ZIP. Everything was working fine below 500. Between 500 to 1,000 files, the code would work a partial amount of the time. Sometimes it would go through fine, the others it would give me the browser error. After 1,000 or so it just wouldn't work properly at all.
The hosting is through GoDaddy.
PHP Version is 5.2.17
max_execution_time is set at 240 (the code never goes this long, usually only takes about 30 sec to run)
memory_limit is set at 500M (more than twice the size of all the files combined)
I'm at a loss, I really don't know what is going on because this code was working just fine for 1,500 files a few weeks ago. And again, the ZIP file is still being created, there are no PHP errors and it's only the Browsers that are coming back with these errors.
I don't know what's wrong with your code, but I'm using the code below and it has been working forever with me.
function create_zip($path, $save_as)
{
if (!extension_loaded('zip'))
throw new ErrorException('Extension ZIP has not been compiled or loaded in php.');
else if(!file_exists($path))
throw new ErrorException('The file/path you want to zip doesn\'t exist!');
$zip = new ZipArchive();
if (!$zip->open($save_as, ZIPARCHIVE::CREATE))
throw new ErrorException('Could not create zip file!');
$ignore = array('.','..');
if($path == dirname($save_as))
$ignore[] = basename($save_as);
$path = str_replace('\\', '/', realpath($path));
if (is_dir($path)) {
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);
foreach ($files as $file) {
$file = str_replace('\\', '/', $file);
if( in_array(substr($file, strrpos($file, '/')+1),$ignore )) continue;
$file = realpath($file);
if (is_dir($file)) {
$zip->addEmptyDir(str_replace($path . '/', '', $file . '/'));
}
else if (is_file($file)) {
$zip->addFromString(str_replace($path . '/', '', $file), file_get_contents($file));
}
}
}
else if (is_file($path)) {
$zip->addFromString(basename($path), file_get_contents($path));
}
return $zip->close();
}
$zip = create_zip('/path/to/your/zip/directory', '/path/to/your/save.zip');
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename('/path/to/your/save.zip').'"');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize('/path/to/your/save.zip'));
echo readfile('/path/to/your/save.zip');
instantate an iterator (before creating the zip archive, just in case the zip file is created inside the source folder) and traverse the directory to get the file list.
See More Code At:click me
When we output images via PHP with image_jpeg or file_get_contents it takes more than twice as long as when we use straight links to the jpg files.
These files are about 180kb.
With our thumbnails (4kb images) there's not much of a time difference between the link and output via PHP.
Anyone know of a why PHP output is slower with larger files and a way to fix it?
All I can think of is that it is being parsed twice when parsed through PHP, instead of directly sending it to the client. Because file_get_contents does what it says, it reads the contents, then sends it to the client. I could be wrong though.
There is different between image_jpeg and file_get_contents. The first is a gd function that creates a jpeg and this take time. The second just reads data from a file.
The problem is how you output it to the browser. If you don't take appropriate measures, content is never cached, so the browser has to download it every time. Static images are always cached by the browser and after the first load, takes almost no time (just a HEAD request).
Try this code:
function CachedFileResponse($thefile,$nocache=0) {
if (!file_exists($thefile)) {
error_log('cache error: file not found: '.$thefile);
header('HTTP/1.0 404 Not Found',true,404);
} else {
$lastmodified=gmdate('D, d M Y H:i:s \G\M\T', filemtime($thefile));
$etag = '"'.md5($lastmodified.filesize($thefile).$thefile).'"';
header('ETag: '.$etag);
header('Last-Modified: '.$lastmodified);
header('Cache-Control: max-age=3600');
header('Expires: '.gmdate('D, d M Y H:i:s \G\M\T', time()+86400));
$ext=strtolower(substr($thefile,strrpos($thefile,'.')+1));
$fname=substr($thefile,strrpos($thefile,'/')+1);
if ($ext=='jpg' || $ext=='jpeg') {
header('Content-Type: image/jpeg');
} elseif ($ext=='gif') {
header('Content-Type: image/gif');
} elseif ($ext=='png') {
header('Content-Type: image/png');
} else {
header('Content-Type: application/binary');
}
header('Content-Length: ' . filesize($thefile));
header('Content-Disposition: filename="'.$fname.'"');
$ifmodifiedsince = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? stripslashes($_SERVER['HTTP_IF_MODIFIED_SINCE']) : false;
$ifnonematch = isset($_SERVER['HTTP_IF_NONE_MATCH']) ? stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) : false;
if ($nocache || (!$ifmodifiedsince && !$ifnonematch) ||
($ifnonematch && $ifnonematch != $etag) ||
($ifmodifiedsince && $ifmodifiedsince != $lastmodified)) {
error_log('cache miss: '.$thefile);
$fp = fopen($thefile, 'rb');
fpassthru($fp);
fclose($fp);
} else {
error_log('cache hit: '.$thefile);
header("HTTP/1.0 304 Not Modified",true,304);
}
}
}