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/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 ["B", "KiB", "MiB", "GiB", "TiB"]:
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
- select.select([], [out_fd], [], 10)
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
- cmd = os.path.expandvars(os.path.expanduser(cmd))
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, cmd
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
- ocmd = cmd
3006
- chk, fork, jtxt, wait, sp_ka, cmd = _parsehook(log, cmd)
3007
- bcmd = [sfsenc(cmd)]
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, ocmd, [bcmd], ka=sp_ka)
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
- ocmd = cmd
3061
- chk, fork, jtxt, wait, sp_ka, cmd = _parsehook(log, cmd)
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 = [cmd, arg]
3079
- if cmd.endswith(".py"):
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, ocmd, [bcmd], ka=sp_ka)
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.17"
5
- S_BUILD_DT = "2024-05-09"
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="PASSWORD", help="password or $filepath")
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="THREADS", default=4, help="parallel connections")
1166
- ap.add_argument("-J", type=int, metavar="THREADS", default=hcores, help="num cpu-cores to use for hashing; set 0 or 1 for single-core hashing")
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="PEM_FILE", help="certificate to expect/verify")
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:]
Binary file
Binary file
Binary file
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.2
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.3.1 ; extra == 'tftpd'
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/2 is recommended for now
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=eHd9z3x3VWKFULKcb37iBuWCUbYDRokq1UFjGHI5njU,99846
3
- copyparty/__version__.py,sha256=HXaSfRCwDZ1gm9Ow7Po9NDC2KxGntKPiZkjTR_ujvpM,255
4
- copyparty/authsrv.py,sha256=4YPt9_VqqcDAdaur4JN809jKUlpAyamVe-1JaeMUkOQ,85177
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=nCeDdzcCpvjPPUcxT4Oh7wvL_8zvddu4oXtbA-zOb8g,7607
10
- copyparty/cfg.py,sha256=gdsFudDxliRNwYm1YdImO5miWzyDQ2i1vHRMkokxCm0,9643
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=OIExjfqOEw-Y_ygez6cIZUQec4SFOmoxEH_WOVvw-aE,15961
14
- copyparty/httpcli.py,sha256=wif37Oa89iAer5sIMoZPWChyWif80AFH7lOaG00h2z0,164293
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=RpROXBJPgTXmwFbLYrAT15ovGYkIMrksluuetKWAJTM,16356
16
+ copyparty/httpsrv.py,sha256=U9CYy_5eK-VO1QZPeiybHUm9MD7-FZXAo22IZsEUErA,16369
17
17
  copyparty/ico.py,sha256=AYHdK6NlYBfBgafVYXia3jHQ9XHZdUL1D8WftLMAzIU,3545
18
- copyparty/mdns.py,sha256=CcraggbDxTT1ntYzD8Ebgqmw5Q4HkyZcfh5ymtCV_ak,17469
18
+ copyparty/mdns.py,sha256=vC078llnL1v0pvL3mnwacuStFHPJUQuxo9Opj-IbHL4,18155
19
19
  copyparty/metrics.py,sha256=O8qiPNDxNjub_PI8C8Qu9rBQ_z0J1mnKonqkcTeAtf4,8845
20
- copyparty/mtag.py,sha256=MpRkwAj_OAhE9alRzYMyoyPUtedSIuBmVxhCkLaIpMA,18593
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=CwsjLzwfIkqY9Fr_w7po_giO2tnXq9_7bdjIBNdiuTY,14062
24
- copyparty/ssdp.py,sha256=H6ZftXttydcnBxcg2-Prm4P-XiybgT3xiJRUXU1pbrE,6343
25
- copyparty/star.py,sha256=K4NuzyfT4956uoW6GJSQ2II-JsSV57apQZwRZ4mjFoo,3790
26
- copyparty/sutil.py,sha256=_G4TM0YFa1vXzhRypHJ88QBdZWtYgDbom4CZjGvGIwc,3074
27
- copyparty/svchub.py,sha256=v81cj-KQ3P7pLcV4sOWEjJSpGdjseZ2tpqL4VruPtmI,32661
28
- copyparty/szip.py,sha256=631TsEwGKV22yAnusJtvE-9fGFWr61HPGBinu-jk1QA,8591
29
- copyparty/tcpsrv.py,sha256=ym6rda7svl_M4DjNesHMI1_6wO7Csu01UV1zGzXEMxI,17637
30
- copyparty/tftpd.py,sha256=7EHAZ9LnjAXupwRNIENJ2eA8Q0lFynnwwbziV3fyzns,13157
31
- copyparty/th_cli.py,sha256=VO2Eo0SGwgSJaHowMLeX3_vxEdQcQh5RFDSf0OraTTw,4568
32
- copyparty/th_srv.py,sha256=utK8kA1mlYI0BsAdLL-l0-51gXoIN0BS5zQkGAcERXg,28041
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=hhh7PrUzRgnlvsapwjG1-X6_bqI51r3Tf5zo4jLvveU,143330
35
- copyparty/util.py,sha256=w22CaPQy0Otq8sJMt9hCPpRbKM2sRLTQtBYAE6DTaHQ,83744
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=HdRHC_4Lvepp1DrRwusdcxvAn8IKGMdrKdggGIshKek,7869
58
- copyparty/web/browser.css.gz,sha256=GGyPK9BBOX63x9XWqO2jrXewHtfAeZ-Jo0BBxqTOGUM,11491
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=Lci32Xx_OxmC9bjEuiQSzfMrb8UGj9Qg5j2D7kOcFjY,68838
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=8xLixaTfTXC808538OOSLhp9AqKowYaunjDeBsbiBEw,8350
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=skuzZHqTU0ag5hButpQmKI9wM7ro-UJ2PnpTodTWYF4,2616
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=eNRKtW7fM9AvipRdJGQyy9mbQIqMda73o8Bo64UWr7s,14416
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=mCVYSJo6wSiPrT_p7QxlIoIGSclcC7qw4COcIaAKS-w,38791
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=elpt4-fI9Fs5zgMYxHuQn7XL4MXMBfINU4WQ0sBF5HY,22582
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.2.dist-info/LICENSE,sha256=gOr4h33pCsBEg9uIy9AYmb7qlocL4V9t2uPJS5wllr0,1072
106
- copyparty-1.13.2.dist-info/METADATA,sha256=mqJMKOtNHic9_FIsW46owpSjsmGYFLF7pUSwjzIQZyg,122479
107
- copyparty-1.13.2.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
108
- copyparty-1.13.2.dist-info/entry_points.txt,sha256=4zw6a3rqASywQomiYLObjjlxybaI65LYYOTJwgKz7b0,128
109
- copyparty-1.13.2.dist-info/top_level.txt,sha256=LnYUPsDyk-8kFgM6YJLG4h820DQekn81cObKSu9g-sI,10
110
- copyparty-1.13.2.dist-info/RECORD,,
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,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.43.0)
2
+ Generator: setuptools (70.3.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5