We have a worker that runs an itty router and serves as a gateway over fetch to image resizing, which we’ve enabled on our zone (zion.xyz). Since there’s a problem fetching within a worker on the same zone (returns a 404), we’ve been using the *.workers.dev host to fetch a resized image as follows:
workers_dev_zone}/space-icon/$CUSTOM_ID/$OPTIONS
The above URL invokes our worker which calls fetch on the Image resizing url, which as I understand can be any zone with the setting enabled. So…
OPTIONS = image resizing options
ACCOUNT_ASH = image resizing account hash
CUSTOM_ID = custom image id image uploaded with
We’ve edited an image at a given CUSTOM_ID path, but when fetching over the worker still occasionally get back the old image. Cache purge everything in our zone doesn’t help, nor do Cache-Control: no-cache headers. Our image origin is imagedelivery.net, Cloudflare’s zone for serving images. I understand there’s a Workers cache key managed by the image resizing worker CF runs on our zone. How can we purge this key such that image resizing will MISS and fetch the image from the origin at imagedelivery.net ?
Why do you need gateway to run *.workers.dev and can’t fetch the same zone? can you handle different path of the url inside worker running on zion.xyz?
We need to run *.workers.dev b/c we are fetching within the worker over image resizing URL which is another zone in the same account and so can’t fetch over the same zone in the original request. AFAIK this is a security limitation on Cloudflare’s side.
I wasn’t aware of this feature! I’ve enabled it. We can use this for now, but would like ultimately to proxy image resizing (rather than make it publicly available) in order to perform authorization.
Hi Alex, below is our worker code that fetches over image resizing url. Curious yours thoughts on the general problem of fetching within a worker over same zone. We will turn off image resizing in favor of flex variants.
// /space-icon/<space_id>/<IMAGE_OPTIONS>
// see https://developers.cloudflare.com/images/image-resizing/url-format/
// for IMAGE_OPTIONS available
router.get('/space-icon/:id+', async (request, env) => {
const { pathname } = new URL(request.url)
const pathSplit = pathname.split('/')
let options: string = pathSplit[pathSplit.length - 1]
let spaceId: string
if (options.match(IMAGE_OPTIONS_REGEX)) {
spaceId = pathSplit[pathSplit.length - 2]
} else {
spaceId = pathSplit[pathSplit.length - 1]
// John's notes 01/23:
// optimized for desktop browsers,
// optimize this for device in the future
// by examining CF-device-id
options = DEFAULT_OPTIONS
}
if (spaceId === undefined) {
return new Response('spaceId error', { status: 400 })
}
// redirect url
const destinationURL = new URL(
[
env.IMAGE_SERVICE,
CDN_CGI_PATH,
options,
env.IMAGE_SERVICE,
CDN_CGI_PATH_ID,
env.IMAGE_HASH,
spaceId,
'public',
].join('/'),
)
const newRequest: Request = new Request(destinationURL, new Request(request.clone()))
try {
// cache this fetch for max of CACHE_TTL seconds before revalidation
const response = await fetch(newRequest, { cf: { cacheTtl: CACHE_TTL } })
// clone response so it's no longer immutable
const newResponse = new Response(response.body, response)
// cache on client, but prefer revalidation when served
// https://developers.cloudflare.com/cache/about/cache-control/#revalidation
newResponse.headers.delete('Cache-Control')
newResponse.headers.set('Cache-Control', 'public, no-cache')
return newResponse
} catch (error) {
return new Response(JSON.stringify({ error: (error as Error).message }), {
status: 500,
})
}
})