copyparty 1.13.2__py3-none-any.whl → 1.13.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- copyparty/__main__.py +94 -43
- copyparty/__version__.py +2 -2
- copyparty/authsrv.py +75 -13
- copyparty/cert.py +10 -6
- copyparty/cfg.py +3 -0
- copyparty/ftpd.py +44 -7
- copyparty/httpcli.py +188 -64
- copyparty/httpsrv.py +3 -3
- copyparty/mdns.py +24 -3
- copyparty/mtag.py +6 -1
- copyparty/smbd.py +1 -1
- copyparty/ssdp.py +23 -3
- copyparty/star.py +4 -4
- copyparty/sutil.py +12 -6
- copyparty/svchub.py +4 -2
- copyparty/szip.py +4 -4
- copyparty/tcpsrv.py +4 -1
- copyparty/tftpd.py +5 -10
- copyparty/th_cli.py +1 -1
- copyparty/th_srv.py +22 -11
- copyparty/up2k.py +84 -16
- copyparty/util.py +69 -22
- copyparty/web/a/u2c.py +14 -6
- copyparty/web/baguettebox.js.gz +0 -0
- copyparty/web/browser.css.gz +0 -0
- copyparty/web/browser.js.gz +0 -0
- copyparty/web/deps/marked.js.gz +0 -0
- copyparty/web/md2.js.gz +0 -0
- copyparty/web/ui.css.gz +0 -0
- copyparty/web/util.js.gz +0 -0
- {copyparty-1.13.2.dist-info → copyparty-1.13.4.dist-info}/METADATA +39 -7
- {copyparty-1.13.2.dist-info → copyparty-1.13.4.dist-info}/RECORD +36 -36
- {copyparty-1.13.2.dist-info → copyparty-1.13.4.dist-info}/WHEEL +1 -1
- {copyparty-1.13.2.dist-info → copyparty-1.13.4.dist-info}/LICENSE +0 -0
- {copyparty-1.13.2.dist-info → copyparty-1.13.4.dist-info}/entry_points.txt +0 -0
- {copyparty-1.13.2.dist-info → copyparty-1.13.4.dist-info}/top_level.txt +0 -0
copyparty/util.py
CHANGED
@@ -137,6 +137,18 @@ else:
|
|
137
137
|
from urllib import unquote # type: ignore # pylint: disable=no-name-in-module
|
138
138
|
|
139
139
|
|
140
|
+
try:
|
141
|
+
socket.inet_pton(socket.AF_INET6, "::1")
|
142
|
+
HAVE_IPV6 = True
|
143
|
+
except:
|
144
|
+
|
145
|
+
def inet_pton(fam, ip):
|
146
|
+
return socket.inet_aton(ip)
|
147
|
+
|
148
|
+
socket.inet_pton = inet_pton
|
149
|
+
HAVE_IPV6 = False
|
150
|
+
|
151
|
+
|
140
152
|
try:
|
141
153
|
struct.unpack(b">i", b"idgi")
|
142
154
|
spack = struct.pack # type: ignore
|
@@ -210,6 +222,7 @@ IMPLICATIONS = [
|
|
210
222
|
["e2vu", "e2v"],
|
211
223
|
["e2vp", "e2v"],
|
212
224
|
["e2v", "e2d"],
|
225
|
+
["tftpvv", "tftpv"],
|
213
226
|
["smbw", "smb"],
|
214
227
|
["smb1", "smb"],
|
215
228
|
["smbvvv", "smbvv"],
|
@@ -337,6 +350,18 @@ APPLESAN_TXT = r"/(__MACOS|Icon\r\r)|/\.(_|DS_Store|AppleDouble|LSOverride|Docum
|
|
337
350
|
APPLESAN_RE = re.compile(APPLESAN_TXT)
|
338
351
|
|
339
352
|
|
353
|
+
HUMANSIZE_UNITS = ("B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB")
|
354
|
+
|
355
|
+
UNHUMANIZE_UNITS = {
|
356
|
+
"b": 1,
|
357
|
+
"k": 1024,
|
358
|
+
"m": 1024 * 1024,
|
359
|
+
"g": 1024 * 1024 * 1024,
|
360
|
+
"t": 1024 * 1024 * 1024 * 1024,
|
361
|
+
"p": 1024 * 1024 * 1024 * 1024 * 1024,
|
362
|
+
"e": 1024 * 1024 * 1024 * 1024 * 1024 * 1024,
|
363
|
+
}
|
364
|
+
|
340
365
|
VF_CAREFUL = {"mv_re_t": 5, "rm_re_t": 5, "mv_re_r": 0.1, "rm_re_r": 0.1}
|
341
366
|
|
342
367
|
|
@@ -1787,7 +1812,7 @@ def gencookie(k , v , r , tls , dur = 0, txt = "") :
|
|
1787
1812
|
|
1788
1813
|
|
1789
1814
|
def humansize(sz , terse = False) :
|
1790
|
-
for unit in
|
1815
|
+
for unit in HUMANSIZE_UNITS:
|
1791
1816
|
if sz < 1024:
|
1792
1817
|
break
|
1793
1818
|
|
@@ -1808,12 +1833,7 @@ def unhumanize(sz ) :
|
|
1808
1833
|
pass
|
1809
1834
|
|
1810
1835
|
mc = sz[-1:].lower()
|
1811
|
-
mi =
|
1812
|
-
"k": 1024,
|
1813
|
-
"m": 1024 * 1024,
|
1814
|
-
"g": 1024 * 1024 * 1024,
|
1815
|
-
"t": 1024 * 1024 * 1024 * 1024,
|
1816
|
-
}.get(mc, 1)
|
1836
|
+
mi = UNHUMANIZE_UNITS.get(mc, 1)
|
1817
1837
|
return int(float(sz[:-1]) * mi)
|
1818
1838
|
|
1819
1839
|
|
@@ -2430,6 +2450,9 @@ def build_netmap(csv ):
|
|
2430
2450
|
csv += ", 127.0.0.0/8, ::1/128" # loopback
|
2431
2451
|
|
2432
2452
|
srcs = [x.strip() for x in csv.split(",") if x.strip()]
|
2453
|
+
if not HAVE_IPV6:
|
2454
|
+
srcs = [x for x in srcs if ":" not in x]
|
2455
|
+
|
2433
2456
|
cidrs = []
|
2434
2457
|
for zs in srcs:
|
2435
2458
|
if not zs.endswith("."):
|
@@ -2496,6 +2519,7 @@ def sendfile_py(
|
|
2496
2519
|
s ,
|
2497
2520
|
bufsz ,
|
2498
2521
|
slp ,
|
2522
|
+
use_poll ,
|
2499
2523
|
) :
|
2500
2524
|
remains = upper - lower
|
2501
2525
|
f.seek(lower)
|
@@ -2524,22 +2548,31 @@ def sendfile_kern(
|
|
2524
2548
|
s ,
|
2525
2549
|
bufsz ,
|
2526
2550
|
slp ,
|
2551
|
+
use_poll ,
|
2527
2552
|
) :
|
2528
2553
|
out_fd = s.fileno()
|
2529
2554
|
in_fd = f.fileno()
|
2530
2555
|
ofs = lower
|
2531
2556
|
stuck = 0.0
|
2557
|
+
if use_poll:
|
2558
|
+
poll = select.poll()
|
2559
|
+
poll.register(out_fd, select.POLLOUT)
|
2560
|
+
|
2532
2561
|
while ofs < upper:
|
2533
2562
|
stuck = stuck or time.time()
|
2534
2563
|
try:
|
2535
2564
|
req = min(2 ** 30, upper - ofs)
|
2536
|
-
|
2565
|
+
if use_poll:
|
2566
|
+
poll.poll(10000)
|
2567
|
+
else:
|
2568
|
+
select.select([], [out_fd], [], 10)
|
2537
2569
|
n = os.sendfile(out_fd, in_fd, ofs, req)
|
2538
2570
|
stuck = 0
|
2539
2571
|
except OSError as ex:
|
2540
2572
|
# client stopped reading; do another select
|
2541
2573
|
d = time.time() - stuck
|
2542
2574
|
if d < 3600 and ex.errno == errno.EWOULDBLOCK:
|
2575
|
+
time.sleep(0.02)
|
2543
2576
|
continue
|
2544
2577
|
|
2545
2578
|
n = 0
|
@@ -2938,7 +2971,8 @@ def retchk(
|
|
2938
2971
|
|
2939
2972
|
def _parsehook(
|
2940
2973
|
log , cmd
|
2941
|
-
)
|
2974
|
+
) :
|
2975
|
+
areq = ""
|
2942
2976
|
chk = False
|
2943
2977
|
fork = False
|
2944
2978
|
jtxt = False
|
@@ -2963,8 +2997,12 @@ def _parsehook(
|
|
2963
2997
|
cap = int(arg[1:]) # 0=none 1=stdout 2=stderr 3=both
|
2964
2998
|
elif arg.startswith("k"):
|
2965
2999
|
kill = arg[1:] # [t]ree [m]ain [n]one
|
3000
|
+
elif arg.startswith("a"):
|
3001
|
+
areq = arg[1:] # required perms
|
2966
3002
|
elif arg.startswith("i"):
|
2967
3003
|
pass
|
3004
|
+
elif not arg:
|
3005
|
+
break
|
2968
3006
|
else:
|
2969
3007
|
t = "hook: invalid flag {} in {}"
|
2970
3008
|
(log or print)(t.format(arg, ocmd))
|
@@ -2991,9 +3029,11 @@ def _parsehook(
|
|
2991
3029
|
"capture": cap,
|
2992
3030
|
}
|
2993
3031
|
|
2994
|
-
|
3032
|
+
argv = cmd.split(",") if "," in cmd else [cmd]
|
3033
|
+
|
3034
|
+
argv[0] = os.path.expandvars(os.path.expanduser(argv[0]))
|
2995
3035
|
|
2996
|
-
return chk, fork, jtxt, wait, sp_ka,
|
3036
|
+
return areq, chk, fork, jtxt, wait, sp_ka, argv
|
2997
3037
|
|
2998
3038
|
|
2999
3039
|
def runihook(
|
@@ -3002,10 +3042,9 @@ def runihook(
|
|
3002
3042
|
vol ,
|
3003
3043
|
ups ,
|
3004
3044
|
) :
|
3005
|
-
|
3006
|
-
|
3007
|
-
|
3008
|
-
if cmd.endswith(".py"):
|
3045
|
+
_, chk, fork, jtxt, wait, sp_ka, acmd = _parsehook(log, cmd)
|
3046
|
+
bcmd = [sfsenc(x) for x in acmd]
|
3047
|
+
if acmd[0].endswith(".py"):
|
3009
3048
|
bcmd = [sfsenc(pybin)] + bcmd
|
3010
3049
|
|
3011
3050
|
vps = [vjoin(*list(s3dec(x[3], x[4]))) for x in ups]
|
@@ -3030,7 +3069,7 @@ def runihook(
|
|
3030
3069
|
|
3031
3070
|
t0 = time.time()
|
3032
3071
|
if fork:
|
3033
|
-
Daemon(runcmd,
|
3072
|
+
Daemon(runcmd, cmd, bcmd, ka=sp_ka)
|
3034
3073
|
else:
|
3035
3074
|
rc, v, err = runcmd(bcmd, **sp_ka) # type: ignore
|
3036
3075
|
if chk and rc:
|
@@ -3051,14 +3090,20 @@ def _runhook(
|
|
3051
3090
|
vp ,
|
3052
3091
|
host ,
|
3053
3092
|
uname ,
|
3093
|
+
perms ,
|
3054
3094
|
mt ,
|
3055
3095
|
sz ,
|
3056
3096
|
ip ,
|
3057
3097
|
at ,
|
3058
3098
|
txt ,
|
3059
3099
|
) :
|
3060
|
-
|
3061
|
-
|
3100
|
+
areq, chk, fork, jtxt, wait, sp_ka, acmd = _parsehook(log, cmd)
|
3101
|
+
if areq:
|
3102
|
+
for ch in areq:
|
3103
|
+
if ch not in perms:
|
3104
|
+
t = "user %s not allowed to run hook %s; need perms %s, have %s"
|
3105
|
+
log(t % (uname, cmd, areq, perms))
|
3106
|
+
return True # fallthrough to next hook
|
3062
3107
|
if jtxt:
|
3063
3108
|
ja = {
|
3064
3109
|
"ap": ap,
|
@@ -3069,21 +3114,22 @@ def _runhook(
|
|
3069
3114
|
"at": at or time.time(),
|
3070
3115
|
"host": host,
|
3071
3116
|
"user": uname,
|
3117
|
+
"perms": perms,
|
3072
3118
|
"txt": txt,
|
3073
3119
|
}
|
3074
3120
|
arg = json.dumps(ja)
|
3075
3121
|
else:
|
3076
3122
|
arg = txt or ap
|
3077
3123
|
|
3078
|
-
acmd
|
3079
|
-
if
|
3124
|
+
acmd += [arg]
|
3125
|
+
if acmd[0].endswith(".py"):
|
3080
3126
|
acmd = [pybin] + acmd
|
3081
3127
|
|
3082
3128
|
bcmd = [fsenc(x) if x == ap else sfsenc(x) for x in acmd]
|
3083
3129
|
|
3084
3130
|
t0 = time.time()
|
3085
3131
|
if fork:
|
3086
|
-
Daemon(runcmd,
|
3132
|
+
Daemon(runcmd, cmd, [bcmd], ka=sp_ka)
|
3087
3133
|
else:
|
3088
3134
|
rc, v, err = runcmd(bcmd, **sp_ka) # type: ignore
|
3089
3135
|
if chk and rc:
|
@@ -3104,6 +3150,7 @@ def runhook(
|
|
3104
3150
|
vp ,
|
3105
3151
|
host ,
|
3106
3152
|
uname ,
|
3153
|
+
perms ,
|
3107
3154
|
mt ,
|
3108
3155
|
sz ,
|
3109
3156
|
ip ,
|
@@ -3113,7 +3160,7 @@ def runhook(
|
|
3113
3160
|
vp = vp.replace("\\", "/")
|
3114
3161
|
for cmd in cmds:
|
3115
3162
|
try:
|
3116
|
-
if not _runhook(log, cmd, ap, vp, host, uname, mt, sz, ip, at, txt):
|
3163
|
+
if not _runhook(log, cmd, ap, vp, host, uname, perms, mt, sz, ip, at, txt):
|
3117
3164
|
return False
|
3118
3165
|
except Exception as ex:
|
3119
3166
|
(log or print)("hook: {}".format(ex))
|
copyparty/web/a/u2c.py
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
#!/usr/bin/env python3
|
2
2
|
from __future__ import print_function, unicode_literals
|
3
3
|
|
4
|
-
S_VERSION = "1.
|
5
|
-
S_BUILD_DT = "2024-
|
4
|
+
S_VERSION = "1.18"
|
5
|
+
S_BUILD_DT = "2024-06-01"
|
6
6
|
|
7
7
|
"""
|
8
8
|
u2c.py: upload to copyparty
|
@@ -1144,7 +1144,7 @@ source file/folder selection uses rsync syntax, meaning that:
|
|
1144
1144
|
ap.add_argument("url", type=unicode, help="server url, including destination folder")
|
1145
1145
|
ap.add_argument("files", type=unicode, nargs="+", help="files and/or folders to process")
|
1146
1146
|
ap.add_argument("-v", action="store_true", help="verbose")
|
1147
|
-
ap.add_argument("-a", metavar="
|
1147
|
+
ap.add_argument("-a", metavar="PASSWD", help="password or $filepath")
|
1148
1148
|
ap.add_argument("-s", action="store_true", help="file-search (disables upload)")
|
1149
1149
|
ap.add_argument("-x", type=unicode, metavar="REGEX", default="", help="skip file if filesystem-abspath matches REGEX, example: '.*/\\.hist/.*'")
|
1150
1150
|
ap.add_argument("--ok", action="store_true", help="continue even if some local files are inaccessible")
|
@@ -1162,8 +1162,8 @@ source file/folder selection uses rsync syntax, meaning that:
|
|
1162
1162
|
ap.add_argument("--drd", action="store_true", help="delete remote files during upload instead of afterwards; reduces peak disk space usage, but will reupload instead of detecting renames")
|
1163
1163
|
|
1164
1164
|
ap = app.add_argument_group("performance tweaks")
|
1165
|
-
ap.add_argument("-j", type=int, metavar="
|
1166
|
-
ap.add_argument("-J", type=int, metavar="
|
1165
|
+
ap.add_argument("-j", type=int, metavar="CONNS", default=2, help="parallel connections")
|
1166
|
+
ap.add_argument("-J", type=int, metavar="CORES", default=hcores, help="num cpu-cores to use for hashing; set 0 or 1 for single-core hashing")
|
1167
1167
|
ap.add_argument("-nh", action="store_true", help="disable hashing while uploading")
|
1168
1168
|
ap.add_argument("-ns", action="store_true", help="no status panel (for slow consoles and macos)")
|
1169
1169
|
ap.add_argument("--cd", type=float, metavar="SEC", default=5, help="delay before reattempting a failed handshake/upload")
|
@@ -1171,7 +1171,7 @@ source file/folder selection uses rsync syntax, meaning that:
|
|
1171
1171
|
ap.add_argument("-z", action="store_true", help="ZOOMIN' (skip uploading files if they exist at the destination with the ~same last-modified timestamp, so same as yolo / turbo with date-chk but even faster)")
|
1172
1172
|
|
1173
1173
|
ap = app.add_argument_group("tls")
|
1174
|
-
ap.add_argument("-te", metavar="
|
1174
|
+
ap.add_argument("-te", metavar="PATH", help="path to ca.pem or cert.pem to expect/verify")
|
1175
1175
|
ap.add_argument("-td", action="store_true", help="disable certificate check")
|
1176
1176
|
# fmt: on
|
1177
1177
|
|
@@ -1208,6 +1208,14 @@ source file/folder selection uses rsync syntax, meaning that:
|
|
1208
1208
|
ar.url = ar.url.rstrip("/") + "/"
|
1209
1209
|
if "://" not in ar.url:
|
1210
1210
|
ar.url = "http://" + ar.url
|
1211
|
+
|
1212
|
+
if "https://" in ar.url.lower():
|
1213
|
+
try:
|
1214
|
+
import ssl, zipfile
|
1215
|
+
except:
|
1216
|
+
t = "ERROR: https is not available for some reason; please use http"
|
1217
|
+
print("\n\n %s\n\n" % (t,))
|
1218
|
+
raise
|
1211
1219
|
|
1212
1220
|
if ar.a and ar.a.startswith("$"):
|
1213
1221
|
fn = ar.a[1:]
|
copyparty/web/baguettebox.js.gz
CHANGED
Binary file
|
copyparty/web/browser.css.gz
CHANGED
Binary file
|
copyparty/web/browser.js.gz
CHANGED
Binary file
|
copyparty/web/deps/marked.js.gz
CHANGED
Binary file
|
copyparty/web/md2.js.gz
CHANGED
Binary file
|
copyparty/web/ui.css.gz
CHANGED
Binary file
|
copyparty/web/util.js.gz
CHANGED
Binary file
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: copyparty
|
3
|
-
Version: 1.13.
|
3
|
+
Version: 1.13.4
|
4
4
|
Summary: Portable file server with accelerated resumable uploads, deduplication, WebDAV, FTP, zeroconf, media indexer, video thumbnails, audio transcoding, and write-only folders
|
5
5
|
Author-email: ed <copyparty@ocv.me>
|
6
6
|
License: MIT
|
@@ -46,7 +46,7 @@ Requires-Dist: pyopenssl ; extra == 'ftps'
|
|
46
46
|
Provides-Extra: pwhash
|
47
47
|
Requires-Dist: argon2-cffi ; extra == 'pwhash'
|
48
48
|
Provides-Extra: tftpd
|
49
|
-
Requires-Dist: partftpy >=0.
|
49
|
+
Requires-Dist: partftpy >=0.4.0 ; extra == 'tftpd'
|
50
50
|
Provides-Extra: thumbnails
|
51
51
|
Requires-Dist: Pillow ; extra == 'thumbnails'
|
52
52
|
Provides-Extra: thumbnails2
|
@@ -137,6 +137,8 @@ turn almost any device into a file server with resumable uploads/downloads using
|
|
137
137
|
* [reverse-proxy](#reverse-proxy) - running copyparty next to other websites
|
138
138
|
* [real-ip](#real-ip) - teaching copyparty how to see client IPs
|
139
139
|
* [prometheus](#prometheus) - metrics/stats can be enabled
|
140
|
+
* [other extremely specific features](#other-extremely-specific-features) - you'll never find a use for these
|
141
|
+
* [custom mimetypes](#custom-mimetypes) - change the association of a file extension
|
140
142
|
* [packages](#packages) - the party might be closer than you think
|
141
143
|
* [arch package](#arch-package) - now [available on aur](https://aur.archlinux.org/packages/copyparty) maintained by [@icxes](https://github.com/icxes)
|
142
144
|
* [fedora package](#fedora-package) - does not exist yet
|
@@ -627,6 +629,7 @@ it does static images with Pillow / pyvips / FFmpeg, and uses FFmpeg for video f
|
|
627
629
|
audio files are covnerted into spectrograms using FFmpeg unless you `--no-athumb` (and some FFmpeg builds may need `--th-ff-swr`)
|
628
630
|
|
629
631
|
images with the following names (see `--th-covers`) become the thumbnail of the folder they're in: `folder.png`, `folder.jpg`, `cover.png`, `cover.jpg`
|
632
|
+
* the order is significant, so if both `cover.png` and `folder.jpg` exist in a folder, it will pick the first matching `--th-covers` entry (`folder.jpg`)
|
630
633
|
* and, if you enable [file indexing](#file-indexing), it will also try those names as dotfiles (`.folder.jpg` and so), and then fallback on the first picture in the folder (if it has any pictures at all)
|
631
634
|
|
632
635
|
in the grid/thumbnail view, if the audio player panel is open, songs will start playing when clicked
|
@@ -634,6 +637,7 @@ in the grid/thumbnail view, if the audio player panel is open, songs will start
|
|
634
637
|
|
635
638
|
enabling `multiselect` lets you click files to select them, and then shift-click another file for range-select
|
636
639
|
* `multiselect` is mostly intended for phones/tablets, but the `sel` option in the `[⚙️] settings` tab is better suited for desktop use, allowing selection by CTRL-clicking and range-selection with SHIFT-click, all without affecting regular clicking
|
640
|
+
* the `sel` option can be made default globally with `--gsel` or per-volume with volflag `gsel`
|
637
641
|
|
638
642
|
|
639
643
|
## zip downloads
|
@@ -763,7 +767,7 @@ uploads can be given a lifetime, afer which they expire / self-destruct
|
|
763
767
|
|
764
768
|
the feature must be enabled per-volume with the `lifetime` [upload rule](#upload-rules) which sets the upper limit for how long a file gets to stay on the server
|
765
769
|
|
766
|
-
clients can specify a shorter expiration time using the [up2k ui](#uploading) -- the relevant options become visible upon navigating into a folder with `lifetimes` enabled -- or by using the `life` [upload modifier](#write)
|
770
|
+
clients can specify a shorter expiration time using the [up2k ui](#uploading) -- the relevant options become visible upon navigating into a folder with `lifetimes` enabled -- or by using the `life` [upload modifier](./docs/devnotes.md#write)
|
767
771
|
|
768
772
|
specifying a custom expiration time client-side will affect the timespan in which unposts are permitted, so keep an eye on the estimates in the up2k ui
|
769
773
|
|
@@ -931,6 +935,8 @@ see [./srv/expand/](./srv/expand/) for usage and examples
|
|
931
935
|
|
932
936
|
* files named `.prologue.html` / `.epilogue.html` will be rendered before/after directory listings unless `--no-logues`
|
933
937
|
|
938
|
+
* files named `descript.ion` / `DESCRIPT.ION` are parsed and displayed in the file listing, or as the epilogue if nonstandard
|
939
|
+
|
934
940
|
* files named `README.md` / `readme.md` will be rendered after directory listings unless `--no-readme` (but `.epilogue.html` takes precedence)
|
935
941
|
|
936
942
|
* `README.md` and `*logue.html` can contain placeholder values which are replaced server-side before embedding into directory listings; see `--help-exp`
|
@@ -1499,8 +1505,9 @@ you can either:
|
|
1499
1505
|
* or do location-based proxying, using `--rp-loc=/stuff` to tell copyparty where it is mounted -- has a slight performance cost and higher chance of bugs
|
1500
1506
|
* if copyparty says `incorrect --rp-loc or webserver config; expected vpath starting with [...]` it's likely because the webserver is stripping away the proxy location from the request URLs -- see the `ProxyPass` in the apache example below
|
1501
1507
|
|
1502
|
-
some reverse proxies (such as [Caddy](https://caddyserver.com/)) can automatically obtain a valid https/tls certificate for you, and some support HTTP/2 and QUIC which could be a nice speed boost
|
1503
|
-
* **warning:** nginx-QUIC is still experimental and can make uploads much slower, so HTTP/
|
1508
|
+
some reverse proxies (such as [Caddy](https://caddyserver.com/)) can automatically obtain a valid https/tls certificate for you, and some support HTTP/2 and QUIC which *could* be a nice speed boost, depending on a lot of factors
|
1509
|
+
* **warning:** nginx-QUIC (HTTP/3) is still experimental and can make uploads much slower, so HTTP/1.1 is recommended for now
|
1510
|
+
* depending on server/client, HTTP/1.1 can also be 5x faster than HTTP/2
|
1504
1511
|
|
1505
1512
|
example webserver configs:
|
1506
1513
|
|
@@ -1580,6 +1587,28 @@ the following options are available to disable some of the metrics:
|
|
1580
1587
|
note: the following metrics are counted incorrectly if multiprocessing is enabled with `-j`: `cpp_http_conns`, `cpp_http_reqs`, `cpp_sus_reqs`, `cpp_active_bans`, `cpp_total_bans`
|
1581
1588
|
|
1582
1589
|
|
1590
|
+
## other extremely specific features
|
1591
|
+
|
1592
|
+
you'll never find a use for these:
|
1593
|
+
|
1594
|
+
|
1595
|
+
### custom mimetypes
|
1596
|
+
|
1597
|
+
change the association of a file extension
|
1598
|
+
|
1599
|
+
using commandline args, you can do something like `--mime gif=image/jif` and `--mime ts=text/x.typescript` (can be specified multiple times)
|
1600
|
+
|
1601
|
+
in a config-file, this is the same as:
|
1602
|
+
|
1603
|
+
```yaml
|
1604
|
+
[global]
|
1605
|
+
mime: gif=image/jif
|
1606
|
+
mime: ts=text/x.typescript
|
1607
|
+
```
|
1608
|
+
|
1609
|
+
run copyparty with `--mimes` to list all the default mappings
|
1610
|
+
|
1611
|
+
|
1583
1612
|
# packages
|
1584
1613
|
|
1585
1614
|
the party might be closer than you think
|
@@ -1829,6 +1858,8 @@ alternatively, some alternatives roughly sorted by speed (unreproducible benchma
|
|
1829
1858
|
|
1830
1859
|
most clients will fail to mount the root of a copyparty server unless there is a root volume (so you get the admin-panel instead of a browser when accessing it) -- in that case, mount a specific volume instead
|
1831
1860
|
|
1861
|
+
if you have volumes that are accessible without a password, then some webdav clients (such as davfs2) require the global-option `--dav-auth` to access any password-protected areas
|
1862
|
+
|
1832
1863
|
|
1833
1864
|
# android app
|
1834
1865
|
|
@@ -1857,6 +1888,7 @@ defaults are usually fine - expect `8 GiB/s` download, `1 GiB/s` upload
|
|
1857
1888
|
|
1858
1889
|
below are some tweaks roughly ordered by usefulness:
|
1859
1890
|
|
1891
|
+
* disabling HTTP/2 and HTTP/3 can make uploads 5x faster, depending on server/client software
|
1860
1892
|
* `-q` disables logging and can help a bunch, even when combined with `-lo` to redirect logs to file
|
1861
1893
|
* `--hist` pointing to a fast location (ssd) will make directory listings and searches faster when `-e2d` or `-e2t` is set
|
1862
1894
|
* and also makes thumbnails load faster, regardless of e2d/e2t
|
@@ -1972,7 +2004,7 @@ volflag `dk` generates dirkeys (per-directory accesskeys) for all folders, grant
|
|
1972
2004
|
|
1973
2005
|
volflag `dky` disables the actual key-check, meaning anyone can see the contents of a folder where they have `g` access, but not its subdirectories
|
1974
2006
|
|
1975
|
-
* `dk` + `dky` gives the same behavior as if all users with `g` access have full read-access, but subfolders are hidden files (their names start with a dot), so `dky` is an alternative to renaming all the folders for that purpose, maybe just for some users
|
2007
|
+
* `dk` + `dky` gives the same behavior as if all users with `g` access have full read-access, but subfolders are hidden files (as if their names start with a dot), so `dky` is an alternative to renaming all the folders for that purpose, maybe just for some users
|
1976
2008
|
|
1977
2009
|
volflag `dks` lets people enter subfolders as well, and also enables download-as-zip/tar
|
1978
2010
|
|
@@ -1997,7 +2029,7 @@ the default configs take about 0.4 sec and 256 MiB RAM to process a new password
|
|
1997
2029
|
|
1998
2030
|
both HTTP and HTTPS are accepted by default, but letting a [reverse proxy](#reverse-proxy) handle the https/tls/ssl would be better (probably more secure by default)
|
1999
2031
|
|
2000
|
-
copyparty doesn't speak HTTP/2 or QUIC, so using a reverse proxy would solve that as well
|
2032
|
+
copyparty doesn't speak HTTP/2 or QUIC, so using a reverse proxy would solve that as well -- but note that HTTP/1 is usually faster than both HTTP/2 and HTTP/3
|
2001
2033
|
|
2002
2034
|
if [cfssl](https://github.com/cloudflare/cfssl/releases/latest) is installed, copyparty will automatically create a CA and server-cert on startup
|
2003
2035
|
* the certs are written to `--crt-dir` for distribution, see `--help` for the other `--crt` options
|
@@ -1,38 +1,38 @@
|
|
1
1
|
copyparty/__init__.py,sha256=fUINM1abqDGzCCH_JcXdOnLdKOV-SrTI2Xo2QgQW2P4,1703
|
2
|
-
copyparty/__main__.py,sha256=
|
3
|
-
copyparty/__version__.py,sha256=
|
4
|
-
copyparty/authsrv.py,sha256=
|
2
|
+
copyparty/__main__.py,sha256=a-eBYg8AECvPEL_h1lcZjAZKhCvZz2dDx5SqmtMMk7k,102946
|
3
|
+
copyparty/__version__.py,sha256=0_JOXMP41MdpQA_5KH0BM5QcsQS9UdNppnA-U2PJYpE,255
|
4
|
+
copyparty/authsrv.py,sha256=zCo1-CmE2UhsnSRFqALTu1GBO6FVlo1l7Ex7PCv52Xg,87191
|
5
5
|
copyparty/broker_mp.py,sha256=YFe1S6Zziht8Qc__dCLj_ff8z0DDny9lqk_Mi5ajsJk,3868
|
6
6
|
copyparty/broker_mpw.py,sha256=4ZI7bJYOwUibeAJVv9_FPGNmHrr9eOtkj_Kz0JEppTU,3197
|
7
7
|
copyparty/broker_thr.py,sha256=eKr--HJGig5zqvNGwH9UoBG9Nvi9mT2axrRmJwknd0s,1759
|
8
8
|
copyparty/broker_util.py,sha256=CnX_LAhQQqouONcDLtVkVlcBX3Z6pWuKDQDmmbHGEg4,1489
|
9
|
-
copyparty/cert.py,sha256=
|
10
|
-
copyparty/cfg.py,sha256=
|
9
|
+
copyparty/cert.py,sha256=BVMXKRzr1du0WgGifh_HrM-NEuezlgPDejaY3UaQUQ0,7728
|
10
|
+
copyparty/cfg.py,sha256=i8-bjWgbguQooxiA172RcptqR_SEOwDHJ4cqldrZ8oQ,9792
|
11
11
|
copyparty/dxml.py,sha256=lZpg-kn-kQsXRtNY1n6fRaS-b7uXzMCyv8ovKnhZcZc,1548
|
12
12
|
copyparty/fsutil.py,sha256=NEdhYYgQxDQ7MmgTbtjMKorikCjDls2AXVX16EH2JfQ,4613
|
13
|
-
copyparty/ftpd.py,sha256=
|
14
|
-
copyparty/httpcli.py,sha256=
|
13
|
+
copyparty/ftpd.py,sha256=g9FDgoIV5DncmkovIo9C2jowtS6SmGX4Wgw44rWqM5g,17192
|
14
|
+
copyparty/httpcli.py,sha256=Z-wBQm7S4oT8UIZ546gk2LjMs4de-IDlthQDh2dJ4xw,168541
|
15
15
|
copyparty/httpconn.py,sha256=6MOQgBtOGrlVRr6ZiHBKYzkzcls-YWwaWEtqE6DweM0,6873
|
16
|
-
copyparty/httpsrv.py,sha256=
|
16
|
+
copyparty/httpsrv.py,sha256=U9CYy_5eK-VO1QZPeiybHUm9MD7-FZXAo22IZsEUErA,16369
|
17
17
|
copyparty/ico.py,sha256=AYHdK6NlYBfBgafVYXia3jHQ9XHZdUL1D8WftLMAzIU,3545
|
18
|
-
copyparty/mdns.py,sha256=
|
18
|
+
copyparty/mdns.py,sha256=vC078llnL1v0pvL3mnwacuStFHPJUQuxo9Opj-IbHL4,18155
|
19
19
|
copyparty/metrics.py,sha256=O8qiPNDxNjub_PI8C8Qu9rBQ_z0J1mnKonqkcTeAtf4,8845
|
20
|
-
copyparty/mtag.py,sha256=
|
20
|
+
copyparty/mtag.py,sha256=cgreqKD_VwP0Gw94gqlmSHE0gZqjJw3NGx3nfFu5UiU,18676
|
21
21
|
copyparty/multicast.py,sha256=Ha27l2oATEa-Qo2WOzkeRgjAm6G_YDCfbVJWR-ao2UE,12319
|
22
22
|
copyparty/pwhash.py,sha256=D82y8emnwpHDQq7Cr8lNuppHshbNA9ptcR2XsGOOk6E,3937
|
23
|
-
copyparty/smbd.py,sha256=
|
24
|
-
copyparty/ssdp.py,sha256=
|
25
|
-
copyparty/star.py,sha256=
|
26
|
-
copyparty/sutil.py,sha256=
|
27
|
-
copyparty/svchub.py,sha256=
|
28
|
-
copyparty/szip.py,sha256=
|
29
|
-
copyparty/tcpsrv.py,sha256=
|
30
|
-
copyparty/tftpd.py,sha256=
|
31
|
-
copyparty/th_cli.py,sha256=
|
32
|
-
copyparty/th_srv.py,sha256=
|
23
|
+
copyparty/smbd.py,sha256=RW-8xoKlrR3PbNdd1q72uYGwI7USMl93eVPqC0HYCic,14066
|
24
|
+
copyparty/ssdp.py,sha256=SiIGQ0FMFa0RM40GIEvkOTT0DMnKwZIy51a-ZDzLNxM,7045
|
25
|
+
copyparty/star.py,sha256=tV5BbX6AiQ7N4UU8DYtSTckNYeoeey4DBqq4LjfymbY,3818
|
26
|
+
copyparty/sutil.py,sha256=xTw2jTrF3m3EXeh6E5Th810Axx5xVeMBNElkSwGb-Bo,3214
|
27
|
+
copyparty/svchub.py,sha256=JbWbypa7OyYkJgsUTo0SRhgvb4WT4B1zDNi110Fuvl0,32743
|
28
|
+
copyparty/szip.py,sha256=5xbfbnTKt97c59pZD_nAzWEYpMel7xFDuGUjj60VjOs,8619
|
29
|
+
copyparty/tcpsrv.py,sha256=ssomz8MUjX62Yf6oDovH-Fzxi-9rZF6JFvsdDgGEho0,17680
|
30
|
+
copyparty/tftpd.py,sha256=GkO1jN08ufPDcO2dri1VfvcDKcMW7x1RtL2Rj0SrN3o,12983
|
31
|
+
copyparty/th_cli.py,sha256=JBazIKlw8oQXW2FLzqjokjqTk33c9V4Ke7Nx5ovoN-M,4560
|
32
|
+
copyparty/th_srv.py,sha256=tbRoaIb9WtUdVwjysxMYDbbEpRNvVwTh2Kj-_vCRbg8,28391
|
33
33
|
copyparty/u2idx.py,sha256=uEUcEbye1jzGlQfEJkLtD060XA6Rv_6lXLgeg6oAU5M,13033
|
34
|
-
copyparty/up2k.py,sha256=
|
35
|
-
copyparty/util.py,sha256=
|
34
|
+
copyparty/up2k.py,sha256=s307fRFB-hBbczzEq6MazsGLW1tIMcAxq0p-5uaSrGA,145406
|
35
|
+
copyparty/util.py,sha256=ABexTMTe6S52-Ii9pixQHKtRa1JvSW0yUgq_s9q7O1s,84960
|
36
36
|
copyparty/bos/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
37
37
|
copyparty/bos/bos.py,sha256=Wb7eWsXJgR5AFlBR9ZOyKrLTwy-Kct9RrGiOu4Jo37Y,1622
|
38
38
|
copyparty/bos/path.py,sha256=yEjCq2ki9CvxA5sCT8pS0keEXwugs0ZeUyUhdBziOCI,777
|
@@ -54,10 +54,10 @@ copyparty/stolen/ifaddr/__init__.py,sha256=_BUN7eM5oD2Jgib6B22tEFSb20fD9urNPPaAl
|
|
54
54
|
copyparty/stolen/ifaddr/_posix.py,sha256=-67NdfGrCktfQPakT2fLbjl2U00QMvyBGkSvrUuTOrU,2626
|
55
55
|
copyparty/stolen/ifaddr/_shared.py,sha256=cJACl8cOxQ-HSYphZTzKMAjAx_TAFyJwUPjfD102Xqw,6111
|
56
56
|
copyparty/stolen/ifaddr/_win32.py,sha256=EE-QyoBgeB7lYQ6z62VjXNaRozaYfCkaJBHGNA8QtZM,4026
|
57
|
-
copyparty/web/baguettebox.js.gz,sha256=
|
58
|
-
copyparty/web/browser.css.gz,sha256=
|
57
|
+
copyparty/web/baguettebox.js.gz,sha256=hIlIpULK0O1MFPs2LNuyoRXMgRVYSvA5Db8eeVB8CSU,7909
|
58
|
+
copyparty/web/browser.css.gz,sha256=8AZ53KZ-fWInji7m-eGNrwdZbWEeLmyjwg1V23ON6Mc,11539
|
59
59
|
copyparty/web/browser.html,sha256=-tLasq2GKe9mUceqXG4PczQ7odBMrX0qlWuyaA9SjPI,4882
|
60
|
-
copyparty/web/browser.js.gz,sha256=
|
60
|
+
copyparty/web/browser.js.gz,sha256=sX93k2srZkfPc7FJpcx-pZrBYPq6V3CbMWhB-HMbHfk,68977
|
61
61
|
copyparty/web/browser2.html,sha256=ciQlgr9GWuIapdsRBFNRvRFvN5T_5n920LqDMbsj5-g,1605
|
62
62
|
copyparty/web/cf.html,sha256=lJThtNFNAQT1ClCHHlivAkDGE0LutedwopXD62Z8Nys,589
|
63
63
|
copyparty/web/dbg-audio.js.gz,sha256=Ma-KZtK8LnmiwNvNKFKXMPYl_Nn_3U7GsJ6-DRWC2HE,688
|
@@ -65,7 +65,7 @@ copyparty/web/md.css.gz,sha256=UZpN0J7ubVM05CZkbZYkQRJeGgJt_GNDEzKTGSQd8h4,2032
|
|
65
65
|
copyparty/web/md.html,sha256=35oLUnDYsAdiW7Zg-iKFEXzEl_bGbnoAxUrNgJL46_o,4119
|
66
66
|
copyparty/web/md.js.gz,sha256=AHRQ3a-PZq_UiGh4CjNwXRllJCvA0IqqYmeHhFWhCig,4179
|
67
67
|
copyparty/web/md2.css.gz,sha256=uIVHKScThdbcfhXNSHgKZnALYpxbnXC-WuEzOJ20Lpc,699
|
68
|
-
copyparty/web/md2.js.gz,sha256=
|
68
|
+
copyparty/web/md2.js.gz,sha256=0fTA3lahQ1iDvJR4Q3W9v8dX5hc5VP8nunTtoDwFySs,8363
|
69
69
|
copyparty/web/mde.css.gz,sha256=2SkAEDKIRPqywNJ8t_heQaeBQ_R73Rf-pQI_bDoKF6o,942
|
70
70
|
copyparty/web/mde.html,sha256=v0MsEinom5LmZzUM-Ht26IEUkrFzMX57XpCyIQXctAg,1687
|
71
71
|
copyparty/web/mde.js.gz,sha256=kN2eUSvr4mFuksfK4-4LimJmWdwsao39Sea2lWtu8L0,2224
|
@@ -76,13 +76,13 @@ copyparty/web/splash.html,sha256=z5OrfZqA5RBxeY86BJiQ5NZNHIIDHDvPlTuht-Q0v64,391
|
|
76
76
|
copyparty/web/splash.js.gz,sha256=P4BLL_SBqfqWniq_gzUD-opVAkblAPgKDwmfxyfDB7o,1469
|
77
77
|
copyparty/web/svcs.html,sha256=Lniv3ndzV1ALGOdvMNKg6za5rafrqltuwoknYbExRxM,11711
|
78
78
|
copyparty/web/svcs.js.gz,sha256=k81ZvZ3I-f4fMHKrNGGOgOlvXnCBz0mVjD-8mieoWCA,520
|
79
|
-
copyparty/web/ui.css.gz,sha256=
|
79
|
+
copyparty/web/ui.css.gz,sha256=u9GiLVb1q5qY3CytUNVNXcieDBtkkHsJ0kgfELcE0Jc,2619
|
80
80
|
copyparty/web/up2k.js.gz,sha256=3IKVXjZq7byJWFKyHVylIIbWozsJ6IL7CrOUCibE8BY,22114
|
81
|
-
copyparty/web/util.js.gz,sha256=
|
81
|
+
copyparty/web/util.js.gz,sha256=wi_FGprem8zUqob0jV7oMKFM7ewFLbA8wmPyOHGqip0,14433
|
82
82
|
copyparty/web/w.hash.js.gz,sha256=__hBMd5oZWfTrb8ZCJNT21isoSqyrxKE6qdaKGQVAhc,1060
|
83
83
|
copyparty/web/a/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
84
84
|
copyparty/web/a/partyfuse.py,sha256=MuRkaSuYsdfWfBFMOkbPwDXqSvNTw3sd7QhhlKCDZ8I,32311
|
85
|
-
copyparty/web/a/u2c.py,sha256=
|
85
|
+
copyparty/web/a/u2c.py,sha256=Oj80BztQ9bNKP5invrLq99q7Wxw8PTiKAuUvn7lU2Rw,39040
|
86
86
|
copyparty/web/a/webdav-cfg.bat,sha256=Y4NoGZlksAIg4cBMb7KdJrpKC6Nx97onaTl6yMjaimk,1449
|
87
87
|
copyparty/web/dd/2.png,sha256=gJ14XFPzaw95L6z92fSq9eMPikSQyu-03P1lgiGe0_I,258
|
88
88
|
copyparty/web/dd/3.png,sha256=4lho8Koz5tV7jJ4ODo6GMTScZfkqsT05yp48EDFIlyg,252
|
@@ -93,7 +93,7 @@ copyparty/web/deps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuF
|
|
93
93
|
copyparty/web/deps/busy.mp3.gz,sha256=EVphk1_HYyRKJmtpeK99vbAstF7ub1f9ndu020H8PQ8,106
|
94
94
|
copyparty/web/deps/easymde.css.gz,sha256=vWxfueI64rPikuqFj69wJBtGisqf93AheQtOZqgUI_c,3041
|
95
95
|
copyparty/web/deps/easymde.js.gz,sha256=1FykpDM7_FiL4EeZAg4Qcggjoo4PE_MBTgRcBWvjD90,77000
|
96
|
-
copyparty/web/deps/marked.js.gz,sha256=
|
96
|
+
copyparty/web/deps/marked.js.gz,sha256=ypjwRuBtfOmty7esebDfCjkRP2rEMxnHNxpVufVzTiM,22520
|
97
97
|
copyparty/web/deps/mini-fa.css.gz,sha256=CTPrNaH8OTVmxajrGP88E2MkjadY9_81TBVnd9sw9Y8,572
|
98
98
|
copyparty/web/deps/mini-fa.woff,sha256=L9DNncV2TIyvsrspMbJouvnnt7F068Hbn7YZYvN76AU,2784
|
99
99
|
copyparty/web/deps/prism.css.gz,sha256=Z_A6rJ3MN5KWnjvXaV787aTW_5DT-xjFd0YZ7_W-Krk,1468
|
@@ -102,9 +102,9 @@ copyparty/web/deps/prismd.css.gz,sha256=ObUlksQVr-OuYlTz-I4B23TeBg2QDVVGRnWBz8cV
|
|
102
102
|
copyparty/web/deps/scp.woff2,sha256=w99BDU5i8MukkMEL-iW0YO9H4vFFZSPWxbkH70ytaAg,8612
|
103
103
|
copyparty/web/deps/sha512.ac.js.gz,sha256=lFZaCLumgWxrvEuDr4bqdKHsqjX82AbVAb7_F45Yk88,7033
|
104
104
|
copyparty/web/deps/sha512.hw.js.gz,sha256=vqoXeracj-99Z5MfY3jK2N4WiSzYQdfjy0RnUlQDhSU,8110
|
105
|
-
copyparty-1.13.
|
106
|
-
copyparty-1.13.
|
107
|
-
copyparty-1.13.
|
108
|
-
copyparty-1.13.
|
109
|
-
copyparty-1.13.
|
110
|
-
copyparty-1.13.
|
105
|
+
copyparty-1.13.4.dist-info/LICENSE,sha256=gOr4h33pCsBEg9uIy9AYmb7qlocL4V9t2uPJS5wllr0,1072
|
106
|
+
copyparty-1.13.4.dist-info/METADATA,sha256=nmidSmZzny9bEM64326-Hvs4o47TRSibX5B68fgy5_c,124011
|
107
|
+
copyparty-1.13.4.dist-info/WHEEL,sha256=Z4pYXqR_rTB7OWNDYFOm1qRk0RX6GFP2o8LgvP453Hk,91
|
108
|
+
copyparty-1.13.4.dist-info/entry_points.txt,sha256=4zw6a3rqASywQomiYLObjjlxybaI65LYYOTJwgKz7b0,128
|
109
|
+
copyparty-1.13.4.dist-info/top_level.txt,sha256=LnYUPsDyk-8kFgM6YJLG4h820DQekn81cObKSu9g-sI,10
|
110
|
+
copyparty-1.13.4.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|