fix(mount): clearer WebDAV 400 diagnosis and path normalize
Probe / first, encode CJK/space path segments, explain 400 with path and /dav hint.
This commit is contained in:
parent
6bced13135
commit
fb3747a66c
|
|
@ -152,10 +152,21 @@ export const mountService = {
|
||||||
username: input.username,
|
username: input.username,
|
||||||
password: input.password,
|
password: input.password,
|
||||||
});
|
});
|
||||||
await listDirectory(client, input.rootPath || "/");
|
// 1) 先探 WebDAV 根:区分「认证/不是 WebDAV」与「根路径写错」
|
||||||
|
try {
|
||||||
|
await listDirectory(client, "/");
|
||||||
|
} catch (e) {
|
||||||
|
const msg = describeWebdavError(e);
|
||||||
|
if (msg.includes("认证失败") || msg.includes("不是 WebDAV") || msg.includes("连接")) {
|
||||||
|
return { ok: false, message: `${msg}(探测 WebDAV 根路径 / 时失败)` };
|
||||||
|
}
|
||||||
|
// 根 400 等:仍继续试 rootPath,部分服务根不可列
|
||||||
|
}
|
||||||
|
const root = normalizeWebdavPath(input.rootPath || "/");
|
||||||
|
await listDirectory(client, root);
|
||||||
return { ok: true, message: "连接成功" };
|
return { ok: true, message: "连接成功" };
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return { ok: false, message: describeWebdavError(e) };
|
return { ok: false, message: describeWebdavError(e, input.rootPath || "/") };
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -165,7 +176,7 @@ export const mountService = {
|
||||||
): Promise<{ entries: DirEntry[]; path: string }> {
|
): Promise<{ entries: DirEntry[]; path: string }> {
|
||||||
const mount = await mountDao.getByIdForUser(input.mountId, userId);
|
const mount = await mountDao.getByIdForUser(input.mountId, userId);
|
||||||
if (!mount) throw new TRPCError({ code: "NOT_FOUND", message: "挂载不存在" });
|
if (!mount) throw new TRPCError({ code: "NOT_FOUND", message: "挂载不存在" });
|
||||||
const abs = joinWebdavPath(mount.rootPath, input.path);
|
const abs = normalizeWebdavPath(joinWebdavPath(mount.rootPath, input.path));
|
||||||
try {
|
try {
|
||||||
const entries = await withClient(mount, (c) => listDirectory(c, abs));
|
const entries = await withClient(mount, (c) => listDirectory(c, abs));
|
||||||
entries.sort((a, b) => {
|
entries.sort((a, b) => {
|
||||||
|
|
@ -183,16 +194,17 @@ export const mountService = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 把 webdav/网络底层错误归一化成用户可读的失败原因 */
|
/** 把 webdav/网络底层错误归一化成用户可读的失败原因 */
|
||||||
function describeWebdavError(e: unknown): string {
|
function describeWebdavError(e: unknown, path?: string): string {
|
||||||
const raw = e instanceof Error ? e.message : String(e);
|
const raw = e instanceof Error ? e.message : String(e);
|
||||||
const s = raw.toLowerCase();
|
const s = raw.toLowerCase();
|
||||||
|
const pathHint = path ? `(路径 ${path})` : "";
|
||||||
if (
|
if (
|
||||||
s.includes("401") ||
|
s.includes("401") ||
|
||||||
s.includes("403") ||
|
s.includes("403") ||
|
||||||
s.includes("unauthorized") ||
|
s.includes("unauthorized") ||
|
||||||
s.includes("forbidden")
|
s.includes("forbidden")
|
||||||
)
|
)
|
||||||
return "认证失败,请检查用户名和密码";
|
return `认证失败,请检查用户名和密码${pathHint}`;
|
||||||
if (s.includes("enotfound") || s.includes("eai_again") || s.includes("getaddrinfo"))
|
if (s.includes("enotfound") || s.includes("eai_again") || s.includes("getaddrinfo"))
|
||||||
return "无法解析服务器地址";
|
return "无法解析服务器地址";
|
||||||
if (s.includes("econnrefused")) return "连接被拒绝,请检查地址和端口";
|
if (s.includes("econnrefused")) return "连接被拒绝,请检查地址和端口";
|
||||||
|
|
@ -200,8 +212,18 @@ function describeWebdavError(e: unknown): string {
|
||||||
return "连接超时";
|
return "连接超时";
|
||||||
if (s.includes("certificate") || s.includes("ssl") || s.includes("tls"))
|
if (s.includes("certificate") || s.includes("ssl") || s.includes("tls"))
|
||||||
return "HTTPS 证书错误";
|
return "HTTPS 证书错误";
|
||||||
|
if (s.includes("400") || s.includes("bad request"))
|
||||||
|
return `HTTP 400:服务器拒绝该请求${pathHint}。请确认 WebDAV 地址含正确前缀(如 http://主机:端口/dav),根路径为共享目录且 URL 可用`;
|
||||||
if (s.includes("404") || s.includes("405") || s.includes("not found"))
|
if (s.includes("404") || s.includes("405") || s.includes("not found"))
|
||||||
return "地址不可用(可能不是 WebDAV 服务)";
|
return `地址或路径不存在${pathHint}(可能不是 WebDAV 服务,或根路径不正确)`;
|
||||||
const short = raw.length > 120 ? `${raw.slice(0, 120)}…` : raw;
|
const short = raw.length > 120 ? `${raw.slice(0, 120)}…` : raw;
|
||||||
return `连接失败:${short}`;
|
return `连接失败:${short}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** WebDAV 路径:补前导 /、去重斜杠、段级百分号编码(中文/空格) */
|
||||||
|
function normalizeWebdavPath(input: string): string {
|
||||||
|
const trimmed = input.trim() || "/";
|
||||||
|
const parts = trimmed.split("/").filter(Boolean);
|
||||||
|
const encoded = parts.map((seg) => encodeURIComponent(decodeURIComponent(seg)));
|
||||||
|
return `/${encoded.join("/")}`;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue