added handling of mutable static resources

This commit is contained in:
2020-03-03 14:17:22 +00:00
parent f6bbb3aef9
commit 1e75eaf836

View File

@@ -1,6 +1,6 @@
import logging import logging
from os import getcwd, listdir from os import getcwd, listdir
from os.path import exists, splitext, isfile, join, relpath, isdir, basename from os.path import exists, splitext, isfile, join, relpath, isdir, basename, getmtime
from mimetypes import init as mimeinit, guess_type from mimetypes import init as mimeinit, guess_type
import hashlib import hashlib
from .md2html import compile_html from .md2html import compile_html
@@ -9,15 +9,17 @@ mimeinit()
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.INFO)
cwd = getcwd() cwd = getcwd()
def is_markdown(filepath): def is_markdown(filepath):
_, ext = splitext(filepath) _, ext = splitext(filepath)
return ext == ".md" return ext == ".md"
cache = dict() cache = dict()
def file_hash(filepath, bufsize=4096): def file_hash(filepath, bufsize=4096):
if bufsize <= 0: if bufsize <= 0:
raise ValueError("Buffer size must be greater than 0") raise ValueError("Buffer size must be greater than 0")
@@ -30,16 +32,26 @@ def file_hash(filepath, bufsize=4096):
md5.update(buf) md5.update(buf)
return md5.digest() return md5.digest()
def application(env, start_response): def application(env, start_response):
path = join(cwd, relpath(env['PATH_INFO'], '/')) path = join(cwd, relpath(env['PATH_INFO'], '/'))
if exists(path): if exists(path):
if isfile(path): if isfile(path):
if path not in cache: cache_result = cache.get(path)
_mtime = None
def mtime():
nonlocal _mtime
if not _mtime:
_mtime = getmtime(path)
return _mtime
if not cache_result or cache_result[1] < mtime():
digest = file_hash(path).hex() digest = file_hash(path).hex()
cache[path] = digest cache[path] = digest, mtime()
else: else:
digest = cache[path] digest = cache_result[0]
def parse_etag(etag): def parse_etag(etag):
if etag is None: if etag is None:
@@ -73,6 +85,7 @@ def application(env, start_response):
if len(result) == 0: if len(result) == 0:
break break
yield result yield result
start_response('200 OK', [('Content-Type', guess_type(basename(path))[0] or 'application/octet-stream'), start_response('200 OK', [('Content-Type', guess_type(basename(path))[0] or 'application/octet-stream'),
('Etag', '"%s"' % digest), ('Etag', '"%s"' % digest),
('Cache-Control', 'no-cache, must-revalidate, max-age=86400'), ('Cache-Control', 'no-cache, must-revalidate, max-age=86400'),