1
0
Fork 0
forked from s3lph/matemat

Implemented (probably quite shaky) static content cache headers.

This commit is contained in:
s3lph 2018-07-14 19:00:37 +02:00
parent 5f2464b023
commit 87b66719e3

View file

@ -10,6 +10,7 @@ from http.server import HTTPServer, BaseHTTPRequestHandler
from http.cookies import SimpleCookie from http.cookies import SimpleCookie
from uuid import uuid4 from uuid import uuid4
from datetime import datetime, timedelta from datetime import datetime, timedelta
from time import localtime
import jinja2 import jinja2
@ -323,7 +324,7 @@ class HttpHandler(BaseHTTPRequestHandler):
# Send the HTTP status code # Send the HTTP status code
self.send_response(hsc) self.send_response(hsc)
# Format the session cookie timeout string and send the session cookie header # Format the session cookie timeout string and send the session cookie header
expires = timeout.strftime("%a, %d %b %Y %H:%M:%S GMT") expires = timeout.strftime('%a, %d %b %Y %H:%M:%S GMT')
self.send_header('Set-Cookie', self.send_header('Set-Cookie',
f'matemat_session_id={session_id}; expires={expires}') f'matemat_session_id={session_id}; expires={expires}')
# Compute the body length and add the appropriate header # Compute the body length and add the appropriate header
@ -345,6 +346,21 @@ class HttpHandler(BaseHTTPRequestHandler):
filepath: str = os.path.abspath(os.path.join(self.server.webroot, path[1:])) filepath: str = os.path.abspath(os.path.join(self.server.webroot, path[1:]))
# Make sure the file is actually inside the webroot directory and that it exists # Make sure the file is actually inside the webroot directory and that it exists
if os.path.commonpath([filepath, self.server.webroot]) == self.server.webroot and os.path.exists(filepath): if os.path.commonpath([filepath, self.server.webroot]) == self.server.webroot and os.path.exists(filepath):
# Parse the If-Modified-Since header to check whether the browser can reuse cached content
datestr: str = self.headers.get('If-Modified-Since', 'Thu, 01 Jan 1970 00:00:00 GMT')
maxage: datetime = datetime.strptime(datestr, '%a, %d %b %Y %H:%M:%S %Z')
# File modification time in LOCAL time
filestat: int = int(os.path.getmtime(filepath))
# Create timezone-unaware datetime object and subtract UTC offset
fileage: datetime = datetime.fromtimestamp(filestat) - timedelta(seconds=localtime().tm_gmtoff)
# If the file has not been replaced by a newer version than requested by the client, send a 304 response
if fileage <= maxage:
self.send_response(304, 'Not Modified')
self.send_header('Content-Length', '0')
self.end_headers()
return
# Open and read the file # Open and read the file
with open(filepath, 'rb') as f: with open(filepath, 'rb') as f:
data = f.read() data = f.read()
@ -358,6 +374,8 @@ class HttpHandler(BaseHTTPRequestHandler):
# Send content type and length header # Send content type and length header
self.send_header('Content-Type', mimetype) self.send_header('Content-Type', mimetype)
self.send_header('Content-Length', str(len(data))) self.send_header('Content-Length', str(len(data)))
self.send_header('Last-Modified', fileage.strftime('%a, %d %b %Y %H:%M:%S GMT'))
self.send_header('Cache-Control', 'max-age=1')
self.end_headers() self.end_headers()
# Send the requested resource as response body # Send the requested resource as response body
self.wfile.write(data) self.wfile.write(data)