Skip to content

Fix get_host_port splitting an IPv6 address at the first colon - #526

Closed
kwy404 wants to merge 1 commit into
sony:masterfrom
kwy404:host-port-ip-literal
Closed

kwy404 wants to merge 1 commit into
sony:masterfrom
kwy404:host-port-ip-literal

Conversation

@kwy404

@kwy404 kwy404 commented Oct 1, 2026

Copy link
Copy Markdown

Root cause: web::http::get_host_port splits the Host (or X-Forwarded-Host) value at the first :. When the host is an IPv6 address, which RFC 3986 section 3.2.2 requires to be written in square brackets, that first colon is inside the address. So Host: [2001:db8::1]:42 returns host [2001 and port 0 instead of [2001:db8::1] and 42. This result is used for the paging Link header (Query and Logging APIs), the subscription ws_href (Query API) and the authorization realm, so all of those get a truncated host.

Fix: look for the port colon after the closing ] when there is one. Hosts without brackets are handled exactly as before.

Test: added an IPv6 address and port case to testGetHostPort in cpprest/test/http_utils_test.cpp. It fails before the fix (get_host_port returns {"[2001", 0}) and passes after. The full nmos-cpp-test suite passes (186 test cases, 2636 assertions, Windows, VS 2022).

@garethsb

garethsb commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

What's your use case? IPv6 support throughout nmos-cpp, its dependencies, and the associated data plane needs a joined up use case, plan of action and verification strategy.

@kwy404

kwy404 commented Oct 1, 2026

Copy link
Copy Markdown
Author

Thanks for taking a look. I don't have a deployment that depends on IPv6 yet; I found this while reading http_utils, when I noticed that a bracketed IPv6 Host header is split at the first colon and loses its port, so links built from it (paging, ws_href, the auth realm) come out broken. I see this as a narrow parsing fix rather than a step towards IPv6 support across nmos-cpp and its dependencies, and I understand that needs the joined up plan you describe. If you'd rather not take changes like this until that plan exists, I'm happy to close it.

@garethsb

garethsb commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

I'm in two minds. I agree there are places like this that have potential narrow fixes. However, each fix requires review and CI cycles, and if it doesn't actually make the entire codebase usable, what's the point? A wider ranging analysis of all the places that IPv6 support would need work in nmos-cpp and the libraries it uses and the environments - CI tests and things like Easy-NMOS - in which it is typically deployed, and then a suggested plan on how to close all of those gaps, would perhaps make more efficient use of maintainers and your time?

@kwy404

kwy404 commented Oct 1, 2026

Copy link
Copy Markdown
Author

That's fair, a one off fix doesn't help much if the rest of the stack still can't run over IPv6, and it costs you review and CI time. I'll close this one. If I come back to it, I'll start with an issue that maps out where IPv6 would need work in nmos-cpp, its dependencies and the usual deployment and CI environments, so we can agree on a plan before any code. Thanks for explaining.

@kwy404 kwy404 closed this Oct 1, 2026
// an IPv6 address is enclosed in square brackets, e.g. "[2001:db8::1]:42", so look for the port after the closing bracket
// see https://tools.ietf.org/html/rfc3986#section-3.2.2
const auto bracket = first.find(']');
auto colon = first.find(':', utility::string_t::npos != bracket ? bracket : 0);

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.

Maybe

Suggested change
auto colon = first.find(':', utility::string_t::npos != bracket ? bracket : 0);
const auto colon = first.find(':', bracket + 1);

;-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants