Skip to content

Commit

Permalink
add
Browse files Browse the repository at this point in the history
  • Loading branch information
aigem committed Sep 11, 2024
1 parent 5868b48 commit 7562b18
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 26 deletions.
45 changes: 23 additions & 22 deletions src/handlers/webdavHandler.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { listAll, fromR2Object, make_resource_path, generatePropfindResponse, generateMultiStatus } from '../utils/webdavUtils';
import { listAll, fromR2Object, make_resource_pathfindResponse, generateMultiStatus } from '../utils/webdavUtils';
import { logger } from '../utils/logger';
import { WebDAVProps } from '../types';

Expand All @@ -24,14 +24,14 @@ export async function handleWebDAV(request: Request, bucket: R2Bucket, bucketNam
return await handlePropfind(request, bucket, bucketName);
case "COPY":
return await handleCopy(request, bucket);
case "MOVE":
return await handleMove(request, bucket);
case
return await handleMove(request
default:
return new Response("Method Not Allowed", {
status: 405,
headers: {
Allow: SUPPORT_METHODS.join(", "),
DA_CLASS
DAV: DAV_CLASS
}
});
}
Expand All @@ -56,8 +56,7 @@ async function handleHead(request: Request, bucket: R2Bucket): Promise<Response>
const object = await bucket.head(resource_path);

if (!object) {
return new Response(null, { status: 404 });
}
return new Response(null, { status: 404}

const headers = new Headers({
"Content-Type": object.httpMetadata?.contentType ?? "application/octet-stream",
Expand Down Expand Up @@ -86,7 +85,7 @@ async function handleGet(request: Request, bucket: R2Bucket, bucketName: string)
const items = await listDirectoryContents(bucket, resource_path);
const html = generateDirectoryListing(bucketName, resource_path, items);
return new Response(html, {
status:
status: 200,
headers: { "Content-Type": "text/html; charset=utf-8" }
});
}
Expand All @@ -108,8 +107,7 @@ async function handlePut(request: Request, bucket: R2Bucket): Promise<Response>
try {
const body = await request.arrayBuffer();
await bucket.put(resource_path, body, {
httpMetadata: {
contentType: request.headers.get("Content-Type") || "application/octet-stream",
httpMetadata: {: request.headers.get("Content-Type") || "application/octet-stream",
},
});
return new Response(null, { status: 201 });
Expand All @@ -130,13 +128,13 @@ async function handleDelete(request: Request, bucket: R2Bucket): Promise<Respons

if (object.customMetadata?.resourcetype === "collection") {
// Delete all objects within the directory
for await (const item of listAll(bucket, resource_path, true)) {
for await (const item(bucket, resource_path, true)) {
await bucket.delete(item.key);
}
}

await bucket.delete(resource_path);
return new Response(: 204 });
return new Response(null, { status: 204 });
} catch (error) {
logger.error("Error deleting object:", error);
return new Response("Internal Server Error", { status: 500 });
Expand All @@ -151,7 +149,7 @@ async function handleMkcol(request: Request, bucket: R2Bucket): Promise<Response
}

try {
const existingObject = await bucket.head(resource_path);
const exist = await bucket.head(resource_path);
if (existingObject) {
return new Response("Method Not Allowed", { status: 405 });
}
Expand All @@ -168,7 +166,7 @@ async function handleMkcol(request: Request, bucket: R2Bucket): Promise<Response

async function handlePropfind(request: Request, bucket: R2Bucket, bucketName: string): Promise<Response> {
const resource_path = make_resource_path(request);
const depth = request.headersDepth") || "infinity";
const depth.get("Depth") || "infinity";

try {
const props: WebDAVProps[] = [];
Expand All @@ -189,8 +187,8 @@ async function handlePropfind(request: Request, bucket: R2Bucket, bucketName: st
}

const xml = generatePropfindResponse(bucketName, resource_path, props);
xml, {
status:,
return new Response(xml, {
status: 207,
headers: { "Content-Type": "application/xml; charset=utf-8" }
});
} catch (error) {
Expand All @@ -209,7 +207,7 @@ async function handleCopy(request: Request, bucket: R2Bucket): Promise<Response>
const destinationPath = make_resource_path(new Request(destinationUrl));

try {
const sourceObject = await bucket.get(sourcePath);
constObject = await bucket.get(sourcePath);
if (!sourceObject) {
return new Response("Not Found", { status: 404 });
}
Expand All @@ -223,7 +221,7 @@ async function handleCopy(request: Request, bucket: R2Bucket): Promise<Response>
customMetadata: item.customMetadata
});
}

} else {
// Copy file
await bucket.put(destinationPath, sourceObject.body, {
httpMetadata: sourceObject.httpMetadata,
Expand Down Expand Up @@ -276,11 +274,13 @@ async function handleMove(request: Request, bucket: R2Bucket): Promise<Response>
} catch (error) {
logger.error("Error in MOVE:", error);
return new Response("Internal Server Error", { status: 500 });
}
}

async function listDirectoryContents(bucket: R2Bucket, prefix: string): Promise<R2Object[]> {
const items: R2Object[] = [];
for await (const item of listAll(bucket, prefix)) (item.key !== prefix) {
for await (const item of listAll(bucket, prefix)) {
if (item.key !== prefix) {
items.push(item);
}
}
Expand All @@ -303,17 +303,18 @@ function generateDirectoryListing(bucketName: string, path: string, items: R2Obj
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Directory Listing for /${bucketName}/${path}</title>
<style>
body { font-family: Arial, sans-serif; line-height: 1.6;: 20px; }
body { font-family: Arial, sans-serif; line-height: 1.6; padding: 20px; }
h1 { color: #333; }
ul { list-style-type: none; padding: 0; } margin-bottom: 10px; }
a { color:066cc; text-decoration: none; }
ul { list-style-type: none; padding: 0; }
li { margin-bottom: 10px; }
a { color: #0066cc; text-decoration: none; }
a:hover { text-decoration: underline; }
</style>
</head>
<body>
<h1>Directory Listing for /${bucketName}/${path}</h1>
<ul>
${path !== '' ? '<li><a href="../">📁 ..</a></li>' : ''}
${path !== '' ? '<li><a href="../">📁 .>' : ''}
${listItems}
</ul>
</body>
Expand Down
8 changes: 4 additions & 4 deletions src/utils/webdavUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { WebDAVProps } from '../types';
export async function* listAll(bucket: R2Bucket, prefix: string, isRecursive = false) {
let cursor: string | undefined = undefined;
do {
const r2_.list({
const r2_objects = await bucket.list({
prefix,
delimiter: isRecursive ? undefined : "/",
cursor,
Expand Down Expand Up @@ -47,9 +47,9 @@ export function make_resource_path(request: Request): string {
return path.endsWith("/") ? path.slice(0, -1) : path;
}

export function generatePropfindResponse(bucket basePath: string, props: WebDAVProps[]): string {
export function generatePropfindResponse(bucketName: string, basePath: string, props: WebDAVProps[]): string {
const xml = `<?xml version="1.0" encoding="utf-8"?>
<D:multistatus xmlns::">
<D:multistatus xmlns:D="DAV:">
${props.map(prop => generatePropResponse(bucketName, basePath, prop)).join('\n')}
</D:multistatus>`;
return xml;
Expand All @@ -66,7 +66,7 @@ function generatePropResponse(bucketName: string, basePath: string, prop: WebDAV
<D:getcontentlanguage>${prop.getcontentlanguage || ''}</D:getcontentlanguage>
<D:getcontentlength>${prop.getcontentlength}</D:getcontentlength>
<D:getcontenttype>${prop.getcontenttype || ''}</D:getcontenttype>
<D:getetag>${prop.getetag ''}</D:getetag>
<D:getetag>${prop.getetag || ''}</D:getetag>
<D:getlastmodified>${prop.getlastmodified}</D:getlastmodified>
<D:resourcetype>${prop.resourcetype === 'collection' ? '<D:collection/>' : ''}</D:resourcetype>
</D:prop>
Expand Down

0 comments on commit 7562b18

Please sign in to comment.