Worker to rewrite Google Firestore URLs for images [+watermark question]

ssl

#1

Fair warning: I am here to test the limits of ‘all levels of knowledge welcome’ :slight_smile:

I’m helping bring up a website that plans on using Wordpress on the backend to host and sell abstract images to art consumers. In improving performance, we decided to use Google Firestore [and indeed the images are now preternaturally fast].

Wondering if a Worker can change the URL from

https://storage.googleapis.com/stateless-www-abstractresource/2018/04/Header-pic-grey-1.jpg

to, for instance,

https://media.abstractresource.com/2018/04/Header-pic-grey-1.jpg

And if so, how to go about this. Also whether a Worker is the best approach.

Questions I have:

*Where/how CORS comes into play with my Cloudflare “HTTPS Everywhere” setting and the potential Worker solution? I’m not sure about where I need to assert “cross resource” when talking about a worker in between client and server.
*Would it be possible to have one worker that does a URL rewrite and adds a watermark / hotlink protection in one ‘worker’ or would these be separate workers running in conjunction?

Thank you very much for any help you can provide! :slight_smile:


#2

Just regarding the technical “changing thing”:

var oldurl = “https://storage.googleapis.com/stateless-www-abstractresource/2018/04/Header-pic-grey-1.jpg”;
var newurl = oldurl.replace(“https://storage.googleapis.com/stateless-www-abstractresource/”, “https://media.abstractresource.com/”);

(Reference)


#3

Hi @rico1,

To do this in a worker, I’d recommend deploying something like the following on the route media.abstractresource.com/*:

addEventListener("fetch", event => {
  event.respondWith(handle(event.request))
}

async function handle(request) {
  // Rewrite the URL.
  let url = request.url.replace(
      "media.abstractresource.com",
      "storage.googleapis.com/stateless-www-abstractresource")

  // Fetch the new URL, preserving the original request's headers/settings.
  return fetch(url, request)
}

Then change all your storage.googleapis.com links in your HTML to point to the media.abstractresource.com versions.

Note:

  1. If you want to use a worker for another reason on your site, you’ll need to combine it into the same script, deploy it on a route matching *abstractresource.com/* and have some if-else logic to detect if you’re processing a request for your media subdomain, or some other subdomain.

  2. I used @cat24max’s suggestion of using String.replace to rewrite the URL, but note that the arguments are reversed: the idea here is that the browser will only ever know the media.abstractresource.com version of the URL.

As for whether using a worker is the best approach: it’s probably the easiest. You could also investigate using a CNAME redirect, but it looks like that requires extra work to get working with HTTPS.

If all of your media.abstractresource.com links are subresources (e.g., <img src=...> tags), then CORS does not come into play.

If you are fetching the media assets via fetch() or XHR on the browser, then CORS does come into play. If this is the case, you could easily modify your worker script to account for that:

  // Fetch the new URL, preserving the original request's headers/settings.
  let response = await fetch(url, request)

  // Copy the response so that we can mutate its headers.
  response = new Response(response.body, response)

  // Allow this resource to be used in a browser script.
  response.set("Access-Control-Allow-Origin", "https://www.abstractresource.com")
  return response

Lastly …

For now, this would need to be done in the same worker. We are actively working on the ability to package worker scripts in Cloudflare Apps for easier composition, like you describe.

Harris


#4

Really, really appreciate the response @harris. Thanks a lot

Figuring out where the breakdown in certain microservice configurations should be is a new and interesting set of problems. I personally strongly prefer leveraging Cloudflare over other platforms so I again have to say I super appreciate the thoughtful and complete response!

I’m going to go investigate the solution and think about the best way to incorporate the various compute clouds available for the watermark process.