4.1.0: modern engine picks the best client IP, with exhaustive tests - #28
Merged
Merged
Conversation
Best match (modern only; legacy unchanged): - Rank addresses public > private > link-local > loopback; never return unspecified, multicast, broadcast or reserved addresses. - Without proxy config, take the first public hop of a chain, not chain[0]. - trusted_route is True for any address resolved through a matching proxy config, including private clients. Parsing and headers: - Parse RFC 7239 Forwarded elements by their for= value. - Reject malformed tokens instead of truncating them; skip non-string header values; case-insensitive header keys; reject empty proxy_list entries. - Add Azure Front Door, DigitalOcean and Envoy headers below all 4.0.0 entries; the released precedence order is pinned by a test. Tests: exhaustive chain/config/header/spelling matrix against an independent reference model, never-worse-than-legacy check, seeded fuzz. CI: upload-artifact v7, download-artifact v8 (Node 24).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The modern engine now picks a better client IP than v3, and this is backed by exhaustive combination tests. The legacy engine is unchanged.
Best match (modern only)
0.0.0.0,::), multicast, broadcast, and reserved addresses are never returned. Python reports multicast asis_global, so v3 could return224.0.0.1as the client.10.0.0.1, 177.139.233.139now yields177.139.233.139instead of10.0.0.1. Withleftmost=False, the scan runs from the right.proxy_count/proxy_list: the client position is fixed exactly as in v3.trusted_routeis nowTruefor any address resolved through a matching config, including private clients.Parsing and headers
Forwardedelements are parsed by theirfor=value, including quoted, bracketed IPv6 with a port.[::1,[::1]junk,1.2.3.4:abc,1.2.3.4:70000).proxy_listentry now raises: it used to match every address.Tests (about 72k checks, roughly 2 s)
Compatibility
Results can differ from 4.0.0 on well-formed input, always toward a better address.
IpWare(algorithm="legacy")keeps exact v3 behavior. The original 86 v3 tests pass on both engines.CI
actions/upload-artifact→ v7 andactions/download-artifact→ v8 (Node 24).Verified locally
ruff check .is clean.python -m buildproduces a 4.1.0 sdist and wheel.No tag has been pushed, so nothing is published to PyPI.
🚀 Generated with Dojo ⛩️