Skip to content
File

Blob: src/worker/webdav/propfind.ts

typescript32 lines
1import { davError, davResponse, parseDepth } from "@/worker/dav/http";
2import { maxDavDepthInfinityNodes, maxXmlBodyBytes } from "@/worker/dav/limits";
3import { parsePropfindXml, type PropfindRequest } from "@/worker/xml/dav-request";
4import type { AppContext } from "@/worker/types";
5import type { SubjectRow } from "@/worker/db/d1/schema";
6import { fileDavObject, resultError, type NormalizedFilesRequestPath } from "@/worker/webdav/object";
7import { multistatusXml, nodePropstats } from "@/worker/webdav/props";
8 
9export async function handlePropfind(c: AppContext, subject: SubjectRow, requestPath: NormalizedFilesRequestPath) {
10 const depth = parseDepth(c.req.header("depth") ?? null, "infinity");
11 if (!depth) return davError(400, "Invalid Depth header");
12 let parsed: PropfindRequest;
13 try {
14 parsed = parsePropfindXml(await c.req.text(), maxXmlBodyBytes(c.env));
15 } catch (cause) {
16 return davError(400, cause instanceof Error ? cause.message : "Invalid PROPFIND body");
17 }
18 const result = await fileDavObject(c.env, subject.storageId).propfind({
19 subjectId: subject.id,
20 storageId: subject.storageId,
21 path: requestPath.path,
22 depth,
23 maxNodes: maxDavDepthInfinityNodes(c.env),
24 nowMs: Date.now(),
25 });
26 if (!result.ok) return resultError(result);
27 return davResponse(
28 multistatusXml(result.nodes.map((node) => ({ href: node.href, propstats: nodePropstats(node, parsed) }))),
29 207,
30 );
31}