diff --git a/copyparty/authsrv.py b/copyparty/authsrv.py
index 5a06614c..b0905c77 100644
--- a/copyparty/authsrv.py
+++ b/copyparty/authsrv.py
@@ -175,16 +175,31 @@ class VFS(object):
pass
for rel, (vn, rem) in vtops:
- for vpath, apath, files, _, _ in vn.walk(rel, rem, uname, dots, scandir):
+ for vpath, apath, files, rd, vd in vn.walk(rel, rem, uname, dots, scandir):
# print(repr([vpath, apath, [x[0] for x in files]]))
- files = [x for x in files if dots or not x[0].startswith(".")]
fnames = [n[0] for n in files]
vpaths = [vpath + "/" + n for n in fnames] if vpath else fnames
apaths = [os.path.join(apath, n) for n in fnames]
- for f in [
- {"vp": vp, "ap": ap, "st": n[1]}
- for vp, ap, n in zip(vpaths, apaths, files)
- ]:
+ files = list(zip(vpaths, apaths, files))
+
+ if not dots:
+ # dotfile filtering based on vpath (intended visibility)
+ files = [x for x in files if "/." not in "/" + x[0]]
+
+ rm = [x for x in rd if x[0].startswith(".")]
+ for x in rm:
+ rd.remove(x)
+
+ rm = [k for k in vd.keys() if k.startswith(".")]
+ for x in rm:
+ del vd[x]
+
+ # up2k filetring based on actual abspath
+ files = [
+ x for x in files if "{0}.hist{0}up2k.".format(os.sep) not in x[1]
+ ]
+
+ for f in [{"vp": v, "ap": a, "st": n[1]} for v, a, n in files]:
yield f
def user_tree(self, uname, readable=False, writable=False):
diff --git a/copyparty/httpcli.py b/copyparty/httpcli.py
index bbe23a43..373cb0ae 100644
--- a/copyparty/httpcli.py
+++ b/copyparty/httpcli.py
@@ -1047,18 +1047,22 @@ class HttpCli(object):
self.log("{}, {}".format(logmsg, spd))
return ret
- def tx_zip(self, vn, rem, items, dots):
+ def tx_zip(self, fmt, uarg, vn, rem, items, dots):
if self.args.no_zip:
raise Pebkac(400, "not enabled")
logmsg = "{:4} {} ".format("", self.req)
self.keepalive = False
- fmt = "zip"
+ if not uarg:
+ uarg = ""
+
if fmt == "tar":
mime = "application/x-tar"
+ packer = StreamTar
else:
mime = "application/zip"
+ packer = StreamZip
fn = items[0] if items and items[0] else self.vpath
if fn:
@@ -1071,12 +1075,13 @@ class HttpCli(object):
)
bascii = unicode(string.ascii_letters + string.digits).encode("utf-8")
+ chcon = ord if PY2 else int
ufn = b"".join(
[
chr(x).encode("utf-8")
if x in bascii
- else "%{:02x}".format(x).encode("ascii")
- for x in fn.encode("utf-8")
+ else "%{:02x}".format(chcon(x)).encode("ascii")
+ for x in fn.encode("utf-8", "xmlcharrefreplace")
]
).decode("ascii")
@@ -1086,7 +1091,7 @@ class HttpCli(object):
fgen = vn.zipgen(rem, items, self.uname, dots, not self.args.no_scandir)
# for f in fgen: print(repr({k: f[k] for k in ["vp", "ap"]}))
- bgen = StreamZip(fgen, False, False)
+ bgen = packer(fgen, utf8="utf" in uarg)
bsent = 0
for buf in bgen.gen():
if not buf:
@@ -1249,8 +1254,10 @@ class HttpCli(object):
return self.tx_file(abspath)
- if "zip" in self.uparam:
- return self.tx_zip(vn, rem, [], False)
+ for k in ["zip", "tar"]:
+ v = self.uparam.get(k)
+ if v is not None:
+ return self.tx_zip(k, v, vn, rem, [], self.args.ed)
fsroot, vfs_ls, vfs_virt = vn.ls(rem, self.uname, not self.args.no_scandir)
stats = {k: v for k, v in vfs_ls}
@@ -1316,7 +1323,7 @@ class HttpCli(object):
if self.args.no_zip:
margin = "DIR"
else:
- margin = 'zip'.format(html_escape(href))
+ margin = 'zip'.format(quotep(href))
elif fn in hist:
margin = '#{}'.format(
base, html_escape(hist[fn][2], quote=True), hist[fn][0]
diff --git a/copyparty/star.py b/copyparty/star.py
index 3c26376a..ebaf8812 100644
--- a/copyparty/star.py
+++ b/copyparty/star.py
@@ -17,11 +17,11 @@ class QFile(object):
class StreamTar(object):
"""construct in-memory tar file from the given path"""
- def __init__(self, top, fgen):
+ def __init__(self, fgen, **kwargs):
self.ci = 0
self.co = 0
self.qfile = QFile()
- self.srcfiles = fgen
+ self.fgen = fgen
# python 3.8 changed to PAX_FORMAT as default,
# waste of space and don't care about the new features
diff --git a/copyparty/szip.py b/copyparty/szip.py
index d9e14344..f5cfa0dd 100644
--- a/copyparty/szip.py
+++ b/copyparty/szip.py
@@ -174,7 +174,7 @@ def gen_ecdr64_loc(ecdr64_pos):
class StreamZip(object):
- def __init__(self, fgen, utf8, pre_crc):
+ def __init__(self, fgen, utf8=False, pre_crc=False):
self.fgen = fgen
self.utf8 = utf8
self.pre_crc = pre_crc
diff --git a/copyparty/web/up2k.js b/copyparty/web/up2k.js
index c9464c6b..7a7b5154 100644
--- a/copyparty/web/up2k.js
+++ b/copyparty/web/up2k.js
@@ -278,7 +278,7 @@ function up2k_init(have_crypto) {
}
else files = e.target.files;
- if (files.length == 0)
+ if (!files || files.length == 0)
return alert('no files selected??');
more_one_file();