mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 00:51:25 +00:00
chore: Enable "curly" rule to avoid single-statement if confusion/errors.
This commit is contained in:
@@ -3,54 +3,80 @@ import net from "node:net";
|
||||
import { pickPrimaryTailnetIPv4, pickPrimaryTailnetIPv6 } from "../infra/tailnet.js";
|
||||
|
||||
export function isLoopbackAddress(ip: string | undefined): boolean {
|
||||
if (!ip) return false;
|
||||
if (ip === "127.0.0.1") return true;
|
||||
if (ip.startsWith("127.")) return true;
|
||||
if (ip === "::1") return true;
|
||||
if (ip.startsWith("::ffff:127.")) return true;
|
||||
if (!ip) {
|
||||
return false;
|
||||
}
|
||||
if (ip === "127.0.0.1") {
|
||||
return true;
|
||||
}
|
||||
if (ip.startsWith("127.")) {
|
||||
return true;
|
||||
}
|
||||
if (ip === "::1") {
|
||||
return true;
|
||||
}
|
||||
if (ip.startsWith("::ffff:127.")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function normalizeIPv4MappedAddress(ip: string): string {
|
||||
if (ip.startsWith("::ffff:")) return ip.slice("::ffff:".length);
|
||||
if (ip.startsWith("::ffff:")) {
|
||||
return ip.slice("::ffff:".length);
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
|
||||
function normalizeIp(ip: string | undefined): string | undefined {
|
||||
const trimmed = ip?.trim();
|
||||
if (!trimmed) return undefined;
|
||||
if (!trimmed) {
|
||||
return undefined;
|
||||
}
|
||||
return normalizeIPv4MappedAddress(trimmed.toLowerCase());
|
||||
}
|
||||
|
||||
function stripOptionalPort(ip: string): string {
|
||||
if (ip.startsWith("[")) {
|
||||
const end = ip.indexOf("]");
|
||||
if (end !== -1) return ip.slice(1, end);
|
||||
if (end !== -1) {
|
||||
return ip.slice(1, end);
|
||||
}
|
||||
}
|
||||
if (net.isIP(ip)) {
|
||||
return ip;
|
||||
}
|
||||
if (net.isIP(ip)) return ip;
|
||||
const lastColon = ip.lastIndexOf(":");
|
||||
if (lastColon > -1 && ip.includes(".") && ip.indexOf(":") === lastColon) {
|
||||
const candidate = ip.slice(0, lastColon);
|
||||
if (net.isIP(candidate) === 4) return candidate;
|
||||
if (net.isIP(candidate) === 4) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
|
||||
export function parseForwardedForClientIp(forwardedFor?: string): string | undefined {
|
||||
const raw = forwardedFor?.split(",")[0]?.trim();
|
||||
if (!raw) return undefined;
|
||||
if (!raw) {
|
||||
return undefined;
|
||||
}
|
||||
return normalizeIp(stripOptionalPort(raw));
|
||||
}
|
||||
|
||||
function parseRealIp(realIp?: string): string | undefined {
|
||||
const raw = realIp?.trim();
|
||||
if (!raw) return undefined;
|
||||
if (!raw) {
|
||||
return undefined;
|
||||
}
|
||||
return normalizeIp(stripOptionalPort(raw));
|
||||
}
|
||||
|
||||
export function isTrustedProxyAddress(ip: string | undefined, trustedProxies?: string[]): boolean {
|
||||
const normalized = normalizeIp(ip);
|
||||
if (!normalized || !trustedProxies || trustedProxies.length === 0) return false;
|
||||
if (!normalized || !trustedProxies || trustedProxies.length === 0) {
|
||||
return false;
|
||||
}
|
||||
return trustedProxies.some((proxy) => normalizeIp(proxy) === normalized);
|
||||
}
|
||||
|
||||
@@ -61,19 +87,31 @@ export function resolveGatewayClientIp(params: {
|
||||
trustedProxies?: string[];
|
||||
}): string | undefined {
|
||||
const remote = normalizeIp(params.remoteAddr);
|
||||
if (!remote) return undefined;
|
||||
if (!isTrustedProxyAddress(remote, params.trustedProxies)) return remote;
|
||||
if (!remote) {
|
||||
return undefined;
|
||||
}
|
||||
if (!isTrustedProxyAddress(remote, params.trustedProxies)) {
|
||||
return remote;
|
||||
}
|
||||
return parseForwardedForClientIp(params.forwardedFor) ?? parseRealIp(params.realIp) ?? remote;
|
||||
}
|
||||
|
||||
export function isLocalGatewayAddress(ip: string | undefined): boolean {
|
||||
if (isLoopbackAddress(ip)) return true;
|
||||
if (!ip) return false;
|
||||
if (isLoopbackAddress(ip)) {
|
||||
return true;
|
||||
}
|
||||
if (!ip) {
|
||||
return false;
|
||||
}
|
||||
const normalized = normalizeIPv4MappedAddress(ip.trim().toLowerCase());
|
||||
const tailnetIPv4 = pickPrimaryTailnetIPv4();
|
||||
if (tailnetIPv4 && normalized === tailnetIPv4.toLowerCase()) return true;
|
||||
if (tailnetIPv4 && normalized === tailnetIPv4.toLowerCase()) {
|
||||
return true;
|
||||
}
|
||||
const tailnetIPv6 = pickPrimaryTailnetIPv6();
|
||||
if (tailnetIPv6 && ip.trim().toLowerCase() === tailnetIPv6.toLowerCase()) return true;
|
||||
if (tailnetIPv6 && ip.trim().toLowerCase() === tailnetIPv6.toLowerCase()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -97,14 +135,20 @@ export async function resolveGatewayBindHost(
|
||||
|
||||
if (mode === "loopback") {
|
||||
// 127.0.0.1 rarely fails, but handle gracefully
|
||||
if (await canBindToHost("127.0.0.1")) return "127.0.0.1";
|
||||
if (await canBindToHost("127.0.0.1")) {
|
||||
return "127.0.0.1";
|
||||
}
|
||||
return "0.0.0.0"; // extreme fallback
|
||||
}
|
||||
|
||||
if (mode === "tailnet") {
|
||||
const tailnetIP = pickPrimaryTailnetIPv4();
|
||||
if (tailnetIP && (await canBindToHost(tailnetIP))) return tailnetIP;
|
||||
if (await canBindToHost("127.0.0.1")) return "127.0.0.1";
|
||||
if (tailnetIP && (await canBindToHost(tailnetIP))) {
|
||||
return tailnetIP;
|
||||
}
|
||||
if (await canBindToHost("127.0.0.1")) {
|
||||
return "127.0.0.1";
|
||||
}
|
||||
return "0.0.0.0";
|
||||
}
|
||||
|
||||
@@ -114,15 +158,21 @@ export async function resolveGatewayBindHost(
|
||||
|
||||
if (mode === "custom") {
|
||||
const host = customHost?.trim();
|
||||
if (!host) return "0.0.0.0"; // invalid config → fall back to all
|
||||
if (!host) {
|
||||
return "0.0.0.0";
|
||||
} // invalid config → fall back to all
|
||||
|
||||
if (isValidIPv4(host) && (await canBindToHost(host))) return host;
|
||||
if (isValidIPv4(host) && (await canBindToHost(host))) {
|
||||
return host;
|
||||
}
|
||||
// Custom IP failed → fall back to LAN
|
||||
return "0.0.0.0";
|
||||
}
|
||||
|
||||
if (mode === "auto") {
|
||||
if (await canBindToHost("127.0.0.1")) return "127.0.0.1";
|
||||
if (await canBindToHost("127.0.0.1")) {
|
||||
return "127.0.0.1";
|
||||
}
|
||||
return "0.0.0.0";
|
||||
}
|
||||
|
||||
@@ -155,9 +205,13 @@ export async function resolveGatewayListenHosts(
|
||||
bindHost: string,
|
||||
opts?: { canBindToHost?: (host: string) => Promise<boolean> },
|
||||
): Promise<string[]> {
|
||||
if (bindHost !== "127.0.0.1") return [bindHost];
|
||||
if (bindHost !== "127.0.0.1") {
|
||||
return [bindHost];
|
||||
}
|
||||
const canBind = opts?.canBindToHost ?? canBindToHost;
|
||||
if (await canBind("::1")) return [bindHost, "::1"];
|
||||
if (await canBind("::1")) {
|
||||
return [bindHost, "::1"];
|
||||
}
|
||||
return [bindHost];
|
||||
}
|
||||
|
||||
@@ -169,7 +223,9 @@ export async function resolveGatewayListenHosts(
|
||||
*/
|
||||
function isValidIPv4(host: string): boolean {
|
||||
const parts = host.split(".");
|
||||
if (parts.length !== 4) return false;
|
||||
if (parts.length !== 4) {
|
||||
return false;
|
||||
}
|
||||
return parts.every((part) => {
|
||||
const n = parseInt(part, 10);
|
||||
return !Number.isNaN(n) && n >= 0 && n <= 255 && part === String(n);
|
||||
|
||||
Reference in New Issue
Block a user