Last active
November 30, 2022 14:37
-
-
Save pkieltyka/d6830df1f95ba5d2fbdef89847804060 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// CORS Anywhere -- Cloudflare Workers edition! | |
// | |
// try: https://cors-anywhere.0xhorizon.workers.dev/https://discordapp.com/api/guilds/444586810765475860/widget.json | |
// | |
addEventListener('fetch', event => { | |
event.respondWith(handleRequest(event, event.request)) | |
}) | |
async function handleRequest(event, request) { | |
// Handle OPTIONS request quickly | |
if (request.method === "OPTIONS") { | |
return handleCORSPreflight(request) | |
} else if (request.method !== "GET" && request.method !== "HEAD") { //&& request.method !== "POST") { | |
return new Response(null, { | |
status: 405, | |
statusText: "Method Not Allowed", | |
}) | |
} | |
// Handle normal GET/HEAD request | |
let url = new URL(request.url) | |
let host = url.host | |
let param = url.pathname | |
if (param.length >= 1) { | |
param = param.substr(1) | |
} | |
if (param === "") { | |
return respondWithText("welcome") | |
} | |
if (!param.startsWith("http")) { | |
return respondWithText("Oops! invalid use, speak to dev team for correct usage.") | |
} | |
if (param.indexOf("://") < 0) { | |
param = param.replace("http:/", "http://") | |
param = param.replace("https:/", "https://") | |
} | |
// Proxy-cache the request (with ttl of 60 seconds) | |
let cacheUrl = new URL(param) | |
let cacheKey = new Request(cacheUrl) | |
let cache = caches.default | |
// Get this request from this zone's cache | |
let resp = await cache.match(cacheKey) | |
if (!resp) { | |
//if not in cache, grab it from the origin | |
originResp = await fetch(cacheUrl, { | |
method: request.method, | |
headers: { | |
...request.headers | |
}, | |
cf: { | |
cacheEverything: true, | |
cacheTtl: 61, | |
scrapeShield: false | |
} | |
}) | |
// must use Response constructor to inherit all of response's fields | |
resp = new Response(originResp.body, { | |
status: originResp.status | |
}) | |
// copy over certain headers, but we don't want all.. | |
let v = originResp.headers.get('content-type') | |
if (v && v !== '') { | |
resp.headers.set('content-type', v) | |
} | |
// set caching and cors headers | |
resp.headers.set('X-Worker', (new Date()).toUTCString()) | |
resp.headers.set('Cache-Control', 'public, max-age=61') | |
resp.headers.set('Access-Control-Allow-Origin', '*') | |
resp.headers.set('Access-Control-Allow-Methods', 'GET, HEAD') | |
// store the fetched response as cacheKey | |
await cache.put(cacheKey, resp.clone()) | |
} | |
return resp | |
} | |
function respondWithText(text) { | |
return new Response(text, { status: 200, headers: { "Content-Type": "text/html" } }) | |
} | |
// We support the GET, POST, HEAD, and OPTIONS methods from any origin, | |
// and accept the Content-Type header on requests. These headers must be | |
// present on all responses to all CORS requests. In practice, this means | |
// all responses to OPTIONS requests. | |
const corsHeaders = { | |
"Access-Control-Allow-Origin": "*", | |
"Access-Control-Allow-Methods": "GET, HEAD, POST, OPTIONS", | |
"Access-Control-Allow-Headers": "Content-Type", | |
} | |
function handleCORSPreflight(request) { | |
if (request.headers.get("Origin") !== null && | |
request.headers.get("Access-Control-Request-Method") !== null) { | |
// Handle CORS pre-flight request. | |
return new Response(null, { | |
headers: corsHeaders | |
}) | |
} else { | |
// Handle standard OPTIONS request. | |
return new Response(null, { | |
headers: { | |
"Allow": "GET, HEAD, POST, OPTIONS", | |
} | |
}) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment