Reputation: 21
How can the following code be re-written to work with the CF Workers feature?
# Start
if(req.url ~ "^/app" ) {
set req.url = regsub(req.url, "^/app/", "/");
set req.http.X-DR-SUBDIR = "app";
}
#end condition
Upvotes: 2
Views: 484
Reputation: 31
Cloudflare Workers implements the Service Worker standard, so you will need to reimplement the VCL code snippet you posted in terms of a Service Worker.
Before I show you how to do that, consider what happens when a request for https://example.com/apple
arrives at the proxy. I would expect the first regex for ^/app
to match, but the second one for ^/app/
not to match -- i.e., the request would be passed through with no change to the URL, but with the addition of an X-DR-SUBDIR: app
header.
I suspect that behavior is a bug, so I'll first implement a worker as if the first regex were ^/app/
.
addEventListener("fetch", event => {
let request = event.request
// Unlike VCL's req.url, request.url is an absolute URL string,
// so we need to parse it to find the start of the path. We'll
// need it as a separate object in order to mutate it, as well.
let url = new URL(request.url)
if (url.pathname.startsWith("/app/")) {
// Rewrite the URL and set the X-DR-SUBDIR header.
url.pathname = url.pathname.slice("/app".length)
// Copying the request with `new Request()` serves two purposes:
// 1. It is the only way to actually change the request's URL.
// 2. It makes `request.headers` mutable. (The headers property
// on the original `event.request` is always immutable, meaning
// our call to `request.headers.set()` below would throw.)
request = new Request(url, request)
request.headers.set("X-DR-SUBDIR", "app")
}
event.respondWith(fetch(request))
})
To revisit the https://example.com/apple
case, if we really wanted a Cloudflare Worker which pedantically reproduces the VCL snippet's behavior, we could change these lines (comments elided):
if (url.pathname.startsWith("/app/")) {
url.pathname = url.pathname.slice("/app".length)
// ...
}
to these:
if (url.pathname.startsWith("/app")) {
if (url.pathname.startsWith("/app/")) {
url.pathname = url.pathname.slice("/app".length)
}
// ...
}
Upvotes: 3