mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 17:08:27 +00:00
refactor(gateway): share host header parsing
This commit is contained in:
@@ -14,6 +14,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
isLoopbackAddress,
|
isLoopbackAddress,
|
||||||
isTrustedProxyAddress,
|
isTrustedProxyAddress,
|
||||||
|
resolveHostName,
|
||||||
parseForwardedForClientIp,
|
parseForwardedForClientIp,
|
||||||
resolveGatewayClientIp,
|
resolveGatewayClientIp,
|
||||||
} from "./net.js";
|
} from "./net.js";
|
||||||
@@ -56,21 +57,6 @@ function normalizeLogin(login: string): string {
|
|||||||
return login.trim().toLowerCase();
|
return login.trim().toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getHostName(hostHeader?: string): string {
|
|
||||||
const host = (hostHeader ?? "").trim().toLowerCase();
|
|
||||||
if (!host) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
if (host.startsWith("[")) {
|
|
||||||
const end = host.indexOf("]");
|
|
||||||
if (end !== -1) {
|
|
||||||
return host.slice(1, end);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const [name] = host.split(":");
|
|
||||||
return name ?? "";
|
|
||||||
}
|
|
||||||
|
|
||||||
function headerValue(value: string | string[] | undefined): string | undefined {
|
function headerValue(value: string | string[] | undefined): string | undefined {
|
||||||
return Array.isArray(value) ? value[0] : value;
|
return Array.isArray(value) ? value[0] : value;
|
||||||
}
|
}
|
||||||
@@ -107,7 +93,7 @@ export function isLocalDirectRequest(req?: IncomingMessage, trustedProxies?: str
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const host = getHostName(req.headers?.host);
|
const host = resolveHostName(req.headers?.host);
|
||||||
const hostIsLocal = host === "localhost" || host === "127.0.0.1" || host === "::1";
|
const hostIsLocal = host === "localhost" || host === "127.0.0.1" || host === "::1";
|
||||||
const hostIsTailscaleServe = host.endsWith(".ts.net");
|
const hostIsTailscaleServe = host.endsWith(".ts.net");
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,25 @@ export function pickPrimaryLanIPv4(): string | undefined {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function normalizeHostHeader(hostHeader?: string): string {
|
||||||
|
return (hostHeader ?? "").trim().toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function resolveHostName(hostHeader?: string): string {
|
||||||
|
const host = normalizeHostHeader(hostHeader);
|
||||||
|
if (!host) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
if (host.startsWith("[")) {
|
||||||
|
const end = host.indexOf("]");
|
||||||
|
if (end !== -1) {
|
||||||
|
return host.slice(1, end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const [name] = host.split(":");
|
||||||
|
return name ?? "";
|
||||||
|
}
|
||||||
|
|
||||||
export function isLoopbackAddress(ip: string | undefined): boolean {
|
export function isLoopbackAddress(ip: string | undefined): boolean {
|
||||||
if (!ip) {
|
if (!ip) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -1,26 +1,7 @@
|
|||||||
import { isLoopbackHost } from "./net.js";
|
import { isLoopbackHost, normalizeHostHeader, resolveHostName } from "./net.js";
|
||||||
|
|
||||||
type OriginCheckResult = { ok: true } | { ok: false; reason: string };
|
type OriginCheckResult = { ok: true } | { ok: false; reason: string };
|
||||||
|
|
||||||
function normalizeHostHeader(hostHeader?: string): string {
|
|
||||||
return (hostHeader ?? "").trim().toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
function resolveHostName(hostHeader?: string): string {
|
|
||||||
const host = normalizeHostHeader(hostHeader);
|
|
||||||
if (!host) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
if (host.startsWith("[")) {
|
|
||||||
const end = host.indexOf("]");
|
|
||||||
if (end !== -1) {
|
|
||||||
return host.slice(1, end);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const [name] = host.split(":");
|
|
||||||
return name ?? "";
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseOrigin(
|
function parseOrigin(
|
||||||
originRaw?: string,
|
originRaw?: string,
|
||||||
): { origin: string; host: string; hostname: string } | null {
|
): { origin: string; host: string; hostname: string } | null {
|
||||||
|
|||||||
@@ -4,21 +4,6 @@ import { GATEWAY_CLIENT_IDS } from "../../protocol/client-info.js";
|
|||||||
|
|
||||||
export type AuthProvidedKind = "token" | "password" | "none";
|
export type AuthProvidedKind = "token" | "password" | "none";
|
||||||
|
|
||||||
export function resolveHostName(hostHeader?: string): string {
|
|
||||||
const host = (hostHeader ?? "").trim().toLowerCase();
|
|
||||||
if (!host) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
if (host.startsWith("[")) {
|
|
||||||
const end = host.indexOf("]");
|
|
||||||
if (end !== -1) {
|
|
||||||
return host.slice(1, end);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const [name] = host.split(":");
|
|
||||||
return name ?? "";
|
|
||||||
}
|
|
||||||
|
|
||||||
export function formatGatewayAuthFailureMessage(params: {
|
export function formatGatewayAuthFailureMessage(params: {
|
||||||
authMode: ResolvedGatewayAuth["mode"];
|
authMode: ResolvedGatewayAuth["mode"];
|
||||||
authProvided: AuthProvidedKind;
|
authProvided: AuthProvidedKind;
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import {
|
|||||||
import { authorizeGatewayConnect, isLocalDirectRequest } from "../../auth.js";
|
import { authorizeGatewayConnect, isLocalDirectRequest } from "../../auth.js";
|
||||||
import { buildDeviceAuthPayload } from "../../device-auth.js";
|
import { buildDeviceAuthPayload } from "../../device-auth.js";
|
||||||
import { isLoopbackAddress, isTrustedProxyAddress, resolveGatewayClientIp } from "../../net.js";
|
import { isLoopbackAddress, isTrustedProxyAddress, resolveGatewayClientIp } from "../../net.js";
|
||||||
|
import { resolveHostName } from "../../net.js";
|
||||||
import { resolveNodeCommandAllowlist } from "../../node-command-policy.js";
|
import { resolveNodeCommandAllowlist } from "../../node-command-policy.js";
|
||||||
import { checkBrowserOrigin } from "../../origin-check.js";
|
import { checkBrowserOrigin } from "../../origin-check.js";
|
||||||
import { GATEWAY_CLIENT_IDS } from "../../protocol/client-info.js";
|
import { GATEWAY_CLIENT_IDS } from "../../protocol/client-info.js";
|
||||||
@@ -58,11 +59,7 @@ import {
|
|||||||
incrementPresenceVersion,
|
incrementPresenceVersion,
|
||||||
refreshGatewayHealthSnapshot,
|
refreshGatewayHealthSnapshot,
|
||||||
} from "../health-state.js";
|
} from "../health-state.js";
|
||||||
import {
|
import { formatGatewayAuthFailureMessage, type AuthProvidedKind } from "./auth-messages.js";
|
||||||
formatGatewayAuthFailureMessage,
|
|
||||||
resolveHostName,
|
|
||||||
type AuthProvidedKind,
|
|
||||||
} from "./auth-messages.js";
|
|
||||||
|
|
||||||
type SubsystemLogger = ReturnType<typeof createSubsystemLogger>;
|
type SubsystemLogger = ReturnType<typeof createSubsystemLogger>;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user