diff --git a/src/index.ts b/src/index.ts
index debd41d..048af48 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -114,11 +114,8 @@ export default {
include: ['httpMetadata', 'customMetadata'],
});
let page = '';
- // for (let dirname of r2_objects.delimitedPrefixes) {
- // page += `${dirname}
`;
- // }
- for (let object of r2_objects.objects) {
- page += `${object.httpMetadata?.contentDisposition ?? object.key}
`;
+ for (let object of r2_objects.objects.filter(object => object.key !== resource_path)) {
+ page += `${object.httpMetadata?.contentDisposition ?? object.key}
`;
}
response = new Response(page, { status: 200, headers: { 'Content-Type': 'text/html' } });
} else {
@@ -170,10 +167,13 @@ export default {
}
// Check if the parent directory exists
- let dirpath = resource_path.split('/').slice(0, -1).join('/') + '/';
- let dir = await bucket.head(dirpath);
- if (!dir || dir.customMetadata?.resourcetype !== '') {
- response = new Response('Conflict', { status: 409 });
+ let dirpath = resource_path.split('/').slice(0, -1).join('/');
+ if (dirpath !== '') {
+ let dir = await bucket.head(dirpath);
+ if (!(dir && dir.customMetadata?.resourcetype === '')) {
+ response = new Response('Conflict', { status: 409 });
+ break;
+ }
}
let body = await request.arrayBuffer();
@@ -185,16 +185,44 @@ export default {
}
break;
case 'DELETE': {
- if (resource_path.endsWith('/')) {
- let r2_objects = await bucket.list({
- prefix: resource_path,
- });
- await Promise.all(r2_objects.objects.map(
- object => bucket.delete(object.key)
- ));
- } else {
- await bucket.delete(resource_path);
+ if (!resource_path.endsWith('/')) {
+ let resource = await bucket.head(resource_path);
+ if (resource === null) {
+ response = new Response('Not Found', { status: 404 });
+ break;
+ } else {
+ if (resource.customMetadata?.resourcetype !== '') {
+ await bucket.delete(resource_path);
+ response = new Response(null, { status: 204 });
+ break;
+ }
+ }
}
+
+ let dirpath = resource_path.slice(0, -1);
+ if (await bucket.head(dirpath) === null) {
+ response = new Response('Not Found', { status: 404 });
+ break;
+ }
+
+ await bucket.delete(dirpath);
+
+ let r2_objects, cursor: string | undefined = undefined;
+ do {
+ r2_objects = await bucket.list({
+ prefix: resource_path,
+ cursor: cursor,
+ });
+ let keys = r2_objects.objects.map(object => object.key);
+ if (keys.length > 0) {
+ await bucket.delete(keys);
+ }
+
+ if (r2_objects.truncated) {
+ cursor = r2_objects.cursor;
+ }
+ } while (r2_objects.truncated);
+
response = new Response(null, { status: 204 });
}
break;
@@ -213,7 +241,7 @@ export default {
}
// Check if the parent directory exists
- let parent_dir = resource_path.split('/').slice(0, -2).join("/");
+ let parent_dir = resource_path.split('/').slice(0, -1).join("/");
if (parent_dir !== '' && !await bucket.head(parent_dir)) {
response = new Response('Conflict', { status: 409 });
@@ -235,7 +263,7 @@ export default {
response = new Response(`
- ${resource_path}
+ /
@@ -260,7 +288,7 @@ export default {
let page = `
- ${resource_path}
+ /${resource_path}
${Object.entries(fromR2Object(object))
@@ -296,23 +324,10 @@ export default {
include: ['httpMetadata', 'customMetadata'],
});
- // for (let dirname of r2_objects.delimitedPrefixes) {
- // page += `
- //
- // ${dirname}
- //
- //
- //
- //
- // HTTP/1.1 200 OK
- //
- // `;
- // }
-
- for (let object of r2_objects.objects) {
+ for (let object of r2_objects.objects.filter(object => object.key !== resource_path)) {
page += `
- ${object.key}
+ /${object.key}
${Object.entries(fromR2Object(object))
@@ -424,36 +439,44 @@ export default {
}
let destination = new URL(destination_header).pathname.slice(1);
let destination_exists = await bucket.head(destination);
- if (destination_exists) {
- if (overwrite) {
- await Promise.all((await bucket.list({
- prefix: destination,
- })).objects.map(object => bucket.delete(object.key)));
- } else {
- response = new Response('Precondition Failed', { status: 412 });
- break;
- }
+ if (destination_exists && !overwrite) {
+ response = new Response('Precondition Failed', { status: 412 });
+ break;
}
+
+ // TODO delete recursively (if destination is a directory)
+ // await bucket.delete(
+ // (await bucket.list({ prefix: destination, delimiter: '/' })).objects.map(object => object.key)
+ // );
+
if (resource_path.endsWith('/')) {
let depth = request.headers.get('Depth') ?? 'infinity';
switch (depth) {
case 'infinity': {
- let r2_objects = await bucket.list({
- prefix: resource_path,
- });
- await Promise.all(r2_objects.objects.map(
- object => (async () => {
- let target = destination + object.key.slice(resource_path.length);
- let src = await bucket.get(object.key);
- if (src !== null) {
- await bucket.put(target, src.body, {
- httpMetadata: object.httpMetadata,
- customMetadata: object.customMetadata,
- });
- await bucket.delete(object.key);
- }
- })()
- ));
+ let r2_objects, cursor: string | undefined = undefined;
+ do {
+ r2_objects = await bucket.list({
+ prefix: resource_path,
+ cursor: cursor,
+ include: ['httpMetadata', 'customMetadata'],
+ });
+ await Promise.all(r2_objects.objects.map(
+ object => (async () => {
+ let target = destination + object.key.slice(resource_path.length);
+ let src = await bucket.get(object.key);
+ if (src !== null) {
+ await bucket.put(target, src.body, {
+ httpMetadata: object.httpMetadata,
+ customMetadata: object.customMetadata,
+ });
+ await bucket.delete(object.key);
+ }
+ })()
+ ));
+ if (r2_objects.truncated) {
+ cursor = r2_objects.cursor;
+ }
+ } while (r2_objects.truncated)
response = new Response('', { status: 201 });
}
break;
@@ -478,6 +501,7 @@ export default {
}
}
}
+ break;
default: {
response = new Response('Method Not Allowed', {
status: 405,