Deploy Natali Proxy Worker #8
This file contains hidden or 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
| name: Deploy Natali Proxy Worker | |
| on: | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| jobs: | |
| deploy-proxy: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Deploy Natali Proxy Worker | |
| env: | |
| CF_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| run: | | |
| set -x | |
| ZONE_ID="5b3f8237bfa2518bff375eb8163623a5" | |
| WORKER_NAME="natalie-proxy" | |
| cat > /tmp/worker.js << 'WORKEREOF' | |
| // GitHub Pages IPs | |
| const GH_IPS = [ | |
| '185.199.108.153', | |
| '185.199.109.153', | |
| '185.199.110.153', | |
| '185.199.111.153' | |
| ]; | |
| const GH_PAGES_DOMAIN = 'spivanatalie64.github.io'; | |
| addEventListener('fetch', event => { | |
| event.respondWith(handleRequest(event.request)); | |
| }); | |
| async function handleRequest(request) { | |
| try { | |
| const url = new URL(request.url); | |
| // Use a random GitHub Pages IP | |
| const ip = GH_IPS[Math.floor(Math.random() * GH_IPS.length)]; | |
| const originUrl = 'https://' + ip + url.pathname + url.search; | |
| const modifiedHeaders = new Headers(request.headers); | |
| modifiedHeaders.set('Host', 'natalie.acreetionos.org'); | |
| // Remove headers that might cause issues | |
| modifiedHeaders.delete('CF-Connecting-IP'); | |
| modifiedHeaders.delete('CF-IPCountry'); | |
| modifiedHeaders.delete('CF-Ray'); | |
| modifiedHeaders.delete('CF-Visitor'); | |
| modifiedHeaders.delete('CDN-Loop'); | |
| modifiedHeaders.delete('X-Forwarded-For'); | |
| const response = await fetch(originUrl, { | |
| method: request.method, | |
| headers: modifiedHeaders, | |
| body: request.body, | |
| redirect: 'manual', | |
| }); | |
| // Handle redirects - follow them manually up to 5 times | |
| let currentResponse = response; | |
| let redirectCount = 0; | |
| const maxRedirects = 5; | |
| while (currentResponse.status >= 300 && currentResponse.status < 400 && redirectCount < maxRedirects) { | |
| const location = currentResponse.headers.get('Location'); | |
| if (!location) break; | |
| // If redirecting back to our domain, skip - we already have the right content | |
| if (location.includes('natalie.acreetionos.org')) { | |
| break; | |
| } | |
| const redirectUrl = new URL(location, originUrl); | |
| currentResponse = await fetch(redirectUrl.toString(), { | |
| method: 'GET', | |
| headers: modifiedHeaders, | |
| redirect: 'manual', | |
| }); | |
| redirectCount++; | |
| } | |
| const newHeaders = new Headers(currentResponse.headers); | |
| newHeaders.set('X-Proxied-By', 'natalie-worker'); | |
| return new Response(currentResponse.body, { | |
| status: currentResponse.status, | |
| statusText: currentResponse.statusText, | |
| headers: newHeaders, | |
| }); | |
| } catch (err) { | |
| return new Response('Worker Error: ' + err.message, { | |
| status: 500, | |
| headers: { 'Content-Type': 'text/plain' }, | |
| }); | |
| } | |
| } | |
| WORKEREOF | |
| cat > /tmp/metadata.json << 'METADATAEOF' | |
| { | |
| "body_part": "script", | |
| "bindings": [], | |
| "compatibility_date": "2026-06-20", | |
| "compatibility_flags": [] | |
| } | |
| METADATAEOF | |
| echo "=== Uploading worker ===" | |
| curl -s -X PUT \ | |
| "https://api.cloudflare.com/client/v4/accounts/6a46b418508c26278ae2d3373f41da81/workers/scripts/$WORKER_NAME" \ | |
| -H "Authorization: Bearer $CF_API_TOKEN" \ | |
| -F "metadata=@/tmp/metadata.json;type=application/json" \ | |
| -F "script=@/tmp/worker.js;type=application/javascript" | jq . | |
| echo "=== Updating route ===" | |
| EXISTING_ROUTES=$(curl -s -H "Authorization: Bearer $CF_API_TOKEN" \ | |
| "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/workers/routes") | |
| NATALIE_ROUTE_ID=$(echo "$EXISTING_ROUTES" | jq -r '.result[] | select(.pattern == "natalie.acreetionos.org/*") | .id') | |
| curl -s -X PUT \ | |
| "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/workers/routes/$NATALIE_ROUTE_ID" \ | |
| -H "Authorization: Bearer $CF_API_TOKEN" \ | |
| -H "Content-Type: application/json" \ | |
| -d "{ | |
| \"pattern\": \"natalie.acreetionos.org/*\", | |
| \"script\": \"$WORKER_NAME\" | |
| }" | jq . | |
| echo "=== Done ===" |