Skip to content

Commit

Permalink
better url format
Browse files Browse the repository at this point in the history
  • Loading branch information
yo-han committed Sep 17, 2024
1 parent c5c85a7 commit 9da9a35
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 9 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ Before you begin, ensure you have met the following requirements:
Once deployed, the worker will handle image requests in the following format:

```
https://your-worker-subdomain.workers.dev/?id=image-id&variant=image-variant
https://your-worker-subdomain.workers.dev/<id>-<variant>.png
```

- `id`: The image name or path to find the image on the old server and use as id in R2
Expand Down
52 changes: 44 additions & 8 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Env } from './types';
import { Env, ParsedImageUrl } from './types';
import { RateLimiter } from './rateLimiter';
import { CONFIG } from './config';
import { cacheStrategy } from './cacheStrategy';
Expand Down Expand Up @@ -52,6 +52,36 @@ async function fetchOriginalCloudflareImage(env: Env, id: string): Promise<Respo
return response;
}

function parseImageUrl(url: string): ParsedImageUrl | null {
// Regular expression to match both URL patterns
const regex = /^\/(.+?)(?:-(\d+)x(\d+))?\.([^\.]+)$/;
const match = url.match(regex);

if (!match) {
return null;
}

const [, imageId, width, height, extension] = match;

if (width && height) {
return {
id: imageId.replace(/[^a-zA-Z0-9-_]/g, "-"),
originalPath: imageId,
width: parseInt(width) || undefined,
height: parseInt(height) || undefined,
extension,
variant: width ? `${width}x${height}`.replace(/[^a-zA-Z0-9-_]/g, "") : 'original'
};
} else {
return {
id: imageId.replace(/[^a-zA-Z0-9-_]/g, "-"),
originalPath: imageId,
extension,
variant: 'original'
};
}
}

/**
* Handles an image request.
* @param {Request} request - The incoming request.
Expand All @@ -62,12 +92,17 @@ export async function handleImageRequest(request: Request, env: Env): Promise<Re

const CLOUDFLARE_IMAGE_EXTENSIONS = ['png', 'jpg', 'jpeg', 'gif', 'webp', 'avif', 'tif', 'tiff', 'svg'];


const url = new URL(request.url);
const id = url.searchParams.get("id")?.replace(/[^a-zA-Z0-9-_]/g, "-");
const variant = url.searchParams.get("variant")?.replace(/[^a-zA-Z0-9-_]/g, "") || "";
const file_path = url.searchParams.get("id")?.replace(/[^a-zA-Z0-9-_\/\.]/g, "-");
const extension = file_path?.split('.')?.pop()?.toLowerCase();
const parsedImage = parseImageUrl(url.pathname);
const bucket = env.R2_IMAGES_BUCKET;

if (!parsedImage) {
return new Response('Invalid image URL', { status: 400 });
}

const { id, originalPath, extension, variant} = parsedImage;

const file_path = originalPath.replace(/[^a-zA-Z0-9-_\/\.]/g, "-");
const image_path = file_path?.replace(new RegExp(`\\.(${CLOUDFLARE_IMAGE_EXTENSIONS.join('|')})$`, 'i'), '');

if (!id) {
Expand All @@ -78,7 +113,7 @@ export async function handleImageRequest(request: Request, env: Env): Promise<Re
return new Response('Invalid image extension', { status: 400 });
}

const bucket = env.R2_IMAGES_BUCKET;

const cacheKey = `${env.CACHE_KEY_PREFIX}/${id}/${variant}`;

try {
Expand Down Expand Up @@ -107,7 +142,7 @@ export async function handleImageRequest(request: Request, env: Env): Promise<Re
const uploadResponse = await uploadToCloudflareImages(env, sourceUrl, id);

if (uploadResponse.ok) {
const postfix = variant !== '' ? `-${variant}` : '';
const postfix = variant !== 'original' ? `-${variant}` : '';
return Response.redirect(`${env.LIVE_PUBLIC_DOMAIN}/${image_path}${postfix}.${extension}`, 302);
} else {
throw new CloudflareApiError('Failed to fetch and upload image', uploadResponse.status, await uploadResponse.text());
Expand Down Expand Up @@ -159,6 +194,7 @@ function createImageResponse(response: Response | R2ObjectBody, isCacheHit: bool
headers.set('Content-Type', 'image/jpeg');
}
headers.set('x-r2-cache', isCacheHit ? 'HIT' : 'MISS');
headers.set('Access-Control-Allow-Origin', '*');

return new Response(body, { headers, status });
}
Expand Down
9 changes: 9 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,13 @@ export interface R2PutOptions {
sha384?: string;
sha512?: string;
expirationTtl?: number;
}

export interface ParsedImageUrl {
id: string;
originalPath: string;
width?: number;
height?: number;
extension: string;
variant: string;
}

0 comments on commit 9da9a35

Please sign in to comment.