Image resizing cache purge problem

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…

fetch

images.zion.xyz/cdn_cgi/$OPTIONS/https://images.zion.xyz/cdn_cgi/$ACCOUNT_HASH/$CUSTOM_ID/public

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 ?

I’m missing a few bits in the setup.

  1. 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?
  2. Any reason to run image resizing on top of images? did you see this feature Flexible variants · Cloudflare Image Optimization docs ?

Hey Alex,
Thanks for the quick reply.

  1. 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.

  2. 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.

Thanks vm!

  1. I’m curious to see worker code. can you send it to DM?
  2. applying resizing on top of images will essentially mean double resizing, iirc: slower, and doubles the bill.

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,
        })
    }
})

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.