diff --git a/README.md b/README.md index d903659b..21c405c3 100644 --- a/README.md +++ b/README.md @@ -510,9 +510,9 @@ select which type of archive you want in the `[⚙️] config` tab: | name | url-suffix | description | |--|--|--| | `tar` | `?tar` | plain gnutar, works great with `curl \| tar -xv` | -| `tar.gz` | `?tar=gz` | gzip compressed tar, for `curl \| tar -xvz` | -| `tar.xz` | `?tar=xz` | gnu-tar with xz / lzma compression (good) | -| `tar.bz2` | `?tar=bz2` | bzip2-compressed tar (mostly useless) | +| `pax` | `?tar=pax` | pax-format tar, futureproof, not as fast | +| `tgz` | `?tar=gz` | gzip compressed gnu-tar (slow), for `curl \| tar -xvz` | +| `txz` | `?tar=xz` | gnu-tar with xz / lzma compression (v.slow) | | `zip` | `?zip=utf8` | works everywhere, glitchy filenames on win7 and older | | `zip_dos` | `?zip` | traditional cp437 (no unicode) to fix glitchy filenames | | `zip_crc` | `?zip=crc` | cp437 with crc32 computed early for truly ancient software | diff --git a/contrib/nixos/modules/copyparty.nix b/contrib/nixos/modules/copyparty.nix index 1a305942..a60257eb 100644 --- a/contrib/nixos/modules/copyparty.nix +++ b/contrib/nixos/modules/copyparty.nix @@ -138,7 +138,8 @@ in { "d" (delete): permanently delete files and folders "g" (get): download files, but cannot see folder contents "G" (upget): "get", but can see filekeys of their own uploads - "a" (upget): can see uploader IPs, config-reload + "h" (html): "get", but folders return their index.html + "a" (admin): can see uploader IPs, config-reload For example: "rwmd" diff --git a/copyparty/httpcli.py b/copyparty/httpcli.py index c31e937e..1d3e53ad 100644 --- a/copyparty/httpcli.py +++ b/copyparty/httpcli.py @@ -2910,13 +2910,13 @@ class HttpCli(object): if fmt == "tar": packer: Type[StreamArc] = StreamTar - if cancmp and uarg.startswith("gz"): + if cancmp and "gz" in uarg: mime = "application/gzip" ext = "tar.gz" - elif cancmp and uarg.startswith("bz2"): + elif cancmp and "bz2" in uarg: mime = "application/x-bzip" ext = "tar.bz2" - elif cancmp and uarg.startswith("xz"): + elif cancmp and "xz" in uarg: mime = "application/x-xz" ext = "tar.xz" else: @@ -2973,7 +2973,7 @@ class HttpCli(object): fgen, utf8="utf" in uarg, pre_crc="crc" in uarg, - cmp=uarg if cancmp else "", + cmp=uarg if cancmp or uarg == "pax" else "", ) bsent = 0 for buf in bgen.gen(): diff --git a/copyparty/star.py b/copyparty/star.py index 6d0d6c77..078b1169 100644 --- a/copyparty/star.py +++ b/copyparty/star.py @@ -1,6 +1,7 @@ # coding: utf-8 from __future__ import print_function, unicode_literals +import re import stat import tarfile @@ -54,16 +55,21 @@ class StreamTar(StreamArc): self.qfile = QFile() self.errf: dict[str, Any] = {} + # python 3.8 changed to PAX_FORMAT as default; + # slower, bigger, and no particular advantage + fmt = tarfile.GNU_FORMAT + if "pax" in cmp: + # unless a client asks for it (currently + # gnu-tar has wider support than pax-tar) + fmt = tarfile.PAX_FORMAT + cmp = re.sub(r"[^a-z0-9]*pax[^a-z0-9]*", "", cmp) + try: cmp, lv = cmp.replace(":", ",").split(",") lv = int(lv) except: lv = None - # python 3.8 changed to PAX_FORMAT as default, - # waste of space and don't care about the new features - fmt = tarfile.GNU_FORMAT - arg = {"name": None, "fileobj": self.qfile, "mode": "w", "format": fmt} if cmp == "gz": fun = tarfile.TarFile.gzopen diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index e86f48fa..694a6c16 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -377,9 +377,10 @@ var Ls = { "fu_xe1": "failed to load unpost list from server:\n\nerror ", "fu_xe2": "404: File not found??", - "fz_tar": "plain gnu-tar file (linux / mac)", - "fz_targz": "tar with gzip level 3 compression$N$Nthis is usually very slow, so$Nuse uncompressed tar instead", - "fz_tarxz": "tar with xz level 1 compression$N$Nthis is usually very slow, so$Nuse uncompressed tar instead", + "fz_tar": "uncompressed gnu-tar file (linux / mac)", + "fz_pax": "uncompressed pax-format tar (slower)", + "fz_targz": "gnu-tar with gzip level 3 compression$N$Nthis is usually very slow, so$Nuse uncompressed tar instead", + "fz_tarxz": "gnu-tar with xz level 1 compression$N$Nthis is usually very slow, so$Nuse uncompressed tar instead", "fz_zip8": "zip with utf8 filenames (maybe wonky on windows 7 and older)", "fz_zipd": "zip with traditional cp437 filenames, for really old software", "fz_zipc": "cp437 with crc32 computed early,$Nfor MS-DOS PKZIP v2.04g (october 1993)$N(takes longer to process before download can start)", @@ -846,6 +847,7 @@ var Ls = { "fu_xe2": "404: Filen finnes ikke??", "fz_tar": "ukomprimert gnu-tar arkiv, for linux og mac", + "fz_pax": "ukomprimert pax-tar arkiv, litt tregere", "fz_targz": "gnu-tar pakket med gzip (nivå 3)$N$NNB: denne er veldig treg;$Nukomprimert tar er bedre", "fz_tarxz": "gnu-tar pakket med xz (nivå 1)$N$NNB: denne er veldig treg;$Nukomprimert tar er bedre", "fz_zip8": "zip med filnavn i utf8 (noe problematisk på windows 7 og eldre)", @@ -6685,6 +6687,7 @@ var arcfmt = (function () { var html = [], fmts = [ ["tar", "tar", L.fz_tar], + ["pax", "tar=pax", L.fz_pax], ["tgz", "tar=gz", L.fz_targz], ["txz", "tar=xz", L.fz_tarxz], ["zip", "zip=utf8", L.fz_zip8], @@ -6716,7 +6719,7 @@ var arcfmt = (function () { for (var a = 0, aa = tds.length; a < aa; a++) { var o = tds[a], txt = o.textContent, href = o.getAttribute('href'); - if (!/^(zip|tar|tgz|txz)$/.exec(txt)) + if (!/^(zip|tar|pax|tgz|txz)$/.exec(txt)) continue; var ofs = href.lastIndexOf('?'); diff --git a/docs/devnotes.md b/docs/devnotes.md index f2935a73..3eeb6027 100644 --- a/docs/devnotes.md +++ b/docs/devnotes.md @@ -125,8 +125,14 @@ authenticate using header `Cookie: cppwd=foo` or url param `&pw=foo` | GET | `?b` | list files/folders at URL as simplified HTML | | GET | `?tree=.` | list one level of subdirectories inside URL | | GET | `?tree` | list one level of subdirectories for each level until URL | -| GET | `?tar` | download everything below URL as a tar file | -| GET | `?zip=utf-8` | download everything below URL as a zip file | +| GET | `?tar` | download everything below URL as a gnu-tar file | +| GET | `?tar=gz:9` | ...as a gzip-level-9 gnu-tar file | +| GET | `?tar=xz:9` | ...as an xz-level-9 gnu-tar file | +| GET | `?tar=pax` | ...as a pax-tar file | +| GET | `?tar=pax,xz` | ...as an xz-level-1 pax-tar file | +| GET | `?zip=utf-8` | ...as a zip file | +| GET | `?zip` | ...as a WinXP-compatible zip file | +| GET | `?zip=crc` | ...as an MSDOS-compatible zip file | | GET | `?ups` | show recent uploads from your IP | | GET | `?ups&filter=f` | ...where URL contains `f` | | GET | `?mime=foo` | specify return mimetype `foo` |