From cae436b56629a1ec7610bc21358f510575c13b25 Mon Sep 17 00:00:00 2001 From: ed Date: Mon, 15 Nov 2021 02:45:18 +0100 Subject: [PATCH] add client-option to disconnect on HTTP 304 --- copyparty/httpcli.py | 31 ++++++++++++++++++++++--------- copyparty/util.py | 11 +++++++++++ copyparty/web/splash.css | 11 +++++++++-- copyparty/web/splash.html | 10 ++++++++++ 4 files changed, 52 insertions(+), 11 deletions(-) diff --git a/copyparty/httpcli.py b/copyparty/httpcli.py index 68f1a64a..b81145d7 100644 --- a/copyparty/httpcli.py +++ b/copyparty/httpcli.py @@ -228,8 +228,8 @@ class HttpCli(object): if pwd and "pw" in self.ouparam and pwd != cookies.get("cppwd"): self.out_headers["Set-Cookie"] = self.get_pwd_cookie(pwd)[0] - ua = self.headers.get("user-agent", "") - self.is_rclone = ua.startswith("rclone/") + self.ua = self.headers.get("user-agent", "") + self.is_rclone = self.ua.startswith("rclone/") if self.is_rclone: uparam["raw"] = False uparam["dots"] = False @@ -284,12 +284,19 @@ class HttpCli(object): n = "604800" if cache == "i" else cache or "69" self.out_headers["Cache-Control"] = "max-age=" + n + def k304(self): + k304 = self.cookies.get("k304", "") + return k304 == "y" or ("; Trident/" in self.ua and not k304) + def send_headers(self, length, status=200, mime=None, headers=None): response = ["{} {} {}".format(self.http_ver, status, HTTPCODE[status])] if length is not None: response.append("Content-Length: " + unicode(length)) + if status == 304 and self.k304(): + self.keepalive = False + # close if unknown length, otherwise take client's preference response.append("Connection: " + ("Keep-Alive" if self.keepalive else "Close")) @@ -432,6 +439,9 @@ class HttpCli(object): if "h" in self.uparam: return self.tx_mounts() + if "k304" in self.uparam: + return self.set_k304() + # conditional redirect to single volumes if self.vpath == "" and not self.ouparam: nread = len(self.rvol) @@ -962,15 +972,13 @@ class HttpCli(object): def get_pwd_cookie(self, pwd): if pwd in self.asrv.iacct: msg = "login ok" - dt = datetime.utcfromtimestamp(time.time() + 60 * 60 * 24 * 365) - exp = dt.strftime("%a, %d %b %Y %H:%M:%S GMT") + dur = 60 * 60 * 24 * 365 else: msg = "naw dude" pwd = "x" # nosec - exp = "Fri, 15 Aug 1997 01:00:00 GMT" + dur = None - ck = "cppwd={}; Path=/; Expires={}; SameSite=Lax".format(pwd, exp) - return [ck, msg] + return [gencookie("cppwd", pwd, dur), msg] def handle_mkdir(self): new_dir = self.parser.require("name", 512) @@ -1383,8 +1391,7 @@ class HttpCli(object): if "gzip" not in supported_editions: decompress = True else: - ua = self.headers.get("user-agent", "") - if re.match(r"MSIE [4-6]\.", ua) and " SV1" not in ua: + if re.match(r"MSIE [4-6]\.", self.ua) and " SV1" not in self.ua: decompress = True if not decompress: @@ -1697,10 +1704,16 @@ class HttpCli(object): tagq=vs["tagq"], mtpq=vs["mtpq"], url_suf=suf, + k304=self.k304(), ) self.reply(html.encode("utf-8")) return True + def set_k304(self): + ck = gencookie("k304", self.uparam["k304"], 60 * 60 * 24 * 365) + self.out_headers["Set-Cookie"] = ck + self.redirect("", "?h#cc") + def tx_404(self, is_403=False): if self.args.vague_403: m = '

404 not found  ┐( ´ -`)┌

or maybe you don\'t have access -- try logging in or go home

' diff --git a/copyparty/util.py b/copyparty/util.py index 7dd5115e..ceec44cb 100644 --- a/copyparty/util.py +++ b/copyparty/util.py @@ -822,6 +822,17 @@ def gen_filekey(salt, fspath, fsize, inode): ).decode("ascii") +def gencookie(k, v, dur): + v = v.replace(";", "") + if dur: + dt = datetime.utcfromtimestamp(time.time() + dur) + exp = dt.strftime("%a, %d %b %Y %H:%M:%S GMT") + else: + exp = "Fri, 15 Aug 1997 01:00:00 GMT" + + return "{}={}; Path=/; Expires={}; SameSite=Lax".format(k, v, exp) + + def humansize(sz, terse=False): for unit in ["B", "KiB", "MiB", "GiB", "TiB"]: if sz < 1024: diff --git a/copyparty/web/splash.css b/copyparty/web/splash.css index e9b7afe2..429eb542 100644 --- a/copyparty/web/splash.css +++ b/copyparty/web/splash.css @@ -38,7 +38,8 @@ a+a { margin: -.2em 0 0 .5em; } .logout, -.btns a { +.btns a, +a.r { color: #c04; border-color: #c7a; } @@ -79,6 +80,11 @@ table { margin-top: .3em; text-align: right; } +blockquote { + margin: 0 0 0 .6em; + padding: .7em 1em; + border-left: .3em solid rgba(128,128,128,0.5); +} html.dark, @@ -96,7 +102,8 @@ html.dark a { border-color: #37a; } html.dark .logout, -html.dark .btns a { +html.dark .btns a, +html.dark a.r { background: #804; border-color: #c28; } diff --git a/copyparty/web/splash.html b/copyparty/web/splash.html index 076ddbe7..ab65a974 100644 --- a/copyparty/web/splash.html +++ b/copyparty/web/splash.html @@ -72,6 +72,16 @@ {%- endif %} +

client config:

+ +

login for more: