Refactor handle_propfind function to use a helper function for generating propfind response

This commit is contained in:
abersheeran 2024-01-06 10:04:51 +08:00
parent e740a54af9
commit a534702d24

View File

@ -281,15 +281,9 @@ async function handle_mkcol(request: Request, bucket: R2Bucket): Promise<Respons
return new Response('', { status: 201 }); return new Response('', { status: 201 });
} }
async function handle_propfind(request: Request, bucket: R2Bucket): Promise<Response> { function generate_propfind_response(object: R2Object | null): string {
let resource_path = make_resource_path(request); if (object === null) {
return `
let is_collection: boolean;
let page = `<?xml version="1.0" encoding="utf-8"?>
<multistatus xmlns="DAV:">`;
if (resource_path === '') {
page += `
<response> <response>
<href>/</href> <href>/</href>
<propstat> <propstat>
@ -302,15 +296,10 @@ async function handle_propfind(request: Request, bucket: R2Bucket): Promise<Resp
<status>HTTP/1.1 200 OK</status> <status>HTTP/1.1 200 OK</status>
</propstat> </propstat>
</response>`; </response>`;
is_collection = true;
} else {
let object = await bucket.head(resource_path);
if (object === null) {
return new Response('Not Found', { status: 404 });
} }
is_collection = object.customMetadata?.resourcetype === '<collection />';
let href = `/${object.key + (object.customMetadata?.resourcetype === '<collection />' ? '/' : '')}`; let href = `/${object.key + (object.customMetadata?.resourcetype === '<collection />' ? '/' : '')}`;
page += ` return `
<response> <response>
<href>${href}</href> <href>${href}</href>
<propstat> <propstat>
@ -325,6 +314,25 @@ async function handle_propfind(request: Request, bucket: R2Bucket): Promise<Resp
</response>`; </response>`;
} }
async function handle_propfind(request: Request, bucket: R2Bucket): Promise<Response> {
let resource_path = make_resource_path(request);
let is_collection: boolean;
let page = `<?xml version="1.0" encoding="utf-8"?>
<multistatus xmlns="DAV:">`;
if (resource_path === '') {
page += generate_propfind_response(null);
is_collection = true;
} else {
let object = await bucket.head(resource_path);
if (object === null) {
return new Response('Not Found', { status: 404 });
}
is_collection = object.customMetadata?.resourcetype === '<collection />';
page += generate_propfind_response(object);
}
if (is_collection) { if (is_collection) {
let depth = request.headers.get('Depth') ?? 'infinity'; let depth = request.headers.get('Depth') ?? 'infinity';
switch (depth) { switch (depth) {
@ -334,20 +342,7 @@ async function handle_propfind(request: Request, bucket: R2Bucket): Promise<Resp
{ {
let prefix = resource_path === '' ? resource_path : resource_path + '/'; let prefix = resource_path === '' ? resource_path : resource_path + '/';
for await (let object of listAll(bucket, prefix)) { for await (let object of listAll(bucket, prefix)) {
let href = `/${object.key + (object.customMetadata?.resourcetype === '<collection />' ? '/' : '')}`; page += generate_propfind_response(object);
page += `
<response>
<href>${href}</href>
<propstat>
<prop>
${Object.entries(fromR2Object(object))
.filter(([_, value]) => value !== undefined)
.map(([key, value]) => `<${key}>${value}</${key}>`)
.join('\n ')}
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>`;
} }
} }
break; break;
@ -355,20 +350,7 @@ async function handle_propfind(request: Request, bucket: R2Bucket): Promise<Resp
{ {
let prefix = resource_path === '' ? resource_path : resource_path + '/'; let prefix = resource_path === '' ? resource_path : resource_path + '/';
for await (let object of listAll(bucket, prefix, true)) { for await (let object of listAll(bucket, prefix, true)) {
let href = `/${object.key + (object.customMetadata?.resourcetype === '<collection />' ? '/' : '')}`; page += generate_propfind_response(object);
page += `
<response>
<href>${href}</href>
<propstat>
<prop>
${Object.entries(fromR2Object(object))
.filter(([_, value]) => value !== undefined)
.map(([key, value]) => `<${key}>${value}</${key}>`)
.join('\n ')}
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>`;
} }
} }
break; break;