Set-Cookie cached , even with F5 ? (unless I press CTRL+F5) - php

I obviously see, that in specific cases, after SetCookie() function, when I reload the page (or re-enter that page), I don't see the cookies set, unless i press CTRL+F5 (which is cache-cleared request).
have you ever met such occasion (this happens only on http version of the file, not on https).
this didn't help:
header('Expires: Sun, 01 Jan 2014 00:00:00 GMT');
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
What I should do in order to get cookies read on next page-enter?

Cookies generally are hard to debug when they go wrong. What you are describing does seem to be related to caching but it sounds very odd.
Here's what you can try doing to see what's wrong.
Make sure you are setting the cookie in the correct domain and path . If your page is e.g. at www.example.com the domain should either be .example.com or www.example.com. The idea is same for the path (if you access www.exampl.com/path then the path needs to either be / or /path
If you need the cookie to be available on http then you should not set the secure attribute on it.
Make sure the cookie is not already expired when set, browsers will probably ignore it if it is.
A few basic things to check.
Assume that you have cookie line:
setcookie('name', 'value', time()+10000,'/test','.example.com');
Open the Chrome (or your favourite browser's) developer console and when you make the request check the cookies being set. There should be something along the lines of:
The duration must not be 0 and the rest should be correct.
When you make the next request the cookie should be sent as well.
This should be an entry in the "Request cookies".
If the cookie is received, but then not sent to the server it might be worth opening the browser settings and finding the stored cookies manually for any hints as to why this is happening. In chrome this would be in chrome://settings/siteData
If you still don't find anything wrong with any of these then check if there's any intermediate caching layer running, that would override the No-Cache header you are setting.

I've found that there was some kind on Nginx caching enabled, causing the browser not to recall the execution from server.
I've fixed that by including the random() string in the url, voiding the cache for that page-call.

Related

Apache file caching after editing by ftp

I am experiencing this strange behaviour, on a shared hosting I am connected by FTP and when I am editing some file(and saving it), it takes at least a few minutes for that change to take effect. For example I put in my index.php file the line echo "test";die;and save it: the program (I am using file zilla) shows that the file is uploaded into server. just in case to be sure, am doing cat index.php (im connected by putty) and I can see that the change in fact is done. But, guess what, when I open in the browser it just works as before (without showing my "test"). But I just wait a few minutes and refresh the page it shows me that "test". Browser cache I deleted(though do not think it matters this case, also trying to refresh the page by CTRL+F5) but after all only after a few minutes changes take into effect. The same thing when I delete that line and double check that it is saved, again during a few minute still I see that echo, when when is nothing in the file already.
So, is there such a thing, that apache has some kind of cache, so even if I change the files in a physical drive after all it uses the file from there and only after a few minutes updates the cache ?
Thanks
I believe that if Varnish is set up correctly you can turn it off via PHP like so.
header('Pragma: no-cache');
header('Cache-Control: private, no-cache, no-store, max-age=0, must-revalidate, proxy-revalidate');
header('Expires: Tue, 04 Sep 2012 05:32:29 GMT');
Files being saved but php script did not change?
Try this in .htaccess - maybe because of new php-versions the apc cache is turned on by default:
php_flag opcache.enable Off

Forcing Codeigniter to work with varnish

I have a codeiginter application that already use codeiginter build-in caching, I applied Varnish as a new caching layer. But as i can see from varnishstat it's not making that difference.
Hitrate ratio: 1 1 1
Hitrate avg: 0.0480 0.0480 0.0480
I think thats because of Codeiginter cookies and HTTP Headers that are being sent back.
This is the http request coming from varnish.
Accept-Ranges:bytes
Age:0
Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection:keep-alive
Content-Encoding:gzip
Content-Length:1755
Content-Type:text/html
Date:Mon, 29 Jul 2013 07:25:59 GMT
Expires:Thu, 19 Nov 1981 08:52:00 GMT
Pragma:no-cache
Server:Apache/2.2.22 (Ubuntu)
Set-Cookie:ci=%2BEZFRauewyNnl3CXHE0cmz6F3G3moadilt5vXu5gghKXkWm4gg0JObnF2Etq6J5rl3XVigbF0je3funibpvEi4X%2BT3rS2VmazGG3T4Vm1%2B8YcbqRgL4xuMcxybndqJy%2BU9mNmsJjOgmYEZ8oPG8BKOtMaxNiMHmgmbBydxt3SzKfFfFUOydFx%2BeeJ7P1WE7V10m6GyfnFO5DrFYNsE%2F37WNAI%2Bpux%2Fwwch5B4DH1%2F6wssPm%2BNwsLQ1%2FBd44hgUXe3mMzzcqvxNjKqs0gjuwzwPT4nibEHirfaJ7TMVGObMjdrbREnoYS2gwoN15cCeKgXmTJQI2vvTuPcdtZVCjcAX6OvTy491HdIvQIdKRhX2BNi8d7ygo%2F7n5T6%2FN%2B0IohNN9iZ%2Fh959W%2Fz4azEJPfTrluucf6cLnlp2T2zb%2Fb3XroWuPqguk4wMpsAstfLsSfA%2F6yEi4Hph%2BPFxX%2BhyBazs11LJ38FA0flWtYY%2Bk%2B6yoF13sTaENN2pWj0bKDTtres9E4y3xMPr%2FZaO78WRA9CccDzcQfbZ3bZUqoXg4HmX%2BHDHiYPLD6uFpnC28LuDrCSbgXFIlhDrC8j65sxNSKhnzlUP7Konr%2FKRfKNzrgtWHBEzuXArW%2BlgIg1MzaW3GIkRy1gr16ZUjIiv7CCx7Y2twAfKOm4t00MvrTcFoxBPN1lzoasNyRLMIvshU8heWZHy17OPEapuO6N%2BuMl9L8LqU0%2FF%2BUeUDyFVwLG39LGkIVuF93VsIYEp6w2UwtccX4OO4P2uwJEoAJMMqUE%2FztELpCv%2BkfRAiub48n%2BRxK%2FhgUHw1LWsWIPv3xngq3MI8ypWCqkWLjPuu5dc%2FdOd3BSW2MYcBwacoB5CEOPBHGq3hw1QSZfY330hkLuyQPHxkh%2FDTija%2FN2Rz6z47JorsCqHGDBK6%2BPswBWvYZeMd0VMD%2F95j%2BFibi6rBqL3hoE%2BDgcfCdly%2FYH9py%2Fe%2Fa0AUiIINTK8EPtpuKdC8dLhKo2jI5J4e1ifZuWjVd3VnL2CvX; path=/
Vary:Accept-Encoding
Via:1.1 varnish
X-Powered-By:PHP/5.3.10-1ubuntu3.5
X-Varnish:1353481467
I noticed difference things:
No matter how hard i try codeiginter won't change the
Cache-Control, Age, Expires until i set them manually
Codeiginiter Sent an old date 1981 I doubled checked the date on my
server it's correct
Codeiginiter keep changing the cookies almost each request.
In my app i have several pages that require username/password but i'm trying to focus first on getting the public pages to be cached. after that I will check the account related pages.
I'm testing on this code:
//$this->output->set_header("Cache-Control:public, max-age=9000");
//$this->output->set_header("Vary: Accept-Encoding,Cookie,User-Agent");
$this->output->cache(2400);
$this->load->view("test");
If your backend is sending Cache-control: max-age=XXX you can forget about Expires header, as it will be ignored in HTTP 1.1 compliant clients & proxys [1] (In fact, it's usual to set it on the past in order to avoid old HTTP 1.0 clients caching items).
Be very careful when setting Vary: User-Agent header, as it can harm your caching chances [2]
And finally, Varnish won't cache a request such as that because of the Set-Cookie header. Varnish needs lazy session initializing (see [3]) to cache thing (or a quite complicated VCL)
If you fix the cookie thing and still have problems the VCL file and varnish version will be really apreciated.
[1] http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
[2] https://www.varnish-cache.org/docs/3.0/tutorial/vary.html
[3] How should I implement lazy session creation in PHP?
Your cookie problem is one I'm currently wrestling with. I'm guessing from your sample that you have changed the cookie_name variable to be ci rather than ci_session.
The simplest thing for you - for certain values of simple - may be to jettison CI's session handling for an alternative or switch to db-based cookies rather than cookie-based. If there's a set-cookie - and there always is when you have sessions initialized/auto-loaded - it won't get cached. If the data is all stored server-side instead you won't have this issue.
Personally I'm not gung-ho to introduce databases for our use of sessions so I'm going to experiment with setting the cache-control header to ignore cookies and using header_remove() at the top of views I know will never be user-specific (like our RSS feed).

Browser does not listen to headers sent by PHP for cache, what can be changed?

I have a systen in place where I have two-layered cache on the website. Every request checks for cache on the web server and if it finds the generated page that has been cached, it returns the cache instead of generating it again.
For example:
User A visits website URL http://www.example.com/home/
Server does not find cache
Server generates the page
Server writes the page to cache
Server returns the generated page to User A
User A is happy
and
User B visits website URL http://www.example.com/home/
Server finds cache
Server returns the cache instead of generating the page again
User B is happy
All that works without problems. But I also want to add an option that browser would not ping the server again (saving servers time of checking if cache exists or not) and use its own cache instead.
User A visits URL http://www.example.com/home/ again
Browser has that page in cache
Browser loads the page for the user from cache
I cannot get the latter working. During original page generation, I am sending to the user with the page the following headers:
header('Cache-Control: public, max-age=10000, must-revalidate');
header('Expires: Fri, 03 Feb 2012 01:59:45 GMT');
But when I check for it with Firebug or Chrome Developer Tools it does not say it is using a cache, instead asking for the data from the server again. I know I must be doing something wrong, since I have the same thing set up for static files like Javascript, and that works.
To test this I didn't just try reloading the page, I created links on the website and moving between those links it asked for the pages from server each time.
Am I missing something?
EDIT:
Alright, apparently what happened was that server sent "Pragma: no-cache" automatically every time. Does anyone know why server would do that? This kept the browser from using cache.
If session is enabled for that page/url, the Pragma: no-cache-header will be added to the http header which prevents the browser from using the cache.
if you use session_start
PHP will add
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Pragma: no-cache
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
the whole point of PHP is to provide dynamic pages after all.
to stop this ...
session_cache_limiter('');
session_start();
and you can then write your own headers based on the content you provide

Caching a GET request for audio with PHP

I have a PHP script that responds to a GET request for audio resources. An HTML5 Audio tag requests an audio file such as:
<audio src="get_audio.php?f=fun" preload></audio>
There is no need for the user to download that same audio file every time so I would like to cache it. In my PHP file I have:
header("Cache-Control: max-age=2419200");
header("Content-Type: audio/mpeg");
...
echo file_get_contents($path);
but when I view the Network tab of Chrome developer tools I see that it re-downloads the audio clip everytime rather than saying "from cache" and if I look in the Response headers I do see the Cache-Control header that I set. Why would it ignore this? Amidoingitright?
It's been a while since I did this in PHP, but try adding:
header("Pragma: public");
above the cache-control header.
I also think you need the expires header:
header('Expires: ' . gmdate('D, d M Y H:i:s', time()+2419200) . ' GMT');
Other than that you could start using the get_headers() function in PHP to debug where it's going wrong.
Do you see a header in the second request called If-Modified-Since:?
This is what you need to catch, parse and respond to - if you don't want to send the file again, you respond with HTTP/1.1 304 Not Modified. If you are using Apache, you can check for the header in the result of apache_request_headers(). If you are not using Apache, you may find it hard to handle this - you will probably have to find a way for the web server to set the headers as environment variables, so they are available in $_ENV or $_SERVER. There is a way to do this in Apache using mod_rewrite (see latest comment on page linked above), so there is probably a way to do it in other server environments as well.
Caching in HTTP 1.1 permits (and indeed, encourages) this behaviour - it means that the cached copy will always be up-to-date.

how we can delete cache forcefully when user logs-in using javascript

Can anybody tell me how we can delete browser cache using javascript. I want this because I am giving user, file for download with url ('http://www.example.com/docs/doc1.xlsx'). and this files are accessible for that specific user only.
I am checking with htaccess redirect to other action which redirect to that specific file url if user does not have access then Access Denied page come.
But problem is when valid user download that file and logs out from application and copied above url and hit enter on browser file gets for download without accessing to server, which happens due to caching in browser.
So I want to delete cache when user logs out of system.
Alternative solutions are most welcome.
In short, you can't (or, at least, I have never seen a way of doing it).
You'll need to do it on the server side by sending the correct cache-busting headers. Something like:
Cache-Control: no-cache, must-revalidate, max-age=0
You can do this using (to steal an example from the PHP documentation):
header("Cache-Control: no-cache, must-revalidate, max-age=0");
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
This is not possible. Php only works serverside and using javascript is not working because of security issues. ActiveX is not an option eigther i guess.
What you can do is to attach a no-cache header for a page that must reload each time.
Rather than giving direct access to the file (as you mentioned "http://www.example.com/docs/doc1.xlsx"), I think you should read the the file in php and give it for download after checking for the valid user..
Example taken from php.net
<?php
// downloading a file
$filename = $_GET['path'];
/**
* YOU CAN CHECK YOUR VALIDATIONS HERE..
*
*
*
*/
// fix for IE catching or PHP bug issue
header("Pragma: public");
header("Expires: 0"); // set expiration time
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
// browser must download file from server instead of cache
// force download dialog
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
// use the Content-Disposition header to supply a recommended filename and
// force the browser to display the save dialog.
header("Content-Disposition: attachment; filename=".basename($filename).";");
/*
The Content-transfer-encoding header should be binary, since the file will be read
directly from the disk and the raw bytes passed to the downloading computer.
The Content-length header is useful to set for downloads. The browser will be able to
show a progress meter as a file downloads. The content-lenght can be determines by
filesize function returns the size of a file.
*/
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($filename));
#readfile($filename);
exit(0);
?>
Hope this helps..
Thanks...
I have resolved issue without major modifications.
Firstly I tried by setting header as you people suggested. Before redirecting for file to download I tried to set header for cache-control, but it doesn't work at all.
So I stretch my mind more and find simple solution by setting headers in .htaccess file which is located in folder where all downloadable files are located. That means cache-control header is set to download files response.
But still one thing in mind why above solutions not working.
And one more thing Pragma: "no-cache" not working for IE. that is it gives error while downloading requested file as "requested site is unavailable or cannot be found".
So I have set it to Pragma: public. But I doubt whether it is secure.

Categories