From ce274d2011fece6a783b1db47695f96d90e888b8 Mon Sep 17 00:00:00 2001 From: ed Date: Wed, 3 Feb 2021 23:18:11 +0100 Subject: [PATCH] handle url-encoded posts --- copyparty/__main__.py | 7 +++++++ copyparty/httpcli.py | 38 +++++++++++++++++++++++++++++++------- copyparty/web/upload.html | 10 +++++++++- 3 files changed, 47 insertions(+), 8 deletions(-) diff --git a/copyparty/__main__.py b/copyparty/__main__.py index 3b4d6fbc..2b4fcce7 100644 --- a/copyparty/__main__.py +++ b/copyparty/__main__.py @@ -127,6 +127,12 @@ def main(): consider the config file for more flexible account/volume management, including dynamic reload at runtime (and being more readable w) + + values for --urlform: + "stash" dumps the data to file and returns length + checksum + "save,get" dumps to file and returns the page like a GET + "print,get" prints the data in the log and returns GET + (leave out the ",get" to return an error instead) """ ), ) @@ -148,6 +154,7 @@ def main(): ap.add_argument("-nih", action="store_true", help="no info hostname") ap.add_argument("-nid", action="store_true", help="no info disk-usage") ap.add_argument("--no-sendfile", action="store_true", help="disable sendfile") + ap.add_argument("--urlform", type=str, default="print,get", help="how to handle url-forms") al = ap.parse_args() # fmt: on diff --git a/copyparty/httpcli.py b/copyparty/httpcli.py index a78d87be..35f574a0 100644 --- a/copyparty/httpcli.py +++ b/copyparty/httpcli.py @@ -294,16 +294,37 @@ class HttpCli(object): if "application/octet-stream" in ctype: return self.handle_post_binary() - raise Pebkac(405, "don't know how to handle {} POST".format(ctype)) + if "application/x-www-form-urlencoded" in ctype: + opt = self.args.urlform + if "stash" in opt: + return self.handle_stash() - def handle_stash(self): + if "save" in opt: + post_sz, _, _, path = self.dump_to_file() + self.log("urlform: {} bytes, {}".format(post_sz, path)) + elif "print" in opt: + reader, _ = self.get_body_reader() + for buf in reader: + buf = buf.decode("utf-8", "replace") + self.log("urlform:\n {}\n".format(buf)) + + if "get" in opt: + return self.handle_get() + + raise Pebkac(405, "POST({}) is disabled".format(ctype)) + + raise Pebkac(405, "don't know how to handle POST({})".format(ctype)) + + def get_body_reader(self): remains = int(self.headers.get("content-length", None)) if remains is None: - reader = read_socket_unbounded(self.sr) self.keepalive = False + return read_socket_unbounded(self.sr), remains else: - reader = read_socket(self.sr, remains) + return read_socket(self.sr, remains), remains + def dump_to_file(self): + reader, remains = self.get_body_reader() vfs, rem = self.conn.auth.vfs.get(self.vpath, self.uname, False, True) fdir = os.path.join(vfs.realpath, rem) @@ -314,6 +335,10 @@ class HttpCli(object): with open(path, "wb", 512 * 1024) as f: post_sz, _, sha_b64 = hashcopy(self.conn, reader, f) + return post_sz, sha_b64, remains, path + + def handle_stash(self): + post_sz, sha_b64, remains, path = self.dump_to_file() spd = self._spd(post_sz) self.log("{} wrote {}/{} bytes to {}".format(spd, post_sz, remains, path)) self.reply("{}\n{}\n".format(post_sz, sha_b64).encode("utf-8")) @@ -517,10 +542,9 @@ class HttpCli(object): raise Pebkac(500, "mkdir failed, check the logs") vpath = "{}/{}".format(self.vpath, sanitized).lstrip("/") + esc_paths = [quotep(vpath), html_escape(vpath)] html = self.conn.tpl_msg.render( - h2='go to /{}'.format( - quotep(vpath), html_escape(vpath) - ), + h2='go to /{}'.format(*esc_paths), pre="aight", click=True, ) diff --git a/copyparty/web/upload.html b/copyparty/web/upload.html index 8fbac2ab..269e8e9b 100644 --- a/copyparty/web/upload.html +++ b/copyparty/web/upload.html @@ -3,7 +3,8 @@ href="#" data-dest="up2k">up2kbupmkdirnew.md + href="#" data-dest="new_md">new.mdmsg
@@ -30,6 +31,13 @@
+
+
+ + +
+
+