diff --git a/src/index.ts b/src/index.ts index 0903dbb..443715a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -29,6 +29,27 @@ export interface Env { 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 SUPPORT_METHODS = [ "OPTIONS", @@ -106,14 +127,12 @@ async function handle_get(request: Request, bucket: R2Bucket): Promise let resource_path = make_resource_path(request); if (request.url.endsWith('/')) { - let r2_objects = await bucket.list({ - prefix: resource_path, - delimiter: '/', - include: ['httpMetadata', 'customMetadata'], - }); let page = ''; if (resource_path !== '') page += `..
`; - 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 === '' ? '/' : '')}`; page += `${object.httpMetadata?.contentDisposition ?? object.key}
`; } @@ -271,7 +290,7 @@ async function handle_propfind(request: Request, bucket: R2Bucket): Promise
- `, { +`, { status: 207, headers: { 'Content-Type': 'text/xml', @@ -353,37 +372,25 @@ async function handle_propfind(request: Request, bucket: R2Bucket): Promise `; - let cursor: string | undefined = undefined; - do { - 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 === '' ? '/' : '')}`; - page += ` + let prefix = resource_path.endsWith('/') || resource_path === "" ? resource_path : resource_path + '/'; + for await (let object of listAll(bucket, prefix)) { + let href = `/${object.key + (object.customMetadata?.resourcetype === '' ? '/' : '')}`; + page += ` ${href} ${Object.entries(fromR2Object(object)) - .filter(([_, value]) => value !== undefined) - .map(([key, value]) => `<${key}>${value}`) - .join('\n ') - } + .filter(([_, value]) => value !== undefined) + .map(([key, value]) => `<${key}>${value}`) + .join('\n ') + } HTTP/1.1 200 OK `; - } + } - if (r2_objects.truncated) { - cursor = r2_objects.cursor; - } - } while (r2_objects.truncated) page += '\n\n'; return new Response(page, { status: 207, @@ -433,36 +440,25 @@ async function handle_propfind(request: Request, bucket: R2Bucket): Promise `; - let cursor: string | undefined = undefined; - do { - 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 === '' ? '/' : '')}`; - page += ` + let prefix = resource_path.endsWith('/') || resource_path === "" ? resource_path : resource_path + '/'; + for await (let object of listAll(bucket, prefix, true)) { + let href = `/${object.key + (object.customMetadata?.resourcetype === '' ? '/' : '')}`; + page += ` ${href} ${Object.entries(fromR2Object(object)) - .filter(([_, value]) => value !== undefined) - .map(([key, value]) => `<${key}>${value}`) - .join('\n ') - } + .filter(([_, value]) => value !== undefined) + .map(([key, value]) => `<${key}>${value}`) + .join('\n ') + } HTTP/1.1 200 OK `; - } + } - if (r2_objects.truncated) { - cursor = r2_objects.cursor; - } - } while (r2_objects.truncated); page += '\n\n'; return new Response(page, { status: 207,