Skip to content

Redeploy Natali Proxy #1

Redeploy Natali Proxy

Redeploy Natali Proxy #1

Workflow file for this run

name: Redeploy Natali Proxy
on:
workflow_dispatch:
permissions:
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy Worker
env:
CF_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
run: |
set -x
# The worker script
cat > /tmp/worker.js << 'JSEOF'
const RAW_BASE = 'https://raw.githubusercontent.com/spivanatalie64/spivanatalie64.github.io/gh-pages';
const MIME = {
'.html': 'text/html; charset=utf-8', '.css': 'text/css; charset=utf-8',
'.js': 'application/javascript; charset=utf-8', '.json': 'application/json; charset=utf-8',
'.png': 'image/png', '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg',
'.gif': 'image/gif', '.svg': 'image/svg+xml', '.ico': 'image/x-icon',
'.webp': 'image/webp', '.pdf': 'application/pdf',
'.woff': 'font/woff', '.woff2': 'font/woff2', '.ttf': 'font/ttf',
};
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request));
});
async function handleRequest(request) {
try {
const url = new URL(request.url);
const path = url.pathname;
const ext = path.match(/\.(\w+)$/)?.[0]?.toLowerCase();
const isAsset = !!MIME[ext];
let rawPath = path;
if (path === '/' || path === '') rawPath = '/index.html';
const response = await fetch(RAW_BASE + rawPath);
if (response.ok || isAsset) {
const h = new Headers(response.headers);
h.set('Content-Type', MIME[ext] || 'text/html; charset=utf-8');
h.delete('content-security-policy');
h.set('Cache-Control', isAsset ? 'public, max-age=86400, s-maxage=2592000' : 'public, max-age=0, s-maxage=600');
h.set('X-Proxied-By', 'natalie-worker');
return new Response(response.body, { status: 200, statusText: 'OK', headers: h });
}
// SPA fallback
const idx = await fetch(RAW_BASE + '/index.html');
if (idx.ok) {
const h = new Headers(idx.headers);
h.set('Content-Type', 'text/html; charset=utf-8');
h.delete('content-security-policy');
h.set('X-Proxied-By', 'natalie-worker');
return new Response(idx.body, { status: 200, statusText: 'OK', headers: h });
}
return new Response('Not Found', { status: 404 });
} catch (err) {
return new Response(err.message, { status: 500, headers: { 'Content-Type': 'text/plain' } });
}
}
JSEOF
# Upload worker
cat > /tmp/meta.json << 'JSONEOF'
{"body_part":"script","bindings":[],"compatibility_date":"2026-06-20","compatibility_flags":[]}
JSONEOF
curl -s -X PUT \
"https://api.cloudflare.com/client/v4/accounts/6a46b418508c26278ae2d3373f41da81/workers/scripts/natalie-proxy" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-F "metadata=@/tmp/meta.json;type=application/json" \
-F "script=@/tmp/worker.js;type=application/javascript" | jq .
# List existing routes and delete ALL natalie routes
ROUTES=$(curl -s -H "Authorization: Bearer $CF_API_TOKEN" \
"https://api.cloudflare.com/client/v4/zones/5b3f8237bfa2518bff375eb8163623a5/workers/routes")
for rid in $(echo "$ROUTES" | jq -r '.result[] | select(.pattern | test("natalie")) | .id'); do
echo "Deleting old route: $rid"
curl -s -X DELETE "https://api.cloudflare.com/client/v4/zones/5b3f8237bfa2518bff375eb8163623a5/workers/routes/$rid" \
-H "Authorization: Bearer $CF_API_TOKEN" | jq .
done
# Add correct route
echo "Adding route..."
curl -s -X POST "https://api.cloudflare.com/client/v4/zones/5b3f8237bfa2518bff375eb8163623a5/workers/routes" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"pattern":"natalie.acreonetionos.org/*","script":"natalie-proxy"}' | jq .
echo "=== Done ==="