Skip to content

Instantly share code, notes, and snippets.

@HashNuke
Last active March 13, 2025 10:16
Show Gist options
  • Save HashNuke/4306c2c116cc2ccda9778412bcaca80c to your computer and use it in GitHub Desktop.
Save HashNuke/4306c2c116cc2ccda9778412bcaca80c to your computer and use it in GitHub Desktop.
Cloudflare worker that downloads files from R2 bucket
import jwt from '@tsndr/cloudflare-worker-jwt'
// Add following config to wrangler.toml
//
// r2_buckets = [
// { binding = "STORAGE_BUCKET", bucket_name = "your_bucket_name" }
// ]
//
// Also requires download_jwt_secret in the worker env
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url)
const jwt_secret = env.download_jwt_secret
const token = url.searchParams.get('token')
// for me to test if the worker is hosted fine.
if (url.searchParams.get('x') == "test") {
return new Response('Hello World!');
}
if (!token) {
return new Response('Unauthorized', { status: 401 })
}
try {
// 1. Verify JWT
const verifiedToken = await jwt.verify(token, jwt_secret)
if (!verifiedToken) {
return new Response('Invalid token', { status: 401 })
}
// 2. Extract file information
const fileKey = verifiedToken.payload.fileKey
// 3. Fetch object from R2
let object = await env.STORAGE_BUCKET.get(fileKey)
if (object === null) {
return new Response('Object not found', { status: 404 })
}
// 4. Set Cache-Control headers
const headers = new Headers()
headers.set('Cache-Control', 'public, max-age=3600') // Cache for 1 hour
headers.set('Content-Type', object.httpMetadata.contentType)
return new Response(object.body, {
headers: headers,
})
} catch (error) {
return new Response('Error: ' + error.message, { status: 500 })
}
},
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment