Skip to content

fix(sync): WebDAV PUT 404 / MKCOL 409 —— 远程目录未自动创建导致同步失败 - #779

Open
jenken827 wants to merge 1 commit into
codedogQBY:mainfrom
jenken827:fix/webdav-sync-404
Open

jenken827 wants to merge 1 commit into
codedogQBY:mainfrom
jenken827:fix/webdav-sync-404

Conversation

@jenken827

Copy link
Copy Markdown

问题

WebDAV 同步报错:WebDAV PUT failed for /readany/sync/device-xxx.json: 404 Not Found。应用启动时远程根目录 /readany 存在,但 /readany/sync 等子目录应由应用自行创建——目录创建逻辑实际执行了,却被错误的响应处理吞掉,静默失败。

根因

  1. WebDavClient.mkcol() 把 409 当成功:RFC 4918 中 409 = 中间父目录缺失,原代码 status === 405 || status === 409 直接 return,导致在返回 409 的服务器上 ensureDirectories() 静默失败。
  2. ensureDirectory() 按错误消息字符串跳过(消息含 "405"/"409" 就当目录已存在,路径含这些数字时误判)。
  3. WebDavBackend.putJSON() 绕过了 put()/putFile() 的"确保父目录重试"兜底,设备快照恰好走这条路。
  4. getJSON()message.includes("404") 判定文件不存在,路径含 "404" 时会把服务器错误误判为文件缺失。

修复

  • put():404/409 时强制逐级 MKCOL 父目录链并重试一次,所有上传路径自愈;
  • mkcol():409 不再当成功,恢复不信任 PROPFIND 探测(存在服务器父目录探测为存在、MKCOL 子目录却 409),强制 MKCOL 每一级并追加无斜杠重试;
  • ensureDirectory() 删除字符串匹配,新增已确认集合记忆;
  • GET/DELETE/MOVE 失败带 HTTP status(消息格式不变);getJSON 按状态码判定 404;
  • backend put/putFile/putJSON 共享 putWithDirectoryHeal();遗留目录改用 ensureDirectory

验证

  • core 全量 591 个单元测试通过,新增 7 个回归测试;
  • 真机(Windows + 非标准 WebDAV 服务)验证:连接测试与同步正常。

注:此次代码调整和PR信息由AI生成

…vice snapshot)

WebDAV sync failed with "WebDAV PUT failed for /readany/sync/device-xxx.json:
404 Not Found" on servers where ensureDirectories() silently no-oped: mkcol
treated 409 (intermediate collection missing) as success, and ensureDirectory
skipped creation whenever the error message merely contained "405"/"409".
The device snapshot upload also bypassed the ensure-parent-and-retry fallback
that put()/putFile() had, so the 404 surfaced straight to the UI.

- WebDavClient.put(): on 404/409 force-create the parent collection chain
  and retry once, so every upload path (put/putJSON) self-heals
- WebDavClient.mkcol(): 409 no longer counts as success — recovery does not
  trust the PROPFIND probe (real servers 409 while the parent probes as
  existing): force-MKCOL every ancestor plus the target (RFC 4918 9.3.1),
  retrying each once without the trailing slash for gateways that
  mishandle collection URIs
- WebDavClient.ensureDirectory(): drop error-message string matching;
  memoize confirmed collections to cut redundant PROPFIND probes
- WebDavClient.get/getText/delete/move: attach the HTTP status to failures
  (WebDavError, message format unchanged) so getJSON() detects 404 by
  status instead of matching "404" anywhere in the message/path
- WebDavBackend: share one ensure-parent-and-retry helper across
  put/putFile/putJSON (putJSON previously had none) and create the legacy
  file/cover directories via ensureDirectory instead of bare mkcol
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant