mirror of
https://github.com/BigBodyCobain/Shadowbroker.git
synced 2026-09-24 18:00:43 +02:00
Merge pull request #3 from suranyami/feat/multi-arch-docker-and-backend-proxy
fix: resolve proxy gzip decoding and BACKEND_URL Docker override issues
Former-commit-id: 7af4af1507
This commit is contained in:
+1
-1
@@ -27,7 +27,7 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
# Points the Next.js server-side proxy at the backend container via Docker networking.
|
# Points the Next.js server-side proxy at the backend container via Docker networking.
|
||||||
# Change this if your backend runs on a different host or port.
|
# Change this if your backend runs on a different host or port.
|
||||||
- BACKEND_URL=${BACKEND_URL:-http://backend:8000}
|
- BACKEND_URL=http://backend:8000
|
||||||
depends_on:
|
depends_on:
|
||||||
- backend
|
- backend
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|||||||
@@ -11,17 +11,20 @@
|
|||||||
|
|
||||||
import { NextRequest, NextResponse } from "next/server";
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
|
|
||||||
// Hop-by-hop headers that must not be forwarded to the backend.
|
// Headers that must not be forwarded to the backend.
|
||||||
const HOP_BY_HOP = new Set([
|
const STRIP_REQUEST = new Set([
|
||||||
"connection",
|
"connection", "keep-alive", "proxy-authenticate", "proxy-authorization",
|
||||||
"keep-alive",
|
"te", "trailers", "transfer-encoding", "upgrade", "host",
|
||||||
"proxy-authenticate",
|
]);
|
||||||
"proxy-authorization",
|
|
||||||
"te",
|
// Headers that must not be forwarded back to the browser.
|
||||||
"trailers",
|
// content-encoding and content-length are stripped because Node.js fetch()
|
||||||
"transfer-encoding",
|
// automatically decompresses gzip/br responses — forwarding these headers
|
||||||
"upgrade",
|
// would cause ERR_CONTENT_DECODING_FAILED in the browser.
|
||||||
"host",
|
const STRIP_RESPONSE = new Set([
|
||||||
|
"connection", "keep-alive", "proxy-authenticate", "proxy-authorization",
|
||||||
|
"te", "trailers", "transfer-encoding", "upgrade",
|
||||||
|
"content-encoding", "content-length",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
async function proxy(req: NextRequest, path: string[]): Promise<NextResponse> {
|
async function proxy(req: NextRequest, path: string[]): Promise<NextResponse> {
|
||||||
@@ -29,28 +32,37 @@ async function proxy(req: NextRequest, path: string[]): Promise<NextResponse> {
|
|||||||
const targetUrl = new URL(`/api/${path.join("/")}`, backendUrl);
|
const targetUrl = new URL(`/api/${path.join("/")}`, backendUrl);
|
||||||
targetUrl.search = req.nextUrl.search;
|
targetUrl.search = req.nextUrl.search;
|
||||||
|
|
||||||
// Forward relevant request headers (strip hop-by-hop)
|
// Forward relevant request headers
|
||||||
const forwardHeaders = new Headers();
|
const forwardHeaders = new Headers();
|
||||||
req.headers.forEach((value, key) => {
|
req.headers.forEach((value, key) => {
|
||||||
if (!HOP_BY_HOP.has(key.toLowerCase())) {
|
if (!STRIP_REQUEST.has(key.toLowerCase())) {
|
||||||
forwardHeaders.set(key, value);
|
forwardHeaders.set(key, value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const isBodyless = req.method === "GET" || req.method === "HEAD";
|
const isBodyless = req.method === "GET" || req.method === "HEAD";
|
||||||
const upstream = await fetch(targetUrl.toString(), {
|
let upstream: Response;
|
||||||
method: req.method,
|
try {
|
||||||
headers: forwardHeaders,
|
upstream = await fetch(targetUrl.toString(), {
|
||||||
body: isBodyless ? undefined : req.body,
|
method: req.method,
|
||||||
// Required for streaming request bodies in Node.js fetch
|
headers: forwardHeaders,
|
||||||
// @ts-ignore
|
body: isBodyless ? undefined : req.body,
|
||||||
duplex: "half",
|
// Required for streaming request bodies in Node.js fetch
|
||||||
});
|
// @ts-ignore
|
||||||
|
duplex: "half",
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
// Backend unreachable — return a clean 502 so the UI can handle it gracefully
|
||||||
|
return new NextResponse(JSON.stringify({ error: "Backend unavailable" }), {
|
||||||
|
status: 502,
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Forward response headers (strip hop-by-hop)
|
// Forward response headers
|
||||||
const responseHeaders = new Headers();
|
const responseHeaders = new Headers();
|
||||||
upstream.headers.forEach((value, key) => {
|
upstream.headers.forEach((value, key) => {
|
||||||
if (!HOP_BY_HOP.has(key.toLowerCase())) {
|
if (!STRIP_RESPONSE.has(key.toLowerCase())) {
|
||||||
responseHeaders.set(key, value);
|
responseHeaders.set(key, value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user