Caching static files in browser - python

I am trying to enable caching for static files such as .css and .js.
I am running a WSGI server with Python.
I have tried setting the following headers for caching purposes:
headers.add_header('Cache-control', f'public, max-age={expires.strftime(RFC_1123_DATE)}')
headers.add_header('Expires', expires.strftime(RFC_1123_DATE))
headers.add_header('Last-Modified', generate_last_modified())
Headers recieved in the browser:
HTTP/1.0 200 OK
Date: Tue, 21 Apr 2020 08:06:17 GMT
Server: WSGIServer/0.2 CPython/3.6.9
Content-Encodings:
Content-Type: text/css; charset=UTF-8
Cache-control: public, max-age=Tue, 28 Apr 2020 08:06:17 GMT
Expires: Tue, 28 Apr 2020 08:06:17 GMT
Content-Length: 23399
Last-Modified: Tue, 21 Apr 2020 08:06:1587452777S GMT
Accept-Ranges: bytes
When using Chrome this code works and the files are stored and retrieved from the cache as you would expect. Chrome is using the Expires header and is ignoring the Cache-Control header.
I checked my developer tools and Disable Cache is not enabled. I checked my settings in Firefox in about:config, caching seems to be enabled.
So what am I missing here? Am I missing a header, is an ETAG required, why is Expires working in Chrome but not in Firefox?

I found the solution.
Firefox cache was full, so after emptying the cache it started sending the if-modified-since header again.
Also my server was returning the current time as the last-modified time instead of the actual last modified time.
To fix the issue all I had to do was compare the if-modified-since time from the browser with the last modified time from the file and send a 304 status if nothing changed.

Related

Partial Content Get Request

I'm trying to get partial content from the website http://dijkstra.cs.bilkent.edu.tr/~cs421/partialt11.txt
Below is my get request:
cmd2 = "GET /{} HTTP/1.0\r\nHost: {}\r\nAuthorization: Basic {}\r\nAccept-Ranges: bytes=1-1800\r\n\r\n".format(path2, host2, token2)
where host2, path2, token2 are defined 100% correctly. matchlist[][] gives the range of bytes I want to recover.
However, no matter what I write into Accept-Ranges: bytes=...-..., I get the same "amount" of the file. It is not the whole file. Plus I get the 200 OK message instead of Partial Content as the status code. Even accept-ranges header is not filled in the response. Why is that? Thanks in advance. Below is the response:
'HTTP/1.1 200 OK\r\n
Date: Sun, 20 Mar 2022 08:29:23 GMT\r\n
Server: Apache/2.4.6 () OpenSSL/1.0.2k-fips PHP/5.6.40 mod_perl/2.0.11 Perl/v5.16.3\r\n
Last-Modified: Mon, 07 Mar 2022 10:38:52 GMT\r\n
ETag: "73a-5d99e786e8eae"\r\n
Accept-Ranges: bytes\r\n
Content-Length: 1850\r\n
Connection: close\r\n
Content-Type: text/plain\r\n\r\n
Modem Noise Killer (alpha version)\n\nWith this circuit diagram, some basic tools including a soldering iron, and\nfour or five components from Radio Shack, you should be able to cut the\nnoise/garbage that appear'
Accept-Ranges is a server response indicating that it will accept partial requests. Client should send Range - i.e., in your case:
Range: bytes=1-1800
However, it's worth noting that the server MAY ignore Range

can't get facebook profile pic from flask-OAuth package

I am using this code for logging in to my app. It works fine, but when I try to get the url for profile pic
pic = facebook.get("/me/picture?fields=url")
I get None in response.
TypeError: must be string or buffer, not None
If I try sending this GET request from facebook Graph API, with same access-token, I get the profile link.
I checked out the version message by printing out get("/me") request, I get
connection: keep-alive
etag: "2c59a2baef08156f18055c64eaa9d9822e35e8f1"
pragma: no-cache
cache-control: private, no-cache, no-store, must-revalidate
date: Fri, 23 Jun 2017 14:20:04 GMT
**facebook-api-version: v2.9**
access-control-allow-origin: *
content-type: text/javascript; charset=UTF-8
Which shows that version is automatically converting when i send request from flask-OAuth as well. Then what is it that I am missing ?
As documented in the Graph API, "me/picture?" will return a 302 redirect to the picture image. To get access to the data about the picture, we need to include redirect=false in the end of query. So I get the url by;
pic = facebook.get('/me/picture?redirect=false').data
print 'picture:', pic['data']["url"]

Testing web-tornado using Firefox's HttpRequest addon

