feat(edge): blox.grudge-studio.com Worker custom domain - #19
Conversation
Proxy https://blox.grudge-studio.com to grudgeblox.vercel.app. Same custom-domain pattern as duelyst. Game WS stays on Railway; no player DB on this Worker.
🤖 CodeAnt AI — Review Status
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Thanks for using CodeAnt! 🎉We're free for open-source projects. if you're enjoying it, help us grow by sharing. Share on X · |
Reviewer's GuideAdds and configures the grudgeblox-edge-proxy Cloudflare Worker, routing blox.grudge-studio.com requests to the Vercel GrudgeBlox origin while preserving request semantics and identifying proxied responses; game WebSockets and player data remain on their existing services. Sequence diagram for GrudgeBlox custom-domain proxyingsequenceDiagram
participant Client
participant Worker as grudgeblox_edge_proxy
participant Vercel as grudgeblox_vercel_app
Client->>Worker: fetch(request)
Worker->>Worker: new URL(request.url)
Worker->>Vercel: fetch(target, method, headers, body)
Vercel-->>Worker: upstream Response
Worker->>Worker: set X-Edge-Proxy
Worker-->>Client: Response(status, body, headers)
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 1 issue
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="workers/blox-proxy/index.js" line_range="15-27" />
<code_context>
+ const headers = new Headers(request.headers);
+ headers.set("Host", new URL(ORIGIN).host);
+ headers.set("X-Forwarded-Host", url.host);
+ const upstream = await fetch(
+ new Request(target, {
+ method: request.method,
+ headers,
+ body: request.method === "GET" || request.method === "HEAD" ? undefined : request.body,
+ redirect: "manual",
+ }),
+ );
+ const out = new Headers(upstream.headers);
+ out.set("X-Edge-Proxy", "grudgeblox-edge-proxy");
+ return new Response(upstream.body, { status: upstream.status, headers: out });
+ },
+};
</code_context>
<issue_to_address>
**issue (bug_risk):** If the upstream responds with HTTP 101 for a WebSocket upgrade, rebuilding it with `new Response(..., { status: upstream.status })` does not preserve the WebSocket response and can throw because the standard `Response` constructor does not accept status 101; the proxied connection therefore fails instead of upgrading.
**Triggers:** When any client sends a WebSocket upgrade through `blox.grudge-studio.com` rather than connecting directly to Railway.
**Suggested fix:** Return the upstream WebSocket response unchanged for status 101, or explicitly handle/reject WebSocket upgrades before forwarding them.
</issue_to_address>Sourcery assessment
Needs a human reviewer. 1 finding to address first, and this changes live DNS routing so requests to blox.grudge-studio.com depend on the Worker and the Vercel origin; a routing, forwarding, or origin failure could cause an outage or expose incorrect responses to users. Reverting restores the prior route, but any outage or externally visible failures occurring before the revert are not undone.
Blocking findings: workers/blox-proxy/index.js:27
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| const upstream = await fetch( | ||
| new Request(target, { | ||
| method: request.method, | ||
| headers, | ||
| body: request.method === "GET" || request.method === "HEAD" ? undefined : request.body, | ||
| redirect: "manual", | ||
| }), | ||
| ); | ||
| const out = new Headers(upstream.headers); | ||
| out.set("X-Edge-Proxy", "grudgeblox-edge-proxy"); | ||
| return new Response(upstream.body, { status: upstream.status, headers: out }); | ||
| }, | ||
| }; |
There was a problem hiding this comment.
issue (bug_risk): If the upstream responds with HTTP 101 for a WebSocket upgrade, rebuilding it with new Response(..., { status: upstream.status }) does not preserve the WebSocket response and can throw because the standard Response constructor does not accept status 101; the proxied connection therefore fails instead of upgrading.
Triggers: When any client sends a WebSocket upgrade through blox.grudge-studio.com rather than connecting directly to Railway.
Suggested fix: Return the upstream WebSocket response unchanged for status 101, or explicitly handle/reject WebSocket upgrades before forwarding them.
There was a problem hiding this comment.
🟡 Changes recommended
A couple of config/runtime details (hard-coded account_id, and setting a forbidden Host header) should be corrected to align with repo conventions and avoid misleading behavior.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Adds a dedicated Cloudflare Worker edge proxy (grudgeblox-edge-proxy) to serve GrudgeBlox via the custom domain blox.grudge-studio.com, forwarding requests to the Vercel origin while tagging responses with X-Edge-Proxy.
Changes:
- Introduce a new Worker with a custom-domain route for
blox.grudge-studio.com. - Implement a simple pass-through proxy to
https://grudgeblox.vercel.appthat preserves method/path/query and adds anX-Edge-Proxyresponse header.
File summaries
| File | Description |
|---|---|
| workers/blox-proxy/wrangler.toml | Defines the new grudgeblox-edge-proxy Worker and binds it to the blox.grudge-studio.com custom domain. |
| workers/blox-proxy/index.js | Implements the request proxying behavior and adds the X-Edge-Proxy header to upstream responses. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| workers_dev = true | ||
| account_id = "ee475864561b02d4588180b8b9acf694" | ||
|
|
| const headers = new Headers(request.headers); | ||
| headers.set("Host", new URL(ORIGIN).host); | ||
| headers.set("X-Forwarded-Host", url.host); |
🤖 Augment PR SummarySummary: Adds a dedicated Cloudflare Worker for
🤖 Was this summary useful? React with 👍 or 👎 |
| export default { | ||
| async fetch(request) { | ||
| const url = new URL(request.url); | ||
| const target = new URL(url.pathname + url.search, ORIGIN); |
There was a problem hiding this comment.
new URL() treats a pathname beginning with // as a scheme-relative URL, so a request such as https://blox.grudge-studio.com//attacker.example/path makes target point at attacker.example rather than ORIGIN. This turns the custom domain into an open proxy and forwards any blox cookies included with that request to the attacker-controlled target.
Severity: high
🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.
User description
Live Worker grudgeblox-edge-proxy binds custom domain blox.grudge-studio.com and proxies to https://grudgeblox.vercel.app. Same pattern as duelyst. Game WS stays on Railway; no player DB on this Worker.
Smoke: https://blox.grudge-studio.com/ and /play/test return 200 with X-Edge-Proxy: grudgeblox-edge-proxy.
Summary by Sourcery
Route GrudgeBlox web traffic through a dedicated edge proxy at
blox.grudge-studio.comwhile leaving game WebSocket and data services unchanged.New Features:
blox.grudge-studio.comcustom domain for GrudgeBlox through a Cloudflare Worker proxy to the Vercel application.Enhancements:
X-Edge-Proxyresponse header.Deployment:
grudgeblox-edge-proxyWorker and bind it to theblox.grudge-studio.comcustom domain.CodeAnt-AI Description
Route GrudgeBlox web traffic through its dedicated custom domain
What Changed
blox.grudge-studio.comX-Edge-ProxyheaderImpact
✅ Dedicated GrudgeBlox web address✅ Preserved page routes and request behavior✅ Unchanged game and player data services💡 Usage Guide
Checking Your Pull Request
Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.
Talking to CodeAnt AI
Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
Preserve Org Learnings with CodeAnt
You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
Check Your Repository Health
To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.