Last active
September 18, 2022 04:30
-
-
Save VishalTaj/4638a609412a06db3f3a9d1106280381 to your computer and use it in GitHub Desktop.
Cloudflare Worker acts as a proxy and push to response payload to CF Cache.
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
async function sha256(message) { | |
// encode as UTF-8 | |
const msgBuffer = new TextEncoder().encode(message) | |
// hash the message | |
const hashBuffer = await crypto.subtle.digest("SHA-256", msgBuffer) | |
// convert ArrayBuffer to Array | |
const hashArray = Array.from(new Uint8Array(hashBuffer)) | |
// convert bytes to hex string | |
const hashHex = hashArray.map(b => ("00" + b.toString(16)).slice(-2)).join("") | |
return hashHex | |
} | |
async function blockMutation(req) { | |
try { | |
const body = await req.clone().json() | |
console.log(json.query.replace(/\s/g, '').indexOf("mutation")) | |
return json.query.replace(/\s/g, '').indexOf("mutation") == 0 | |
} catch (e) { | |
return false | |
} | |
} | |
async function handlePostRequest(event) { | |
const request = event.request | |
const body = await request.clone().text() | |
const isMutation = await blockMutation(request) | |
// Hash the request body to use it as a part of the cache key | |
if (!isMutation) { | |
const hash = await sha256(body) | |
const cacheUrl = new URL(request.url) | |
// Store the URL in cache by prepending the body's hash | |
cacheUrl.pathname = cacheUrl.pathname + hash | |
// Convert to a GET to be able to cache | |
const cacheKey = new Request(cacheUrl.toString(), { | |
headers: request.headers, | |
method: "GET", | |
}) | |
const cache = caches.default | |
// Find the cache key in the cache | |
let response = await cache.match(cacheKey) | |
// Otherwise, fetch response to POST request from origin | |
if (!response) { | |
response = await fetch(request) | |
response = new Response(response.body, response) | |
response.headers.append('X-GQL-Cache-Time', `${new Date().getTime()}`) | |
if (response.status == 200) | |
event.waitUntil(cache.put(cacheKey, response.clone())) | |
} | |
return response | |
} else { | |
response = new Response("Mutation Query not allowed") | |
response.status = "403" | |
return response | |
} | |
} | |
addEventListener("fetch", event => { | |
try { | |
const request = event.request | |
// will skip cache if X-Skip-Cache == 0 | |
if (request.method.toUpperCase() === "POST" && request.headers.get('X-Skip-Cache') != 0) | |
return event.respondWith(handlePostRequest(event)) | |
return event.respondWith(fetch(request)) | |
} catch (e) { | |
console.log(e.message) | |
return event.respondWith(new Response("Error thrown " + e.message)) | |
} | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment