Skip to content

feat(request): add client IP address extractor - #724

Merged
m4tx merged 4 commits into
masterfrom
client-ip-extractor-fixes
Nov 6, 2026
Merged

m4tx merged 4 commits into
masterfrom
client-ip-extractor-fixes

Conversation

@m4tx

@m4tx m4tx commented Nov 1, 2026

Copy link
Copy Markdown
Member

Description

This is a followup to #673, which refactors the code a little bit and fixes a few shortcomings.

The details are in the commits. I've left the work done by @Wervice as the base commit (mostly unchaged - only fixed some hyper migration-related rebase issues) to properly attribute their work, and applied my changes on top of that.

We should merge this by rebasing, not by squashing as usual.

Type of change

  • Bug fix
  • New feature
  • Documentation
  • Refactor / cleanup
  • Performance improvement
  • Other (describe above)

Checklist

  • I've read the contributing guide
  • Tests pass locally (just test-all)
  • Code passes clippy (just clippy)
  • Code is properly formatted (cargo fmt)
  • New tests added (regression test for bugs, coverage for new features)
  • Documentation (both code and site) updated (if applicable)

@m4tx
m4tx requested review from a team and a balanced review from Copilot November 1, 2026 19:58
@m4tx m4tx mentioned this pull request Nov 1, 2026
7 of 12 tasks

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The Forwarded header parser treats quoted commas and semicolons as delimiters, allowing client-controlled metadata to produce incorrect client IPs and potentially enable IP spoofing through a trusted proxy.

1 open issue
What changed in this PR

This follow-up to #673 adds client IP extraction to Cot’s request handling, with configurable trusted proxies and forwarding headers.

Changes:

  • Adds ClientIpAddr, using the connection’s peer address unless a trusted proxy supplies forwarding headers.
  • Introduces client IP configuration, documentation, and the ipnet dependency.
  • Adds test-request support, parser tests, and an end-to-end extraction test.
File Description
docs/​configuration.md Documents trusted proxies and forwarding headers.
cot/​tests/​extractors.rs Adds an end-to-end client IP test.
cot/​src/​test.rs Supports peer addresses in test requests.
cot/​src/​request/​extractors/​client_ip.rs Implements client IP extraction and parser tests.
cot/​src/​request/​extractors.rs Exports ClientIpAddr.
cot/​src/​request.rs Defines the internal peer-address extension.
cot/​src/​project.rs Attaches connection peer addresses to requests.
cot/​src/​config.rs Adds proxy and header configuration with defaults and tests.
cot/​Cargo.toml Adds the workspace ipnet dependency.
Cargo.toml Declares ipnet with serialization support.
Cargo.lock Records the updated dependency relationships.

Review effort: Balanced

Comment thread cot/src/request/extractors/client_ip.rs Resolved
@github-actions github-actions Bot added A-docs Area: Documentation A-deps Area: Dependencies C-lib Crate: cot (main library crate) labels Nov 1, 2026
@github-actions

github-actions Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

🐰 Bencher Report

Projectcot
Branchclient-ip-extractor-fixes
Testbedgithub-ubuntu-latest
Click to view all benchmark results
BenchmarkLatencyBenchmark Result
microseconds (µs)
(Result Δ%)
Upper Boundary
microseconds (µs)
(Limit %)
empty_router/empty_router📈 view plot
🚷 view threshold
8,930.60 µs
(-27.58%)Baseline: 12,331.92 µs
18,304.07 µs
(48.79%)
json_api/json_api📈 view plot
🚷 view threshold
985.82 µs
(+1.19%)Baseline: 974.23 µs
1,367.30 µs
(72.10%)
nested_routers/nested_routers📈 view plot
🚷 view threshold
959.60 µs
(+3.74%)Baseline: 925.04 µs
1,280.81 µs
(74.92%)
single_root_route/single_root_route📈 view plot
🚷 view threshold
927.63 µs
(+5.17%)Baseline: 882.00 µs
1,229.57 µs
(75.44%)
single_root_route_burst/single_root_route_burst📈 view plot
🚷 view threshold
16,655.00 µs
(+1.76%)Baseline: 16,366.89 µs
22,689.57 µs
(73.40%)
🐰 View full continuous benchmarking report in Bencher

@codecov

