diff --git a/copyparty/httpcli.py b/copyparty/httpcli.py index 8953059f..b50599c6 100644 --- a/copyparty/httpcli.py +++ b/copyparty/httpcli.py @@ -72,9 +72,13 @@ class HttpCli(object): if rem.startswith("/") or rem.startswith("../") or "/../" in rem: raise Exception("that was close") - def j2(self, name, **kwargs): + def j2(self, name, **ka): tpl = self.conn.hsrv.j2[name] - return tpl.render(**kwargs) if kwargs else tpl + if ka: + ka["ts"] = self.conn.hsrv.cachebuster() + return tpl.render(**ka) + + return tpl def run(self): """returns true if connection can be reused""" @@ -1383,6 +1387,7 @@ class HttpCli(object): "md_plug": "true" if self.args.emp else "false", "md_chk_rate": self.args.mcr, "md": boundary, + "ts": self.conn.hsrv.cachebuster(), } html = template.render(**targs).encode("utf-8", "replace") html = html.split(boundary.encode("utf-8")) @@ -1626,7 +1631,6 @@ class HttpCli(object): url_suf = self.urlq() is_ls = "ls" in self.uparam - ts = "" # "?{}".format(time.time()) tpl = "browser" if "b" in self.uparam: @@ -1651,7 +1655,6 @@ class HttpCli(object): "vdir": quotep(self.vpath), "vpnodes": vpnodes, "files": [], - "ts": ts, "perms": json.dumps(perms), "taglist": [], "tag_order": [], diff --git a/copyparty/httpsrv.py b/copyparty/httpsrv.py index b0e13d0c..8bb5d0ed 100644 --- a/copyparty/httpsrv.py +++ b/copyparty/httpsrv.py @@ -4,6 +4,8 @@ from __future__ import print_function, unicode_literals import os import sys import time +import base64 +import struct import socket import threading @@ -25,7 +27,6 @@ except ImportError: sys.exit(1) from .__init__ import E, MACOS -from .authsrv import AuthSrv from .httpconn import HttpConn @@ -48,6 +49,8 @@ class HttpSrv(object): self.clients = {} self.workload = 0 self.workload_thr_alive = False + self.cb_ts = 0 + self.cb_v = 0 env = jinja2.Environment() env.loader = jinja2.FileSystemLoader(os.path.join(E.mod, "web")) @@ -177,3 +180,25 @@ class HttpSrv(object): self.clients[cli] = now self.workload = total + + def cachebuster(self): + if time.time() - self.cb_ts < 1: + return self.cb_v + + with self.mutex: + if time.time() - self.cb_ts < 1: + return self.cb_v + + v = E.t0 + try: + with os.scandir(os.path.join(E.mod, "web")) as dh: + for fh in dh: + inf = fh.stat(follow_symlinks=False) + v = max(v, inf.st_mtime) + except: + pass + + v = base64.urlsafe_b64encode(struct.pack(">xxL", int(v))) + self.cb_v = v.decode("ascii")[-4:] + self.cb_ts = time.time() + return self.cb_v diff --git a/copyparty/web/browser.html b/copyparty/web/browser.html index 8280420f..0a0b4b30 100644 --- a/copyparty/web/browser.html +++ b/copyparty/web/browser.html @@ -6,10 +6,10 @@ ⇆🎉 {{ title }} - - + + {%- if css %} - + {%- endif %} @@ -127,9 +127,9 @@ have_tags_idx = {{ have_tags_idx|tojson }}, have_zip = {{ have_zip|tojson }}; - - - + + + diff --git a/copyparty/web/md.html b/copyparty/web/md.html index 171d0dd8..8dc6a618 100644 --- a/copyparty/web/md.html +++ b/copyparty/web/md.html @@ -3,9 +3,9 @@ 📝🎉 {{ title }} - + {%- if edit %} - + {%- endif %} @@ -146,10 +146,10 @@ var md_opt = { })(); - - - + + + {%- if edit %} - + {%- endif %} diff --git a/copyparty/web/mde.html b/copyparty/web/mde.html index eaf3fa3b..05077288 100644 --- a/copyparty/web/mde.html +++ b/copyparty/web/mde.html @@ -3,9 +3,9 @@ 📝🎉 {{ title }} - - - + + +
@@ -43,7 +43,7 @@ var lightswitch = (function () { })(); - - - + + + diff --git a/copyparty/web/msg.html b/copyparty/web/msg.html index 5e5e0615..31f0c256 100644 --- a/copyparty/web/msg.html +++ b/copyparty/web/msg.html @@ -6,7 +6,7 @@ copyparty - + diff --git a/copyparty/web/splash.html b/copyparty/web/splash.html index 133e2b12..f9b71f1b 100644 --- a/copyparty/web/splash.html +++ b/copyparty/web/splash.html @@ -6,7 +6,7 @@ copyparty - + diff --git a/tests/util.py b/tests/util.py index a1536f64..214f49d2 100644 --- a/tests/util.py +++ b/tests/util.py @@ -108,6 +108,9 @@ class VHttpSrv(object): aliases = ["splash", "browser", "browser2", "msg", "md", "mde"] self.j2 = {x: J2_FILES for x in aliases} + def cachebuster(self): + return "a" + class VHttpConn(object): def __init__(self, args, asrv, log, buf):