Firefox & IE: Corrupted data when retrieved from cache - asp.net

I have a request to the server which looks like this:
http://localhost/Combine.aspx/flag/file1.js,file2.js,file3.js
I have also tried this:
http://localhost/Combine.aspx/flag/value/file1.js/file2.js/file3.js
It simply combines the three files which it was given: this works fine.
Upon the first request from Firefox, the page displays correctly. When the page is refreshed again, the content looks like this:
��������`I�%&/m�{J�J��t��`$�����iG#)�*��eVe]f#�흼��{���{��;�N'
In that case, no request is made to the server, the file is only retrieved from the firefox cache, as far as I can tell.
If I force-refresh the page with Control-F5, the page looks normal again.
Here is the request and response (in firebug) with Control-F5 (works):
Response
Cache-Control public
Content-Type application/javascript; charset=utf-8
Content-Encoding gzip
Expires Sun, 26 Feb 2012 02:57:26 GMT
Last-Modified Fri, 07 Jan 2011 21:08:54 GMT
Etag CLYvZwbFmainWEMi8h-6x-zNEIQ1
Vary Accept-Encoding
Server Microsoft-IIS/7.5
Set-Cookie auth=longstring; path=/
X-AspNet-Version 2.0.50727
X-Powered-By ASP.NET
Date Thu, 03 Mar 2011 02:57:26 GMT
Content-Length 918
Request
Host localhost
User-Agent Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.14) Gecko/20110218 Firefox/3.6.14
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/;q=0.8
Accept-Language en-us,en;q=0.5
Accept-Encoding gzip,deflate
Accept-Charset ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive 115
Connection keep-alive
Cookie auth=longstring
Pragma no-cache
Cache-Control no-cache
Here is the same with just F5 (doesn't work):
Response:
Cache-Control public
Content-Type application/javascript; charset=utf-8
Content-Encoding gzip
Expires Sun, 26 Feb 2012 02:57:26 GMT
Last-Modified Fri, 07 Jan 2011 21:08:54 GMT
Etag CLYvZwbFmainWEMi8h-6x-zNEIQ1
Vary Accept-Encoding
Server Microsoft-IIS/7.5
X-AspNet-Version 2.0.50727
X-Powered-By ASP.NET
Date Thu, 03 Mar 2011 03:01:31 GMT
Content-Length 1533
Request:
Host localhost
User-Agent Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.14) Gecko/20110218 Firefox/3.6.14
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/;q=0.8
Accept-Language en-us,en;q=0.5
Accept-Encoding gzip,deflate
Accept-Charset ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive 115
Connection keep-alive
Cookie auth=longstring
The only thing that I can tell is different is the Content-Length (which is likely causing the corruption), but since it never hits the server, I have no control over it.
What could be causing this?
Edit:
This happens on IE8 as well, but instead of viewing a corrupt file, it downloads the corrupt file. No request is ever made to the server (set a breakpoint in visual studio).
As for chrome, when viewing the url directly, a request to the server is made every time, and it works every time. I believe, though, that if it were included in a tag, it would behave similar to Firefox.
Oh, and also:
If I turn off the Expires header (which is one of the flags in the URL), everything works fine.
Edit 2:
I was able to work around this by not sending both an Expires and ETag header, only one or the other. I have no clue why an ETag header would cause such corruption, though.

It is because of your IIS configuration. Adjust IIS as ASP 4.0 Classic, not Default Application Pool

Related

Browser Cache Issue

I have a Symfony2 app using assetic. Everything is fine except that in localhost my assetic assets does not get cached by browser.
Any idea why the following assets does not get served cached with response 304 and in milliseconds but instead with 200 response and takes about 15 seconds....
Response Headers
Accept-Ranges bytes
Cache-Control max-age=604800
Connection Keep-Alive
Content-Encoding gzip
Content-Type application/javascript
Date Fri, 20 Mar 2015 13:26:55 GMT
Etag "159d57-511b83723ef71-gzip"
Expires Fri, 27 Mar 2015 13:26:55 GMT
Keep-Alive timeout=5, max=100
Last-Modified Fri, 20 Mar 2015 13:23:00 GMT
Server Apache/2.4.9 (Win64) PHP/5.5.12
Transfer-Encoding chunked
Vary Accept-Encoding
Request Headers
Accept text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Encoding gzip, deflate
Accept-Language en-US,en;q=0.5
Cache-Control max-age=0
Connection keep-alive
Cookie XDEBUG_SESSION=16069
Host localhost
If-Modified-Since Fri, 20 Mar 2015 13:23:00 GMT
If-None-Match "159d57-511b83723ef71-gzip"
User-Agent Mozilla/5.0 (Windows NT 6.1; WOW64; rv:36.0) Gecko/20100101 Firefox/36.0
Even if I go directly to this file through browser and then press F5 cache is not working.... But instead in other files i get 304 instead of 200...
I am sorry for trouble, problem was the Apache deflate bug when using ETAGs. By disabling ETAGs its working fine and returns 304.

Why are browsers not caching these static files

my question seems duplicate of this
but I am having a case
when I refresh a page with F5 then images are not getting fetched from cache instead request is going to server and server responding 304 status code(not modified)
but if I type a URL in address-bar or navigate page from browser back/forward button then images are coming from cache.
but I am having one doubt here why request is made for cached images to origin server on F5 (page refresh)
Nginx configuration
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires 2d;
proxy_pass http://localhost:3001;
break;
}
Request header
===================================
GET /assets/first_banner.png HTTP/1.1
Host: localhost:3000
Connection: keep-alive
Cache-Control: no-cache
Pragma: no-cache
Accept: image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.65 Safari/537.36
Referer: http://localhost:3000/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
===================================
Response header:
===================================
HTTP/1.1 200 OK
Server: nginx/1.1.19
Date: Sun, 08 Dec 2013 20:31:06 GMT
Content-Type: image/png
Content-Length: 141498
Connection: keep-alive
Cache-Control: max-age=172800
Last-Modified: Wed, 23 Oct 2013 05:34:11 GMT
Etag: "0fc96d0218a47398d37dacca76916727"
X-Ua-Compatible: IE=Edge
X-Request-Id: 48d1ec3a24e2c0f13250ea74101f6753
X-Runtime: 0.021479
Expires: Tue, 10 Dec 2013 20:31:06 GMT
===================================
When you hit F5 you tell the browser to check the webserver if the content, cached locally or not, is still valid.
If the object is expired on the webserver then the browser fetch the asset again. If the object is still valid, the local browser-cached content is used.

LiveHttpHeaders: which cache-control info is right

Using LiveHttpHeaders for Firefox 6 I was trying to see if my css, JS files being cached using Headers Module from Apache using htaccess. But I confuse, there are 2 values from the 'Cache-Control' data:
GET /proz/css/global.css HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0
Accept: text/css,*/*;q=0.1
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Referer: http://localhost/proz/
Cookie: PHPSESSID=el34de37pe3bnp4rdtbst1kd43
If-Modified-Since: Fri, 16 Sep 2011 21:15:32 GMT
If-None-Match: "400000000b06a-2999-4ad157e5b4583"
Cache-Control: max-age=0
HTTP/1.1 304 Not Modified
Date: Sat, 17 Sep 2011 03:04:50 GMT
Server: Apache/2.2.17 (Win32) PHP/5.2.8
Connection: Keep-Alive
Keep-Alive: timeout=5, max=99
Etag: "400000000b06a-2999-4ad157e5b4583"
Cache-Control: max-age=604800, public
Vary: Accept-Encoding
Which one is the true data, the first Cache-Control data (max-age=0) or the latter one.
I also would like to know how do I make sure that my JS, CSS, HTML files being compress after I use deflate module in htaccess. And yes, both headers and deflate modules are turn on.
There are two parts in this listing:
The part before the blank line is the request, sent by your browser
The part after the blank line is the response, sent by the server
The Cache-Control: max-age=0 sent by the client (your browser) tells the server (or any proxy in the middle) to send the most fresh version of the file. The browser usually sends this when you hit the refresh button.
The Cache-Control: max-age=604800, public sent by the server tells the client (your browser or a proxy) that the file is valid for 604800 seconds and can be cached for that time. (The browser won't even attemps to ask the server if a newer version exists, unless you hit refresh, as you did in this case.)
The server replied 304 Not Modified, this means that your browser already has the most recent version and it doesn't need to download it again (it did not downloaded it again).
The Vary: Accept-Encoding header indicate that the server taken some decisions based on the client's Accent-Encoding header. This may indicate that, if the server didn't replied 304 Not Modified, it would have compressed the file.
To verify this last point, clear your cache, and request the file again, and look at the content of the Content-Encoding header (must be gzip or deflate if the data is compressed).

How can I stop browsers caching my web page using HTTP 1.1 headers?

Although I have set Expires to a date in the past, and Cache-Control to no-store, no-cache, I still get one of my web pages cached.
Here are the HTTP headers sent to the browser:
Date: Tue, 02 Nov 2010 09:13:23 GMT
Server: Apache/2.2.15 (el)
X-Powered-By: PHP/5.2.13
Set-Cookie: PHPSESSID=2luvb7b316lfc8ht570s1l1v84; path=/
Set-Cookie: Newsletter_Counter=17; expires=Wed, 02-Nov-2011 09:13:23 GMT; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 20
Connection: close
Content-Type: text/html; charset=UTF-8
Same behavior for FF 3.6, Safari and IE 8.
How do I get browsers to stop caching the page?
Browsers decide caching themselves. You can use a random GET parameter to force browsers not to cache, e.g.
http://www.foo.com/yourfile.zip?id=1234
The following headers have always worked well for me (for HTTP/1.1). You should not need Pragma: no-cache.
Cache-Control: no-cache
Expires: <some date in the past>
Vary: *
Try changing your Vary value to the asterisk from my example.
Per http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.44:
"A Vary field value of "*" implies that a cache cannot determine from the request headers of a subsequent request whether this response is the appropriate representation."
Using Cache-Control: no-store should forbid any storage:
no-store
[…] If sent in a response, a cache MUST NOT store any part of either this response or the request that elicited it. This directive applies to both non- shared and shared caches. […]
You certainly seem to be doing the right things (but like a lot of people seem to assume that sending a 'Pragma: no-cache' response header has some effect on browser side caching - it should not).
What do you mean its getting cached? It will not (usually) be fetched again from the server if the user clicks on the 'back button' and was retrieved using a GET operation.

HTTP Expires header not respected by browser?

I have a situation where my (embedded) web server is sending Expires header, but the browser does not seem to respect the header setting, i.e., if I refresh the page, the browser requests the resources that are supposed to be cached. Following are the headers that are getting exchanged:
https://192.168.1.180/scgi-bin/ajax/ajax.cgi
GET /scgi-bin/ajax/ajax.cgi HTTP/1.1
Host: 192.168.1.180
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.11) Gecko/2009060215 Firefox/3.0.11 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Cache-Control: max-age=0
HTTP/1.x 200 OK
Date: Wed, 24 Jun 2009 20:26:47 GMT
Server: Embedded HTTP Server.
Connection: close
Content-Type: text/html
----------------------------------------------------------
https://192.168.1.180/scgi-bin/ajax/static.cgi?fn=images/logo.jpg&ts=20090624201057
GET /scgi-bin/ajax/static.cgi?fn=images/logo.jpg&ts=20090624201057 HTTP/1.1
Host: 192.168.1.180
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.11) Gecko/2009060215 Firefox/3.0.11 (.NET CLR 3.5.30729)
Accept: image/png,image/*;q=0.8,*/*;q=0.5
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: https://192.168.1.180/scgi-bin/ajax/ajax.cgi
Cache-Control: max-age=0
HTTP/1.x 200 OK
Date: Wed, 24 Jun 2009 20:26:47 GMT
Server: Embedded HTTP Server.
Connection: close
Expires: Wed, 1 Jun 2011 20:00:00 GMT
Content-Type: image/jpg
----------------------------------------------------------
The ajax.cgi returns an html page with a logo graphic (via the static.cgi script), which I'd like cached, but the browser is asking for the logo on every refresh.
The browser ignores the Expires header if you refresh the page. It always checks whether the cache entry is still valid by contacting the web server. Ideally, it will use the If-Modified-Since request header so that the server can return '304 Not modified' if the cache entry is still valid.
You're not setting the Last-Modified header, so the browser has to perform an unconditional GET of the content to ensure that it is up to date.
Some rules of thumb for setting Expires and Last-Modified are described in this blog post:
http://blog.httpwatch.com/2007/12/10/two-simple-rules-for-http-caching/
What are you doing in your browser? I looks like you click the reload button or even something like shift+Reload. Normally, the browser wouldn't send a Cache-Control: max-age=0 header. That means the browser has thrown away the cached image and wants to get it again.
If you just navigate to another page and then back again, the browser should respect your Expires header.
Additionally, you could add a Cache-control: public header to your response. That allows proxies and the browser explicitly to cache the image.
Any errors in your https certificate will cause the browser to not respect your headers.
Try it without https and see if it works over plain http.
See this answer https://stackoverflow.com/a/17716911
The CGI script looks like it has a timestamp parameter...this isn't changing, is it? The browser should be treating each unique URL as a different object in the cache, so if that is updating with every request, it won't match with the cached image.
Additionally, the Expires field is not exactly in RFC 1123 format, because you need two digits for the date. This may or may not be an issue, but it's something to check. The browser is including Cache-Control: max-age=0, which indicates that it believes its cache to be potentially out of date.
Once the server gets this validation request, it can return 304 (Not Modified), or 200 (OK), as it is doing currently.

Resources