I am testing my web-tornado application using Firefox's HttpRequest add-on but after I log in and receive my secure cookie data, I am not able to re-use it to consume protected methods.
This is my response data:
POST http://mylocalurl:8888/user/login
Content-Type: application/x-www-form-urlencoded
Login=mylogin;Pass=123
-- response -- 200 OK Content-Length: 33
Content-Type: text/html; charset=UTF-8
Server: TornadoServer/2.2.1
Set-Cookie:
IdUser="Mjk=|1395170421|ffaf0d6fecf2f91c0dccca7cab03d799ef6637a0";
expires=Thu, 17 Apr 2014 19:20:21 GMT; Path=/
{
"Success": true }
-- end response --
Now why I am trying to do is to configure HttpRequester to use this cookie for my new requests. I tried to add it using the "Headers" tab but my server keeps sending me a 403, Forbidden.
Can anyone help me on this ? It could be with another tool (for linux) too.
I really like fiddler2 for these kind of things and there's an alpha build for mono that you may wish to try out: http://www.telerik.com/download/fiddler
If you don't mind paid software you can use Charles, for which there is a free trial.
And if you are testing and already using python, why not use a simple python script with requests and its Session object with cookie-persistence..

Google App Engine adding cache-control and other headers

I have a Flask application on Google App Engine and I want to tell browsers to cache a response that uses the Cache-Control header. It works as expected on dev_appserver.py but when deployed to App Engine the headers are modified and break the cache header.
Here is the Flask view in particular:
#app.route("/resource")
def resource():
response = make_response(render_template("resource.html"))
response.headers['Cache-Control'] = "max-age=31536000"
logging.error("HEADERS: {}".format(response.headers))
return response
The logs for both development server and App Engine show:
Content-Type: text/html; charset=utf-8
Content-Length: 112628
Cache-Control: max-age=31536000
When I run it with the development app server it works as expected, as you can see from the headers below.
When I open Chrome's development tools the headers for App Engine are:
alternate-protocol:443:quic
cache-control:no-cache, must-revalidate
content-encoding:gzip
content-length:19520
content-type:text/html; charset=utf-8
date:Wed, 22 Jan 2014 19:53:47 GMT
expires:Fri, 01 Jan 1990 00:00:00 GMT
pragma:no-cache
server:Google Frontend
set-cookie:session=; expires=Thu, 01-Jan-1970 00:00:00 GMT; Max-Age=0; Path=/
status:200 OK
strict-transport-security:max-age=31536000
vary:Accept-Encoding
version:HTTP/1.1
x-appengine-estimated-cpm-us-dollars:$0.002267
x-appengine-resource-usage:ms=7388 cpu_ms=5069
x-frame-options:DENY
x-ua-compatible:chrome=1
In contrast the development app server headers are as expected:
Cache-Control:max-age=31536000, private
Content-Length:112628
content-type:text/html; charset=utf-8
Date:Wed, 22 Jan 2014 19:57:05 GMT
Expires:Wed, 22 Jan 2014 19:57:05 GMT
Server:Development/2.0
set-cookie:session=; expires=Thu, 01-Jan-1970 00:00:00 GMT; Max-Age=0; Path=/
x-frame-options:DENY
x-ua-compatible:chrome=1
Of course I have checked to make sure that I am not adding the extra headers, and I could find no reference of the cache-related headers (pragma, expires and cache-control) being added outside the given view.
So it seems App Engine is adding a bunch of headers when deployed, which seems unusual. What might I have overlooked?
-- EDIT --
As #dinoboff noted from the docs in a comment below:
Cache-Control, Expires and Vary
These headers specify caching policy to intermediate web proxies (such as Internet Service Providers) and browsers. If your script sets these headers, they will usually be unmodified, unless the response has a Set-Cookie header, or is generated for a user who is signed in using an administrator account.
These headers are additional headers that are added because you are looking at the site as a logged in admin user. They will not be present for "normal" users.
This blog post talks about the X-AppEngine-Resource-Usage header specifically: http://googleappengine.blogspot.co.uk/2009/08/new-features-in-124.html
And as they note:
You can view these headers using plugins such as Firefox's Live HTTP
Headers or Firebug. Note that only logged in administrators see these
figures - ordinary users, and users who aren't logged in, won't see
them at all.

Firefox waiting for response

I have set up simple python script that responds with hello:
def main(environ, start_response):
start_response('200 OK', [
('Content-type', 'text/plain')
])
return 'hello'
Everything works fine in Chrome, I can refresh page every second
But in Firefox I receive 'pending' status and eventually after veeeeeery long time Firefox shows the respond message.
What's wrong here? I tried with Content-Length but it didn't help
Here are the responses:
No, tested with two different Firefox on separate machines.
Firefox:
Status=OK - 200
Server=nginx
Date=Thu, 24 Jan 2013 14:28:31 GMT
Content-Type=text/plain
Transfer-Encoding=chunked
Connection=keep-alive
Content-Encoding=gzip
Chrome:
HTTP/1.1 200 OK
Server: nginx
Date: Thu, 24 Jan 2013 20:24:06 GMT
Content-Type: text/plain
Transfer-Encoding: chunked
Connection: keep-alive
Content-Encoding: gzip

Categories

Resources