somratpro Claude Opus 4.7 commited on
Commit
6050e80
Β·
1 Parent(s): c63d0d1

Fix white screen: rewrite internal-host Location headers in proxy

Browse files

Root 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>

Files changed (1) hide show
  1. health-server.js +39 -1
health-server.js CHANGED
@@ -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
- res.writeHead(proxyRes.statusCode || 502, proxyRes.headers);
 
 
 
 
 
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
  );