Turning a Git Repository into a Simple File Host with Cloudflare Workers
Finn Greig
Recently I used Cloudflare Workers for the first time to create the website you're reading right now (look at Fruition to learn how I did it), and I decided to try out writing some of my own workers to get an idea of what it could do.
I was in need of a simple static file host to serve various small files - stuff like HTML, presentations, PDFs etc - and thought about how Git repository hosts generally allow you to view a file within a repository in its raw format, served directly to you without modifications. I figured that I could use a Cloudflare Worker to proxy a request to a raw file path on my Git hosting service, and rewrite any necessary headers to ensure that files are served to browsers correctly.
Here's how I did it:
- If you do not already have an account, sign up at CloudFlare and follow the step-by-step instructions provided to set up your domain to use their services.
- Click the workers button at the top of the page
- Set up your worker subdomain - this can be anything you like (if prompted), then click the manage workers button
- Click the create worker button
- In the script editor on the left half of the page, replace the example script with this:
addEventListener('fetch', event => { event.respondWith(handleRequest(event.request)) }) // add a link to the raw file content host pointed at your primary ref const REPO_URL = 'https://raw.githubusercontent.com/exampleuser/examplerepo/main/' const PATH_REGEX = /(?<=/*YOUR DOMAIN HERE*/\/).+/ const mimeTable = { 'html': 'text/html', 'css': 'text/css', 'jpeg': 'image/jpeg', 'jpg': 'image/jpeg', 'js': 'text/javascript', 'json': 'application/json', 'png': 'image/png', 'txt': 'text/plain' } /** * Respond to the request * @param {Request} request */ async function handleRequest(request) { const req = new Request(request); const path = req.url.match(PATH_REGEX)[0]; const extension = path.split('.').pop(); const file = await fetch(REPO_URL + path); if (!file.ok) return new Response(null, {status: file.status}); const response = new Response(file.body, file); const contentDisposition = response.headers.get('content-disposition'); if (contentDisposition) response.headers.delete('content-disposition'); response.headers.set('content-type', mimeTable[extension]); return response; }
- Click the save and deploy button, and confirm that you want to save and deploy
- Go back to your domain's dashboard, and click the workers button again like in step 2
- Click the add route button
- Specify the route that the worker function will serve git repository assets for (e.g.
files.exampledomain.com/*
), select your worker function that you just created in the worker dropdown and then click save - Click the DNS button at the top of the page
- Add a CNAME record, with the name set to the domain used in the worker route, and the target can be set to a non-existent record (e.g.
sinkhole.exampledomain.com
) - Try and open a file in your git repository by visiting
https://<WORKER_ROUTE_DOMAIN>/<FILENAME>.<EXT>
Your git repository is now like a simple file hosting server - files can be loaded directly over HTTP now. Since the worker script removes the content-disposition header if it is present and corrects the content-type header, it can also be used as an asset source within HTML and CSS.
I hope this helps you as much as it did for me - if you enjoyed this and found it interesting, please share it with your friends - I appreciate it a lot 😁