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/httpcli.py CHANGED
@@ -642,8 +642,12 @@ class HttpCli(object):
642
642
  if not self._check_nonfatal(pex, post):
643
643
  self.keepalive = False
644
644
 
645
- em = str(ex)
646
- msg = em if pex is ex else min_ex()
645
+ if pex is ex:
646
+ em = msg = str(ex)
647
+ else:
648
+ em = repr(ex)
649
+ msg = min_ex()
650
+
647
651
  if pex.code != 404 or self.do_log:
648
652
  self.log(
649
653
  "%s\033[0m, %s" % (msg, self.vpath),
@@ -691,6 +695,7 @@ class HttpCli(object):
691
695
  self.vpath,
692
696
  self.host,
693
697
  self.uname,
698
+ "",
694
699
  time.time(),
695
700
  0,
696
701
  self.ip,
@@ -1627,6 +1632,7 @@ class HttpCli(object):
1627
1632
  self.vpath,
1628
1633
  self.host,
1629
1634
  self.uname,
1635
+ self.asrv.vfs.get_perms(self.vpath, self.uname),
1630
1636
  time.time(),
1631
1637
  len(buf),
1632
1638
  self.ip,
@@ -1670,6 +1676,8 @@ class HttpCli(object):
1670
1676
  remains = int(self.headers.get("content-length", -1))
1671
1677
  if remains == -1:
1672
1678
  self.keepalive = False
1679
+ self.in_hdr_recv = True
1680
+ self.s.settimeout(max(self.args.s_tbody // 20, 1))
1673
1681
  return read_socket_unbounded(self.sr, bufsz), remains
1674
1682
  else:
1675
1683
  return read_socket(self.sr, bufsz, remains), remains
@@ -1774,6 +1782,7 @@ class HttpCli(object):
1774
1782
  self.vpath,
1775
1783
  self.host,
1776
1784
  self.uname,
1785
+ self.asrv.vfs.get_perms(self.vpath, self.uname),
1777
1786
  at,
1778
1787
  remains,
1779
1788
  self.ip,
@@ -1864,6 +1873,7 @@ class HttpCli(object):
1864
1873
  self.vpath,
1865
1874
  self.host,
1866
1875
  self.uname,
1876
+ self.asrv.vfs.get_perms(self.vpath, self.uname),
1867
1877
  mt,
1868
1878
  post_sz,
1869
1879
  self.ip,
@@ -1900,6 +1910,9 @@ class HttpCli(object):
1900
1910
  0 if ANYWIN else bos.stat(path).st_ino,
1901
1911
  )[: vfs.flags["fk"]]
1902
1912
 
1913
+ if "media" in self.uparam or "medialinks" in vfs.flags:
1914
+ vsuf += "&v" if vsuf else "?v"
1915
+
1903
1916
  vpath = "/".join([x for x in [vfs.vpath, rem, fn] if x])
1904
1917
  vpath = quotep(vpath)
1905
1918
 
@@ -2021,7 +2034,7 @@ class HttpCli(object):
2021
2034
 
2022
2035
  v = self.uparam[k]
2023
2036
 
2024
- if self._use_dirkey():
2037
+ if self._use_dirkey(self.vn, ""):
2025
2038
  vn = self.vn
2026
2039
  rem = self.rem
2027
2040
  else:
@@ -2543,6 +2556,7 @@ class HttpCli(object):
2543
2556
  self.vpath,
2544
2557
  self.host,
2545
2558
  self.uname,
2559
+ self.asrv.vfs.get_perms(self.vpath, self.uname),
2546
2560
  at,
2547
2561
  0,
2548
2562
  self.ip,
@@ -2606,6 +2620,7 @@ class HttpCli(object):
2606
2620
  self.vpath,
2607
2621
  self.host,
2608
2622
  self.uname,
2623
+ self.asrv.vfs.get_perms(self.vpath, self.uname),
2609
2624
  at,
2610
2625
  sz,
2611
2626
  self.ip,
@@ -2681,6 +2696,9 @@ class HttpCli(object):
2681
2696
  0 if ANYWIN or not ap else bos.stat(ap).st_ino,
2682
2697
  )[: vfs.flags["fk"]]
2683
2698
 
2699
+ if "media" in self.uparam or "medialinks" in vfs.flags:
2700
+ vsuf += "&v" if vsuf else "?v"
2701
+
2684
2702
  vpath = "{}/{}".format(upload_vpath, lfn).strip("/")
2685
2703
  rel_url = quotep(self.args.RS + vpath) + vsuf
2686
2704
  msg += 'sha512: {} // {} // {} bytes // <a href="/{}">{}</a> {}\n'.format(
@@ -2847,6 +2865,7 @@ class HttpCli(object):
2847
2865
  self.vpath,
2848
2866
  self.host,
2849
2867
  self.uname,
2868
+ self.asrv.vfs.get_perms(self.vpath, self.uname),
2850
2869
  time.time(),
2851
2870
  0,
2852
2871
  self.ip,
@@ -2885,6 +2904,7 @@ class HttpCli(object):
2885
2904
  self.vpath,
2886
2905
  self.host,
2887
2906
  self.uname,
2907
+ self.asrv.vfs.get_perms(self.vpath, self.uname),
2888
2908
  new_lastmod,
2889
2909
  sz,
2890
2910
  self.ip,
@@ -2939,22 +2959,24 @@ class HttpCli(object):
2939
2959
 
2940
2960
  return file_lastmod, True
2941
2961
 
2942
- def _use_dirkey(self, ap = "") :
2962
+ def _use_dirkey(self, vn , ap ) :
2943
2963
  if self.can_read or not self.can_get:
2944
2964
  return False
2945
2965
 
2946
- if self.vn.flags.get("dky"):
2966
+ if vn.flags.get("dky"):
2947
2967
  return True
2948
2968
 
2949
2969
  req = self.uparam.get("k") or ""
2950
2970
  if not req:
2951
2971
  return False
2952
2972
 
2953
- dk_len = self.vn.flags.get("dk")
2973
+ dk_len = vn.flags.get("dk")
2954
2974
  if not dk_len:
2955
2975
  return False
2956
2976
 
2957
- ap = ap or self.vn.canonical(self.rem)
2977
+ if not ap:
2978
+ ap = vn.canonical(self.rem)
2979
+
2958
2980
  zs = self.gen_fk(2, self.args.dk_salt, ap, 0, 0)[:dk_len]
2959
2981
  if req == zs:
2960
2982
  return True
@@ -2963,6 +2985,71 @@ class HttpCli(object):
2963
2985
  self.log(t % (zs, req, self.req, ap), 6)
2964
2986
  return False
2965
2987
 
2988
+ def _use_filekey(self, vn , ap , st ) :
2989
+ if self.can_read or not self.can_get:
2990
+ return False
2991
+
2992
+ req = self.uparam.get("k") or ""
2993
+ if not req:
2994
+ return False
2995
+
2996
+ fk_len = vn.flags.get("fk")
2997
+ if not fk_len:
2998
+ return False
2999
+
3000
+ if not ap:
3001
+ ap = self.vn.canonical(self.rem)
3002
+
3003
+ alg = 2 if "fka" in vn.flags else 1
3004
+
3005
+ zs = self.gen_fk(
3006
+ alg, self.args.fk_salt, ap, st.st_size, 0 if ANYWIN else st.st_ino
3007
+ )[:fk_len]
3008
+
3009
+ if req == zs:
3010
+ return True
3011
+
3012
+ t = "wrong filekey, want %s, got %s\n vp: %s\n ap: %s"
3013
+ self.log(t % (zs, req, self.req, ap), 6)
3014
+ return False
3015
+
3016
+ def _add_logues(
3017
+ self, vn , abspath , lnames
3018
+ ) :
3019
+ logues = ["", ""]
3020
+ if not self.args.no_logues:
3021
+ for n, fn in enumerate([".prologue.html", ".epilogue.html"]):
3022
+ if lnames is not None and fn not in lnames:
3023
+ continue
3024
+ fn = os.path.join(abspath, fn)
3025
+ if bos.path.exists(fn):
3026
+ with open(fsenc(fn), "rb") as f:
3027
+ logues[n] = f.read().decode("utf-8")
3028
+ if "exp" in vn.flags:
3029
+ logues[n] = self._expand(
3030
+ logues[n], vn.flags.get("exp_lg") or []
3031
+ )
3032
+
3033
+ readme = ""
3034
+ if not self.args.no_readme and not logues[1]:
3035
+ if lnames is None:
3036
+ fns = ["README.md", "readme.md"]
3037
+ elif "readme.md" in lnames:
3038
+ fns = [lnames["readme.md"]]
3039
+ else:
3040
+ fns = []
3041
+
3042
+ for fn in fns:
3043
+ fn = os.path.join(abspath, fn)
3044
+ if bos.path.isfile(fn):
3045
+ with open(fsenc(fn), "rb") as f:
3046
+ readme = f.read().decode("utf-8")
3047
+ break
3048
+ if readme and "exp" in vn.flags:
3049
+ readme = self._expand(readme, vn.flags.get("exp_md") or [])
3050
+
3051
+ return logues, readme
3052
+
2966
3053
  def _expand(self, txt , phs ) :
2967
3054
  for ph in phs:
2968
3055
  if ph.startswith("hdr."):
@@ -2992,6 +3079,7 @@ class HttpCli(object):
2992
3079
  logtail = ""
2993
3080
 
2994
3081
  if ptop is not None:
3082
+ ap_data = "<%s>" % (req_path,)
2995
3083
  try:
2996
3084
  dp, fn = os.path.split(req_path)
2997
3085
  tnam = fn + ".PARTIAL"
@@ -3338,7 +3426,16 @@ class HttpCli(object):
3338
3426
 
3339
3427
  if lower < upper and not broken:
3340
3428
  with open(req_path, "rb") as f:
3341
- remains = sendfile_py(self.log, lower, upper, f, self.s, wr_sz, wr_slp)
3429
+ remains = sendfile_py(
3430
+ self.log,
3431
+ lower,
3432
+ upper,
3433
+ f,
3434
+ self.s,
3435
+ wr_sz,
3436
+ wr_slp,
3437
+ not self.args.no_poll,
3438
+ )
3342
3439
 
3343
3440
  spd = self._spd((upper - lower) - remains)
3344
3441
  if self.do_log:
@@ -3850,7 +3947,7 @@ class HttpCli(object):
3850
3947
  dk_sz = False
3851
3948
  if dk:
3852
3949
  vn, rem = vfs.get(top, self.uname, False, False)
3853
- if vn.flags.get("dks") and self._use_dirkey(vn.canonical(rem)):
3950
+ if vn.flags.get("dks") and self._use_dirkey(vn, vn.canonical(rem)):
3854
3951
  dk_sz = vn.flags.get("dk")
3855
3952
 
3856
3953
  dots = False
@@ -4159,6 +4256,9 @@ class HttpCli(object):
4159
4256
  add_og = True
4160
4257
  og_fn = ""
4161
4258
 
4259
+ if "v" in self.uparam:
4260
+ add_og = og_ua = True
4261
+
4162
4262
  if "b" in self.uparam:
4163
4263
  self.out_headers["X-Robots-Tag"] = "noindex, nofollow"
4164
4264
 
@@ -4171,9 +4271,20 @@ class HttpCli(object):
4171
4271
  if idx and hasattr(idx, "p_end"):
4172
4272
  icur = idx.get_cur(dbv)
4173
4273
 
4274
+ if "k" in self.uparam or "dky" in vn.flags:
4275
+ if is_dir:
4276
+ use_dirkey = self._use_dirkey(vn, abspath)
4277
+ use_filekey = False
4278
+ else:
4279
+ use_filekey = self._use_filekey(vn, abspath, st)
4280
+ use_dirkey = False
4281
+ else:
4282
+ use_dirkey = use_filekey = False
4283
+
4174
4284
  th_fmt = self.uparam.get("th")
4175
4285
  if self.can_read or (
4176
- self.can_get and (vn.flags.get("dk") or "fk" not in vn.flags)
4286
+ self.can_get
4287
+ and (use_filekey or use_dirkey or (not is_dir and "fk" not in vn.flags))
4177
4288
  ):
4178
4289
  if th_fmt is not None:
4179
4290
  nothumb = "dthumb" in dbv.flags
@@ -4190,18 +4301,21 @@ class HttpCli(object):
4190
4301
  if cfn:
4191
4302
  fn = cfn[0]
4192
4303
  fp = os.path.join(abspath, fn)
4193
- if bos.path.exists(fp):
4194
- vrem = "{}/{}".format(vrem, fn).strip("/")
4195
- is_dir = False
4304
+ st = bos.stat(fp)
4305
+ vrem = "{}/{}".format(vrem, fn).strip("/")
4306
+ is_dir = False
4196
4307
  except:
4197
4308
  pass
4198
4309
  else:
4199
4310
  for fn in self.args.th_covers:
4200
4311
  fp = os.path.join(abspath, fn)
4201
- if bos.path.exists(fp):
4312
+ try:
4313
+ st = bos.stat(fp)
4202
4314
  vrem = "{}/{}".format(vrem, fn).strip("/")
4203
4315
  is_dir = False
4204
4316
  break
4317
+ except:
4318
+ pass
4205
4319
 
4206
4320
  if is_dir:
4207
4321
  return self.tx_svg("folder")
@@ -4253,21 +4367,10 @@ class HttpCli(object):
4253
4367
 
4254
4368
  if not is_dir and (self.can_read or self.can_get):
4255
4369
  if not self.can_read and not fk_pass and "fk" in vn.flags:
4256
- alg = 2 if "fka" in vn.flags else 1
4257
- correct = self.gen_fk(
4258
- alg,
4259
- self.args.fk_salt,
4260
- abspath,
4261
- st.st_size,
4262
- 0 if ANYWIN else st.st_ino,
4263
- )[: vn.flags["fk"]]
4264
- got = self.uparam.get("k")
4265
- if got != correct:
4266
- t = "wrong filekey, want %s, got %s\n vp: %s\n ap: %s"
4267
- self.log(t % (correct, got, self.req, abspath), 6)
4370
+ if not use_filekey:
4268
4371
  return self.tx_404()
4269
4372
 
4270
- if add_og:
4373
+ if add_og and not abspath.lower().endswith(".md"):
4271
4374
  if og_ua or self.host not in self.headers.get("referer", ""):
4272
4375
  self.vpath, og_fn = vsplit(self.vpath)
4273
4376
  vpath = self.vpath
@@ -4282,7 +4385,7 @@ class HttpCli(object):
4282
4385
  (abspath.endswith(".md") or self.can_delete)
4283
4386
  and "nohtml" not in vn.flags
4284
4387
  and (
4285
- "v" in self.uparam
4388
+ ("v" in self.uparam and abspath.endswith(".md"))
4286
4389
  or "edit" in self.uparam
4287
4390
  or "edit2" in self.uparam
4288
4391
  )
@@ -4295,7 +4398,7 @@ class HttpCli(object):
4295
4398
  )
4296
4399
 
4297
4400
  elif is_dir and not self.can_read:
4298
- if self._use_dirkey(abspath):
4401
+ if use_dirkey:
4299
4402
  is_dk = True
4300
4403
  elif not self.can_write:
4301
4404
  return self.tx_404(True)
@@ -4352,29 +4455,6 @@ class HttpCli(object):
4352
4455
  tpl = "browser2"
4353
4456
  is_js = False
4354
4457
 
4355
- logues = ["", ""]
4356
- if not self.args.no_logues:
4357
- for n, fn in enumerate([".prologue.html", ".epilogue.html"]):
4358
- fn = os.path.join(abspath, fn)
4359
- if bos.path.exists(fn):
4360
- with open(fsenc(fn), "rb") as f:
4361
- logues[n] = f.read().decode("utf-8")
4362
- if "exp" in vn.flags:
4363
- logues[n] = self._expand(
4364
- logues[n], vn.flags.get("exp_lg") or []
4365
- )
4366
-
4367
- readme = ""
4368
- if not self.args.no_readme and not logues[1]:
4369
- for fn in ["README.md", "readme.md"]:
4370
- fn = os.path.join(abspath, fn)
4371
- if bos.path.isfile(fn):
4372
- with open(fsenc(fn), "rb") as f:
4373
- readme = f.read().decode("utf-8")
4374
- break
4375
- if readme and "exp" in vn.flags:
4376
- readme = self._expand(readme, vn.flags.get("exp_md") or [])
4377
-
4378
4458
  vf = vn.flags
4379
4459
  unlist = vf.get("unlist", "")
4380
4460
  ls_ret = {
@@ -4393,8 +4473,6 @@ class HttpCli(object):
4393
4473
  "frand": bool(vn.flags.get("rand")),
4394
4474
  "unlist": unlist,
4395
4475
  "perms": perms,
4396
- "logues": logues,
4397
- "readme": readme,
4398
4476
  }
4399
4477
  cgv = {
4400
4478
  "ls0": None,
@@ -4412,8 +4490,8 @@ class HttpCli(object):
4412
4490
  "have_zip": (not self.args.no_zip),
4413
4491
  "have_unpost": int(self.args.unpost),
4414
4492
  "sb_md": "" if "no_sb_md" in vf else (vf.get("md_sbf") or "y"),
4415
- "readme": readme,
4416
4493
  "dgrid": "grid" in vf,
4494
+ "dgsel": "gsel" in vf,
4417
4495
  "dsort": vf["sort"],
4418
4496
  "dcrop": vf["crop"],
4419
4497
  "dth3x": vf["th3x"],
@@ -4434,7 +4512,6 @@ class HttpCli(object):
4434
4512
  "have_b_u": (self.can_write and self.uparam.get("b") == "u"),
4435
4513
  "sb_lg": "" if "no_sb_lg" in vf else (vf.get("lg_sbf") or "y"),
4436
4514
  "url_suf": url_suf,
4437
- "logues": logues,
4438
4515
  "title": html_escape("%s %s" % (self.args.bname, self.vpath), crlf=True),
4439
4516
  "srv_info": srv_infot,
4440
4517
  "dtheme": self.args.theme,
@@ -4454,6 +4531,10 @@ class HttpCli(object):
4454
4531
  j2a["no_prism"] = True
4455
4532
 
4456
4533
  if not self.can_read and not is_dk:
4534
+ logues, readme = self._add_logues(vn, abspath, None)
4535
+ ls_ret["logues"] = j2a["logues"] = logues
4536
+ ls_ret["readme"] = cgv["readme"] = readme
4537
+
4457
4538
  if is_ls:
4458
4539
  return self.tx_ls(ls_ret)
4459
4540
 
@@ -4510,6 +4591,8 @@ class HttpCli(object):
4510
4591
  ):
4511
4592
  ls_names = exclude_dotfiles(ls_names)
4512
4593
 
4594
+ lnames = {x.lower(): x for x in ls_names}
4595
+
4513
4596
  add_dk = vf.get("dk")
4514
4597
  add_fk = vf.get("fk")
4515
4598
  fk_alg = 2 if "fka" in vf else 1
@@ -4699,9 +4782,45 @@ class HttpCli(object):
4699
4782
  else:
4700
4783
  taglist = list(tagset)
4701
4784
 
4785
+ logues, readme = self._add_logues(vn, abspath, lnames)
4786
+ ls_ret["logues"] = j2a["logues"] = logues
4787
+ ls_ret["readme"] = cgv["readme"] = readme
4788
+
4702
4789
  if not files and not dirs and not readme and not logues[0] and not logues[1]:
4703
4790
  logues[1] = "this folder is empty"
4704
4791
 
4792
+ if "descript.ion" in lnames and os.path.isfile(
4793
+ os.path.join(abspath, lnames["descript.ion"])
4794
+ ):
4795
+ rem = []
4796
+ with open(os.path.join(abspath, lnames["descript.ion"]), "rb") as f:
4797
+ for bln in [x.strip() for x in f]:
4798
+ try:
4799
+ if bln.endswith(b"\x04\xc2"):
4800
+ # multiline comment; replace literal r"\n" with " // "
4801
+ bln = bln.replace(br"\\n", b" // ")[:-2]
4802
+ ln = bln.decode("utf-8", "replace")
4803
+ if ln.startswith('"'):
4804
+ fn, desc = ln.split('" ', 1)
4805
+ fn = fn[1:]
4806
+ else:
4807
+ fn, desc = ln.split(" ", 1)
4808
+ fe = next(
4809
+ (x for x in files if x["name"].lower() == fn.lower()), None
4810
+ )
4811
+ if fe:
4812
+ fe["tags"]["descript.ion"] = desc
4813
+ else:
4814
+ t = "<li><code>%s</code> %s</li>"
4815
+ rem.append(t % (html_escape(fn), html_escape(desc)))
4816
+ except:
4817
+ pass
4818
+ if "descript.ion" not in taglist:
4819
+ taglist.insert(0, "descript.ion")
4820
+ if rem and not logues[1]:
4821
+ t = "<h3>descript.ion</h3><ul>\n"
4822
+ logues[1] = t + "\n".join(rem) + "</ul>"
4823
+
4705
4824
  if is_ls:
4706
4825
  ls_ret["dirs"] = dirs
4707
4826
  ls_ret["files"] = files
@@ -4771,14 +4890,13 @@ class HttpCli(object):
4771
4890
  self.conn.hsrv.j2[tpl] = j2env.get_template(tname)
4772
4891
  thumb = ""
4773
4892
  is_pic = is_vid = is_au = False
4774
- covernames = self.args.th_coversd
4775
- for fn in ls_names:
4776
- if fn.lower() in covernames:
4777
- thumb = fn
4893
+ for fn in self.args.th_coversd:
4894
+ if fn in lnames:
4895
+ thumb = lnames[fn]
4778
4896
  break
4779
4897
  if og_fn:
4780
4898
  ext = og_fn.split(".")[-1].lower()
4781
- if ext in self.thumbcli.thumbable:
4899
+ if self.thumbcli and ext in self.thumbcli.thumbable:
4782
4900
  is_pic = (
4783
4901
  ext in self.thumbcli.fmt_pil
4784
4902
  or ext in self.thumbcli.fmt_vips
copyparty/httpsrv.py CHANGED
@@ -12,7 +12,7 @@ import time
12
12
 
13
13
  import queue
14
14
 
15
- from .__init__ import ANYWIN, CORES, EXE, MACOS, TYPE_CHECKING, EnvParams
15
+ from .__init__ import ANYWIN, CORES, EXE, MACOS, TYPE_CHECKING, EnvParams, unicode
16
16
 
17
17
  try:
18
18
  MNFE = ModuleNotFoundError
@@ -331,11 +331,11 @@ class HttpSrv(object):
331
331
 
332
332
  try:
333
333
  sck, saddr = srv_sck.accept()
334
- cip, cport = saddr[:2]
334
+ cip = unicode(saddr[0])
335
335
  if cip.startswith("::ffff:"):
336
336
  cip = cip[7:]
337
337
 
338
- addr = (cip, cport)
338
+ addr = (cip, saddr[1])
339
339
  except (OSError, socket.error) as ex:
340
340
  if self.stopping:
341
341
  break
copyparty/mdns.py CHANGED
@@ -357,7 +357,7 @@ class MDNS(MCast):
357
357
  except:
358
358
  pass
359
359
 
360
- self.srv = {}
360
+ self.srv.clear()
361
361
 
362
362
  def eat(self, buf , addr , sck ) :
363
363
  cip = addr[0]
copyparty/mtag.py CHANGED
@@ -133,6 +133,9 @@ def au_unpk(
133
133
  zil = [x for x in zil if x.filename.lower().split(".")[-1] == au]
134
134
  fi = zf.open(zil[0])
135
135
 
136
+ else:
137
+ raise Exception("unknown compression %s" % (pk,))
138
+
136
139
  with os.fdopen(fd, "wb") as fo:
137
140
  while True:
138
141
  buf = fi.read(32768)
copyparty/smbd.py CHANGED
@@ -237,7 +237,7 @@ class SMB(object):
237
237
 
238
238
  xbu = vfs.flags.get("xbu")
239
239
  if xbu and not runhook(
240
- self.nlog, xbu, ap, vpath, "", "", 0, 0, "1.7.6.2", 0, ""
240
+ self.nlog, xbu, ap, vpath, "", "", "", 0, 0, "1.7.6.2", 0, ""
241
241
  ):
242
242
  yeet("blocked by xbu server config: " + vpath)
243
243
 
copyparty/ssdp.py CHANGED
@@ -184,7 +184,7 @@ class SSDPd(MCast):
184
184
  except:
185
185
  pass
186
186
 
187
- self.srv = {}
187
+ self.srv.clear()
188
188
 
189
189
  def eat(self, buf , addr ) :
190
190
  cip = addr[0]
copyparty/svchub.py CHANGED
@@ -473,8 +473,10 @@ class SvcHub(object):
473
473
  zsl = al.th_covers.split(",")
474
474
  zsl = [x.strip() for x in zsl]
475
475
  zsl = [x for x in zsl if x]
476
- al.th_covers = set(zsl)
477
- al.th_coversd = set(zsl + ["." + x for x in zsl])
476
+ al.th_covers = zsl
477
+ al.th_coversd = zsl + ["." + x for x in zsl]
478
+ al.th_covers_set = set(al.th_covers)
479
+ al.th_coversd_set = set(al.th_coversd)
478
480
 
479
481
  for k in "c".split(" "):
480
482
  vl = getattr(al, k)
copyparty/tcpsrv.py CHANGED
@@ -15,6 +15,7 @@ from .util import (
15
15
  E_ADDR_IN_USE,
16
16
  E_ADDR_NOT_AVAIL,
17
17
  E_UNREACH,
18
+ HAVE_IPV6,
18
19
  IP6ALL,
19
20
  Netdev,
20
21
  min_ex,
@@ -108,8 +109,10 @@ class TcpSrv(object):
108
109
 
109
110
  eps = {
110
111
  "127.0.0.1": Netdev("127.0.0.1", 0, "", "local only"),
111
- "::1": Netdev("::1", 0, "", "local only"),
112
112
  }
113
+ if HAVE_IPV6:
114
+ eps["::1"] = Netdev("::1", 0, "", "local only")
115
+
113
116
  nonlocals = [x for x in self.args.i if x not in [k.split("/")[0] for k in eps]]
114
117
  if nonlocals:
115
118
  try:
copyparty/tftpd.py CHANGED
@@ -33,7 +33,7 @@ from partftpy import (
33
33
  )
34
34
  from partftpy.TftpShared import TftpException
35
35
 
36
- from .__init__ import EXE, TYPE_CHECKING
36
+ from .__init__ import EXE, PY2, TYPE_CHECKING
37
37
  from .authsrv import VFS
38
38
  from .bos import bos
39
39
  from .util import BytesIO, Daemon, ODict, exclude_dotfiles, min_ex, runhook, undot
@@ -92,7 +92,7 @@ class Tftpd(object):
92
92
  TftpServer,
93
93
  ]
94
94
  cbak = []
95
- if not self.args.tftp_no_fast and not EXE:
95
+ if not self.args.tftp_no_fast and not EXE and not PY2:
96
96
  try:
97
97
  ptn = re.compile(r"(^\s*)log\.debug\(.*\)$")
98
98
  for C in Cs:
@@ -102,7 +102,7 @@ class Tftpd(object):
102
102
  cfn = C.__spec__.origin
103
103
  exec (compile(src2, filename=cfn, mode="exec"), C.__dict__)
104
104
  except Exception:
105
- t = "failed to optimize tftp code; run with --tftp-noopt if there are issues:\n"
105
+ t = "failed to optimize tftp code; run with --tftp-no-fast if there are issues:\n"
106
106
  self.log("tftp", t + min_ex(), 3)
107
107
  for n, zd in enumerate(cbak):
108
108
  Cs[n].__dict__ = zd
@@ -147,11 +147,6 @@ class Tftpd(object):
147
147
 
148
148
  self._disarm(fos)
149
149
 
150
- ip = next((x for x in self.args.i if ":" not in x), None)
151
- if not ip:
152
- self.log("tftp", "IPv6 not supported for tftp; listening on 0.0.0.0", 3)
153
- ip = "0.0.0.0"
154
-
155
150
  self.port = int(self.args.tftp)
156
151
  self.srv = []
157
152
  self.ips = []
@@ -165,7 +160,7 @@ class Tftpd(object):
165
160
  if "::" in ips:
166
161
  ips.append("0.0.0.0")
167
162
 
168
- if self.args.ftp4:
163
+ if self.args.tftp4:
169
164
  ips = [x for x in ips if ":" not in x]
170
165
 
171
166
  ips = list(ODict.fromkeys(ips)) # dedup
@@ -330,7 +325,7 @@ class Tftpd(object):
330
325
 
331
326
  xbu = vfs.flags.get("xbu")
332
327
  if xbu and not runhook(
333
- self.nlog, xbu, ap, vpath, "", "", 0, 0, "8.3.8.7", 0, ""
328
+ self.nlog, xbu, ap, vpath, "", "", "", 0, 0, "8.3.8.7", 0, ""
334
329
  ):
335
330
  yeet("blocked by xbu server config: " + vpath)
336
331