copyparty 1.13.3__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/up2k.py CHANGED
@@ -651,7 +651,7 @@ class Up2k(object):
651
651
  return False, flags
652
652
 
653
653
  ret = {k: v for k, v in flags.items() if not k.startswith("e2t")}
654
- if ret.keys() == flags.keys():
654
+ if len(ret) == len(flags):
655
655
  return False, flags
656
656
 
657
657
  return True, ret
@@ -1192,6 +1192,9 @@ class Up2k(object):
1192
1192
  fat32 = True
1193
1193
  cv = ""
1194
1194
 
1195
+ th_cvd = self.args.th_coversd
1196
+ th_cvds = self.args.th_coversd_set
1197
+
1195
1198
  assert self.pp and self.mem_cur
1196
1199
  self.pp.msg = "a%d %s" % (self.pp.n, cdir)
1197
1200
 
@@ -1276,12 +1279,21 @@ class Up2k(object):
1276
1279
 
1277
1280
  files.append((sz, lmod, iname))
1278
1281
  liname = iname.lower()
1279
- if sz and (
1280
- iname in self.args.th_coversd
1281
- or (
1282
+ if (
1283
+ sz
1284
+ and (
1285
+ liname in th_cvds
1286
+ or (
1287
+ not cv
1288
+ and liname.rsplit(".", 1)[-1] in CV_EXTS
1289
+ and not iname.startswith(".")
1290
+ )
1291
+ )
1292
+ and (
1282
1293
  not cv
1283
- and liname.rsplit(".", 1)[-1] in CV_EXTS
1284
- and not iname.startswith(".")
1294
+ or liname not in th_cvds
1295
+ or cv.lower() not in th_cvds
1296
+ or th_cvd.index(iname) < th_cvd.index(cv)
1285
1297
  )
1286
1298
  ):
1287
1299
  cv = iname
@@ -2755,6 +2767,7 @@ class Up2k(object):
2755
2767
  job["vtop"],
2756
2768
  job["host"],
2757
2769
  job["user"],
2770
+ self.asrv.vfs.get_perms(job["vtop"], job["user"]),
2758
2771
  job["lmod"],
2759
2772
  job["size"],
2760
2773
  job["addr"],
@@ -3077,7 +3090,7 @@ class Up2k(object):
3077
3090
 
3078
3091
  return ret, dst
3079
3092
 
3080
- def finish_upload(self, ptop , wark , busy_aps ) :
3093
+ def finish_upload(self, ptop , wark , busy_aps ) :
3081
3094
  self.busy_aps = busy_aps
3082
3095
  with self.mutex, self.reg_mutex:
3083
3096
  self._finish_upload(ptop, wark)
@@ -3282,6 +3295,7 @@ class Up2k(object):
3282
3295
  djoin(vtop, rd, fn),
3283
3296
  host,
3284
3297
  usr,
3298
+ self.asrv.vfs.get_perms(djoin(vtop, rd, fn), usr),
3285
3299
  int(ts),
3286
3300
  sz,
3287
3301
  ip,
@@ -3316,15 +3330,29 @@ class Up2k(object):
3316
3330
  with self.rescan_cond:
3317
3331
  self.rescan_cond.notify_all()
3318
3332
 
3319
- if rd and sz and fn.lower() in self.args.th_coversd:
3333
+ if rd and sz and fn.lower() in self.args.th_coversd_set:
3320
3334
  # wasteful; db_add will re-index actual covers
3321
3335
  # but that won't catch existing files
3322
3336
  crd, cdn = rd.rsplit("/", 1) if "/" in rd else ("", rd)
3323
3337
  try:
3324
- db.execute("delete from cv where rd=? and dn=?", (crd, cdn))
3325
- db.execute("insert into cv values (?,?,?)", (crd, cdn, fn))
3338
+ q = "select fn from cv where rd=? and dn=?"
3339
+ db_cv = db.execute(q, (crd, cdn)).fetchone()[0]
3340
+ db_lcv = db_cv.lower()
3341
+ if db_lcv in self.args.th_coversd_set:
3342
+ idx_db = self.args.th_coversd.index(db_lcv)
3343
+ idx_fn = self.args.th_coversd.index(fn.lower())
3344
+ add_cv = idx_fn < idx_db
3345
+ else:
3346
+ add_cv = True
3326
3347
  except:
3327
- pass
3348
+ add_cv = True
3349
+
3350
+ if add_cv:
3351
+ try:
3352
+ db.execute("delete from cv where rd=? and dn=?", (crd, cdn))
3353
+ db.execute("insert into cv values (?,?,?)", (crd, cdn, fn))
3354
+ except:
3355
+ pass
3328
3356
 
3329
3357
  def handle_rm(
3330
3358
  self,
@@ -3467,6 +3495,7 @@ class Up2k(object):
3467
3495
  vpath,
3468
3496
  "",
3469
3497
  uname,
3498
+ self.asrv.vfs.get_perms(vpath, uname),
3470
3499
  stl.st_mtime,
3471
3500
  st.st_size,
3472
3501
  ip,
@@ -3500,6 +3529,7 @@ class Up2k(object):
3500
3529
  vpath,
3501
3530
  "",
3502
3531
  uname,
3532
+ self.asrv.vfs.get_perms(vpath, uname),
3503
3533
  stl.st_mtime,
3504
3534
  st.st_size,
3505
3535
  ip,
@@ -3632,7 +3662,18 @@ class Up2k(object):
3632
3662
  xar = dvn.flags.get("xar")
3633
3663
  if xbr:
3634
3664
  if not runhook(
3635
- self.log, xbr, sabs, svp, "", uname, stl.st_mtime, st.st_size, "", 0, ""
3665
+ self.log,
3666
+ xbr,
3667
+ sabs,
3668
+ svp,
3669
+ "",
3670
+ uname,
3671
+ self.asrv.vfs.get_perms(svp, uname),
3672
+ stl.st_mtime,
3673
+ st.st_size,
3674
+ "",
3675
+ 0,
3676
+ "",
3636
3677
  ):
3637
3678
  t = "move blocked by xbr server config: {}".format(svp)
3638
3679
  self.log(t, 1)
@@ -3657,7 +3698,20 @@ class Up2k(object):
3657
3698
  self.rescan_cond.notify_all()
3658
3699
 
3659
3700
  if xar:
3660
- runhook(self.log, xar, dabs, dvp, "", uname, 0, 0, "", 0, "")
3701
+ runhook(
3702
+ self.log,
3703
+ xar,
3704
+ dabs,
3705
+ dvp,
3706
+ "",
3707
+ uname,
3708
+ self.asrv.vfs.get_perms(dvp, uname),
3709
+ 0,
3710
+ 0,
3711
+ "",
3712
+ 0,
3713
+ "",
3714
+ )
3661
3715
 
3662
3716
  return "k"
3663
3717
 
@@ -3756,7 +3810,20 @@ class Up2k(object):
3756
3810
  wunlink(self.log, sabs, svn.flags)
3757
3811
 
3758
3812
  if xar:
3759
- runhook(self.log, xar, dabs, dvp, "", uname, 0, 0, "", 0, "")
3813
+ runhook(
3814
+ self.log,
3815
+ xar,
3816
+ dabs,
3817
+ dvp,
3818
+ "",
3819
+ uname,
3820
+ self.asrv.vfs.get_perms(dvp, uname),
3821
+ 0,
3822
+ 0,
3823
+ "",
3824
+ 0,
3825
+ "",
3826
+ )
3760
3827
 
3761
3828
  return "k"
3762
3829
 
@@ -4045,6 +4112,7 @@ class Up2k(object):
4045
4112
  vp_chk,
4046
4113
  job["host"],
4047
4114
  job["user"],
4115
+ self.asrv.vfs.get_perms(vp_chk, job["user"]),
4048
4116
  int(job["lmod"]),
4049
4117
  job["size"],
4050
4118
  job["addr"],
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"],
@@ -2437,6 +2450,9 @@ def build_netmap(csv ):
2437
2450
  csv += ", 127.0.0.0/8, ::1/128" # loopback
2438
2451
 
2439
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
+
2440
2456
  cidrs = []
2441
2457
  for zs in srcs:
2442
2458
  if not zs.endswith("."):
@@ -2955,7 +2971,8 @@ def retchk(
2955
2971
 
2956
2972
  def _parsehook(
2957
2973
  log , cmd
2958
- ) :
2974
+ ) :
2975
+ areq = ""
2959
2976
  chk = False
2960
2977
  fork = False
2961
2978
  jtxt = False
@@ -2980,8 +2997,12 @@ def _parsehook(
2980
2997
  cap = int(arg[1:]) # 0=none 1=stdout 2=stderr 3=both
2981
2998
  elif arg.startswith("k"):
2982
2999
  kill = arg[1:] # [t]ree [m]ain [n]one
3000
+ elif arg.startswith("a"):
3001
+ areq = arg[1:] # required perms
2983
3002
  elif arg.startswith("i"):
2984
3003
  pass
3004
+ elif not arg:
3005
+ break
2985
3006
  else:
2986
3007
  t = "hook: invalid flag {} in {}"
2987
3008
  (log or print)(t.format(arg, ocmd))
@@ -3008,9 +3029,11 @@ def _parsehook(
3008
3029
  "capture": cap,
3009
3030
  }
3010
3031
 
3011
- 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]))
3012
3035
 
3013
- return chk, fork, jtxt, wait, sp_ka, cmd
3036
+ return areq, chk, fork, jtxt, wait, sp_ka, argv
3014
3037
 
3015
3038
 
3016
3039
  def runihook(
@@ -3019,10 +3042,9 @@ def runihook(
3019
3042
  vol ,
3020
3043
  ups ,
3021
3044
  ) :
3022
- ocmd = cmd
3023
- chk, fork, jtxt, wait, sp_ka, cmd = _parsehook(log, cmd)
3024
- bcmd = [sfsenc(cmd)]
3025
- 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"):
3026
3048
  bcmd = [sfsenc(pybin)] + bcmd
3027
3049
 
3028
3050
  vps = [vjoin(*list(s3dec(x[3], x[4]))) for x in ups]
@@ -3047,7 +3069,7 @@ def runihook(
3047
3069
 
3048
3070
  t0 = time.time()
3049
3071
  if fork:
3050
- Daemon(runcmd, ocmd, [bcmd], ka=sp_ka)
3072
+ Daemon(runcmd, cmd, bcmd, ka=sp_ka)
3051
3073
  else:
3052
3074
  rc, v, err = runcmd(bcmd, **sp_ka) # type: ignore
3053
3075
  if chk and rc:
@@ -3068,14 +3090,20 @@ def _runhook(
3068
3090
  vp ,
3069
3091
  host ,
3070
3092
  uname ,
3093
+ perms ,
3071
3094
  mt ,
3072
3095
  sz ,
3073
3096
  ip ,
3074
3097
  at ,
3075
3098
  txt ,
3076
3099
  ) :
3077
- ocmd = cmd
3078
- 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
3079
3107
  if jtxt:
3080
3108
  ja = {
3081
3109
  "ap": ap,
@@ -3086,21 +3114,22 @@ def _runhook(
3086
3114
  "at": at or time.time(),
3087
3115
  "host": host,
3088
3116
  "user": uname,
3117
+ "perms": perms,
3089
3118
  "txt": txt,
3090
3119
  }
3091
3120
  arg = json.dumps(ja)
3092
3121
  else:
3093
3122
  arg = txt or ap
3094
3123
 
3095
- acmd = [cmd, arg]
3096
- if cmd.endswith(".py"):
3124
+ acmd += [arg]
3125
+ if acmd[0].endswith(".py"):
3097
3126
  acmd = [pybin] + acmd
3098
3127
 
3099
3128
  bcmd = [fsenc(x) if x == ap else sfsenc(x) for x in acmd]
3100
3129
 
3101
3130
  t0 = time.time()
3102
3131
  if fork:
3103
- Daemon(runcmd, ocmd, [bcmd], ka=sp_ka)
3132
+ Daemon(runcmd, cmd, [bcmd], ka=sp_ka)
3104
3133
  else:
3105
3134
  rc, v, err = runcmd(bcmd, **sp_ka) # type: ignore
3106
3135
  if chk and rc:
@@ -3121,6 +3150,7 @@ def runhook(
3121
3150
  vp ,
3122
3151
  host ,
3123
3152
  uname ,
3153
+ perms ,
3124
3154
  mt ,
3125
3155
  sz ,
3126
3156
  ip ,
@@ -3130,7 +3160,7 @@ def runhook(
3130
3160
  vp = vp.replace("\\", "/")
3131
3161
  for cmd in cmds:
3132
3162
  try:
3133
- 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):
3134
3164
  return False
3135
3165
  except Exception as ex:
3136
3166
  (log or print)("hook: {}".format(ex))
Binary file
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
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=0z21tPU_24uD5Ule4pT5PhFKSmi774Q-pxi9lXt10Vw,100949
3
- copyparty/__version__.py,sha256=x893bLkpUdr1zLkE3NI7Yqq_loU2TKQ_HgyT9bWygDY,254
4
- copyparty/authsrv.py,sha256=kTf6iBchUDqb62oLypsQdTIsDY2NTn1D1YoZd8t1d1k,85272
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=2lc__-IIOQsS_Lmsz6miwOobl0lLiyGHbXtOJYtag_4,164393
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=--Up4OLu8BMV3JQvl2xuqSx7nc5LcV6IadqD5Drrbj0,18152
18
+ copyparty/mdns.py,sha256=vC078llnL1v0pvL3mnwacuStFHPJUQuxo9Opj-IbHL4,18155
19
19
  copyparty/metrics.py,sha256=O8qiPNDxNjub_PI8C8Qu9rBQ_z0J1mnKonqkcTeAtf4,8845
20
- copyparty/mtag.py,sha256=Eg7ioGzys25pf-f6GEL0j_rRL5nGe4jZzTMZMD0wxCU,18599
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=XVanfBewbriKJvHgP5QpDjJn-l8Jb7AoOQ2u53LYwUY,7042
23
+ copyparty/smbd.py,sha256=RW-8xoKlrR3PbNdd1q72uYGwI7USMl93eVPqC0HYCic,14066
24
+ copyparty/ssdp.py,sha256=SiIGQ0FMFa0RM40GIEvkOTT0DMnKwZIy51a-ZDzLNxM,7045
25
25
  copyparty/star.py,sha256=tV5BbX6AiQ7N4UU8DYtSTckNYeoeey4DBqq4LjfymbY,3818
26
26
  copyparty/sutil.py,sha256=xTw2jTrF3m3EXeh6E5Th810Axx5xVeMBNElkSwGb-Bo,3214
27
- copyparty/svchub.py,sha256=v81cj-KQ3P7pLcV4sOWEjJSpGdjseZ2tpqL4VruPtmI,32661
27
+ copyparty/svchub.py,sha256=JbWbypa7OyYkJgsUTo0SRhgvb4WT4B1zDNi110Fuvl0,32743
28
28
  copyparty/szip.py,sha256=5xbfbnTKt97c59pZD_nAzWEYpMel7xFDuGUjj60VjOs,8619
29
- copyparty/tcpsrv.py,sha256=ym6rda7svl_M4DjNesHMI1_6wO7Csu01UV1zGzXEMxI,17637
30
- copyparty/tftpd.py,sha256=7EHAZ9LnjAXupwRNIENJ2eA8Q0lFynnwwbziV3fyzns,13157
29
+ copyparty/tcpsrv.py,sha256=ssomz8MUjX62Yf6oDovH-Fzxi-9rZF6JFvsdDgGEho0,17680
30
+ copyparty/tftpd.py,sha256=GkO1jN08ufPDcO2dri1VfvcDKcMW7x1RtL2Rj0SrN3o,12983
31
31
  copyparty/th_cli.py,sha256=JBazIKlw8oQXW2FLzqjokjqTk33c9V4Ke7Nx5ovoN-M,4560
32
32
  copyparty/th_srv.py,sha256=tbRoaIb9WtUdVwjysxMYDbbEpRNvVwTh2Kj-_vCRbg8,28391
33
33
  copyparty/u2idx.py,sha256=uEUcEbye1jzGlQfEJkLtD060XA6Rv_6lXLgeg6oAU5M,13033
34
- copyparty/up2k.py,sha256=LuJS-DyxkVMq9AOJtiGjGr-9RaPxcrquFDO8LzfamYY,143358
35
- copyparty/util.py,sha256=kRm2zAoHaihFBnA856iR8hfz8sXNNmYh7GsfnxuCVlw,84151
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
@@ -57,7 +57,7 @@ copyparty/stolen/ifaddr/_win32.py,sha256=EE-QyoBgeB7lYQ6z62VjXNaRozaYfCkaJBHGNA8
57
57
  copyparty/web/baguettebox.js.gz,sha256=hIlIpULK0O1MFPs2LNuyoRXMgRVYSvA5Db8eeVB8CSU,7909
58
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=kggLwqztclrse8G6I4GqlzmZ04wmPpMu06Qw0H6pm3U,68833
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
@@ -76,9 +76,9 @@ 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
@@ -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=0KvEM32CEJgafd23OBa4L27GyfCEQ6oRI-OoWhIkIcQ,22538
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.3.dist-info/LICENSE,sha256=gOr4h33pCsBEg9uIy9AYmb7qlocL4V9t2uPJS5wllr0,1072
106
- copyparty-1.13.3.dist-info/METADATA,sha256=HAszIqsIs6owRR8n9YyeA8h49mSnEqiKZ1QVgDNMCqg,122479
107
- copyparty-1.13.3.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
108
- copyparty-1.13.3.dist-info/entry_points.txt,sha256=4zw6a3rqASywQomiYLObjjlxybaI65LYYOTJwgKz7b0,128
109
- copyparty-1.13.3.dist-info/top_level.txt,sha256=LnYUPsDyk-8kFgM6YJLG4h820DQekn81cObKSu9g-sI,10
110
- copyparty-1.13.3.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