Skip to content

fix(url): normalizeHost with ipv6 hostname#201

Merged
pimterry merged 2 commits into
httptoolkit:mainfrom
chimurai:fix-ipv6-bracket-literals
May 21, 2026
Merged

fix(url): normalizeHost with ipv6 hostname#201
pimterry merged 2 commits into
httptoolkit:mainfrom
chimurai:fix-ipv6-bracket-literals

Conversation

@chimurai
Copy link
Copy Markdown
Contributor

@chimurai chimurai commented May 19, 2026

Hi,

Been using mockttp for a long time in http-proxy-middleware to mock the proxy target server.

Great work on this library 🙏

Recently I updated httpxy (dependency of http-proxy-middleware) with improved IPv6 support: unjs/httpxy#136

After updating httpxy some of existing IPv6 tests started to fail: https://github.com/chimurai/http-proxy-middleware/blob/ffbf5bd59712704c9df178d5df61d96062a11b22/test/e2e/ipv6.spec.ts

These tests are using mockttp with as target server.

I applied the fixes from this PR in this draft PR: chimurai/http-proxy-middleware#1234

Looks like it fixes the issue.

For full transparency, I used Copilot to help with analysis and creating this PR and the description below.


Summary

Fix IPv6 host serialization when reconstructing absolute request URLs from parsed destination data.

Mockttp already parses bracketed IPv6 Host headers correctly, but when rebuilding host[:port] strings it was dropping the brackets. For requests like Host: [::1]:8000, that produced invalid absolute URLs such as http://::1:8000/api, which fail URL parsing and trigger a 400 before request handlers run.

Changes

  • Update host normalization to re-add brackets when serializing IPv6 literal hostnames
  • Preserve existing default-port behavior so :80 for HTTP and :443 for HTTPS are still omitted
  • Leave parsing behavior unchanged for bracketed IPv6 input
  • Add regression coverage for:
    • IPv6 normalization with non-default HTTP and HTTPS ports
    • IPv6 normalization with default ports
    • Request preprocessing from Host: [::1]:8000
    • Existing IPv4 and DNS host formatting behavior

Example

Before:

Host: [::1]:8000
reconstructed URL: http://::1:8000/api
URL parsing fails, request returns 400

After:

Host: [::1]:8000
reconstructed URL: http://[::1]:8000/api
request is processed normally

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented May 19, 2026

CLA assistant check
All committers have signed the CLA.

Copy link
Copy Markdown
Member

@pimterry pimterry left a comment

Choose a reason for hiding this comment

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

Core change here all looks good to me! Thanks @chimurai, and great to hear you're finding Mockttp useful in http-proxy-middleware.

There is a broken test here though - not really for a good reason, but an example test value that was used as an invalid hostname in client-error events is now detected as IPv6 and gets square brackets inserted in the error report 😆. Can you have a look?

This isn't a valid IPv6 hostname, so I'd guess our regex is too relaxed there. If there's a quick safe change we can make to tighten that up then great, or if not we can just change the test data to something less ambiguous. The specific parsing behaviour for totally broken input like this isn't guaranteed (or really even guaranteeable) so as long as the test ends up passing and overall behaviour is sensible then it's not a big a deal.

@chimurai
Copy link
Copy Markdown
Contributor Author

chimurai commented May 20, 2026

Updated the test with less ambiguous invalid ipv6 address:

-`a:1:2`
+`a^1:2`

Tried different popular IPv6 regex pattern without success.

Also tried using the already installed ipaddr.js dependency:

ipaddr.IPv6.isValid(string), also without success

@pimterry pimterry merged commit feff512 into httptoolkit:main May 21, 2026
10 checks passed
@pimterry
Copy link
Copy Markdown
Member

Merged, thanks @chimurai! I'll release as v4.4.2 now.

@chimurai
Copy link
Copy Markdown
Contributor Author

Thanks for the quick reply and support 🙏

@chimurai chimurai deleted the fix-ipv6-bracket-literals branch May 22, 2026 19:41
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.

3 participants