mirror of
https://github.com/9001/copyparty.git
synced 2025-08-17 17:12:13 -06:00
bubble OS-filesystem errors to client
send a 500 or 404 if a folder is inaccessible or does not exist previously it would return an empty directory listing instead
This commit is contained in:
parent
71d9e010d9
commit
119e88d87b
|
@ -393,7 +393,8 @@ class Gateway(object):
|
||||||
if r.status != 200:
|
if r.status != 200:
|
||||||
self.closeconn()
|
self.closeconn()
|
||||||
info("http error %s reading dir %r", r.status, web_path)
|
info("http error %s reading dir %r", r.status, web_path)
|
||||||
raise FuseOSError(errno.ENOENT)
|
err = errno.ENOENT if r.status == 404 else errno.EIO
|
||||||
|
raise FuseOSError(err)
|
||||||
|
|
||||||
ctype = r.getheader("Content-Type", "")
|
ctype = r.getheader("Content-Type", "")
|
||||||
if ctype == "application/json":
|
if ctype == "application/json":
|
||||||
|
|
|
@ -1142,7 +1142,10 @@ class Ctl(object):
|
||||||
|
|
||||||
if self.ar.drd:
|
if self.ar.drd:
|
||||||
dp = os.path.join(top, rd)
|
dp = os.path.join(top, rd)
|
||||||
lnodes = set(os.listdir(dp))
|
try:
|
||||||
|
lnodes = set(os.listdir(dp))
|
||||||
|
except:
|
||||||
|
lnodes = list(ls) # fs eio; don't delete
|
||||||
if ptn:
|
if ptn:
|
||||||
zs = dp.replace(sep, b"/").rstrip(b"/") + b"/"
|
zs = dp.replace(sep, b"/").rstrip(b"/") + b"/"
|
||||||
zls = [zs + x for x in lnodes]
|
zls = [zs + x for x in lnodes]
|
||||||
|
|
|
@ -591,10 +591,11 @@ class VFS(object):
|
||||||
scandir: bool,
|
scandir: bool,
|
||||||
permsets: list[list[bool]],
|
permsets: list[list[bool]],
|
||||||
lstat: bool = False,
|
lstat: bool = False,
|
||||||
|
throw: bool = False,
|
||||||
) -> tuple[str, list[tuple[str, os.stat_result]], dict[str, "VFS"]]:
|
) -> tuple[str, list[tuple[str, os.stat_result]], dict[str, "VFS"]]:
|
||||||
"""replaces _ls for certain shares (single-file, or file selection)"""
|
"""replaces _ls for certain shares (single-file, or file selection)"""
|
||||||
vn, rem = self.shr_src # type: ignore
|
vn, rem = self.shr_src # type: ignore
|
||||||
abspath, real, _ = vn.ls(rem, "\n", scandir, permsets, lstat)
|
abspath, real, _ = vn.ls(rem, "\n", scandir, permsets, lstat, throw)
|
||||||
real = [x for x in real if os.path.basename(x[0]) in self.shr_files]
|
real = [x for x in real if os.path.basename(x[0]) in self.shr_files]
|
||||||
return abspath, real, {}
|
return abspath, real, {}
|
||||||
|
|
||||||
|
@ -605,11 +606,12 @@ class VFS(object):
|
||||||
scandir: bool,
|
scandir: bool,
|
||||||
permsets: list[list[bool]],
|
permsets: list[list[bool]],
|
||||||
lstat: bool = False,
|
lstat: bool = False,
|
||||||
|
throw: bool = False,
|
||||||
) -> tuple[str, list[tuple[str, os.stat_result]], dict[str, "VFS"]]:
|
) -> tuple[str, list[tuple[str, os.stat_result]], dict[str, "VFS"]]:
|
||||||
"""return user-readable [fsdir,real,virt] items at vpath"""
|
"""return user-readable [fsdir,real,virt] items at vpath"""
|
||||||
virt_vis = {} # nodes readable by user
|
virt_vis = {} # nodes readable by user
|
||||||
abspath = self.canonical(rem)
|
abspath = self.canonical(rem)
|
||||||
real = list(statdir(self.log, scandir, lstat, abspath))
|
real = list(statdir(self.log, scandir, lstat, abspath, throw))
|
||||||
real.sort()
|
real.sort()
|
||||||
if not rem:
|
if not rem:
|
||||||
# no vfs nodes in the list of real inodes
|
# no vfs nodes in the list of real inodes
|
||||||
|
|
|
@ -296,6 +296,7 @@ class FtpFs(AbstractedFS):
|
||||||
self.uname,
|
self.uname,
|
||||||
not self.args.no_scandir,
|
not self.args.no_scandir,
|
||||||
[[True, False], [False, True]],
|
[[True, False], [False, True]],
|
||||||
|
throw=True,
|
||||||
)
|
)
|
||||||
vfs_ls = [x[0] for x in vfs_ls1]
|
vfs_ls = [x[0] for x in vfs_ls1]
|
||||||
vfs_ls.extend(vfs_virt.keys())
|
vfs_ls.extend(vfs_virt.keys())
|
||||||
|
|
|
@ -1450,6 +1450,7 @@ class HttpCli(object):
|
||||||
not self.args.no_scandir,
|
not self.args.no_scandir,
|
||||||
[[True, False]],
|
[[True, False]],
|
||||||
lstat="davrt" not in vn.flags,
|
lstat="davrt" not in vn.flags,
|
||||||
|
throw=True,
|
||||||
)
|
)
|
||||||
if not self.can_read:
|
if not self.can_read:
|
||||||
vfs_ls = []
|
vfs_ls = []
|
||||||
|
@ -5459,6 +5460,7 @@ class HttpCli(object):
|
||||||
not self.args.no_scandir,
|
not self.args.no_scandir,
|
||||||
[[True, False], [False, True]],
|
[[True, False], [False, True]],
|
||||||
lstat="lt" in self.uparam,
|
lstat="lt" in self.uparam,
|
||||||
|
throw=True,
|
||||||
)
|
)
|
||||||
stats = {k: v for k, v in vfs_ls}
|
stats = {k: v for k, v in vfs_ls}
|
||||||
ls_names = [x[0] for x in vfs_ls]
|
ls_names = [x[0] for x in vfs_ls]
|
||||||
|
|
|
@ -269,6 +269,7 @@ class Tftpd(object):
|
||||||
"*",
|
"*",
|
||||||
not self.args.no_scandir,
|
not self.args.no_scandir,
|
||||||
[[True, False]],
|
[[True, False]],
|
||||||
|
throw=True,
|
||||||
)
|
)
|
||||||
dnames = set([x[0] for x in vfs_ls if stat.S_ISDIR(x[1].st_mode)])
|
dnames = set([x[0] for x in vfs_ls if stat.S_ISDIR(x[1].st_mode)])
|
||||||
dirs1 = [(v.st_mtime, v.st_size, k + "/") for k, v in vfs_ls if k in dnames]
|
dirs1 = [(v.st_mtime, v.st_size, k + "/") for k, v in vfs_ls if k in dnames]
|
||||||
|
|
|
@ -896,7 +896,9 @@ class ThumbSrv(object):
|
||||||
prev_b64 = None
|
prev_b64 = None
|
||||||
prev_fp = ""
|
prev_fp = ""
|
||||||
try:
|
try:
|
||||||
t1 = statdir(self.log_func, not self.args.no_scandir, False, thumbpath)
|
t1 = statdir(
|
||||||
|
self.log_func, not self.args.no_scandir, False, thumbpath, False
|
||||||
|
)
|
||||||
ents = sorted(list(t1))
|
ents = sorted(list(t1))
|
||||||
except:
|
except:
|
||||||
return 0
|
return 0
|
||||||
|
|
|
@ -1347,7 +1347,7 @@ class Up2k(object):
|
||||||
rds = rd + "/" if rd else ""
|
rds = rd + "/" if rd else ""
|
||||||
cdirs = cdir + os.sep
|
cdirs = cdir + os.sep
|
||||||
|
|
||||||
g = statdir(self.log_func, not self.args.no_scandir, True, cdir)
|
g = statdir(self.log_func, not self.args.no_scandir, True, cdir, False)
|
||||||
gl = sorted(g)
|
gl = sorted(g)
|
||||||
partials = set([x[0] for x in gl if "PARTIAL" in x[0]])
|
partials = set([x[0] for x in gl if "PARTIAL" in x[0]])
|
||||||
for iname, inf in gl:
|
for iname, inf in gl:
|
||||||
|
|
|
@ -2862,7 +2862,7 @@ def sendfile_kern(
|
||||||
|
|
||||||
|
|
||||||
def statdir(
|
def statdir(
|
||||||
logger: Optional["RootLogger"], scandir: bool, lstat: bool, top: str
|
logger: Optional["RootLogger"], scandir: bool, lstat: bool, top: str, throw: bool
|
||||||
) -> Generator[tuple[str, os.stat_result], None, None]:
|
) -> Generator[tuple[str, os.stat_result], None, None]:
|
||||||
if lstat and ANYWIN:
|
if lstat and ANYWIN:
|
||||||
lstat = False
|
lstat = False
|
||||||
|
@ -2898,6 +2898,12 @@ def statdir(
|
||||||
logger(src, "[s] {} @ {}".format(repr(ex), fsdec(abspath)), 6)
|
logger(src, "[s] {} @ {}".format(repr(ex), fsdec(abspath)), 6)
|
||||||
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
|
if throw:
|
||||||
|
zi = getattr(ex, "errno", 0)
|
||||||
|
if zi == errno.ENOENT:
|
||||||
|
raise Pebkac(404, str(ex))
|
||||||
|
raise
|
||||||
|
|
||||||
t = "{} @ {}".format(repr(ex), top)
|
t = "{} @ {}".format(repr(ex), top)
|
||||||
if logger:
|
if logger:
|
||||||
logger(src, t, 1)
|
logger(src, t, 1)
|
||||||
|
@ -2906,7 +2912,7 @@ def statdir(
|
||||||
|
|
||||||
|
|
||||||
def dir_is_empty(logger: "RootLogger", scandir: bool, top: str):
|
def dir_is_empty(logger: "RootLogger", scandir: bool, top: str):
|
||||||
for _ in statdir(logger, scandir, False, top):
|
for _ in statdir(logger, scandir, False, top, False):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -2919,7 +2925,7 @@ def rmdirs(
|
||||||
top = os.path.dirname(top)
|
top = os.path.dirname(top)
|
||||||
depth -= 1
|
depth -= 1
|
||||||
|
|
||||||
stats = statdir(logger, scandir, lstat, top)
|
stats = statdir(logger, scandir, lstat, top, False)
|
||||||
dirs = [x[0] for x in stats if stat.S_ISDIR(x[1].st_mode)]
|
dirs = [x[0] for x in stats if stat.S_ISDIR(x[1].st_mode)]
|
||||||
dirs = [os.path.join(top, x) for x in dirs]
|
dirs = [os.path.join(top, x) for x in dirs]
|
||||||
ok = []
|
ok = []
|
||||||
|
|
Loading…
Reference in a new issue