I made Imgy cheaper to run and also I broke it sometimes

I chucked together a Cloudflare worker for Imgy as I want to switch the backend from Amazon S3 to Backblaze for the Bandwidth Alliance savings and also why not.


update: I should absolutely be crediting this post. I can’t remember chicken or egg but either I read this and basically just followed it or I found it while looking into it

https://jross.me/free-personal-image-hosting-with-backblaze-b2-and-cloudflare-workers/


The party is going down in index.js and now I’ll do that thing where the person breaks down the script but all you want to do is jump to the final thing, here ya go:

async function handleRequest(request) {
    var url = new URL(request.url);

    // Override our source
    url.hostname = "my-image-vault.s3.xx-fake-1.amazonaws.com";

    let response = await fetch(url, request, {
        cf: {
            cacheTtl: 604800,
            cacheEverything: true, 
        }, 
    });
    
    response = new Response(response.body, response);

    if ( response.status >= 100 && response.status <= 399 ) {
        response.headers.set("Cache-Control", "max-age=604800")
        return response;
    }

    let body =
`<!DOCTYPE html>
<html>
<head>
    <title>Image error</title>
</head>
<body>
    <div class="flex-container">
        <div class="row">
            <div class="flex-item">Image error: ` + response.status + `</div>
            <div class="flex-item small">If you were expecting something to be here and it's vanished, please do <a href='https://ic4.io/contact'>let me know</a>!</div>
        </div>
    </div>
    <style>
        html, body {
            height: 100%;
            background-color: white;
            color: #15202b;
        }
        body {
            margin: 0;
        }
        a, a:visited {
            color: #123456;
        }
        .flex-container {
            height: 100%;
            display: flex;
            align-items: center;
            justify-content: center;
        }
        .row {
            width: auto;
        }
        .flex-item {
            font-size: 2em;
            text-align: center;
            margin-bottom: 1.4em;
        }
        .small {
            font-size: 1.2em;
        }
    </style>
</body>
</html>`;

    let imageNotFound = new Response(body, {
        status: response.status,
        statusText: "Image error",
        headers: {
            "Content-Type": "text/html"
        }
    });

    return imageNotFound;
    
}

addEventListener('fetch', event => {
    event.respondWith(handleRequest(event.request));
});

Basically we grab the requested path from url.hostname and set the cache to a week. If we get a response code not between 100-399 we’ll error out

Anyway I broke Imgy because I wasn’t doing that 100-399 bit.. That meant every time the image was cached in the browser and it got a 304 response I rewrote the response to a 404 error.. Oops! :)

I now check for 100-399 instead of just checking for response.status being 200 and I’m no longer rewriting the status cause that was a pain to sort out

Make sure you’re checking the right thing or whatever