Skip to content

Instantly share code, notes, and snippets.

@jasonbyrne
Created May 17, 2022 11:37
Show Gist options
  • Save jasonbyrne/4f6c9218ec1f15268706750a72b8ab35 to your computer and use it in GitHub Desktop.
Save jasonbyrne/4f6c9218ec1f15268706750a72b8ab35 to your computer and use it in GitHub Desktop.
Fetch Thumbnail, resize and serve with Cloudflare Worker
import { IncomingRequest } from '../incoming-request'
const buckets: { [key: string]: string } = {
'bucket-name': 'https://bucket-url/',
}
interface RequestInitWithCf extends RequestInit {
cf: RequestInitCfProperties & {
image: BasicImageTransformations & {
quality?: number | undefined
}
}
}
export async function fetchThumbnail(req: IncomingRequest): Promise<Response> {
const options: RequestInitWithCf = {
cf: {
cacheTtl: 3000,
cacheEverything: true,
image: {
fit: 'scale-down',
width: 240,
},
},
}
// First part should be the bucket
const pathStart = req.getPath(2, 1)
const bucket = buckets[pathStart]
if (!bucket) {
return new Response(`No such bucket: "${pathStart}". ${req.path}`, {
status: 404,
})
}
// Valid file name
if (!/^[A-Za-z0-9-.]+\.(jpg|gif|png|jpeg)$/i.test(req.fileName)) {
return new Response('Invalid file name format.', { status: 400 })
}
// Generate source image url
const imageURL = `${bucket}${req.getPath(3)}`
// Width
const width = req.queryString<number>('width', parseInt) || 240
// Enforce width range
if (width < 10 || width > 1200) {
return new Response('Width must be between 10 and 1200.', { status: 400 })
}
// Set width
options.cf.image.width = width
// Build a request that passes through request headers
const imageRequest = new Request(imageURL, {
headers: req.headers,
})
// Fetch the image and return it
const response = await fetch(imageRequest, options)
//response.headers.set('Cache-Control', 'max-age=3000')
return response
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment