Strip brackets from IPv6 addresses before passing them to a socket.#731
Strip brackets from IPv6 addresses before passing them to a socket.#731tarcieri merged 4 commits intohttprb:mainfrom
Conversation
|
A few thoughts on this:
|
|
Apparently the bracketed hosts are defined in RFC3896 § 3.2.2:
So only IPv6 addresses should be allowed. Here is a regex for IPv6 addresses: https://gist.github.com/syzdek/6086792 Alternatively you could speculatively attempt to parse the captured inner address as an |
|
Thank you for the feedback and the useful references. I like the idea of moving this into An open question for me is whether the bracket-stripped form should be part of bracketed = Addressable::URI.parse("http://[2606:2800:220:1:248:1893:25c8:1946]/foo?bar=baz")
bracketed.host # => "[2606:2800:220:1:248:1893:25c8:1946]"
bracketed.port # => nil
unbracketed = Addressable::URI.parse("http://2606:2800:220:1:248:1893:25c8:1946/foo?bar=baz")
unbracketed.host # => "2606:2800:220:1:248:1893:25c8"
unbracketed.port # => 1946Should we maintain the bracketed host in the underlying I notice that currently host-related methods are just delegated to the |
|
@jeraki I would suggest changing |
|
Using ip_bracketed = IPAddr.new("[2606:2800:220:1:248:1893:25c8:1946]")
ip_bracketed.to_s # => "2606:2800:220:1:248:1893:25c8:1946"
ip_unbracketed = IPAddr.new("2606:2800:220:1:248:1893:25c8:1946")
ip_unbracketed.to_s # => "2606:2800:220:1:248:1893:25c8:1946"So the logic for def host
begin
ip = IPAddr.new(uri.host)
return ip.to_s if ip.ipv6?
rescue IPAddr::Error
end
uri.host
endAlso, Come to think of it, |
|
I think it's fine to change the behavior. The current behavior is broken per #730, so changing it is a bugfix. As to how to approach the setter and whether it should mutate the underlying |
|
Okay, I pushed up a new commit that does the stripping via RuboCop was reporting a violation because the top-level |
|
The only thing I'm still unsure about is whether to add logic to |
|
@jeraki I mentioned that particular issue earlier. I suggested the setters need to use the bracketed form of IPv6 addresses with That's another thing I think would be easier with eagerly updating instance variables, rather than trying to do it lazily. I think if you have one private helper method, called from both the constructor and the setter, which extracts the instance variables out of |
…ying Addressable::URI when calling URI#host=.
|
Sorry for the delay. I pushed a commit to process |
|
Looks good now, thanks! |
|
Thanks for your guidance! When you get a chance, could you publish a new gem that includes this change? |
|
Sure |
|
Conceptually, it's weird having brackets in However, the Addressable gem makes the distinction that |
|
@cben that sounds like a great point. Could one of you open a PR to switch to revert this and switch to Can't believe there are 3 different methods to get the hostname |
Changelog: ## [5.3.1] - 2025-06-09 ### Changed - Revert switch to the native llhttp on MRI, as it's not compatible with standalone bundles ([#802](httprb/http#802)) ## [5.3.0] - 2025-06-09 ### Added - (backported) Add .retriable feature to Http - (backported) Add more specific ConnectionError classes - (backported) New feature: RaiseError ### Changed - (backported) Drop depenency on base64 - (backported) Cache header normalization to reduce object allocation - (backported) Use native llhttp on MRI ## [5.2.0] - 2024-02-05 ### Added - Add `Connection#finished_request?` ([#743](httprb/http#743)) - Add `Instrumentation#on_error` ([#746](httprb/http#746)) - Add `base64` dependency (suppresses warnings on Ruby 3.0) ([#759](httprb/http#759)) - Add `PURGE` HTTP verb ([#757](httprb/http#757)) - Add Ruby-3.3 support ### Changed - **BREAKING** Process features in reverse order ([#766](httprb/http#766)) - **BREAKING** Downcase Content-Type charset name ([#753](httprb/http#753)) - **BREAKING** Make URI normalization more conservative ([#758](httprb/http#758)) ### Fixed - Close sockets on initialize failure ([#762](httprb/http#762)) - Prevent CRLF injection due to broken URL normalizer ([#765](httprb/http#765)) [unreleased]: httprb/http@v5.3.0...5-x-stable [5.3.0]: httprb/http@v5.2.0...v5.3.0 [5.2.0]: httprb/http@v5.1.1...v5.2.0 ## 5.1.1 (2022-12-17) * [#731](httprb/http#731) Strip brackets from IPv6 addresses in `HTTP::URI`. ([@jeraki]) * [#722](httprb/http#722) Add `on_redirect` callback. ([@benubois]) ## 5.1.0 (2022-06-17) * Drop ruby-2.5 support. * [#715](httprb/http#715) Set default encoding to UTF-8 for `application/json`. ([@drwl]) * [#712](httprb/http#712) Recognize cookies set by redirect. ([@tkellogg]) * [#707](httprb/http#707) Distinguish connection timeouts. ([@YuLeven]) ## 5.0.4 (2021-10-07) * [#698](httprb/http#698) Fix `HTTP::Timeout::Global#connect_ssl`. ([@tarcieri]) ## 5.0.3 (2021-10-06) * [#695](httprb/http#695) Revert DNS resolving feature. ([@PhilCoggins]) * [#694](httprb/http#694) Fix cookies extraction. ([@flosacca]) ## 5.0.2 (2021-09-10) * [#686](httprb/http#686) Correctly reset the parser. ([@bryanp]) * [#684](httprb/http#684) Don't set Content-Length for GET, HEAD, DELETE, or CONNECT requests without a BODY. ([@jyn514]) * [#679](httprb/http#679) Use features on redirected requests. ([@nomis]) * [#678](httprb/http#678) Restore `HTTP::Response` `:uri` option for backwards compatibility. ([@schwern]) * [#676](httprb/http#676) Update addressable because of CVE-2021-32740. ([@matheussilvasantos]) * [#653](httprb/http#653) Avoid force encodings on frozen strings. ([@bvicenzo]) * [#638](httprb/http#638) DNS failover handling. ([@midnight-wonderer]) ## 5.0.1 (2021-06-26) * [#670](httprb/http#670) Revert `Response#parse` behavior introduced in [#540]. ([@DannyBen]) * [#669](httprb/http#669) Prevent bodies from being resubmitted when following unsafe redirects. ([@odinhb]) * [#664](httprb/http#664) Bump llhttp-ffi to 0.3.0. ([@bryanp]) ## 5.0.0 (2021-05-12) * [#656](httprb/http#656) Handle connection timeouts in `Features` ([@semenyukdmitry]) * [#651](httprb/http#651) Replace `http-parser` with `llhttp` ([@bryanp]) * [#647](httprb/http#647) Add support for `MKCALENDAR` HTTP verb ([@meanphil]) * [#632](httprb/http#632) Respect the SSL context's `verify_hostname` value ([@colemannugent]) * [#625](httprb/http#625) Fix inflator with empty responses ([@LukaszMaslej]) * [#599](httprb/http#599) Allow passing `HTTP::FormData::{Multipart,UrlEncoded}` object directly. ([@ixti]) * [#593](httprb/http#593) [#592](httprb/http#592) Support informational (1XX) responses. ([@ixti]) * [#590](httprb/http#590) [#589](httprb/http#589) Fix response headers paring. ([@Bonias]) * [#587](httprb/http#587) [#585](httprb/http#585) Fix redirections when server responds with multiple Location headers. ([@ixti]) * [#581](httprb/http#581) [#582](httprb/http#582) Add Ruby 2.7.x support. ([@janko]) * [#577](httprb/http#577) Fix `Chainable#timeout` with frozen Hash. ([@antonvolkoff]) * [#576](httprb/http#576) [#524](httprb/http#524) **BREAKING CHANGE** Preserve header names casing. ([@joshuaflanagan]) * [#540](httprb/http#540) [#538](httprb/http#538) **BREAKING CHANGE** Require explicit MIME type for Response#parse ([@ixti]) * [#532](httprb/http#532) Fix pipes support in request bodies. ([@ixti]) * [#530](httprb/http#530) Improve header fields name/value validation. ([@Bonias]) * [#506](httprb/http#506) [#521](httprb/http#521) Skip auto-deflate when there is no body. ([@Bonias]) * [#489](httprb/http#489) Fix HTTP parser. ([@ixti], [@fxposter]) * [#546](httprb/http#546) **BREAKING CHANGE** Provide initiating `HTTP::Request` object on `HTTP::Response`. ([@joshuaflanagan]) * [#571](httprb/http#571) Drop Ruby 2.3.x support. ([@ixti]) * [3ed0c31](httprb/http@3ed0c31) Drop Ruby 2.4.x support.
Fixes #730.
I took my best guess at how you'd want this change implemented and tested, but I'm happy to revise it based on feedback. Thanks!