Skip to content
File

Blob: src/worker/dav/http.ts

typescript42 lines
1export const DAV_XML = "application/xml; charset=utf-8";
2 
3export function davResponse(body: string | null, status: number, headers: HeadersInit = {}): Response {
4 const responseHeaders = new Headers(headers);
5 if (body !== null && !responseHeaders.has("content-type")) responseHeaders.set("content-type", DAV_XML);
6 return new Response(body, { status, headers: responseHeaders });
7}
8 
9export function emptyResponse(status: number, headers: HeadersInit = {}): Response {
10 return new Response(null, { status, headers });
11}
12 
13export function methodNotAllowed(allow: string): Response {
14 return new Response("Method Not Allowed", { status: 405, headers: { Allow: allow } });
15}
16 
17export function unauthorizedDav(): Response {
18 return new Response("Unauthorized", {
19 status: 401,
20 headers: { "WWW-Authenticate": 'Basic realm="dab"' },
21 });
22}
23 
24export function davError(status: number, message: string, headers: HeadersInit = {}): Response {
25 return new Response(message, { status, headers });
26}
27 
28// RFC 4791 7.8 / RFC 6352 8.3: signal that the server truncated a query report
29// result set with a DAV:error body containing DAV:number-of-matches-within-limits.
30export function numberOfMatchesWithinLimitsError(): Response {
31 const body =
32 '<?xml version="1.0" encoding="utf-8"?>' + '<D:error xmlns:D="DAV:"><D:number-of-matches-within-limits/></D:error>';
33 return davResponse(body, 403);
34}
35 
36export function parseDepth(value: string | null, fallback: "0" | "1" | "infinity"): "0" | "1" | "infinity" | null {
37 if (value === null || value === "") return fallback;
38 const normalized = value.toLowerCase();
39 if (normalized === "0" || normalized === "1" || normalized === "infinity") return normalized;
40 return null;
41}