/** * Copyright (c) 2026 AzerothJS. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ /** * Options for {@link clientIp}: whether to read forwarding headers at all (`trustProxy`) and * how many proxy hops are YOURS (`trustedHops`) - the address is picked from the right end of * `X-Forwarded-For`, because the left end is client-supplied fiction. */ export interface ClientIpOptions { /** Believe the forwarded-for header (default false - peer address only). */ trustProxy?: boolean; /** How many proxies you run in front of this server, the direct peer included (default 1). */ trustedHops?: number; /** The forwarding header to read (default `x-forwarded-for`). */ header?: string; } /** * The entry of an APPENDED forwarded header (`X-Forwarded-For`) that `trustedHops` proxies * vouch for: that many from the RIGHT end, because each hop appends and the left end is * client-supplied fiction. Undefined when the chain is too short to have traversed the * proxies claimed. */ export declare function appendedForwardedEntry(value: string | string[] | undefined, trustedHops: number): string | undefined; /** * The believable value of a REPLACED forwarded header (`X-Forwarded-Proto`, * `X-Forwarded-Host`), which nginx, HAProxy, Traefik, ALB and Cloudflare each SET rather * than append: a chain of any length leaves ONE entry, so no hop count applies. The entry * taken is the last written, which is the whole value in that normal shape. More than one * entry means an untrusted client sent a value and a proxy wrote alongside it - the * host-poisoning shape - and the proxy can only have written after what it received, so the * right-most entry is still the trusted one. Undefined when the header is absent or empty. */ export declare function replacedForwardedValue(value: string | string[] | undefined): string | undefined; /** * The client's IP address. Without `trustProxy` this is the unspoofable TCP peer; with it, the * correct entry from the forwarding header per the declared `trustedHops`, falling back to the * peer when the header is absent or too short to trust. May be undefined when no socket backs * the request (an in-process `app.handle` test) and no trusted header is present. */ export declare function clientIp(request: Request, options?: ClientIpOptions): string | undefined; /** * Normalizes an address into a rate-limit bucket key. IPv4 buckets per host, but IPv6 is * truncated to `prefixBits` (default 64): a /64 is the standard single-customer allocation, * inside which one host can hop across 2^64 addresses for free - keying on the full /128 * hands every such host an unlimited supply of fresh buckets. Brackets, port and zone are * stripped first, IPv4-mapped IPv6 collapses to its IPv4 form, and anything unparseable * becomes its own bucket, length-capped so a forwarded-header key cannot bloat the store. */ export declare function ipBucket(address: string, prefixBits?: number): string;