mirror of
https://github.com/9001/copyparty.git
synced 2025-08-17 09:02:15 -06:00
make it 5% faster
This commit is contained in:
parent
746229846d
commit
d5c9c8ebbd
|
@ -441,7 +441,7 @@ class VFS(object):
|
|||
|
||||
def _find(self, vpath: str) -> tuple["VFS", str]:
|
||||
"""return [vfs,remainder]"""
|
||||
if vpath == "":
|
||||
if not vpath:
|
||||
return self, ""
|
||||
|
||||
if "/" in vpath:
|
||||
|
@ -451,7 +451,7 @@ class VFS(object):
|
|||
rem = ""
|
||||
|
||||
if name in self.nodes:
|
||||
return self.nodes[name]._find(undot(rem))
|
||||
return self.nodes[name]._find(rem)
|
||||
|
||||
return self, vpath
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ from .util import chkcmd, min_ex
|
|||
if True: # pylint: disable=using-constant-test
|
||||
from typing import Optional, Union
|
||||
|
||||
from .util import RootLogger
|
||||
from .util import RootLogger, undot
|
||||
|
||||
|
||||
class Fstab(object):
|
||||
|
@ -52,7 +52,7 @@ class Fstab(object):
|
|||
self.log(msg.format(path, fs, min_ex()), 3)
|
||||
return fs
|
||||
|
||||
path = path.lstrip("/")
|
||||
path = undot(path)
|
||||
try:
|
||||
return self.cache[path]
|
||||
except:
|
||||
|
@ -124,7 +124,7 @@ class Fstab(object):
|
|||
if ANYWIN:
|
||||
path = self._winpath(path)
|
||||
|
||||
path = path.lstrip("/")
|
||||
path = undot(path)
|
||||
ptn = re.compile(r"^[^\\/]*")
|
||||
vn, rem = self.tab._find(path)
|
||||
if not self.trusted:
|
||||
|
|
|
@ -19,7 +19,7 @@ import threading # typechk
|
|||
import time
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
from email.utils import formatdate, parsedate
|
||||
from email.utils import parsedate
|
||||
from operator import itemgetter
|
||||
|
||||
import jinja2 # typechk
|
||||
|
@ -54,6 +54,7 @@ from .util import (
|
|||
alltrace,
|
||||
atomic_move,
|
||||
exclude_dotfiles,
|
||||
formatdate,
|
||||
fsenc,
|
||||
gen_filekey,
|
||||
gen_filekey_dbg,
|
||||
|
@ -787,7 +788,7 @@ class HttpCli(object):
|
|||
|
||||
# close if unknown length, otherwise take client's preference
|
||||
response.append("Connection: " + ("Keep-Alive" if self.keepalive else "Close"))
|
||||
response.append("Date: " + formatdate(usegmt=True))
|
||||
response.append("Date: " + formatdate())
|
||||
|
||||
# headers{} overrides anything set previously
|
||||
if headers:
|
||||
|
@ -811,9 +812,9 @@ class HttpCli(object):
|
|||
self.cbonk(self.conn.hsrv.gmal, zs, "cc_hdr", "Cc in out-hdr")
|
||||
raise Pebkac(999)
|
||||
|
||||
response.append("\r\n")
|
||||
try:
|
||||
# best practice to separate headers and body into different packets
|
||||
self.s.sendall("\r\n".join(response).encode("utf-8") + b"\r\n\r\n")
|
||||
self.s.sendall("\r\n".join(response).encode("utf-8"))
|
||||
except:
|
||||
raise Pebkac(400, "client d/c while replying headers")
|
||||
|
||||
|
@ -1146,7 +1147,7 @@ class HttpCli(object):
|
|||
return self.tx_mounts()
|
||||
|
||||
# conditional redirect to single volumes
|
||||
if self.vpath == "" and not self.ouparam:
|
||||
if not self.vpath and not self.ouparam:
|
||||
nread = len(self.rvol)
|
||||
nwrite = len(self.wvol)
|
||||
if nread + nwrite == 1 or (self.rvol == self.wvol and nread == 1):
|
||||
|
@ -1305,7 +1306,7 @@ class HttpCli(object):
|
|||
|
||||
pvs: dict[str, str] = {
|
||||
"displayname": html_escape(rp.split("/")[-1]),
|
||||
"getlastmodified": formatdate(mtime, usegmt=True),
|
||||
"getlastmodified": formatdate(mtime),
|
||||
"resourcetype": '<D:collection xmlns:D="DAV:"/>' if isdir else "",
|
||||
"supportedlock": '<D:lockentry xmlns:D="DAV:"><D:lockscope><D:exclusive/></D:lockscope><D:locktype><D:write/></D:locktype></D:lockentry>',
|
||||
}
|
||||
|
@ -2952,7 +2953,7 @@ class HttpCli(object):
|
|||
return True
|
||||
|
||||
def _chk_lastmod(self, file_ts: int) -> tuple[str, bool]:
|
||||
file_lastmod = formatdate(file_ts, usegmt=True)
|
||||
file_lastmod = formatdate(file_ts)
|
||||
cli_lastmod = self.headers.get("if-modified-since")
|
||||
if cli_lastmod:
|
||||
try:
|
||||
|
@ -3034,8 +3035,8 @@ class HttpCli(object):
|
|||
for n, fn in enumerate([".prologue.html", ".epilogue.html"]):
|
||||
if lnames is not None and fn not in lnames:
|
||||
continue
|
||||
fn = os.path.join(abspath, fn)
|
||||
if bos.path.exists(fn):
|
||||
fn = "%s/%s" % (abspath, fn)
|
||||
if bos.path.isfile(fn):
|
||||
with open(fsenc(fn), "rb") as f:
|
||||
logues[n] = f.read().decode("utf-8")
|
||||
if "exp" in vn.flags:
|
||||
|
@ -3053,7 +3054,7 @@ class HttpCli(object):
|
|||
fns = []
|
||||
|
||||
for fn in fns:
|
||||
fn = os.path.join(abspath, fn)
|
||||
fn = "%s/%s" % (abspath, fn)
|
||||
if bos.path.isfile(fn):
|
||||
with open(fsenc(fn), "rb") as f:
|
||||
readme = f.read().decode("utf-8")
|
||||
|
@ -3588,7 +3589,7 @@ class HttpCli(object):
|
|||
# (useragent-sniffing kinshi due to caching proxies)
|
||||
mime, ico = self.ico.get(txt, not small, "raster" in self.uparam)
|
||||
|
||||
lm = formatdate(self.E.t0, usegmt=True)
|
||||
lm = formatdate(self.E.t0)
|
||||
self.reply(ico, mime=mime, headers={"Last-Modified": lm})
|
||||
return True
|
||||
|
||||
|
|
|
@ -5,11 +5,11 @@ import errno
|
|||
import re
|
||||
import select
|
||||
import socket
|
||||
from email.utils import formatdate
|
||||
import time
|
||||
|
||||
from .__init__ import TYPE_CHECKING
|
||||
from .multicast import MC_Sck, MCast
|
||||
from .util import CachedSet, html_escape, min_ex
|
||||
from .util import CachedSet, formatdate, html_escape, min_ex
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .broker_util import BrokerCli
|
||||
|
@ -229,7 +229,7 @@ CONFIGID.UPNP.ORG: 1
|
|||
|
||||
"""
|
||||
v4 = srv.ip.replace("::ffff:", "")
|
||||
zs = zs.format(formatdate(usegmt=True), v4, srv.hport, self.args.zsid)
|
||||
zs = zs.format(formatdate(), v4, srv.hport, self.args.zsid)
|
||||
zb = zs[1:].replace("\n", "\r\n").encode("utf-8", "replace")
|
||||
srv.sck.sendto(zb, addr[:2])
|
||||
|
||||
|
|
|
@ -37,9 +37,7 @@ def dostime2unix(buf: bytes) -> int:
|
|||
|
||||
|
||||
def unixtime2dos(ts: int) -> bytes:
|
||||
tt = time.gmtime(ts + 1)
|
||||
dy, dm, dd, th, tm, ts = list(tt)[:6]
|
||||
|
||||
dy, dm, dd, th, tm, ts, _, _, _ = time.gmtime(ts + 1)
|
||||
bd = ((dy - 1980) << 9) + (dm << 5) + dd
|
||||
bt = (th << 11) + (tm << 5) + ts // 2
|
||||
try:
|
||||
|
|
|
@ -36,7 +36,7 @@ from partftpy.TftpShared import TftpException
|
|||
from .__init__ import EXE, PY2, TYPE_CHECKING
|
||||
from .authsrv import VFS
|
||||
from .bos import bos
|
||||
from .util import BytesIO, Daemon, ODict, exclude_dotfiles, min_ex, runhook, undot
|
||||
from .util import UTC, BytesIO, Daemon, ODict, exclude_dotfiles, min_ex, runhook, undot
|
||||
|
||||
if True: # pylint: disable=using-constant-test
|
||||
from typing import Any, Union
|
||||
|
@ -262,7 +262,7 @@ class Tftpd(object):
|
|||
dirs1 = [(v.st_mtime, v.st_size, k + "/") for k, v in vfs_ls if k in dnames]
|
||||
fils1 = [(v.st_mtime, v.st_size, k) for k, v in vfs_ls if k not in dnames]
|
||||
real1 = dirs1 + fils1
|
||||
realt = [(datetime.fromtimestamp(mt), sz, fn) for mt, sz, fn in real1]
|
||||
realt = [(datetime.fromtimestamp(mt, UTC), sz, fn) for mt, sz, fn in real1]
|
||||
reals = [
|
||||
(
|
||||
"%04d-%02d-%02d %02d:%02d:%02d"
|
||||
|
|
|
@ -26,7 +26,6 @@ import threading
|
|||
import time
|
||||
import traceback
|
||||
from collections import Counter
|
||||
from email.utils import formatdate
|
||||
|
||||
from ipaddress import IPv4Address, IPv4Network, IPv6Address, IPv6Network
|
||||
from queue import Queue
|
||||
|
@ -1821,10 +1820,21 @@ def gen_filekey_dbg(
|
|||
return ret
|
||||
|
||||
|
||||
WKDAYS = "Mon Tue Wed Thu Fri Sat Sun".split()
|
||||
MONTHS = "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split()
|
||||
RFC2822 = "%s, %02d %s %04d %02d:%02d:%02d GMT"
|
||||
|
||||
|
||||
def formatdate(ts: Optional[int] = None) -> str:
|
||||
# gmtime ~= datetime.fromtimestamp(ts, UTC).timetuple()
|
||||
y, mo, d, h, mi, s, wd, _, _ = time.gmtime(ts)
|
||||
return RFC2822 % (WKDAYS[wd], d, MONTHS[mo - 1], y, h, mi, s)
|
||||
|
||||
|
||||
def gencookie(k: str, v: str, r: str, tls: bool, dur: int = 0, txt: str = "") -> str:
|
||||
v = v.replace("%", "%25").replace(";", "%3B")
|
||||
if dur:
|
||||
exp = formatdate(time.time() + dur, usegmt=True)
|
||||
exp = formatdate(time.time() + dur)
|
||||
else:
|
||||
exp = "Fri, 15 Aug 1997 01:00:00 GMT"
|
||||
|
||||
|
@ -1839,12 +1849,10 @@ def humansize(sz: float, terse: bool = False) -> str:
|
|||
|
||||
sz /= 1024.0
|
||||
|
||||
ret = " ".join([str(sz)[:4].rstrip("."), unit])
|
||||
|
||||
if not terse:
|
||||
return ret
|
||||
|
||||
return ret.replace("iB", "").replace(" ", "")
|
||||
if terse:
|
||||
return "%s%s" % (str(sz)[:4].rstrip("."), unit[:1])
|
||||
else:
|
||||
return "%s %s" % (str(sz)[:4].rstrip("."), unit)
|
||||
|
||||
|
||||
def unhumanize(sz: str) -> int:
|
||||
|
@ -1896,7 +1904,7 @@ def uncyg(path: str) -> str:
|
|||
def undot(path: str) -> str:
|
||||
ret: list[str] = []
|
||||
for node in path.split("/"):
|
||||
if node in ["", "."]:
|
||||
if node == "." or not node:
|
||||
continue
|
||||
|
||||
if node == "..":
|
||||
|
@ -2709,30 +2717,30 @@ def rmdirs_up(top: str, stop: str) -> tuple[list[str], list[str]]:
|
|||
|
||||
def unescape_cookie(orig: str) -> str:
|
||||
# mw=idk; doot=qwe%2Crty%3Basd+fgh%2Bjkl%25zxc%26vbn # qwe,rty;asd fgh+jkl%zxc&vbn
|
||||
ret = ""
|
||||
ret = []
|
||||
esc = ""
|
||||
for ch in orig:
|
||||
if ch == "%":
|
||||
if len(esc) > 0:
|
||||
ret += esc
|
||||
if esc:
|
||||
ret.append(esc)
|
||||
esc = ch
|
||||
|
||||
elif len(esc) > 0:
|
||||
elif esc:
|
||||
esc += ch
|
||||
if len(esc) == 3:
|
||||
try:
|
||||
ret += chr(int(esc[1:], 16))
|
||||
ret.append(chr(int(esc[1:], 16)))
|
||||
except:
|
||||
ret += esc
|
||||
ret.append(esc)
|
||||
esc = ""
|
||||
|
||||
else:
|
||||
ret += ch
|
||||
ret.append(ch)
|
||||
|
||||
if len(esc) > 0:
|
||||
ret += esc
|
||||
if esc:
|
||||
ret.append(esc)
|
||||
|
||||
return ret
|
||||
return "".join(ret)
|
||||
|
||||
|
||||
def guess_mime(url: str, fallback: str = "application/octet-stream") -> str:
|
||||
|
|
|
@ -168,6 +168,11 @@ class TestHttpCli(unittest.TestCase):
|
|||
h, ret = self.put(url)
|
||||
res = h.startswith("HTTP/1.1 201 ")
|
||||
self.assertEqual(res, wok)
|
||||
if wok:
|
||||
vp = h.split("\nLocation: http://a:1/")[1].split("\r")[0]
|
||||
vn, rem = self.asrv.vfs.get(vp, "*", False, False)
|
||||
ap = os.path.join(vn.realpath, rem)
|
||||
os.unlink(ap)
|
||||
|
||||
def can_rw(self, fp):
|
||||
# lowest non-neutral folder declares permissions
|
||||
|
|
Loading…
Reference in a new issue