diff --git a/src/gateway/auth.ts b/src/gateway/auth.ts index 60864f581..8220cccb0 100644 --- a/src/gateway/auth.ts +++ b/src/gateway/auth.ts @@ -16,6 +16,7 @@ import { resolveGatewayCredentialsFromValues } from "./credentials.js"; import { isLocalishHost, isLoopbackAddress, + resolveRequestClientIp, isTrustedProxyAddress, resolveClientIp, } from "./net.js"; @@ -105,23 +106,6 @@ function resolveTailscaleClientIp(req?: IncomingMessage): string | undefined { }); } -export function resolveRequestClientIp( - req?: IncomingMessage, - trustedProxies?: string[], - allowRealIpFallback = false, -): string | undefined { - if (!req) { - return undefined; - } - return resolveClientIp({ - remoteAddr: req.socket?.remoteAddress ?? "", - forwardedFor: headerValue(req.headers?.["x-forwarded-for"]), - realIp: headerValue(req.headers?.["x-real-ip"]), - trustedProxies, - allowRealIpFallback, - }); -} - export function isLocalDirectRequest( req?: IncomingMessage, trustedProxies?: string[], diff --git a/src/gateway/net.ts b/src/gateway/net.ts index db8779606..3ea32fc16 100644 --- a/src/gateway/net.ts +++ b/src/gateway/net.ts @@ -1,3 +1,4 @@ +import type { IncomingMessage } from "node:http"; import net from "node:net"; import os from "node:os"; import { pickPrimaryTailnetIPv4, pickPrimaryTailnetIPv6 } from "../infra/tailnet.js"; @@ -184,6 +185,27 @@ export function resolveClientIp(params: { return undefined; } +function headerValue(value: string | string[] | undefined): string | undefined { + return Array.isArray(value) ? value[0] : value; +} + +export function resolveRequestClientIp( + req?: IncomingMessage, + trustedProxies?: string[], + allowRealIpFallback = false, +): string | undefined { + if (!req) { + return undefined; + } + return resolveClientIp({ + remoteAddr: req.socket?.remoteAddress ?? "", + forwardedFor: headerValue(req.headers?.["x-forwarded-for"]), + realIp: headerValue(req.headers?.["x-real-ip"]), + trustedProxies, + allowRealIpFallback, + }); +} + export function isLocalGatewayAddress(ip: string | undefined): boolean { if (isLoopbackAddress(ip)) { return true; diff --git a/src/gateway/server-http.ts b/src/gateway/server-http.ts index 110d64e09..fea650fd3 100644 --- a/src/gateway/server-http.ts +++ b/src/gateway/server-http.ts @@ -23,7 +23,6 @@ import { import { authorizeHttpGatewayConnect, isLocalDirectRequest, - resolveRequestClientIp, type GatewayAuthResult, type ResolvedGatewayAuth, } from "./auth.js"; @@ -53,6 +52,7 @@ import { } from "./hooks.js"; import { sendGatewayAuthFailure, setDefaultSecurityHeaders } from "./http-common.js"; import { getBearerToken } from "./http-utils.js"; +import { resolveRequestClientIp } from "./net.js"; import { handleOpenAiHttpRequest } from "./openai-http.js"; import { handleOpenResponsesHttpRequest } from "./openresponses-http.js"; import {