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 %} +enabling this will disconnect your client on every HTTP 304, which can prevent some buggy browsers/proxies from getting stuck (suddenly not being able to load pages), but it will also make things slower in general