Class ClientAddressResolver
Forwarded (RFC 7239) or X-Forwarded-For header.The rule is the usual one: a forwarded header is believed only when the immediate peer is in the operator's list of trusted proxies (ServerSettings.getGeoTrustedProxies(), empty by default, so by default nothing is believed); the chain is walked from the right (the proxy nearest to the server) to the left, and the first address that is not itself a trusted proxy is the client. An entry that is not an IP literal (an obfuscated identifier, a host name, garbage) ends the walk and the immediate peer stands - a spoofed header can never name an address the operator did not vouch for. When Forwarded is present it is used and X-Forwarded-For is ignored, per RFC 7239 section 7.4.
isPrivateOrLocal(InetAddress) answers whether an address may be looked up at all: loopback, unspecified, link-local, RFC 1918 site-local, carrier-grade NAT (RFC 6598, 100.64.0.0/10) and IPv6 unique-local (RFC 4193, fc00::/7) addresses are not geolocatable and must not be sent to any provider. A client-reported local address is by nature one of these on most networks; it is information, never a lookup key.
Pure functions over Java types, no server state: fully testable.
- Author:
- Christopher Mindus
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final recordThe two forwarded-address headers of an HTTP upgrade request, in the order received.static final recordThe resolved client address and its source.static enumWhere the resolved address came from.static final classThe operator's trusted proxies: a set of IP addresses and CIDR prefixes.Method Summary
Modifier and TypeMethodDescriptionstatic booleanisPrivateOrLocal(InetAddress address) Returns if an address cannot be geolocated and must not be sent to any provider: unspecified, loopback, link-local, RFC 1918 site-local, carrier-grade NAT100.64.0.0/10(RFC 6598) and IPv6 unique-localfc00::/7(RFC 4193).static List<InetAddress> parseForwarded(List<String> values) ParsesForwardedvalues (RFC 7239): comma-separated elements, each a semicolon-separated list ofname=valuepairs, of whichfor=carries the node; a quoted value may hold an IPv6 literal in brackets and a port.static List<InetAddress> parseXForwardedFor(List<String> values) ParsesX-Forwarded-Forvalues: comma-separated IP literals, leftmost the client.resolve(InetAddress remote, ClientAddressResolver.ForwardedHeaders headers, ClientAddressResolver.TrustedProxies trusted) Resolves the client address.static StringtoText(InetAddress address) Formats an address for a log line: the literal without the leading slash ofInetAddress.toString(), lower case for IPv6.
Method Details
resolve
public static ClientAddressResolver.Resolution resolve(InetAddress remote, ClientAddressResolver.ForwardedHeaders headers, ClientAddressResolver.TrustedProxies trusted) Resolves the client address.- Parameters:
remote- The address of the immediate peer as seen by Jetty, null for unknown.headers- The forwarded headers of the upgrade request, null for none.trusted- The trusted proxies, null for none.- Returns:
- The resolution, never null;
ClientAddressResolver.Resolution.NONEwhenremoteis null.
parseXForwardedFor
ParsesX-Forwarded-Forvalues: comma-separated IP literals, leftmost the client.- Parameters:
values- The header values in the order received.- Returns:
- The chain, or null when an element is not an IP literal.
parseForwarded
ParsesForwardedvalues (RFC 7239): comma-separated elements, each a semicolon-separated list ofname=valuepairs, of whichfor=carries the node; a quoted value may hold an IPv6 literal in brackets and a port.- Parameters:
values- The header values in the order received.- Returns:
- The chain of
for=nodes, or null when a node is not an IP literal.
isPrivateOrLocal
Returns if an address cannot be geolocated and must not be sent to any provider: unspecified, loopback, link-local, RFC 1918 site-local, carrier-grade NAT100.64.0.0/10(RFC 6598) and IPv6 unique-localfc00::/7(RFC 4193).- Parameters:
address- The address, null counts as not geolocatable.- Returns:
- true when the address is private or local.
toText
Formats an address for a log line: the literal without the leading slash ofInetAddress.toString(), lower case for IPv6.- Parameters:
address- The address, null for "-".- Returns:
- The text.