Skip to content

Instantly share code, notes, and snippets.

@VishalTaj
Last active September 18, 2022 04:30
Show Gist options
  • Save VishalTaj/4638a609412a06db3f3a9d1106280381 to your computer and use it in GitHub Desktop.
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.
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