Google Chrome won't cache content - http

I've been searching all over for a solution to this, but so far nothing. I am dynamically rendering an HTML page in Node.js/Express, generating an ETag by SHA256 hashing the HTML string, and sending the page through nginx. For some reason, Google Chrome won't cache the page or send an "If-None-Match" header for the previous ETag.
Here are my request and response headers:
Request:
GET / HTTP/1.1
Host: dev.logan.oikoi.co
Connection: keep-alive
Cache-Control: max-age=0
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.82 Safari/537.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: km_ai=Q%2FR9nmmebaNLthhixes8jxMubzQ%3D; km_uq=; kvcd=1346083163009; km_vs=1; km_lv=1346083163
Response:
HTTP/1.1 200 OK
Server: nginx/1.2.3
Date: Sun, 26 Aug 2012 06:20:46 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
X-Powered-By: Express
Cache-Control: public, max-age=0, must-revalidate, proxy-revalidate
Expires: Thu, 01 Jan 1970 00:00:00 GMT
ETag: "2e26404f4306e4d2a7c821f537aa3e714d655d260462f8a7fdd9f0a8ad501900"
Set-Cookie: connect.sid=rPrRyvqf3LhbilN0syPU3htr.776UPuqojSyF1YgS0AFcyac4qQtv%2FXF9TFSHQ96p6e8; path=/; expires=Sun, 26 Aug 2012 10:20:46 GMT; httpOnly; secure
Content-Encoding: gzip
Edit: I forgot to mention in my initial post, but Firefox has no problem caching the page.

Your response has these headers -
Cache-Control: public, max-age=0, must-revalidate, proxy-revalidate
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Remove these headers and you should be good.
FYI :
must-revalidate forces the browser to make a request every time the resource is request
Expires header and max-age=0 tell the browser to not cache the resource

Related

Why cookie received in "Set-Cookie" response not sent in next request (only FireFox)?

I have this issue where I am trying to login to a server(running on my local network). The login works perfectly when using Chrome/Edge but fails on FireFox.
In browser devtools/wireshark I see the server sends a cookie _oauth2_proxy_csrf when I access the login page. This cookie should be included in all future requests from my browser to server.
On chrome
Response from server
Server: nginx/1.15.7
Date: Sun, 05 Jul 2020 12:18:43 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 281
Location: http://192.168.0.101/oauth2/oauth2/auth?approval_prompt=force&client_id=oauth2-proxy&redirect_uri=http%3A%2F%2Flocalhost%2Foauth-proxy%2Fcallback&response_type=code&scope=openid+email+profile+roles&state=472474af0548b13655fd6e8515f0fc31%3A%2F
Connection: keep-alive
Cache-Control: no-cache, no-store, must-revalidate, max-age=0
Expires: Thu, 01 Jan 1970 00:00:00 UTC
Set-Cookie: _oauth2_proxy_csrf=472474af0548b13655fd6e8515f0fc31; Path=/; Expires=Sun, 12 Jul 2020 12:18:43 GMT; HttpOnly; SameSite=Lax
chrome next request
GET /oauth2/oauth2/auth?approval_prompt=force&client_id=oauth2-proxy&redirect_uri=http%3A%2F%2Flocalhost%2Foauth-proxy%2Fcallback&response_type=code&scope=openid+email+profile+roles&state=472474af0548b13655fd6e8515f0fc31%3A%2F HTTP/1.1
Host: 192.168.0.101
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: _oauth2_proxy_csrf=472474af0548b13655fd6e8515f0fc31
every thing fine, can login if I continue with this flow but
On FireFox
Response from server
HTTP/1.1 302 Found
Server: nginx/1.15.7
Date: Sun, 05 Jul 2020 12:21:33 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 281
Location: http://192.168.0.101/oauth2/oauth2/auth?approval_prompt=force&client_id=oauth2-proxy&redirect_uri=http%3A%2F%2Flocalhost%2Foauth-proxy%2Fcallback&response_type=code&scope=openid+email+profile+roles&state=4b06492a222e53045d0447826a50c47e%3A%2F
Connection: keep-alive
Cache-Control: no-cache, no-store, must-revalidate, max-age=0
Expires: Thu, 01 Jan 1970 00:00:00 UTC
Set-Cookie: _oauth2_proxy_csrf=4b06492a222e53045d0447826a50c47e; Path=/; Expires=Sun, 12 Jul 2020 12:21:33 GMT; HttpOnly; SameSite=Lax
Firefox next request (no cookie set)
GET /oauth2/oauth2/auth?approval_prompt=force&client_id=oauth2-proxy&redirect_uri=http%3A%2F%2Flocalhost%2Foauth-proxy%2Fcallback&response_type=code&scope=openid+email+profile+roles&state=4b06492a222e53045d0447826a50c47e%3A%2F HTTP/1.1
Host: 192.168.0.101
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:80.0) Gecko/20100101 Firefox/80.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-GB,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1
server fails to login (error: no named cookie found)
I have seen other cookie issues on google but I have not seen anything similar to mine.
So the problem was with server's time. It was creating cookies with expire time already in the past 12 Jul 2020 12:18:43 GMT vs browsers time of September 2020.
Apprently chrome had no issue sending back the cookie in the next request but Firefox discarded the cookie.

Content-Length gives size of entire file for first Partial Content response

I'm hosting a large (1.8GB) video file under Xampp. I've created the following HTML file:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<video controls width="800" src="test01.mp4" />
</body>
</html>
And (good news) the video is not downloaded all at once when the page loads - it is downloaded in pieces as needed to play the video.
However, I'm having trouble understanding the HTTP responses that are sent. When I initially load the page, the first two HTTP requests regarding the video are:
GET http://localhost:90/movies/test01.mp4
Host: localhost:90
User-Agent: Mozilla/5.0 (Windows NT 6.2; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0
Accept: video/webm,video/ogg,video/*;q=0.9,application/ogg;q=0.7,audio/*;q=0.6,*/*;q=0.5
Accept-Language: en-US,en;q=0.5
Referer: http://localhost:90/movies/
Range: bytes=0-
DNT: 1
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Response headers:
HTTP/1.1 206 Partial Content
Date: Mon, 09 Jul 2018 00:16:32 GMT
Server: Apache/2.4.29 (Win32) OpenSSL/1.1.0g PHP/7.2.3
Last-Modified: Fri, 29 Jun 2018 09:00:33 GMT
ETag: "77ab7f58-56fc414a18560"
Accept-Ranges: bytes
Content-Length: 2007727960
Cache-Control: no-cache, must-revalidate
Content-Range: bytes 0-2007727959/2007727960
Keep-Alive: timeout=5, max=99
Connection: Keep-Alive
Content-Type: video/mp4
Second request headers:
Host: localhost:90
User-Agent: Mozilla/5.0 (Windows NT 6.2; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0
Accept: video/webm,video/ogg,video/*;q=0.9,application/ogg;q=0.7,audio/*;q=0.6,*/*;q=0.5
Accept-Language: en-US,en;q=0.5
Referer: http://localhost:90/movies/
Range: bytes=1992327168-
DNT: 1
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Second response headers:
HTTP/1.1 206 Partial Content
Date: Mon, 09 Jul 2018 00:16:35 GMT
Server: Apache/2.4.29 (Win32) OpenSSL/1.1.0g PHP/7.2.3
Last-Modified: Fri, 29 Jun 2018 09:00:33 GMT
ETag: "77ab7f58-56fc414a18560"
Accept-Ranges: bytes
Content-Length: 15400792
Cache-Control: no-cache, must-revalidate
Content-Range: bytes 1992327168-2007727959/2007727960
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: video/mp4
The first response has Content-Length: 2007727960 which is 1.8 GB. However, the full video is not transferred - Firefox's network tab reports that the transferred data is only 54.75 MB.
The second request then asks for Range: bytes=1992327168- so somehow the browser could tell the response body length of the first response even with an incorrect Content-Length header. Unlike the first response, the second response has Content-Length set correctly.
In the first request, why is Content-Length not set to the length of the response body as it should be? How then does the client know how long the response body is?
The easiest explanation is that the Content-Length is indeed correct, but Firefox aborts the read operation after ~54MB.

What is the name for the top part of an HTTP message?

I've been trying to think of the proper name for the top part of an HTTP message, which includes the request line and the headers. "Headers" doesn't quite cut it because of the request line and "request" doesn't work because that would include the body as well.
Can somebody please enlighten me? :(
Can be HTTP request headers in the following format:
GET /tutorials/other/top-20-mysql-best-practices/ HTTP/1.1
Host: net.tutsplus.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.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
Cookie: PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120
Pragma: no-cache
Cache-Control: no-cache
Could also be HTTP response header in the following format:
HTTP/1.x 200 OK
Transfer-Encoding: chunked
Date: Sat, 28 Nov 2009 04:36:25 GMT
Server: LiteSpeed
Connection: close
X-Powered-By: W3 Total Cache/0.8
Pragma: public
Expires: Sat, 28 Nov 2009 05:36:25 GMT
Etag: "pub1259380237;gz"
Cache-Control: max-age=3600, public
Content-Type: text/html; charset=UTF-8
Last-Modified: Sat, 28 Nov 2009 03:50:37 GMT
X-Pingback: http://net.tutsplus.com/xmlrpc.php
Content-Encoding: gzip
Vary: Accept-Encoding, Cookie, User-Agent
Here Mate, take a look. I thing that there no other valid answers. TonyGW is correct.
Is an screenshot from "Head First Servlets and JSP 2nd Edition"

Servlet response ETag Cache

I want to use ETag to cache the version of a request and return 304 not modifed response to the client so the client can use last cached page.
So my url is like this which returns a json response
"http://server/WEB_GWT/prmCall?prmName=PRM_SIS_PROG_REG_STATUS"
In my servlet handling this request, I am always putting ETag information to store its value to be the version of url param PRM_SIS_PROG_REG_STATUS.
So response header returning to client is
HTTP/1.1 200 OK
Date: Sat, 07 Dec 2013 16:07:49 GMT
Server: IBM_HTTP_Server
ETag: "5"
Last-Modified: Sat, 07 Dec 2013 16:07:49 GMT
Content-Length: 356
Keep-Alive: timeout=10, max=99
Connection: Keep-Alive
Content-Type: application/json
Content-Language: tr-TR
In my next request, I am expecting this request header to include "If-None-Match" header to return the version of the request but I cannot get this header param. Any idea why I cannot get my ETag back.
My next request header is
GET /OZU_GWT/prmCall?prmName=PRM_SIS_PROG_REG_STATUS HTTP/1.1
Host: 10.100.199.103
Connection: keep-alive
Cache-Control: max-age=0
If-Modified-Since: Thu, 01 Jan 1970 00:00:00 GMT
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36
Accept: */*
Referer: http://10.100.199.103/OZU_GWT/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: tr-TR,tr;q=0.8,en-US;q=0.6,en;q=0.4
Cookie: JSESSIONID=0000kvocMBmjoWPbpKt_VAsDUMv:-1
Inoder to cache your request you need to include "Cache-Control" directive and specify the way in which the response should be cached and for what period.
HTTP/1.1 200 OK
Date: Sat, 07 Dec 2013 16:07:49 GMT
Server: IBM_HTTP_Server
ETag: "5"
Cache-Control : public, max-age=86400
Content-Length: 356
Keep-Alive: timeout=10, max=99
Connection: Keep-Alive
Content-Type: application/json
Content-Language: tr-TR
Here the Cache-Control header says that the content can be stored by "public" caching servers and the duration after which it needs to revalidate the content is 86400 seconds. And so when you refresh the page again "If-None-Match" and "If-Modified-Since" conditional headers will kick in and use the cached data.
After some investigation,I found out SmartGWT framework requests are sent to server with bypassCache:true flag which was sending my xhr request without any cache header. I managed to fixed it by overriding following method in DataSource class.
#Override
protected Object transformRequest(DSRequest dsRequest) {
dsRequest.setBypassCache(false);

Set-cookie is intermittently not being obeyed

I have an asp.net mvc application which is authenticating a username/password and if correct setting a cookie in the browser and doing a 302 to another page.
For some reason though the browser will ignore the set-cookie and thus never stores the cookie. The weird thing is:
The exact same code on my local environment works perfectly even though the same code run in my test environment in a different tab fails
It works perfectly in some browsers but not others
It will sometimes work in a browser that previously failed to work
I have opened up fiddler and have been comparing the requests/responses and everything looks identical. Can anyone give any suggestions of whats going on?
Not working
Login response:
HTTP/1.1 302 Found
Cache-Control: private
Content-Type: text/html; charset=utf-8
Location: https://foo.test/bar
Server: Microsoft-IIS/7.0
X-AspNetMvc-Version: 2.0
X-AspNet-Version: 2.0.50727
Set-Cookie: .ASPXAUTH=7C02633DAD998CB9CD25CC413FF34506DBF9095B78FC69FD03F83C4F7A091BF45469D389510F5ADD286AB6131EEC14609199C9CAD6B82E2BAFB61DE382BC34A65B72FEE5A9DD53820250E339FB6B863974C91F25CD2BE53646296C6E72F6C18F53C4BE7F9977CE9DB58647D9190093A167DCCBC698D5D4803739D0ECDA4621E744FF886EF7E0E1D3B0ED4A12FB08E34D521F20AA5C9549C66BD3171C68313E70E0ACCB851FA7A7D1509EF30345998A80DF0577F38A8C85E141C4F17803205CDDE05DD2C9; expires=Wed, 22-Dec-2010 16:45:06 GMT; path=/
X-Powered-By: ASP.NET
Date: Sun, 01 Jan 2012 15:36:01 GMT
Content-Length: 220
<html><head><title>Object moved</title></head><body>
<h2>Object moved to here.</h2>
</body></html>
Next request (note no new cookie):
GET https://foo.test/bar HTTP/1.1
Host: foo.test
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.2.4) Gecko/20100611 Firefox/3.6.4
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-gb,fr;q=0.7,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Referer: https://foo.test/login
Cookie: ASP.NET_SessionId=oskgcf45t5oqvo453kmftw45;
Working
Login response:
HTTP/1.1 302 Found
Cache-Control: private
Content-Type: text/html; charset=utf-8
Location: https://foo.local/bar
Server: Microsoft-IIS/7.5
X-AspNetMvc-Version: 2.0
X-AspNet-Version: 2.0.50727
Set-Cookie: .ASPXAUTH=CE23F217A77AC4D7DE76D16EDC27B21257973DECEF8F85D2FD3E345D051C81BE42F35978884BF7E508BF298824BADE1461C56966F5C6A2BF96F2E99F038068CBC068755494A3CD36BB2283040378982B7F96C76E1E2DCF1F6F481AB9C1399D7CFADF30B3049BDE7E94215DF58D091364974C69399AF92B0E03A10C3BF25907DC187060E681D4867E24DBB39F2D26659FDCDCD661DF8DFD88ABD7E4D931207614611013CA68065F7805D055E1FFF72B91C07C5576D4581FB9E4A04029E51E0A78ADD6B894; expires=Wed, 22-Dec-2010 16:49:34 GMT; path=/
X-Powered-By: ASP.NET
Date: Wed, 22 Dec 2010 16:19:34 GMT
Content-Length: 221
<html><head><title>Object moved</title></head><body>
<h2>Object moved to here.</h2>
</body></html>
Next request (note the new cookie):
GET https://local.toptable.com/ism/confirm?c=2&o=True&v=1313&t=12-00&d=21-12-2010&l=True HTTP/1.1
Host: foo.local
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.2.4) Gecko/20100611 Firefox/3.6.4
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-gb,fr;q=0.7,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Referer: https://foo.local/login
Cookie: ASP.NET_SessionId=5aefag4544y4pvqht1k3k455; .ASPXAUTH=CE23F217A77AC4D7DE76D16EDC27B21257973DECEF8F85D2FD3E345D051C81BE42F35978884BF7E508BF298824BADE1461C56966F5C6A2BF96F2E99F038068CBC068755494A3CD36BB2283040378982B7F96C76E1E2DCF1F6F481AB9C1399D7CFADF30B3049BDE7E94215DF58D091364974C69399AF92B0E03A10C3BF25907DC187060E681D4867E24DBB39F2D26659FDCDCD661DF8DFD88ABD7E4D931207614611013CA68065F7805D055E1FFF72B91C07C5576D4581FB9E4A04029E51E0A78ADD6B894
In the "Not Working" login response, the server's Date: header has the value Sun, 01 Jan 2012 15:36:01 GMT (the future!), and your cookie expiration is set for Wed, 22-Dec-2010 16:45:06 GMT which will cause the browser to immediately expire the cookie, thus not storing it.

Resources