Skip to content

Instantly share code, notes, and snippets.

@gfodor
Created July 18, 2022 17:33
Show Gist options
  • Save gfodor/6d1dd995bc515276b7b80d84fae27e96 to your computer and use it in GitHub Desktop.
Save gfodor/6d1dd995bc515276b7b80d84fae27e96 to your computer and use it in GitHub Desktop.
const ALLOWED_ORIGIN_SUFFIXES = ["notify.windows.com", "android.googleapis.com", "fcm.googleapis.com", "updates.push.services.mozilla.com", "gateway.push.apple.com"];
const CORS_PROXY_HOST = "https://proxy.web-push.workers.dev";
addEventListener("fetch", e => {
const request = e.request;
const origin = request.headers.get("Origin");
// eslint-disable-next-line no-useless-escape
const isCorsProxy = request.url.indexOf(CORS_PROXY_HOST) === 0;
const proxyUrl = new URL(CORS_PROXY_HOST);
const targetPath = request.url.substring(CORS_PROXY_HOST.length + 1);
let targetUrl;
// Do not allow cors proxying from main domain, always require cors-proxy. subdomain to ensure CSP stays sane.
if (!isCorsProxy) return;
// Must be a POST of application/octet-stream
if (request.method !== "POST") return;
if (request.headers.get("content-type") !== "application/octet-stream") return;
// This is a weird workaround that seems to stem from the cloudflare worker receiving the wrong url
targetUrl = targetPath.replace(/^http(s?):\/([^/])/, "http$1://$2");
if (!targetUrl.startsWith("http://") && !targetUrl.startsWith("https://")) {
targetUrl = proxyUrl.protocol + "//" + targetUrl;
}
const targetUrlOrigin = new URL(targetUrl).origin;
if (!ALLOWED_ORIGIN_SUFFIXES.find(r => targetUrlOrigin.endsWith(r))) return;
const requestHeaders = new Headers(request.headers);
requestHeaders.delete("Origin"); // Some domains disallow access from improper Origins
e.respondWith((async () => {
const body = atob(await request.text());
const res = await fetch(targetUrl, { body, headers: requestHeaders, method: request.method, redirect: "manual", referrer: request.referrer, referrerPolicy: request.referrerPolicy });
const responseHeaders = new Headers(res.headers);
if (origin) {
responseHeaders.set("Access-Control-Allow-Origin", origin);
responseHeaders.set("Access-Control-Allow-Methods", "POST");
responseHeaders.set("Access-Control-Expose-Headers", "Accept-Ranges, Content-Encoding, Content-Length, Content-Range");
}
responseHeaders.set("Vary", "Origin");
responseHeaders.set('X-Content-Type-Options', "nosniff");
return new Response(res.body, { status: res.status, statusText: res.statusText, headers: responseHeaders });
})());
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment