All files / src/core/server proxy.ts

100% Statements 10/10
80% Branches 12/15
100% Functions 1/1
100% Lines 10/10

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34                                          30x 25x   5x 30x 30x 30x 30x 30x 30x 30x    
/**
 * Proxy (X-Forwarded-*) helpers for the request handler
 */
 
import type { IncomingMessage } from 'http';
 
export interface EffectiveRequest {
  /** Effective URL (derived from X-Forwarded-* when trustProxy is true). */
  url: string;
  /** Client IP (X-Forwarded-For or socket.remoteAddress). */
  clientIp?: string;
}
 
/**
 * Derives effective URL and client IP from request when behind a reverse proxy.
 * When trustProxy is false, returns the request url as-is and no clientIp.
 */
export function getEffectiveRequest(
  req: IncomingMessage,
  trustProxy: boolean
): EffectiveRequest {
  if (!trustProxy) {
    return { url: req.url ?? '' };
  }
  const proto = (req.headers['x-forwarded-proto'] as string)?.split(',')[0]?.trim() || 'http';
  const host = (req.headers['x-forwarded-host'] as string)?.split(',')[0]?.trim() || req.headers.host || 'localhost';
  const path = req.url?.split('?')[0] ?? '/';
  const query = req.url?.includes('?') ? req.url.slice(req.url.indexOf('?')) : '';
  const effectiveUrl = `${proto}://${host}${path}${query}`;
  const forwardedFor = (req.headers['x-forwarded-for'] as string)?.split(',')[0]?.trim();
  const clientIp = forwardedFor || (req.socket?.remoteAddress);
  return { url: effectiveUrl, clientIp };
}