ianlewis / homepage

My homepage/blog
MIT License
4 stars 3 forks source link

Page Caching using Cloud CDN #14

Closed ianlewis closed 8 years ago

ianlewis commented 8 years ago

Add cache headers to the top page.

ianlewis commented 8 years ago

I can't cache any pages if I need to care about auth and cookies. I will have to disable auth for the user facing part of the website before caching can work.

More info about caching pages is here: https://cloud.google.com/cdn/docs/caching

ianlewis commented 8 years ago

I want to at least have the static files be cached. Currently they don't have a Cache-Control: public header. For some reason the Content-Length header is also 0. It's also missing a Cache-Control: s-maxage, Cache-Control: max-age, or Expires header.

$ curl -I https://www.ianlewis.org/static/CACHE/css/e3b3d94c2620.css
HTTP/1.1 200 OK
Server: nginx/1.11.1
Date: Mon, 19 Sep 2016 01:12:36 GMT
Content-Type: text/css
Content-Length: 0
Etag: 1474202929.27
Last-Modified: Sun, 18 Sep 2016 12:48:49 -0000
Via: 1.1 google
Alt-Svc: clear
ianlewis commented 8 years ago

The static library doesn't seem to add the necessary headers. It simply iterates over the file and sends it.

https://github.com/lukearno/static/blob/master/static/apps.py

It uses wsgi.file_wrapper to send the file which would be supplied by the wsgi web server. In my case waitress.

ianlewis commented 8 years ago

The waitress docs say that waitress will set the Content-Length if the file-like object passed to it is "sufficiently file-like". I guess that means that the file-like object passed to it by static is not sufficiently file-like?

ianlewis commented 8 years ago

wsgi apps must not set a Transfer-Encoding apparently.

https://www.python.org/dev/peps/pep-0333/#handling-the-content-length-header

ianlewis commented 8 years ago

It sounds like the conclusion will be that I need a better web server than waitress :(

ianlewis commented 8 years ago

Upgrading to waitress 1.0.0 didn't fix the Content-Length issue. Maybe file a bug? I need to write a quick app to repro the bug.

ianlewis commented 8 years ago

I tried it with a minimal app and it seems like waitress isn't the problem.

from waitress import serve

def app(environ, start_response, headers=[]):
    fd = open("test.txt", "rb")
    way_to_send = environ.get('wsgi.file_wrapper')

    start_response("200 OK", [])
    return way_to_send(fd, 16 * 4096)

serve(app, host="localhost", port=8000)

I get the proper content header

$ echo "this is a test" > test.txt
$ curl -I http://localhost:8000/
HTTP/1.1 200 OK
Content-Length: 15
Date: Mon, 19 Sep 2016 02:29:20 GMT
Server: waitress

For some reason the length from the file-like object from static can't be used by waitress?

ianlewis commented 8 years ago

It is sending the content-length. I just wasn't using curl properly

$ curl -i http://localhost:8000/static/css/style.css
HTTP/1.1 200 OK
Content-Length: 4813
Content-Type: text/css
Date: Mon, 19 Sep 2016 08:53:50 -0000
Etag: 1474168922.18
Last-Modified: Sun, 18 Sep 2016 03:22:02 -0000
Server: waitress
...
ianlewis commented 8 years ago

This seems to be working at least for static files. I'll go ahead and close this since caching the html pages themselves will need a bit more thought.