Refactor listAll function and handle_get function

This commit is contained in:
abersheeran 2023-12-18 13:25:06 +08:00
parent 4295fddbdb
commit 5fd9089b14

View File

@ -29,6 +29,27 @@ export interface Env {
PASSWORD: string; PASSWORD: string;
} }
async function* listAll(bucket: R2Bucket, prefix: string, isRecursive: boolean = false) {
let cursor: string | undefined = undefined;
do {
var r2_objects = await bucket.list({
prefix: prefix,
delimiter: isRecursive ? undefined : '/',
cursor: cursor,
include: ['httpMetadata', 'customMetadata'],
});
for (let object of r2_objects.objects) {
yield object;
}
if (r2_objects.truncated) {
cursor = r2_objects.cursor;
}
} while (r2_objects.truncated)
}
const DAV_CLASS = "1"; const DAV_CLASS = "1";
const SUPPORT_METHODS = [ const SUPPORT_METHODS = [
"OPTIONS", "OPTIONS",
@ -106,14 +127,12 @@ async function handle_get(request: Request, bucket: R2Bucket): Promise<Response>
let resource_path = make_resource_path(request); let resource_path = make_resource_path(request);
if (request.url.endsWith('/')) { if (request.url.endsWith('/')) {
let r2_objects = await bucket.list({
prefix: resource_path,
delimiter: '/',
include: ['httpMetadata', 'customMetadata'],
});
let page = ''; let page = '';
if (resource_path !== '') page += `<a href="../">..</a><br>`; if (resource_path !== '') page += `<a href="../">..</a><br>`;
for (let object of r2_objects.objects.filter(object => object.key !== resource_path)) { for await (const object of listAll(bucket, resource_path)) {
if (object.key === resource_path) {
continue
}
let href = `/${object.key + (object.customMetadata?.resourcetype === '<collection />' ? '/' : '')}`; let href = `/${object.key + (object.customMetadata?.resourcetype === '<collection />' ? '/' : '')}`;
page += `<a href="${href}">${object.httpMetadata?.contentDisposition ?? object.key}</a><br>`; page += `<a href="${href}">${object.httpMetadata?.contentDisposition ?? object.key}</a><br>`;
} }
@ -353,16 +372,8 @@ async function handle_propfind(request: Request, bucket: R2Bucket): Promise<Resp
let page = `<?xml version="1.0" encoding="utf-8"?> let page = `<?xml version="1.0" encoding="utf-8"?>
<multistatus xmlns="DAV:">`; <multistatus xmlns="DAV:">`;
let cursor: string | undefined = undefined; let prefix = resource_path.endsWith('/') || resource_path === "" ? resource_path : resource_path + '/';
do { for await (let object of listAll(bucket, prefix)) {
var r2_objects = await bucket.list({
prefix: resource_path.endsWith('/') || resource_path === "" ? resource_path : resource_path + '/',
delimiter: '/',
cursor: cursor,
include: ['httpMetadata', 'customMetadata'],
});
for (let object of r2_objects.objects.filter(object => object.key !== resource_path)) {
let href = `/${object.key + (object.customMetadata?.resourcetype === '<collection />' ? '/' : '')}`; let href = `/${object.key + (object.customMetadata?.resourcetype === '<collection />' ? '/' : '')}`;
page += ` page += `
<response> <response>
@ -380,10 +391,6 @@ async function handle_propfind(request: Request, bucket: R2Bucket): Promise<Resp
</response>`; </response>`;
} }
if (r2_objects.truncated) {
cursor = r2_objects.cursor;
}
} while (r2_objects.truncated)
page += '\n</multistatus>\n'; page += '\n</multistatus>\n';
return new Response(page, { return new Response(page, {
status: 207, status: 207,
@ -433,15 +440,8 @@ async function handle_propfind(request: Request, bucket: R2Bucket): Promise<Resp
let page = `<?xml version="1.0" encoding="utf-8"?> let page = `<?xml version="1.0" encoding="utf-8"?>
<multistatus xmlns="DAV:">`; <multistatus xmlns="DAV:">`;
let cursor: string | undefined = undefined; let prefix = resource_path.endsWith('/') || resource_path === "" ? resource_path : resource_path + '/';
do { for await (let object of listAll(bucket, prefix, true)) {
var r2_objects = await bucket.list({
prefix: resource_path.endsWith('/') || resource_path === "" ? resource_path : resource_path + '/',
cursor: cursor,
include: ['httpMetadata', 'customMetadata'],
});
for (let object of r2_objects.objects.filter(object => object.key !== resource_path)) {
let href = `/${object.key + (object.customMetadata?.resourcetype === '<collection />' ? '/' : '')}`; let href = `/${object.key + (object.customMetadata?.resourcetype === '<collection />' ? '/' : '')}`;
page += ` page += `
<response> <response>
@ -459,10 +459,6 @@ async function handle_propfind(request: Request, bucket: R2Bucket): Promise<Resp
</response>`; </response>`;
} }
if (r2_objects.truncated) {
cursor = r2_objects.cursor;
}
} while (r2_objects.truncated);
page += '\n</multistatus>\n'; page += '\n</multistatus>\n';
return new Response(page, { return new Response(page, {
status: 207, status: 207,