codecov Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.05015% with 10 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
cot/src/request/extractors/client_ip.rs 97.08% 3 Missing and 5 partials ⚠️
cot/src/config.rs 96.22% 0 Missing and 2 partials ⚠️
Flag Coverage Δ
rust 91.19% <97.05%> (+0.09%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
cot/src/project.rs 87.52% <100.00%> (+0.23%) ⬆️
cot/src/request.rs 96.65% <ø> (+1.43%) ⬆️
cot/src/request/extractors.rs 90.21% <ø> (ø)
cot/src/test.rs 85.33% <100.00%> (+0.22%) ⬆️
cot/src/config.rs 94.73% <96.22%> (+0.10%) ⬆️
cot/src/request/extractors/client_ip.rs 97.08% <97.08%> (ø)

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@m4tx
m4tx force-pushed the client-ip-extractor-fixes branch 3 times, most recently from 172a0ea to dc417b4 Compare November 1, 2026 22:16
@m4tx m4tx changed the title Client ip extractor fixes feat(request): add client IP address extractor Nov 1, 2026
@m4tx
m4tx requested a balanced review from Copilot November 1, 2026 22:20

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

IPv4-mapped IPv6 proxy addresses fail to match trusted IPv4 networks, causing forwarding headers to be ignored or proxy traversal to stop prematurely; canonical address matching and regression tests are needed.

1 open issue
1 resolved since last review

Review effort: Balanced

Comment thread cot/src/request/extractors/client_ip.rs Resolved
@m4tx
m4tx force-pushed the client-ip-extractor-fixes branch from dc417b4 to 66b7332 Compare November 1, 2026 22:48
@m4tx
m4tx requested a balanced review from Copilot November 1, 2026 22:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The parser rejects valid Forwarded client addresses with obfuscated ports, causing the extractor to return the trusted proxy’s IP instead of the client’s.

1 open issue
1 resolved since last review

Review effort: Balanced

Comment thread cot/src/request/extractors/client_ip.rs Resolved
@m4tx
m4tx force-pushed the client-ip-extractor-fixes branch from 66b7332 to b310d11 Compare November 1, 2026 23:01
@m4tx
m4tx requested a balanced review from Copilot November 1, 2026 23:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The client-IP extractor change has no active review issues requiring resolution.

No open issues 🎉

1 resolved since last review

Review effort: Balanced

@m4tx
m4tx force-pushed the client-ip-extractor-fixes branch from b310d11 to 3c1a3a9 Compare November 6, 2026 18:23
Wervice and others added 3 commits November 6, 2026 19:24
- Return an error instead of panicking when the remote address of the
  request is unknown.
- Use the right-most untrusted address across all header instances, not
  the client-controlled left-most one.
- Treat invalid addresses as unknown instead of returning 500.
- Add `[client_ip]` to the config reference.
- Move header parsing into a private module.
- Drop `RequestExt::client_ip`; rename `direct_peer_ip` to `peer_ip`.
- Use the standard builder for `ClientIpConfig`; drop getters and `new`.
- Make the tests table-driven.
@m4tx
m4tx force-pushed the client-ip-extractor-fixes branch from 3c1a3a9 to 25fef2e Compare November 6, 2026 18:25
@m4tx
m4tx enabled auto-merge (rebase) November 6, 2026 18:25
@m4tx
m4tx merged commit 71589d9 into master Nov 6, 2026
43 checks passed
@m4tx
m4tx deleted the client-ip-extractor-fixes branch November 6, 2026 18:56
m4tx added a commit that referenced this pull request Nov 6, 2026
- Return an error instead of panicking when the remote address of the
  request is unknown.
- Use the right-most untrusted address across all header instances, not
  the client-controlled left-most one.
- Treat invalid addresses as unknown instead of returning 500.
- Add `[client_ip]` to the config reference.
m4tx added a commit that referenced this pull request Nov 6, 2026
- Move header parsing into a private module.
- Drop `RequestExt::client_ip`; rename `direct_peer_ip` to `peer_ip`.
- Use the standard builder for `ClientIpConfig`; drop getters and `new`.
- Make the tests table-driven.
@cotbot cotbot Bot mentioned this pull request Nov 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-deps Area: Dependencies A-docs Area: Documentation C-lib Crate: cot (main library crate)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants