import { davError, davResponse, parseDepth } from "@/worker/dav/http"; import { maxDavDepthInfinityNodes, maxXmlBodyBytes } from "@/worker/dav/limits"; import { parsePropfindXml, type PropfindRequest } from "@/worker/xml/dav-request"; import type { AppContext } from "@/worker/types"; import type { SubjectRow } from "@/worker/db/d1/schema"; import { fileDavObject, resultError, type NormalizedFilesRequestPath } from "@/worker/webdav/object"; import { multistatusXml, nodePropstats } from "@/worker/webdav/props"; export async function handlePropfind(c: AppContext, subject: SubjectRow, requestPath: NormalizedFilesRequestPath) { const depth = parseDepth(c.req.header("depth") ?? null, "infinity"); if (!depth) return davError(400, "Invalid Depth header"); let parsed: PropfindRequest; try { parsed = parsePropfindXml(await c.req.text(), maxXmlBodyBytes(c.env)); } catch (cause) { return davError(400, cause instanceof Error ? cause.message : "Invalid PROPFIND body"); } const result = await fileDavObject(c.env, subject.storageId).propfind({ subjectId: subject.id, storageId: subject.storageId, path: requestPath.path, depth, maxNodes: maxDavDepthInfinityNodes(c.env), nowMs: Date.now(), }); if (!result.ok) return resultError(result); return davResponse( multistatusXml(result.nodes.map((node) => ({ href: node.href, propstats: nodePropstats(node, parsed) }))), 207, ); }