copyparty 1.6.9__py2.py3-none-any.whl → 1.6.11__py2.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 CHANGED
@@ -752,7 +752,7 @@ def add_ftp(ap):
752
752
 
753
753
  def add_webdav(ap):
754
754
  ap2 = ap.add_argument_group('WebDAV options')
755
- ap2.add_argument("--daw", action="store_true", help="enable full write support. \033[1;31mWARNING:\033[0m This has side-effects -- PUT-operations will now \033[1;31mOVERWRITE\033[0m existing files, rather than inventing new filenames to avoid loss of data. You might want to instead set this as a volflag where needed. By not setting this flag, uploaded files can get written to a filename which the client does not expect (which might be okay, depending on client)")
755
+ ap2.add_argument("--daw", action="store_true", help="enable full write support, even if client may not be webdav. \033[1;31mWARNING:\033[0m This has side-effects -- PUT-operations will now \033[1;31mOVERWRITE\033[0m existing files, rather than inventing new filenames to avoid loss of data. You might want to instead set this as a volflag where needed. By not setting this flag, uploaded files can get written to a filename which the client does not expect (which might be okay, depending on client)")
756
756
  ap2.add_argument("--dav-inf", action="store_true", help="allow depth:infinite requests (recursive file listing); extremely server-heavy but required for spec compliance -- luckily few clients rely on this")
757
757
  ap2.add_argument("--dav-mac", action="store_true", help="disable apple-garbage filter -- allow macos to create junk files (._* and .DS_Store, .Spotlight-*, .fseventsd, .Trashes, .AppleDouble, __MACOS)")
758
758
 
copyparty/__version__.py CHANGED
@@ -1,8 +1,8 @@
1
1
  # coding: utf-8
2
2
 
3
- VERSION = (1, 6, 9)
3
+ VERSION = (1, 6, 11)
4
4
  CODENAME = "cors k"
5
- BUILD_DT = (2023, 3, 16)
5
+ BUILD_DT = (2023, 4, 1)
6
6
 
7
7
  S_VERSION = ".".join(map(str, VERSION))
8
8
  S_BUILD_DT = "{0:04d}-{1:02d}-{2:02d}".format(*BUILD_DT)
copyparty/httpcli.py CHANGED
@@ -861,7 +861,17 @@ class HttpCli(object):
861
861
  vn, rem = self.asrv.vfs.get(self.vpath, self.uname, True, False, err=401)
862
862
  depth = self.headers.get("depth", "infinity").lower()
863
863
 
864
- if depth == "infinity":
864
+ try:
865
+ topdir = {"vp": "", "st": bos.stat(vn.canonical(rem))}
866
+ except OSError as ex:
867
+ if ex.errno != errno.ENOENT:
868
+ raise
869
+ raise Pebkac(404)
870
+
871
+ if not stat.S_ISDIR(topdir["st"].st_mode):
872
+ fgen = []
873
+
874
+ elif depth == "infinity":
865
875
  if not self.args.dav_inf:
866
876
  self.log("client wants --dav-inf", 3)
867
877
  zb = b'<?xml version="1.0" encoding="utf-8"?>\n<D:error xmlns:D="DAV:"><D:propfind-finite-depth/></D:error>'
@@ -900,13 +910,6 @@ class HttpCli(object):
900
910
  t2 = " or 'infinity'" if self.args.dav_inf else ""
901
911
  raise Pebkac(412, t.format(depth, t2))
902
912
 
903
- try:
904
- topdir = {"vp": "", "st": os.stat(vn.canonical(rem))}
905
- except OSError as ex:
906
- if ex.errno != errno.ENOENT:
907
- raise
908
- raise Pebkac(404)
909
-
910
913
  fgen = itertools.chain([topdir], fgen) # type: ignore
911
914
  vtop = vjoin(self.args.R, vjoin(vn.vpath, rem))
912
915
 
@@ -1108,7 +1111,14 @@ class HttpCli(object):
1108
1111
  if self.do_log:
1109
1112
  self.log("MKCOL " + self.req)
1110
1113
 
1111
- return self._mkdir(self.vpath)
1114
+ try:
1115
+ return self._mkdir(self.vpath, True)
1116
+ except Pebkac as ex:
1117
+ if ex.code >= 500:
1118
+ raise
1119
+
1120
+ self.reply(b"", ex.code)
1121
+ return True
1112
1122
 
1113
1123
  def handle_move(self) :
1114
1124
  dst = self.headers["destination"]
@@ -1422,9 +1432,9 @@ class HttpCli(object):
1422
1432
  self.log(t, 1)
1423
1433
  raise Pebkac(403, t)
1424
1434
 
1425
- if is_put and not (self.args.no_dav or self.args.nw):
1435
+ if is_put and not (self.args.no_dav or self.args.nw) and bos.path.exists(path):
1426
1436
  # allow overwrite if...
1427
- # * volflag 'daw' is set
1437
+ # * volflag 'daw' is set, or client is definitely webdav
1428
1438
  # * and account has delete-access
1429
1439
  # or...
1430
1440
  # * file exists, is empty, sufficiently new
@@ -1434,9 +1444,11 @@ class HttpCli(object):
1434
1444
  if self.args.dotpart:
1435
1445
  tnam = "." + tnam
1436
1446
 
