make it 5% faster

This commit is contained in:
ed 2024-07-31 17:51:53 +00:00
parent 746229846d
commit d5c9c8ebbd
8 changed files with 55 additions and 43 deletions

View file

@ -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

View file

@ -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:

View file

@ -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

View file

@ -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])

View file

@ -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:

View file

@ -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"

View file

@ -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:

View file

@ -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