Spaces:
Running
Fix white screen: rewrite internal-host Location headers in proxy
Browse filesRoot cause: Postiz's Next.js middleware builds redirect URLs using the
incoming Host header, which health-server sets to 127.0.0.1:5000 (nginx's
address). The middleware produces absolute URLs like:
307 Location: http://127.0.0.1:5000/auth/login
HF Spaces' reverse proxy blocks redirects to internal IPs and silently
returns 200 with empty body β the white screen users see.
Additionally, Postiz's middleware redirects to /auth/* without the basePath
prefix (/app), so even relative redirects would land on a 404.
Fix: add rewriteLocation() that normalises every Location header from the
Postiz nginx upstream before forwarding to the browser:
- Absolute URL to internal host (127.0.0.1, localhost) β extract path
- Path missing /app basePath prefix β prepend /app
- External URLs (twitter.com, etc.) β unchanged
Result: 307 http://127.0.0.1:5000/auth/login β 307 /app/auth/login
Browser follows the redirect, health-server routes /app/auth/login to
nginx, Next.js serves the login page.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- health-server.js +39 -1
|
@@ -637,6 +637,39 @@ function buildProxyHeaders(headers) {
|
|
| 637 |
};
|
| 638 |
}
|
| 639 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 640 |
function proxyHttp(req, res, overridePath) {
|
| 641 |
const targetPath = overridePath !== undefined ? overridePath : req.url;
|
| 642 |
let upstreamStarted = false;
|
|
@@ -645,7 +678,12 @@ function proxyHttp(req, res, overridePath) {
|
|
| 645 |
path: targetPath, headers: buildProxyHeaders(req.headers) },
|
| 646 |
(proxyRes) => {
|
| 647 |
upstreamStarted = true;
|
| 648 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 649 |
proxyRes.pipe(res);
|
| 650 |
},
|
| 651 |
);
|
|
|
|
| 637 |
};
|
| 638 |
}
|
| 639 |
|
| 640 |
+
function rewriteLocation(loc) {
|
| 641 |
+
// Postiz's Next.js middleware redirects without the basePath prefix (/app)
|
| 642 |
+
// and may use an internal hostname (127.0.0.1:NGINX_PORT) that HF Spaces'
|
| 643 |
+
// reverse proxy blocks (returning 200 empty body instead of the redirect).
|
| 644 |
+
//
|
| 645 |
+
// Normalise every Location header from the Postiz nginx proxy:
|
| 646 |
+
// 1. If it's an absolute URL to an internal host β extract the path.
|
| 647 |
+
// 2. If the resulting path doesn't start with /app β prepend /app.
|
| 648 |
+
//
|
| 649 |
+
// Examples:
|
| 650 |
+
// http://127.0.0.1:5000/auth/login β /app/auth/login
|
| 651 |
+
// http://localhost:4200/auth β /app/auth
|
| 652 |
+
// /auth/login β /app/auth/login
|
| 653 |
+
// /app/auth/login β /app/auth/login (unchanged)
|
| 654 |
+
// https://twitter.com/oauth/... β unchanged (external host)
|
| 655 |
+
if (!loc) return loc;
|
| 656 |
+
let path = null;
|
| 657 |
+
if (loc.startsWith("/")) {
|
| 658 |
+
path = loc;
|
| 659 |
+
} else {
|
| 660 |
+
try {
|
| 661 |
+
const u = new URL(loc);
|
| 662 |
+
if (/^(127\.0\.0\.1|localhost)(:\d+)?$/.test(u.host)) {
|
| 663 |
+
path = u.pathname + u.search + u.hash;
|
| 664 |
+
}
|
| 665 |
+
} catch {}
|
| 666 |
+
}
|
| 667 |
+
if (path !== null && !path.startsWith("/app/") && path !== "/app") {
|
| 668 |
+
return "/app" + path;
|
| 669 |
+
}
|
| 670 |
+
return loc;
|
| 671 |
+
}
|
| 672 |
+
|
| 673 |
function proxyHttp(req, res, overridePath) {
|
| 674 |
const targetPath = overridePath !== undefined ? overridePath : req.url;
|
| 675 |
let upstreamStarted = false;
|
|
|
|
| 678 |
path: targetPath, headers: buildProxyHeaders(req.headers) },
|
| 679 |
(proxyRes) => {
|
| 680 |
upstreamStarted = true;
|
| 681 |
+
// Rewrite Location headers: add /app basePath if missing, convert
|
| 682 |
+
// internal-host absolute URLs to relative paths.
|
| 683 |
+
const outHeaders = Object.assign({}, proxyRes.headers);
|
| 684 |
+
const fixedLoc = rewriteLocation(outHeaders["location"]);
|
| 685 |
+
if (fixedLoc !== outHeaders["location"]) outHeaders["location"] = fixedLoc;
|
| 686 |
+
res.writeHead(proxyRes.statusCode || 502, outHeaders);
|
| 687 |
proxyRes.pipe(res);
|
| 688 |
},
|
| 689 |
);
|