1437
- if (vfs.flags.get("daw") and self.can_delete) or (
1447
+ if (
1448
+ self.can_delete
1449
+ and (vfs.flags.get("daw") or "x-oc-mtime" in self.headers)
1450
+ ) or (
1438
1451
  not bos.path.exists(os.path.join(fdir, tnam))
1439
- and bos.path.exists(path)
1440
1452
  and not bos.path.getsize(path)
1441
1453
  and bos.path.getmtime(path) >= time.time() - self.args.blank_wt
1442
1454
  ):
@@ -1460,6 +1472,16 @@ class HttpCli(object):
1460
1472
  if self.args.nw:
1461
1473
  return post_sz, sha_hex, sha_b64, remains, path, ""
1462
1474
 
1475
+ at = mt = time.time() - lifetime
1476
+ cli_mt = self.headers.get("x-oc-mtime")
1477
+ if cli_mt:
1478
+ try:
1479
+ mt = int(cli_mt)
1480
+ times = (int(time.time()), mt)
1481
+ bos.utime(path, times, False)
1482
+ except:
1483
+ pass
1484
+
1463
1485
  if nameless and "magic" in vfs.flags:
1464
1486
  try:
1465
1487
  ext = self.conn.hsrv.magician.ext(path)
@@ -1482,7 +1504,6 @@ class HttpCli(object):
1482
1504
  fn = fn2
1483
1505
  path = path2
1484
1506
 
1485
- at = time.time() - lifetime
1486
1507
  if xau and not runhook(
1487
1508
  self.log,
1488
1509
  xau,
@@ -1490,7 +1511,7 @@ class HttpCli(object):
1490
1511
  self.vpath,
1491
1512
  self.host,
1492
1513
  self.uname,
1493
- at,
1514
+ mt,
1494
1515
  post_sz,
1495
1516
  self.ip,
1496
1517
  at,
@@ -1550,6 +1571,11 @@ class HttpCli(object):
1550
1571
  t = "{}\n{}\n{}\n{}\n".format(post_sz, sha_b64, sha_hex[:56], url)
1551
1572
 
1552
1573
  h = {"Location": url} if is_put and url else {}
1574
+
1575
+ if "x-oc-mtime" in self.headers:
1576
+ h["X-OC-MTime"] = "accepted"
1577
+ t = "" # some webdav clients expect/prefer this
1578
+
1553
1579
  self.reply(t.encode("utf-8"), 201, headers=h)
1554
1580
  return True
1555
1581
 
@@ -1950,7 +1976,7 @@ class HttpCli(object):
1950
1976
  sanitized = sanitize_fn(new_dir, "", [])
1951
1977
  return self._mkdir(vjoin(self.vpath, sanitized))
1952
1978
 
1953
- def _mkdir(self, vpath ) :
1979
+ def _mkdir(self, vpath , dav = False) :
1954
1980
  nullwrite = self.args.nw
1955
1981
  vfs, rem = self.asrv.vfs.get(vpath, self.uname, False, True)
1956
1982
  self._assert_safe_rem(rem)
@@ -1976,7 +2002,12 @@ class HttpCli(object):
1976
2002
  raise Pebkac(500, min_ex())
1977
2003
 
1978
2004
  self.out_headers["X-New-Dir"] = quotep(vpath.split("/")[-1])
1979
- self.redirect(vpath, status=201)
2005
+
2006
+ if dav:
2007
+ self.reply(b"", 201)
2008
+ else:
2009
+ self.redirect(vpath, status=201)
2010
+
1980
2011
  return True
1981
2012
 
1982
2013
  def handle_new_md(self) :
copyparty/th_srv.py CHANGED
@@ -558,12 +558,19 @@ class ThumbSrv(object):
558
558
  if "ac" not in ret:
559
559
  raise Exception("not audio")
560
560
 
561
+ try:
562
+ dur = ret[".dur"][1]
563
+ except:
564
+ dur = 0
565
+
561
566
  src_opus = abspath.lower().endswith(".opus") or ret["ac"][1] == "opus"
562
567
  want_caf = tpath.endswith(".caf")
563
568
  tmp_opus = tpath
564
569
  if want_caf:
565
570
  tmp_opus = tpath.rsplit(".", 1)[0] + ".opus"
566
571
 
572
+ caf_src = abspath if src_opus else tmp_opus
573
+
567
574
  if not want_caf or (not src_opus and not bos.path.isfile(tmp_opus)):
568
575
  # fmt: off
569
576
  cmd = [
@@ -581,7 +588,32 @@ class ThumbSrv(object):
581
588
  # fmt: on
582
589
  self._run_ff(cmd)
583
590
 
584
- if want_caf:
591
+ # iOS fails to play some "insufficiently complex" files
592
+ # (average file shorter than 8 seconds), so of course we
593
+ # fix that by mixing in some inaudible pink noise :^)
594
+ # 6.3 sec seems like the cutoff so lets do 7, and
595
+ # 7 sec of psyqui-musou.opus @ 3:50 is 174 KiB
596
+ if want_caf and (dur < 20 or bos.path.getsize(caf_src) < 256 * 1024):
597
+ # fmt: off
598
+ cmd = [
599
+ b"ffmpeg",
600
+ b"-nostdin",
601
+ b"-v", b"error",
602
+ b"-hide_banner",
603
+ b"-i", fsenc(abspath),
604
+ b"-filter_complex", b"anoisesrc=a=0.001:d=7:c=pink,asplit[l][r]; [l][r]amerge[s]; [0:a:0][s]amix",
605
+ b"-map_metadata", b"-1",
606
+ b"-ac", b"2",
607
+ b"-c:a", b"libopus",
608
+ b"-b:a", b"128k",
609
+ b"-f", b"caf",
610
+ fsenc(tpath)
611
+ ]
612
+ # fmt: on
613
+ self._run_ff(cmd)
614
+
615
+ elif want_caf:
616
+ # simple remux should be safe
585
617
  # fmt: off
586
618
  cmd = [
587
619
  b"ffmpeg",
copyparty/up2k.py CHANGED
@@ -1029,7 +1029,7 @@ class Up2k(object):
1029
1029
  zh.update(cv.encode("utf-8", "replace"))
1030
1030
  zh.update(spack(b"<d", cst.st_mtime))
1031
1031
  dhash = base64.urlsafe_b64encode(zh.digest()[:12]).decode("ascii")
1032
- sql = "select d from dh where d = ? and h = ?"
1032
+ sql = "select d from dh where d=? and +h=?"
1033
1033
  try:
1034
1034
  c = db.c.execute(sql, (rd, dhash))
1035
1035
  drd = rd
@@ -1313,9 +1313,9 @@ class Up2k(object):
1313
1313
 
1314
1314
  w, drd, dfn = zb[:-1].decode("utf-8").split("\x00")
1315
1315
  with self.mutex:
1316
- q = "select mt, sz from up where w = ? and rd = ? and fn = ?"
1316
+ q = "select mt, sz from up where rd=? and fn=? and +w=?"
1317
1317
  try:
1318
- mt, sz = cur.execute(q, (w, drd, dfn)).fetchone()
1318
+ mt, sz = cur.execute(q, (drd, dfn, w)).fetchone()
1319
1319
  except:
1320
1320
  # file moved/deleted since spooling
1321
1321
  continue
@@ -2220,7 +2220,7 @@ class Up2k(object):
2220
2220
  q = r"select * from up where w = ?"
2221
2221
  argv = [wark]
2222
2222
  else:
2223
- q = r"select * from up where substr(w,1,16) = ? and w = ?"
2223
+ q = r"select * from up where substr(w,1,16)=? and +w=?"
2224
2224
  argv = [wark[:16], wark]
2225
2225
 
2226
2226
  c2 = cur.execute(q, tuple(argv))
@@ -3297,9 +3297,16 @@ class Up2k(object):
3297
3297
  """
3298
3298
  dupes = []
3299
3299
  sabs = djoin(sptop, srem)
3300
- q = "select rd, fn from up where substr(w,1,16)=? and w=?"
3300
+
3301
+ if self.no_expr_idx:
3302
+ q = r"select rd, fn from up where w = ?"
3303
+ argv = (wark,)
3304
+ else:
3305
+ q = r"select rd, fn from up where substr(w,1,16)=? and +w=?"
3306
+ argv = (wark[:16], wark)
3307
+
3301
3308
  for ptop, cur in self.cur.items():
3302
- for rd, fn in cur.execute(q, (wark[:16], wark)):
3309
+ for rd, fn in cur.execute(q, argv):
3303
3310
  if rd.startswith("//") or fn.startswith("//"):
3304
3311
  rd, fn = s3dec(rd, fn)
3305
3312
 
copyparty/web/a/up2k.py CHANGED
@@ -1009,8 +1009,9 @@ class Ctl(object):
1009
1009
  file, cid = task
1010
1010
  try:
1011
1011
  upload(file, cid, self.ar.a, stats)
1012
- except:
1013
- eprint("upload failed, retrying: {0} #{1}\n".format(file.name, cid[:8]))
1012
+ except Exception as ex:
1013
+ t = "upload failed, retrying: {0} #{1} ({2})\n"
1014
+ eprint(t.format(file.name, cid[:8], ex))
1014
1015
  # handshake will fix it
1015
1016
 
1016
1017
  with self.mutex:
@@ -1049,6 +1050,8 @@ def main():
1049
1050
  print(ver)
1050
1051
  return
1051
1052
 
1053
+ sys.argv = [x for x in sys.argv if x != "--ws"]
1054
+
1052
1055
  # fmt: off
1053
1056
  ap = app = argparse.ArgumentParser(formatter_class=APF, description="copyparty up2k uploader / filesearch tool, " + ver, epilog="""
1054
1057
  NOTE:
@@ -1067,7 +1070,6 @@ source file/folder selection uses rsync syntax, meaning that:
1067
1070
 
1068
1071
  ap = app.add_argument_group("compatibility")
1069
1072
  ap.add_argument("--cls", action="store_true", help="clear screen before start")
1070
- ap.add_argument("--ws", action="store_true", help="copyparty is running on windows; wait before deleting files after uploading")
1071
1073
 
1072
1074
  ap = app.add_argument_group("folder sync")
1073
1075
  ap.add_argument("--dl", action="store_true", help="delete local files after uploading")
@@ -1131,10 +1133,6 @@ source file/folder selection uses rsync syntax, meaning that:
1131
1133
 
1132
1134
  if ar.dr and not ar.drd:
1133
1135
  print("\npass 2/2: delete")
1134
- if getattr(ctl, "up_br") and ar.ws:
1135
- # wait for up2k to mtime if there was uploads
1136
- time.sleep(4)
1137
-
1138
1136
  ar.drd = True
1139
1137
  ar.z = True
1140
1138
  Ctl(ar, ctl.stats)
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
copyparty/web/md.js.gz CHANGED
Binary file
copyparty/web/svcs.html CHANGED
@@ -43,10 +43,9 @@
43
43
  <h1>WebDAV</h1>
44
44
 
45
45
  <div class="os win">
46
- <p><em>note: rclone-FTP is a bit faster, so {% if args.ftp or args.ftps %}try that first{% else %}consider enabling FTP in server settings{% endif %}</em></p>
47
46
  <p>if you can, install <a href="https://winfsp.dev/rel/">winfsp</a>+<a href="https://downloads.rclone.org/rclone-current-windows-amd64.zip">rclone</a> and then paste this in cmd:</p>
48
47
  <pre>
49
- rclone config create {{ aname }}-dav webdav url=http{{ s }}://{{ rip }}{{ hport }} vendor=other{% if accs %} user=k pass=<b>{{ pw }}</b>{% endif %}
48
+ rclone config create {{ aname }}-dav webdav url=http{{ s }}://{{ rip }}{{ hport }} vendor=owncloud pacer_min_sleep=0.01ms{% if accs %} user=k pass=<b>{{ pw }}</b>{% endif %}
50
49
  rclone mount --vfs-cache-mode writes --dir-cache-time 5s {{ aname }}-dav:{{ rvp }} <b>W:</b>
51
50
  </pre>
52
51
  {% if s %}
@@ -69,9 +68,9 @@
69
68
  printf '%s\n' "http{{ s }}://{{ ep }}/{{ rvp }} <b>{{ pw }}</b> k" >> /etc/davfs2/secrets
70
69
  printf '%s\n' "http{{ s }}://{{ ep }}/{{ rvp }} <b>mp</b> davfs rw,user,uid=1000,noauto 0 0" >> /etc/fstab
71
70
  </pre>
72
- <p>or you can use rclone instead, which is much slower but doesn't require root:</p>
71
+ <p>or you can use rclone instead, which is much slower but doesn't require root (plus it keeps lastmodified on upload):</p>
73
72
  <pre>
74
- rclone config create {{ aname }}-dav webdav url=http{{ s }}://{{ rip }}{{ hport }} vendor=other{% if accs %} user=k pass=<b>{{ pw }}</b>{% endif %}
73
+ rclone config create {{ aname }}-dav webdav url=http{{ s }}://{{ rip }}{{ hport }} vendor=owncloud pacer_min_sleep=0.01ms{% if accs %} user=k pass=<b>{{ pw }}</b>{% endif %}
75
74
  rclone mount --vfs-cache-mode writes --dir-cache-time 5s {{ aname }}-dav:{{ rvp }} <b>mp</b>
76
75
  </pre>
77
76
  {% if s %}
copyparty/web/ui.css.gz CHANGED
Binary file
copyparty/web/util.js.gz CHANGED
Binary file
@@ -1,29 +1,16 @@
1
1
  # 💾🎉 copyparty
2
2
 
3
- * portable file sharing hub (py2/py3) [(on PyPI)](https://pypi.org/project/copyparty/)
4
- * MIT-Licensed, 2019-05-26, ed @ irc.rizon.net
3
+ turn almost any device into a file server with resumable uploads/downloads using [*any*](#browser-support) web browser
5
4
 
5
+ * server only needs Python (2 or 3), all dependencies optional
6
+ * 🔌 protocols: [http](#the-browser) // [ftp](#ftp-server) // [webdav](#webdav-server) // [smb/cifs](#smb-server)
7
+ * 📱 [android app](#android-app) // [iPhone shortcuts](#ios-shortcuts)
6
8
 
7
- ## summary
8
-
9
- turn your phone or raspi into a portable file server with resumable uploads/downloads using *any* web browser
10
-
11
- * server only needs Python (`2.7` or `3.3+`), all dependencies optional
12
- * browse/upload with [IE4](#browser-support) / netscape4.0 on win3.11 (heh)
13
- * protocols: [http](#the-browser) // [ftp](#ftp-server) // [webdav](#webdav-server) // [smb/cifs](#smb-server)
14
-
15
- **[Get started](#quickstart)!** or visit the **[read-only demo server](https://a.ocv.me/pub/demo/)** 👀 running from a basement in finland
9
+ 👉 **[Get started](#quickstart)!** or visit the **[read-only demo server](https://a.ocv.me/pub/demo/)** 👀 running from a basement in finland
16
10
 
17
11
  📷 **screenshots:** [browser](#the-browser) // [upload](#uploading) // [unpost](#unpost) // [thumbnails](#thumbnails) // [search](#searching) // [fsearch](#file-search) // [zip-DL](#zip-downloads) // [md-viewer](#markdown-viewer)
18
12
 
19
13
 
20
- ## get the app
21
-
22
- <a href="https://f-droid.org/packages/me.ocv.partyup/"><img src="https://ocv.me/fdroid.png" alt="Get it on F-Droid" height="50" /> '' <img src="https://img.shields.io/f-droid/v/me.ocv.partyup.svg" alt="f-droid version info" /></a> '' <a href="https://github.com/9001/party-up"><img src="https://img.shields.io/github/release/9001/party-up.svg?logo=github" alt="github version info" /></a>
23
-
24
- (the app is **NOT** the full copyparty server! just a basic upload client, nothing fancy yet)
25
-
26
-
27
14
  ## readme toc
28
15
 
29
16
  * top
@@ -82,12 +69,16 @@ turn your phone or raspi into a portable file server with resumable uploads/down
82
69
  * [reverse-proxy](#reverse-proxy) - running copyparty next to other websites
83
70
  * [browser support](#browser-support) - TLDR: yes
84
71
  * [client examples](#client-examples) - interact with copyparty using non-browser clients
72
+ * [folder sync](#folder-sync) - sync folders to/from copyparty
85
73
  * [mount as drive](#mount-as-drive) - a remote copyparty server as a local filesystem
74
+ * [android app](#android-app) - upload to copyparty with one tap
75
+ * [iOS shortcuts](#iOS-shortcuts) - there is no iPhone app, but
86
76
  * [performance](#performance) - defaults are usually fine - expect `8 GiB/s` download, `1 GiB/s` upload
87
77
  * [client-side](#client-side) - when uploading files
88
78
  * [security](#security) - some notes on hardening
89
79
  * [gotchas](#gotchas) - behavior that might be unexpected
90
80
  * [cors](#cors) - cross-site request config
81
+ * [https](#https) - both HTTP and HTTPS are accepted
91
82
  * [recovering from crashes](#recovering-from-crashes)
92
83
  * [client crashes](#client-crashes)
93
84
  * [frefox wsod](#frefox-wsod) - firefox 87 can crash during uploads
@@ -139,7 +130,7 @@ some recommended options:
139
130
 
140
131
  you may also want these, especially on servers:
141
132
 
142
- * [contrib/systemd/copyparty.service](contrib/systemd/copyparty.service) to run copyparty as a systemd service
133
+ * [contrib/systemd/copyparty.service](contrib/systemd/copyparty.service) to run copyparty as a systemd service (see guide inside)
143
134
  * [contrib/systemd/prisonparty.service](contrib/systemd/prisonparty.service) to run it in a chroot (for extra security)
144
135
  * [contrib/rc/copyparty](contrib/rc/copyparty) to run copyparty on FreeBSD
145
136
  * [contrib/nginx/copyparty.conf](contrib/nginx/copyparty.conf) to [reverse-proxy](#reverse-proxy) behind nginx (for better https)
@@ -177,7 +168,7 @@ firewall-cmd --reload
177
168
  * ☑ write-only folders
178
169
  * ☑ [unpost](#unpost): undo/delete accidental uploads
179
170
  * ☑ [self-destruct](#self-destruct) (specified server-side or client-side)
180
- * ☑ symlink/discard existing files (content-matching)
171
+ * ☑ symlink/discard duplicates (content-matching)
181
172
  * download
182
173
  * ☑ single files in browser
183
174
  * ☑ [folders as zip / tar files](#zip-downloads)
@@ -199,7 +190,7 @@ firewall-cmd --reload
199
190
  * ☑ search by name/path/date/size
200
191
  * ☑ [search by ID3-tags etc.](#searching)
201
192
  * client support
202
- * ☑ [sync folder to server](https://github.com/9001/copyparty/tree/hovudstraum/bin#up2kpy)
193
+ * ☑ [folder sync](#folder-sync)
203
194
  * ☑ [curl-friendly](https://user-images.githubusercontent.com/241032/215322619-ea5fd606-3654-40ad-94ee-2bc058647bb2.png)
204
195
  * markdown
205
196
  * ☑ [viewer](#markdown-viewer)
@@ -278,7 +269,7 @@ server notes:
278
269
 
279
270
  * iPhones: the volume control doesn't work because [apple doesn't want it to](https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html#//apple_ref/doc/uid/TP40009523-CH5-SW11)
280
271
  * *future workaround:* enable the equalizer, make it all-zero, and set a negative boost to reduce the volume
281
- * "future" because `AudioContext` is broken in the current iOS version (15.1), maybe one day...
272
+ * "future" because `AudioContext` can't maintain a stable playback speed in the current iOS version (15.7), maybe one day...
282
273
 
283
274
  * Windows: folders cannot be accessed if the name ends with `.`
284
275
  * python or windows bug
@@ -1102,13 +1093,15 @@ see the top of [./copyparty/web/browser.css](./copyparty/web/browser.css) where
1102
1093
 
1103
1094
  ## reverse-proxy
1104
1095
 
1105
- running copyparty next to other websites hosted on an existing webserver such as nginx or apache
1096
+ running copyparty next to other websites hosted on an existing webserver such as nginx, caddy, or apache
1106
1097
 
1107
1098
  you can either:
1108
1099
  * give copyparty its own domain or subdomain (recommended)
1109
1100
  * 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
1110
1101
  * 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
1111
1102
 
1103
+ 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
1104
+
1112
1105
  example webserver configs:
1113
1106
 
1114
1107
  * [nginx config](contrib/nginx/copyparty.conf) -- entire domain/subdomain
@@ -1186,7 +1179,7 @@ interact with copyparty using non-browser clients
1186
1179
  * `(printf 'PUT / HTTP/1.1\r\n\r\n'; cat movie.mkv) >/dev/tcp/127.0.0.1/3923`
1187
1180
 
1188
1181
  * python: [up2k.py](https://github.com/9001/copyparty/blob/hovudstraum/bin/up2k.py) is a command-line up2k client [(webm)](https://ocv.me/stuff/u2cli.webm)
1189
- * file uploads, file-search, folder sync, autoresume of aborted/broken uploads
1182
+ * file uploads, file-search, [folder sync](#folder-sync), autoresume of aborted/broken uploads
1190
1183
  * can be downloaded from copyparty: controlpanel -> connect -> [up2k.py](http://127.0.0.1:3923/.cpr/a/up2k.py)
1191
1184
  * see [./bin/README.md#up2kpy](bin/README.md#up2kpy)
1192
1185
 
@@ -1207,17 +1200,27 @@ you can provide passwords using header `PW: hunter2`, cookie `cppwd=hunter2`, ur
1207
1200
  NOTE: curl will not send the original filename if you use `-T` combined with url-params! Also, make sure to always leave a trailing slash in URLs unless you want to override the filename
1208
1201
 
1209
1202
 
1203
+ ## folder sync
1204
+
1205
+ sync folders to/from copyparty
1206
+
1207
+ the commandline uploader [up2k.py](https://github.com/9001/copyparty/tree/hovudstraum/bin#up2kpy) with `--dr` is the best way to sync a folder to copyparty; verifies checksums and does files in parallel, and deletes unexpected files on the server after upload has finished which makes file-renames really cheap (it'll rename serverside and skip uploading)
1208
+
1209
+ alternatively there is [rclone](./docs/rclone.md) which allows for bidirectional sync and is *way* more flexible (stream files straight from sftp/s3/gcs to copyparty, ...), although there is no integrity check and it won't work with files over 100 MiB if copyparty is behind cloudflare
1210
+
1211
+ * starting from rclone v1.63 (currently [in beta](https://beta.rclone.org/?filter=latest)), rclone will also be faster than up2k.py
1212
+
1213
+
1210
1214
  ## mount as drive
1211
1215
 
1212
1216
  a remote copyparty server as a local filesystem; go to the control-panel and click `connect` to see a list of commands to do that
1213
1217
 
1214
1218
  alternatively, some alternatives roughly sorted by speed (unreproducible benchmark), best first:
1215
1219
 
1216
- * [rclone-http](./docs/rclone.md) (25s), read-only
1220
+ * [rclone-webdav](./docs/rclone.md) (25s), read/WRITE ([v1.63-beta](https://beta.rclone.org/?filter=latest))
1221
+ * [rclone-http](./docs/rclone.md) (26s), read-only
1222
+ * [partyfuse.py](./bin/#partyfusepy) (35s), read-only
1217
1223
  * [rclone-ftp](./docs/rclone.md) (47s), read/WRITE
1218
- * [rclone-webdav](./docs/rclone.md) (51s), read/WRITE
1219
- * copyparty-1.5.0's webdav server is faster than rclone-1.60.0 (69s)
1220
- * [partyfuse.py](./bin/#partyfusepy) (71s), read-only
1221
1224
  * davfs2 (103s), read/WRITE, *very fast* on small files
1222
1225
  * [win10-webdav](#webdav-server) (138s), read/WRITE
1223
1226
  * [win10-smb2](#smb-server) (387s), read/WRITE
@@ -1225,6 +1228,27 @@ alternatively, some alternatives roughly sorted by speed (unreproducible benchma
1225
1228
  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
1226
1229
 
1227
1230
 
1231
+ # android app
1232
+
1233
+ upload to copyparty with one tap
1234
+
1235
+ <a href="https://f-droid.org/packages/me.ocv.partyup/"><img src="https://ocv.me/fdroid.png" alt="Get it on F-Droid" height="50" /> '' <img src="https://img.shields.io/f-droid/v/me.ocv.partyup.svg" alt="f-droid version info" /></a> '' <a href="https://github.com/9001/party-up"><img src="https://img.shields.io/github/release/9001/party-up.svg?logo=github" alt="github version info" /></a>
1236
+
1237
+ the app is **NOT** the full copyparty server! just a basic upload client, nothing fancy yet
1238
+
1239
+ if you want to run the copyparty server on your android device, see [install on android](#install-on-android)
1240
+
1241
+
1242
+ # iOS shortcuts
1243
+
1244
+ there is no iPhone app, but the following shortcuts are almost as good:
1245
+
1246
+ * [upload to copyparty](https://www.icloud.com/shortcuts/41e98dd985cb4d3bb433222bc1e9e770) ([offline](https://github.com/9001/copyparty/raw/hovudstraum/contrib/ios/upload-to-copyparty.shortcut)) ([png](https://user-images.githubusercontent.com/241032/226118053-78623554-b0ed-482e-98e4-6d57ada58ea4.png)) based on the [original](https://www.icloud.com/shortcuts/ab415d5b4de3467b9ce6f151b439a5d7) by [Daedren](https://github.com/Daedren) (thx!)
1247
+ * can strip exif, upload files, pics, vids, links, clipboard
1248
+ * can download links and rehost the target file on copyparty (see first comment inside the shortcut)
1249
+ * pics become lowres if you share from gallery to shortcut, so better to launch the shortcut and pick stuff from there
1250
+
1251
+
1228
1252
  # performance
1229
1253
 
1230
1254
  defaults are usually fine - expect `8 GiB/s` download, `1 GiB/s` upload
@@ -1320,6 +1344,13 @@ by default, except for `GET` and `HEAD` operations, all requests must either:
1320
1344
  cors can be configured with `--acao` and `--acam`, or the protections entirely disabled with `--allow-csrf`
1321
1345
 
1322
1346
 
1347
+ ## https
1348
+
1349
+ 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)
1350
+
1351
+ copyparty doesn't speak HTTP/2 or QUIC, so using a reverse proxy would solve that as well
1352
+
1353
+
1323
1354
  # recovering from crashes
1324
1355
 
1325
1356
  ## client crashes
@@ -1387,7 +1418,7 @@ these are standalone programs and will never be imported / evaluated by copypart
1387
1418
 
1388
1419
  the self-contained "binary" [copyparty-sfx.py](https://github.com/9001/copyparty/releases/latest/download/copyparty-sfx.py) will unpack itself and run copyparty, assuming you have python installed of course
1389
1420
 
1390
- you can reduce the sfx size by repacking it; see [./docs/devnotes.md#sfx-repack](#./docs/devnotes.md#sfx-repack)
1421
+ you can reduce the sfx size by repacking it; see [./docs/devnotes.md#sfx-repack](./docs/devnotes.md#sfx-repack)
1391
1422
 
1392
1423
 
1393
1424
  ## copyparty.exe
@@ -1009,8 +1009,9 @@ class Ctl(object):
1009
1009
  file, cid = task
1010
1010
  try:
1011
1011
  upload(file, cid, self.ar.a, stats)
1012
- except:
1013
- eprint("upload failed, retrying: {0} #{1}\n".format(file.name, cid[:8]))
1012
+ except Exception as ex:
1013
+ t = "upload failed, retrying: {0} #{1} ({2})\n"
1014
+ eprint(t.format(file.name, cid[:8], ex))
1014
1015
  # handshake will fix it
1015
1016
 
1016
1017
  with self.mutex:
@@ -1049,6 +1050,8 @@ def main():
1049
1050
  print(ver)
1050
1051
  return
1051
1052
 
1053
+ sys.argv = [x for x in sys.argv if x != "--ws"]
1054
+
1052
1055
  # fmt: off
1053
1056
  ap = app = argparse.ArgumentParser(formatter_class=APF, description="copyparty up2k uploader / filesearch tool, " + ver, epilog="""
1054
1057
  NOTE:
@@ -1067,7 +1070,6 @@ source file/folder selection uses rsync syntax, meaning that:
1067
1070
 
1068
1071
  ap = app.add_argument_group("compatibility")
1069
1072
  ap.add_argument("--cls", action="store_true", help="clear screen before start")
1070
- ap.add_argument("--ws", action="store_true", help="copyparty is running on windows; wait before deleting files after uploading")
1071
1073
 
1072
1074
  ap = app.add_argument_group("folder sync")
1073
1075
  ap.add_argument("--dl", action="store_true", help="delete local files after uploading")
@@ -1131,10 +1133,6 @@ source file/folder selection uses rsync syntax, meaning that:
1131
1133
 
1132
1134
  if ar.dr and not ar.drd:
1133
1135
  print("\npass 2/2: delete")
1134
- if getattr(ctl, "up_br") and ar.ws:
1135
- # wait for up2k to mtime if there was uploads
1136
- time.sleep(4)
1137
-
1138
1136
  ar.drd = True
1139
1137
  ar.z = True
1140
1138
  Ctl(ar, ctl.stats)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: copyparty
3
- Version: 1.6.9
3
+ Version: 1.6.11
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
  Home-page: https://github.com/9001/copyparty
6
6
  Author: ed
@@ -47,30 +47,17 @@ Requires-Dist: pyvips ; extra == 'thumbnails2'
47
47
 
48
48
  # 💾🎉 copyparty
49
49
 
50
- * portable file sharing hub (py2/py3) [(on PyPI)](https://pypi.org/project/copyparty/)
51
- * MIT-Licensed, 2019-05-26, ed @ irc.rizon.net
50
+ turn almost any device into a file server with resumable uploads/downloads using [*any*](#browser-support) web browser
52
51
 
52
+ * server only needs Python (2 or 3), all dependencies optional
53
+ * 🔌 protocols: [http](#the-browser) // [ftp](#ftp-server) // [webdav](#webdav-server) // [smb/cifs](#smb-server)
54
+ * 📱 [android app](#android-app) // [iPhone shortcuts](#ios-shortcuts)
53
55
 
54
- ## summary
55
-
56
- turn your phone or raspi into a portable file server with resumable uploads/downloads using *any* web browser
57
-
58
- * server only needs Python (`2.7` or `3.3+`), all dependencies optional
59
- * browse/upload with [IE4](#browser-support) / netscape4.0 on win3.11 (heh)
60
- * protocols: [http](#the-browser) // [ftp](#ftp-server) // [webdav](#webdav-server) // [smb/cifs](#smb-server)
61
-
62
- **[Get started](#quickstart)!** or visit the **[read-only demo server](https://a.ocv.me/pub/demo/)** 👀 running from a basement in finland
56
+ 👉 **[Get started](#quickstart)!** or visit the **[read-only demo server](https://a.ocv.me/pub/demo/)** 👀 running from a basement in finland
63
57
 
64
58
  📷 **screenshots:** [browser](#the-browser) // [upload](#uploading) // [unpost](#unpost) // [thumbnails](#thumbnails) // [search](#searching) // [fsearch](#file-search) // [zip-DL](#zip-downloads) // [md-viewer](#markdown-viewer)
65
59
 
66
60
 
67
- ## get the app
68
-
69
- <a href="https://f-droid.org/packages/me.ocv.partyup/"><img src="https://ocv.me/fdroid.png" alt="Get it on F-Droid" height="50" /> '' <img src="https://img.shields.io/f-droid/v/me.ocv.partyup.svg" alt="f-droid version info" /></a> '' <a href="https://github.com/9001/party-up"><img src="https://img.shields.io/github/release/9001/party-up.svg?logo=github" alt="github version info" /></a>
70
-
71
- (the app is **NOT** the full copyparty server! just a basic upload client, nothing fancy yet)
72
-
73
-
74
61
  ## readme toc
75
62
 
76
63
  * top
@@ -129,12 +116,16 @@ turn your phone or raspi into a portable file server with resumable uploads/down
129
116
  * [reverse-proxy](#reverse-proxy) - running copyparty next to other websites
130
117
  * [browser support](#browser-support) - TLDR: yes
131
118
  * [client examples](#client-examples) - interact with copyparty using non-browser clients
119
+ * [folder sync](#folder-sync) - sync folders to/from copyparty
132
120
  * [mount as drive](#mount-as-drive) - a remote copyparty server as a local filesystem
121
+ * [android app](#android-app) - upload to copyparty with one tap
122
+ * [iOS shortcuts](#iOS-shortcuts) - there is no iPhone app, but
133
123
  * [performance](#performance) - defaults are usually fine - expect `8 GiB/s` download, `1 GiB/s` upload
134
124
  * [client-side](#client-side) - when uploading files
135
125
  * [security](#security) - some notes on hardening
136
126
  * [gotchas](#gotchas) - behavior that might be unexpected
137
127
  * [cors](#cors) - cross-site request config
128
+ * [https](#https) - both HTTP and HTTPS are accepted
138
129
  * [recovering from crashes](#recovering-from-crashes)
139
130
  * [client crashes](#client-crashes)
140
131
  * [frefox wsod](#frefox-wsod) - firefox 87 can crash during uploads
@@ -186,7 +177,7 @@ some recommended options:
186
177
 
187
178
  you may also want these, especially on servers:
188
179
 
189
- * [contrib/systemd/copyparty.service](contrib/systemd/copyparty.service) to run copyparty as a systemd service
180
+ * [contrib/systemd/copyparty.service](contrib/systemd/copyparty.service) to run copyparty as a systemd service (see guide inside)
190
181
  * [contrib/systemd/prisonparty.service](contrib/systemd/prisonparty.service) to run it in a chroot (for extra security)
191
182
  * [contrib/rc/copyparty](contrib/rc/copyparty) to run copyparty on FreeBSD
192
183
  * [contrib/nginx/copyparty.conf](contrib/nginx/copyparty.conf) to [reverse-proxy](#reverse-proxy) behind nginx (for better https)
@@ -224,7 +215,7 @@ firewall-cmd --reload
224
215
  * ☑ write-only folders
225
216
  * ☑ [unpost](#unpost): undo/delete accidental uploads
226
217
  * ☑ [self-destruct](#self-destruct) (specified server-side or client-side)
227
- * ☑ symlink/discard existing files (content-matching)
218
+ * ☑ symlink/discard duplicates (content-matching)
228
219
  * download
229
220
  * ☑ single files in browser
230
221
  * ☑ [folders as zip / tar files](#zip-downloads)
@@ -246,7 +237,7 @@ firewall-cmd --reload
246
237
  * ☑ search by name/path/date/size
247
238
  * ☑ [search by ID3-tags etc.](#searching)
248
239
  * client support
249
- * ☑ [sync folder to server](https://github.com/9001/copyparty/tree/hovudstraum/bin#up2kpy)
240
+ * ☑ [folder sync](#folder-sync)
250
241
  * ☑ [curl-friendly](https://user-images.githubusercontent.com/241032/215322619-ea5fd606-3654-40ad-94ee-2bc058647bb2.png)
251
242
  * markdown
252
243
  * ☑ [viewer](#markdown-viewer)
@@ -325,7 +316,7 @@ server notes:
325
316
 
326
317
  * iPhones: the volume control doesn't work because [apple doesn't want it to](https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html#//apple_ref/doc/uid/TP40009523-CH5-SW11)
327
318
  * *future workaround:* enable the equalizer, make it all-zero, and set a negative boost to reduce the volume
328
- * "future" because `AudioContext` is broken in the current iOS version (15.1), maybe one day...
319
+ * "future" because `AudioContext` can't maintain a stable playback speed in the current iOS version (15.7), maybe one day...
329
320
 
330
321
  * Windows: folders cannot be accessed if the name ends with `.`
331
322
  * python or windows bug
@@ -1149,13 +1140,15 @@ see the top of [./copyparty/web/browser.css](./copyparty/web/browser.css) where
1149
1140
 
1150
1141
  ## reverse-proxy
1151
1142
 
1152
- running copyparty next to other websites hosted on an existing webserver such as nginx or apache
1143
+ running copyparty next to other websites hosted on an existing webserver such as nginx, caddy, or apache
1153
1144
 
1154
1145
  you can either:
1155
1146
  * give copyparty its own domain or subdomain (recommended)
1156
1147
  * 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
1157
1148
  * 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
1158
1149
 
1150
+ 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
1151
+
1159
1152
  example webserver configs:
1160
1153
 
1161
1154
  * [nginx config](contrib/nginx/copyparty.conf) -- entire domain/subdomain
@@ -1233,7 +1226,7 @@ interact with copyparty using non-browser clients
1233
1226
  * `(printf 'PUT / HTTP/1.1\r\n\r\n'; cat movie.mkv) >/dev/tcp/127.0.0.1/3923`
1234
1227
 
1235
1228
  * python: [up2k.py](https://github.com/9001/copyparty/blob/hovudstraum/bin/up2k.py) is a command-line up2k client [(webm)](https://ocv.me/stuff/u2cli.webm)
1236
- * file uploads, file-search, folder sync, autoresume of aborted/broken uploads
1229
+ * file uploads, file-search, [folder sync](#folder-sync), autoresume of aborted/broken uploads
1237
1230
  * can be downloaded from copyparty: controlpanel -> connect -> [up2k.py](http://127.0.0.1:3923/.cpr/a/up2k.py)
1238
1231
  * see [./bin/README.md#up2kpy](bin/README.md#up2kpy)
1239
1232
 
@@ -1254,17 +1247,27 @@ you can provide passwords using header `PW: hunter2`, cookie `cppwd=hunter2`, ur
1254
1247
  NOTE: curl will not send the original filename if you use `-T` combined with url-params! Also, make sure to always leave a trailing slash in URLs unless you want to override the filename
1255
1248
 
1256
1249
 
1250
+ ## folder sync
1251
+
1252
+ sync folders to/from copyparty
1253
+
1254
+ the commandline uploader [up2k.py](https://github.com/9001/copyparty/tree/hovudstraum/bin#up2kpy) with `--dr` is the best way to sync a folder to copyparty; verifies checksums and does files in parallel, and deletes unexpected files on the server after upload has finished which makes file-renames really cheap (it'll rename serverside and skip uploading)
1255
+
1256
+ alternatively there is [rclone](./docs/rclone.md) which allows for bidirectional sync and is *way* more flexible (stream files straight from sftp/s3/gcs to copyparty, ...), although there is no integrity check and it won't work with files over 100 MiB if copyparty is behind cloudflare
1257
+
1258
+ * starting from rclone v1.63 (currently [in beta](https://beta.rclone.org/?filter=latest)), rclone will also be faster than up2k.py
1259
+
1260
+
1257
1261
  ## mount as drive
1258
1262
 
1259
1263
  a remote copyparty server as a local filesystem; go to the control-panel and click `connect` to see a list of commands to do that
1260
1264
 
1261
1265
  alternatively, some alternatives roughly sorted by speed (unreproducible benchmark), best first:
1262
1266
 
1263
- * [rclone-http](./docs/rclone.md) (25s), read-only
1267
+ * [rclone-webdav](./docs/rclone.md) (25s), read/WRITE ([v1.63-beta](https://beta.rclone.org/?filter=latest))
1268
+ * [rclone-http](./docs/rclone.md) (26s), read-only
1269
+ * [partyfuse.py](./bin/#partyfusepy) (35s), read-only
1264
1270
  * [rclone-ftp](./docs/rclone.md) (47s), read/WRITE
1265
- * [rclone-webdav](./docs/rclone.md) (51s), read/WRITE
1266
- * copyparty-1.5.0's webdav server is faster than rclone-1.60.0 (69s)
1267
- * [partyfuse.py](./bin/#partyfusepy) (71s), read-only
1268
1271
  * davfs2 (103s), read/WRITE, *very fast* on small files
1269
1272
  * [win10-webdav](#webdav-server) (138s), read/WRITE
1270
1273
  * [win10-smb2](#smb-server) (387s), read/WRITE
@@ -1272,6 +1275,27 @@ alternatively, some alternatives roughly sorted by speed (unreproducible benchma
1272
1275
  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
1273
1276
 
1274
1277
 
1278
+ # android app
1279
+
1280
+ upload to copyparty with one tap
1281
+
1282
+ <a href="https://f-droid.org/packages/me.ocv.partyup/"><img src="https://ocv.me/fdroid.png" alt="Get it on F-Droid" height="50" /> '' <img src="https://img.shields.io/f-droid/v/me.ocv.partyup.svg" alt="f-droid version info" /></a> '' <a href="https://github.com/9001/party-up"><img src="https://img.shields.io/github/release/9001/party-up.svg?logo=github" alt="github version info" /></a>
1283
+
1284
+ the app is **NOT** the full copyparty server! just a basic upload client, nothing fancy yet
1285
+
1286
+ if you want to run the copyparty server on your android device, see [install on android](#install-on-android)
1287
+
1288
+
1289
+ # iOS shortcuts
1290
+
1291
+ there is no iPhone app, but the following shortcuts are almost as good:
1292
+
1293
+ * [upload to copyparty](https://www.icloud.com/shortcuts/41e98dd985cb4d3bb433222bc1e9e770) ([offline](https://github.com/9001/copyparty/raw/hovudstraum/contrib/ios/upload-to-copyparty.shortcut)) ([png](https://user-images.githubusercontent.com/241032/226118053-78623554-b0ed-482e-98e4-6d57ada58ea4.png)) based on the [original](https://www.icloud.com/shortcuts/ab415d5b4de3467b9ce6f151b439a5d7) by [Daedren](https://github.com/Daedren) (thx!)
1294
+ * can strip exif, upload files, pics, vids, links, clipboard
1295
+ * can download links and rehost the target file on copyparty (see first comment inside the shortcut)
1296
+ * pics become lowres if you share from gallery to shortcut, so better to launch the shortcut and pick stuff from there
1297
+
1298
+
1275
1299
  # performance
1276
1300
 
1277
1301
  defaults are usually fine - expect `8 GiB/s` download, `1 GiB/s` upload
@@ -1367,6 +1391,13 @@ by default, except for `GET` and `HEAD` operations, all requests must either:
1367
1391
  cors can be configured with `--acao` and `--acam`, or the protections entirely disabled with `--allow-csrf`
1368
1392
 
1369
1393
 
1394
+ ## https
1395
+
1396
+ 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)
1397
+
1398
+ copyparty doesn't speak HTTP/2 or QUIC, so using a reverse proxy would solve that as well
1399
+
1400
+
1370
1401
  # recovering from crashes
1371
1402
 
1372
1403
  ## client crashes
@@ -1434,7 +1465,7 @@ these are standalone programs and will never be imported / evaluated by copypart
1434
1465
 
1435
1466
  the self-contained "binary" [copyparty-sfx.py](https://github.com/9001/copyparty/releases/latest/download/copyparty-sfx.py) will unpack itself and run copyparty, assuming you have python installed of course
1436
1467
 
1437
- you can reduce the sfx size by repacking it; see [./docs/devnotes.md#sfx-repack](#./docs/devnotes.md#sfx-repack)
1468
+ you can reduce the sfx size by repacking it; see [./docs/devnotes.md#sfx-repack](./docs/devnotes.md#sfx-repack)
1438
1469
 
1439
1470
 
1440
1471
  ## copyparty.exe
@@ -1,6 +1,6 @@
1
1
  copyparty/__init__.py,sha256=ZIYqHdNC97NeoBTkFDSZ6E8aAma1tfjLhbax9oQHl4U,1063
2
- copyparty/__main__.py,sha256=g4skZeniCre3SHHXmS7YQQw5U-OCHLtWyhE8LKwJakA,66891
3
- copyparty/__version__.py,sha256=phw_xFNyG8ZYW5GwqPxta-ZhG9hgAfNzeuuGeR4D2A8,247
2
+ copyparty/__main__.py,sha256=NeG2cQHE4uRQ02zHZ7gv-NAlRgmTWmVSslPH5Uk84NI,66925
3
+ copyparty/__version__.py,sha256=Rjr8n-EApIithnjIGWw74_DGKrayh0_AUylCp1sLxk0,247
4
4
  copyparty/authsrv.py,sha256=Sh793NWnpklcz1ZEj-pt0FISjx-_BZJ8fkWm5rbWKrA,62030
5
5
  copyparty/broker_mp.py,sha256=SEJT7qIH7L0YH0e1yHucsUuYJE5m3DKymO57070_UCs,3590
6
6
  copyparty/broker_mpw.py,sha256=GlSn4PRd_OqqeG39FiXgNvPzXVQW6UCiAcqmBSr2q6g,3200
@@ -10,7 +10,7 @@ copyparty/cfg.py,sha256=ukauOEs_WKxzkt4MzIfLAU9eKGq9ZGcyIKSFMScc8xg,6436
10
10
  copyparty/dxml.py,sha256=lZpg-kn-kQsXRtNY1n6fRaS-b7uXzMCyv8ovKnhZcZc,1548
11
11
  copyparty/fsutil.py,sha256=c4fTvmclKbVABNsjU4rGddsjCgRwi9YExAyo-06ATc8,3932
12
12
  copyparty/ftpd.py,sha256=pPLkQTNmqfZRGfzALzZApEj6N8l3yo24RqDGDqISeyE,13841
13
- copyparty/httpcli.py,sha256=G9jaDyEAF82JCZpZYSHzIvGBTSFwEcncPSNcTxQ5aYo,119888
13
+ copyparty/httpcli.py,sha256=BcoVcyvVq32_ilEvbAjzB1zgvCyK28MXQTWUMB0gVFA,120713
14
14
  copyparty/httpconn.py,sha256=LXyJphs-FtyhFeDF-YUGVXKGf9KvHA86UzVx4FvRZo0,6674
15
15
  copyparty/httpsrv.py,sha256=EQsGZgKvN_D_eZ-XbFPZgFXTQc2Y2EXCo2qQhfWbf_4,14143
16
16
  copyparty/ico.py,sha256=eP_FGZEsnCLr6Q1ypITp7kbMKtQiDeROv0ydrbEKfIY,2643
@@ -25,9 +25,9 @@ copyparty/svchub.py,sha256=gqrIWzUT7Cz4Fd_lK0DKd5dLvNQuM0_YhJzpgXeUE78,22903
25
25
  copyparty/szip.py,sha256=o8NzYcqUUjg2MPvESa4VnAaANqD_JofBSr7Sb7eWu4I,8166
26
26
  copyparty/tcpsrv.py,sha256=ccUXnAa7IeRPWaaTAuOVcSgdBetlHVoJozsTrZcFx8Q,16633
27
27
  copyparty/th_cli.py,sha256=hcb-GGN7krnHF3LIp3tDix_OYwXnCRoTpsiO0TaDqOg,3826
28
- copyparty/th_srv.py,sha256=Y1Z51K91D6lBqq810sSu1wltQnruPvhJnhliX5rAj6k,20969
28
+ copyparty/th_srv.py,sha256=O7SJDLBx6pcRUiOR4G6Rqpi7FGthekedGTK3CXIFi_E,22119
29
29
  copyparty/u2idx.py,sha256=n3DSFc67tIk-Jn8-Z5EEG8Xb_qv48KomJFYvoXlmV-U,10493
30
- copyparty/up2k.py,sha256=0I-YREZDULliJTuxyqhz2j1XT2QnM3da1ojc31ZY_0Y,121148
30
+ copyparty/up2k.py,sha256=sZem4PlqUnXsNPpn2XzbfU0Zz3EMrPYpMeqYBKuDQd4,121292
31
31
  copyparty/util.py,sha256=hAZ4AN5rMQgDPYKiRdA3Qh-dZ0cBsaODR-mNrSuNwzw,71782
32
32
  copyparty/bos/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
33
  copyparty/bos/bos.py,sha256=Md2RwMauEdOS7SfK5aiHby8T1KgQoTaoEjVCYU98_4I,1560
@@ -49,17 +49,17 @@ copyparty/stolen/ifaddr/__init__.py,sha256=_BUN7eM5oD2Jgib6B22tEFSb20fD9urNPPaAl
49
49
  copyparty/stolen/ifaddr/_posix.py,sha256=-67NdfGrCktfQPakT2fLbjl2U00QMvyBGkSvrUuTOrU,2626
50
50
  copyparty/stolen/ifaddr/_shared.py,sha256=cJACl8cOxQ-HSYphZTzKMAjAx_TAFyJwUPjfD102Xqw,6111
51
51
  copyparty/stolen/ifaddr/_win32.py,sha256=EE-QyoBgeB7lYQ6z62VjXNaRozaYfCkaJBHGNA8QtZM,4026
52
- copyparty/web/baguettebox.js.gz,sha256=Irf0YDki85Pgke63z_TZws92UiGtrzpyg-39eguYAho,7282
53
- copyparty/web/browser.css.gz,sha256=k6iCbhvebd54n3NMGLPtltG9Ude8QyomZKI1bgRjQNc,10925
52
+ copyparty/web/baguettebox.js.gz,sha256=9ZXtLOKGTCRzIisSRIvqnO1s1ZQ90pxzoTU6vPol0m4,7295
53
+ copyparty/web/browser.css.gz,sha256=9oT_dnWhHdVrERi9GkNQElpcAhG1UtbUurqR033167U,10929
54
54
  copyparty/web/browser.html,sha256=561cy72h48x7g6_ZHXsAS3xYqnNwrXB1KK9VBVBqio8,5286
55
- copyparty/web/browser.js.gz,sha256=CLCD-X_N1K7_7ljSwD5jno-_-NpjuWP0ChzFAUeMyfc,57351
55
+ copyparty/web/browser.js.gz,sha256=28jB3rWCHZsS2a2OZHzI-GQZihMa4RxKyBp9PLL31IU,57919
56
56
  copyparty/web/browser2.html,sha256=3kR3QiDXYqtAo7gOoBtdTP3eRvibUCZHVVAbmAfaAVU,1604
57
57
  copyparty/web/cf.html,sha256=AQSPDFq1-Ww-9SyVLZtjVPfl054aqXs6svi5cQBlAdA,585
58
58
  copyparty/web/copyparty.gif,sha256=S1YS9GrKPbueEob_yTeWqzDcDoRXU_Z209BJ4YF-9pQ,126
59
59
  copyparty/web/dbg-audio.js.gz,sha256=MgESInC83l8nnKTd8JSbSmLy_lXwlypML153FAm2TmU,687
60
60
  copyparty/web/md.css.gz,sha256=gEI11ImLwhWYrsfb4YWx1OS1RgkpxHGsuMTJpcychJg,2011
61
61
  copyparty/web/md.html,sha256=CmkW3Aw2qGowEsFBk-4THRWJBR-fyNmkl1Dr15lPwdg,4063
62
- copyparty/web/md.js.gz,sha256=M0mX1a1w-a867BBcxtvRzxtVKcDvrIORUfPYNwBL_JA,4112
62
+ copyparty/web/md.js.gz,sha256=-4-0wF1YlLqHyiLpJQHTUPV4bys52hbbA9sKWEeRaFY,4121
63
63
  copyparty/web/md2.css.gz,sha256=83brwCdNBp7n0zr2O3fYFn9OP1i-mXfd-nde78imLGw,680
64
64
  copyparty/web/md2.js.gz,sha256=zpXdpg7yxZYPEU5UphdMQPsYQBkfSJM8z5OIKaoITpw,8209
65
65
  copyparty/web/mde.css.gz,sha256=L6YhxnYBoqT5bSwD99rx8ALXDh8d_1-sCvbc_p3MoAU,929
@@ -70,15 +70,15 @@ copyparty/web/msg.html,sha256=JQFDP-jOhBM4pln5bOyncC9lJ6YpN2TMIyNn-bLNSqE,898
70
70
  copyparty/web/splash.css.gz,sha256=dVMI8zrGO2glmPDS0QKhVmBgExe3p-QdUUIJ5EUWdrA,927
71
71
  copyparty/web/splash.html,sha256=tqCewuM2HMkkR7MH8ijgtAM1LHqlawqJgTGvG7NzECY,3741
72
72
  copyparty/web/splash.js.gz,sha256=2VuxIx4y0hyW9I5NWG83Bcabk5NJDftQt7a_j9Gb5nY,1235
73
- copyparty/web/svcs.html,sha256=yf-2pYOKa7EEmFbY_SGjnAjhzCH4DlynbcRHe6GicqY,9354
73
+ copyparty/web/svcs.html,sha256=crtzPR4VKBKVRKY5m1DsDk4vmgBdVLpbOCgRa3nTrYk,9274
74
74
  copyparty/web/svcs.js.gz,sha256=SSVKYYgZkEKMdDLjekvcXB00v-rCVJXh2GD_YtCvu7c,519
75
- copyparty/web/ui.css.gz,sha256=kU3LGyd2MpBzbp1_7Dy1_11V9Nw7QPuNQlpLB_z0uEk,2377
75
+ copyparty/web/ui.css.gz,sha256=Vx-kzNtCsAq7N3W9n27WE8zd6nNLegT0_v5AWmYyk7g,2418
76
76
  copyparty/web/up2k.js.gz,sha256=fGYvDuq34kVz16occIYU9KUQZF9ZemcQLI57o2_DmK4,21538
77
- copyparty/web/util.js.gz,sha256=zDKTUnRffdMaJx4WJd-GYK0S_4OpbcWOMjSOB_mVNYs,12616
77
+ copyparty/web/util.js.gz,sha256=isC6LW43SGcZn9ueMfmxGmKzSxJtwqjY3_R2AhNPUdM,13078
78
78
  copyparty/web/w.hash.js.gz,sha256=07eXr3ktdGNmFBLpqWCp6LsAx8AqIyy1KDNz2-r3p8U,1059
79
79
  copyparty/web/a/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
80
80
  copyparty/web/a/partyfuse.py,sha256=mJKqR8LjX19P4Knqa02ob5ogwPVtJXSqxkEEGZU0r60,32276
81
- copyparty/web/a/up2k.py,sha256=jskvi0oMgSw82oq5OW1AYxrOq9kkY4VY3N10GOTRTIY,35130
81
+ copyparty/web/a/up2k.py,sha256=ZplodaoKL19ND5kI7LVi-5wYTCo2Qy8zYesv6OrO4gQ,34969
82
82
  copyparty/web/a/webdav-cfg.bat,sha256=Y4NoGZlksAIg4cBMb7KdJrpKC6Nx97onaTl6yMjaimk,1449
83
83
  copyparty/web/dd/2.png,sha256=gJ14XFPzaw95L6z92fSq9eMPikSQyu-03P1lgiGe0_I,258
84
84
  copyparty/web/dd/3.png,sha256=4lho8Koz5tV7jJ4ODo6GMTScZfkqsT05yp48EDFIlyg,252
@@ -86,24 +86,24 @@ copyparty/web/dd/4.png,sha256=fIwEVmtZNZtloZuVEKPKnkx3SELwRJmB3US61y7t2lI,248
86
86
  copyparty/web/dd/5.png,sha256=Lfpu8-yOlhONuoMbygloKqQVPXSm9gjxH2gUYn5QQAE,250
87
87
  copyparty/web/dd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
88
88
  copyparty/web/deps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
89
- copyparty/web/deps/easymde.css.gz,sha256=jHGAXW4LIyUMAPOtxNckmkJQ9s8fj4Qx6NQEsULiG8A,3053
90
- copyparty/web/deps/easymde.js.gz,sha256=rmnom8pPzoPGCu6kdPASwkYeotcipTc-W-1gBn4yDOw,76951
91
- copyparty/web/deps/marked.js.gz,sha256=h7GetwsXIFZS4QfirCkUsI7vyyJdxk0UH-LKetjO5Zo,14556
92
- copyparty/web/deps/mini-fa.css.gz,sha256=sXyzSXMZTqTl3dhIIpKMkXFa9qhInOoIo7oL4yBUWCY,584
89
+ copyparty/web/deps/easymde.css.gz,sha256=bidHOWlCCwqvOrsz82ZzkTJzxXTJcKVVt328XZ72wYk,3053
90
+ copyparty/web/deps/easymde.js.gz,sha256=O0gNqyYoNMQ5wWd2bNO5D9VIS4SeI_GKN1aBPTyd6VI,76953
91
+ copyparty/web/deps/marked.js.gz,sha256=1xWr45dJMkwk0H58fZiLYmUYj1yaMP0BQ7S85XQgfQU,14819
92
+ copyparty/web/deps/mini-fa.css.gz,sha256=HKDETLj1IIUG3PhKixczxvPr5FAo-eD5phR03cf5Ijc,584
93
93
  copyparty/web/deps/mini-fa.woff,sha256=L9DNncV2TIyvsrspMbJouvnnt7F068Hbn7YZYvN76AU,2784
94
94
  copyparty/web/deps/prism.css.gz,sha256=dDssFDwbLNlB9QJsOepOdMse8FgrLrHIVpx1gNj4ZvY,1478
95
95
  copyparty/web/deps/prism.js.gz,sha256=DR0OAfTUb6PkzSPgxjnjj7jqlpvuCHdMDJKbsQP7s5E,41428
96
96
  copyparty/web/deps/prismd.css.gz,sha256=hzzspI_ptCygzmsIp9rKsf1M4yU12Ma7TfE-wyoXt3E,1647
97
97
  copyparty/web/deps/scp.woff2,sha256=w99BDU5i8MukkMEL-iW0YO9H4vFFZSPWxbkH70ytaAg,8612
98
- copyparty/web/deps/sha512.ac.js.gz,sha256=IzAmZIkSyMbnn7GK3k5PW085PNcZxtk_u4UW_E1d6ek,7043
98
+ copyparty/web/deps/sha512.ac.js.gz,sha256=qELXngcl-Zitrpwolm4EWqVBPyEht013iP7uDuUDPk4,7043
99
99
  copyparty/web/deps/sha512.hw.js.gz,sha256=0xJaw75Tghoblu72C2h4YoU1izSR99mBtDMoGqZ3xvs,8119
100
- copyparty-1.6.9.data/data/share/doc/copyparty/LICENSE,sha256=yyzj1id78vWoLs8zbMRJY7xkkLz0lv-9dfyeIauqdfM,1059
101
- copyparty-1.6.9.data/data/share/doc/copyparty/README.md,sha256=SG-Kd3cYnahsKrjGjQeC2_rcC1TUr9NIaf0kgZyJ0cM,80896
102
- copyparty-1.6.9.data/scripts/partyfuse.py,sha256=zhVQm5m-pWcUyo4aOvzZveOMeLJSY7gB2UGFYXp10XM,32262
103
- copyparty-1.6.9.data/scripts/up2k.py,sha256=6J3zq9wZPgRTti32p2d7kg5YHfZvlu4ZZiElU3492bU,35116
104
- copyparty-1.6.9.dist-info/LICENSE,sha256=yyzj1id78vWoLs8zbMRJY7xkkLz0lv-9dfyeIauqdfM,1059
105
- copyparty-1.6.9.dist-info/METADATA,sha256=oI9g3XQj2tOIuB42qWkuwvRSA9MD_lijW-8w61zQyK8,82982
106
- copyparty-1.6.9.dist-info/WHEEL,sha256=bb2Ot9scclHKMOLDEHY6B2sicWOgugjFKaJsT7vwMQo,110
107
- copyparty-1.6.9.dist-info/entry_points.txt,sha256=v3KsE-NQ_WGZkl78BlR8lZ4oHWhGbtjaEw3-iGXLfLQ,54
108
- copyparty-1.6.9.dist-info/top_level.txt,sha256=LnYUPsDyk-8kFgM6YJLG4h820DQekn81cObKSu9g-sI,10
109
- copyparty-1.6.9.dist-info/RECORD,,
100
+ copyparty-1.6.11.data/data/share/doc/copyparty/LICENSE,sha256=yyzj1id78vWoLs8zbMRJY7xkkLz0lv-9dfyeIauqdfM,1059
101
+ copyparty-1.6.11.data/data/share/doc/copyparty/README.md,sha256=4XP68C2c4bQew3J3SvqaZ7WLtzsk217qWX37BTj-Dms,83258
102
+ copyparty-1.6.11.data/scripts/partyfuse.py,sha256=zhVQm5m-pWcUyo4aOvzZveOMeLJSY7gB2UGFYXp10XM,32262
103
+ copyparty-1.6.11.data/scripts/up2k.py,sha256=cgAbhiy6uEIg3dxFhq3qHYOuPxtJlk_94BzNkHfjj7Y,34955
104
+ copyparty-1.6.11.dist-info/LICENSE,sha256=yyzj1id78vWoLs8zbMRJY7xkkLz0lv-9dfyeIauqdfM,1059
105
+ copyparty-1.6.11.dist-info/METADATA,sha256=Ol7LxCKf5jo5ANwFgaetbAXtMnsbh1AHH9dSKmg74Kk,85345
106
+ copyparty-1.6.11.dist-info/WHEEL,sha256=bb2Ot9scclHKMOLDEHY6B2sicWOgugjFKaJsT7vwMQo,110
107
+ copyparty-1.6.11.dist-info/entry_points.txt,sha256=v3KsE-NQ_WGZkl78BlR8lZ4oHWhGbtjaEw3-iGXLfLQ,54
108
+ copyparty-1.6.11.dist-info/top_level.txt,sha256=LnYUPsDyk-8kFgM6YJLG4h820DQekn81cObKSu9g-sI,10
109
+ copyparty-1.6.11.dist-info/RECORD,,