I have this code in a assets controller to get images:
function images($path,$image_name)
{
$image = "../assets/images/$path/$image_name";
if (file_exists ($image) && (is_file($image))) {
$name = $image_name;
} else {
}
$file = getimagesize($image);
$filesize = filesize($image);
$time_cache = 360000000000;
$ts = gmdate("D, d M Y H:i:s", time() + $time_cache) . " GMT";
header("Content-Type: {$file['mime']}\n");
header("Content-disposition: inline; filename=\"$name\"\n");
header("Content-Length: $filesize\n");
header("Expires: $ts");
header("Pragma: cache");
header("Cache-Control: max-age=$time_cache");
readfile ($image);
}
I have set csrf protection to true in config/config.php file and every request for an image is sent with Set-Cookie header. So the csrf-cookie can get set multiple times on some pages. Is that something to worry about, and if so, is there a way to prevent this?
I managed to do this with header_remove("set-cookie");
So the code looks like this
header("Content-Type: {$file['mime']}\n");
header("Content-disposition: inline; filename=\"$name\"\n");
header("Content-Length: $filesize\n");
header("Expires: $ts");
header("Pragma: cache");
header("Cache-Control: max-age=$time_cache");
header_remove("set-cookie");
readfile ($image);
If in only one page/image request you uses setcookie function many times, php will send many times the same cookie to browser in one response. Maybe some browsers crashes reading that.
I've had problems with ajax requests in Internet Explorer due to multiple cookie definitions, when accidentally start the session object in CakePHP into a loop. I only detected that problem sniffing the connection with wireshark.
Related
I have a website made with WordPress and Windows Plesk panel hosting. Most of these type of hosting do not support htaccess due to IIS.
I want to solve Leverage browser caching in wordpress without using htaccess file.
I have tried below non htaccess caching thing but the site is displaying blank screen.
<?php
if (isset($_GET['img'])) {$filename = $_GET['img'];}else{exit;}
$allowed = array('gif','png','jpg');
$ext = pathinfo($filename, PATHINFO_EXTENSION);
if(!in_array($ext,$allowed)) {exit;}
$stc = 31536000;
$ts = gmdate("D, d M Y H:i:s", time() + $stc) . " GMT";
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . basename($filename));
header('Content-Transfer-Encoding: binary');
header("Expires: $ts");
header("Cache-Control: max-age=$stc, public");
header("Pragma: cache");
ob_clean();
flush();
readfile($filename);
exit;
?>
Hi You can do below things to achieve A Grade in Gtmetrix by doing the below things.
some hosting provider do not like htaccess and therefore I preferred go for Hyper Cache plugins, and do all necessary configurations.
Then Add below things in header.php of your Wordpress themes.
<?php
$stc = 31536000;
$ts = gmdate("D, d M Y H:i:s", time() + $stc) . " GMT";
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . basename($filename));
header('Content-Transfer-Encoding: binary');
header("Expires: $ts");
header("Cache-Control: max-age=$stc, public");
header("Pragma: cache");
ob_clean();
flush();
exit;
?>
After check and do let me know.
Thanks!
I have a PHP file protector script:
.htaccess
RewriteEngine on
RewriteRule ^(.*).(zip|tgz)$ ../wp-file-protector.php?file=$1.$2 [QSA]
wp-file-protector.php
<?php
global $wpdb;
/** Make sure that the WordPress bootstrap has run before continuing. */
require( dirname(__FILE__) . '/wp-load.php' );
$current_user = wp_get_current_user();
if ($current_user->ID > 0){
$order = $_GET['order'];
$items = new_get_order_by_id_and_user($order, $current_user->ID);
if($items != false){
$file_enabled = true;
//Some authentication
$filepath = dirname(__FILE__).'/../downloads/'.$_GET['file'];
if($file_enabled && file_exists($filepath)){
$filename = basename($filepath);
$extension = end(explode('.', $filename));
ob_clean();
// http headers for zip downloads
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");
if($extension == 'tgz'){
header("Content-Type: application/gzip");
}else{
header("Content-type: application/octet-stream");
}
header("Content-Disposition: attachment; filename=\"".$filename."\"");
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($filepath));
ob_end_flush();
#readfile($filepath);
}
}
}
I works fine with zipped and other files. The problem appears with gzipped files. I got unexpected results (also different results for Firefox download and open action).
I think I need some good header for the gzipped files. What should I use?
Also good to know that the request is running through the Cloudflare service, so maybe I should send out some header, which tells cloudflare server to not to gzip it.
I'm stuck :(
Update #1
header("Content-type: application/x-gzip");
This also doesn't work. When I choose save in firefox, it tells when opening that corrupted. When I choose open, I got a file without extension, but it seems tar as I can go deeper into the dir.
So i am generating mp3 file and it's working fine because when i download it i can play it just fine, but now what i want to do is output that file to my browser and play it in my browser, so what i have tried is:
header("Pragma: no-cache");
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Content-Type: audio/mepeg');
header("Content-Disposition: attachment; filename=\"validate.mp3\"");
header("Content-Transfer-Encoding: binary");
header("Content-length: $size");
AND
<embed autoplay="true" height="0" width="0" src="actions/play_file" />
Well ofcourse id doesn't work, it just forces to download that file because i have used
"Content-Disposition: attachment; filename=\"validate.mp3\"")
And im so sure if im using right html tag for this?
But if i am, all i need is just right headers to make this work.
Here's a way to feed up the file:
header("Content-type: audio/mpeg");
header("Content-length: " . filesize($file));
header("Cache-Control: no-cache");
header("Content-Transfer-Encoding: binary");
readfile($file);
Or in chunks
$total = filesize($filepath);
$blocksize = (2 << 20); //2M chunks
$sent = 0;
$handle = fopen($filepath, "r");
// Push headers that tell what kind of file is coming down the pike
header('Content-type: '.$content_type);
header('Content-Disposition: attachment; filename='.$filename);
header('Content-length: '.$filesize * 1024);
// Now we need to loop through the file and echo out chunks of file data
// Dumping the whole file fails at > 30M!
while($sent < $total){
echo fread($handle, $blocksize);
$sent += $blocksize;
}
exit(0);
The important thing for you to do is specify the Content-Type header. What the browser (or other user-agent) does with it is up to them, not to you. The content type you are using now is incorrect. Use audio/mpeg.
The only way to get it to always play is to include a player on a web page. For that, you can use HTML5 audio tags, Flash, embed, etc.
... and yet... Another more simpler approach ... I have tested this approach since the moment a Polish company by the name of Ivona, was purchased by Amazon on Jan. 24, 2013, so it is proven to work out of the box, after setting your AWS Polly credentials.
header('Accept-Ranges: none');
header('Content-Type: audio/mpeg');
echo $audio;
I am having trouble getting my image script to cache the image in the browser (firefox).
Here is the code :
$type = 'image/jpeg';
$image = '../../files/image.jpeg';
header("Content-type: $type");
header("Cache-Control: private, max-age=10800, pre-check=10800");
header("Pragma: private");
header("Expires: " . date(DATE_RFC822,strtotime("1 week")));
if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])){
header('Last-Modified: '.$_SERVER['HTTP_IF_MODIFIED_SINCE'],true,304);
exit;
} else {
header('Last-Modified: '.gmdate('D, d M Y H:i:s', filemtime($image)).' GMT', true, 200);
echo #readfile($image);
exit;
}
The image gets outputted, however after that it always goes to the else statement with the 200 response code instead of the 304. I tried to force the 304, but it looks like the image is never cached by the browser.
Try to call it as jpg (add this in htaccess:
RewriteEngine on
RewriteRule image.jpg your_script.php [L]
)
don't forgot to change your_script.php and image.jpg
Not sure if the title makes sense sorry... basically I'm generating Word documents that I wanted to open automatically on the client's machine, but it seems this isn't possible, so instead of just presenting a list and having them manually click on each one, I was wondering if at the very least it could bring up the 'Would you like to save or open this file' dialogue :(
Long shot, but I know a lot of sites will do this when you download stuff... re-directing to download server etc
Thanks
The best you can do is provide a "hint" with the Content-disposition header.
http://php.net/manual/en/function.header.php
Specifying something like
<?php
header('Content-type: application/msword');
header('Content-Disposition: attachment; filename="downloaded.pdf"');
// output content of document
?>
should cause most browsers to prompt the user to download the document, while this:
header('Content-Dispotion: inline')
should usually cause the browser to show the file in the existing window.
You can set the contenttype and content-disposition header to open the open/save dialog box in browser.
See
Header Field Definition
for details.
You need to send the correct header and so on.
I found this that seems good:
<?php
function send_file($name) {
ob_end_clean();
$path = "protected/".$name;
if (!is_file($path) or connection_status()!=0) return(FALSE);
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Expires: ".gmdate("D, d M Y H:i:s", mktime(date("H")+2, date("i"), date("s"), date("m"), date("d"), date("Y")))." GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Content-Type: application/octet-stream");
header("Content-Length: ".(string)(filesize($path)));
header("Content-Disposition: inline; filename=$name");
header("Content-Transfer-Encoding: binary\n");
if ($file = fopen($path, 'rb')) {
while(!feof($file) and (connection_status()==0)) {
print(fread($file, 1024*8));
flush();
}
fclose($file);
}
return((connection_status()==0) and !connection_aborted());
}
?>
And here's an example of using the function:
<?php
if (!send_file("platinumdemo.zip")) {
die ("file transfer failed");
// either the file transfer was incomplete
// or the file was not found
} else {
// the download was a success
// log, or do whatever else
}
?>