Project

General

Profile

Bug #14016

URI IPv6 address can't be used to open socket

Added by chucke (Tiago Cardoso) over 1 year ago. Updated over 1 year ago.

Status:
Rejected
Priority:
Normal
Assignee:
-
Target version:
-
ruby -v:
2.4.2
[ruby-core:83283]

Description

The example occurred when trying to use IPv6 to establish communication between HTTP client and server.

I first created an URI, passed it to Net::HTTP.get, and it blew with the following message:

SocketError: Failed to open TCP connection to [::1]:9292 (getaddrinfo: nodename nor servname provided, or not known)

It seems to me that the URI and the Socket classes don't play well with its expected representation of an IPv6 address:

URI::HTTP.build(host: "[::1]").host #=> "[::1]"
URI::HTTP.build(host: "::1").host #=> ”[::1]”
TCPSocket.new("::1", 9292) #=> #<TCPSocket fd:15>
TCPSocket.new("[::1]", 9292) #=> #<TCPSocket fd:15>

History

Updated by chucke (Tiago Cardoso) over 1 year ago

I got the last one wrong:

TCPSocket.new("[::1]", 9292) #=> getaddrinfo: nodename nor servname provided, or not known)

if someone be so kind as to edit/replace the original description, I'd be very thankful.

Updated by chucke (Tiago Cardoso) over 1 year ago

Another notable inconsistency (when compared with the second example above):

uri.host = "::1"  #=> URI::InvalidComponentError: bad component(expected host component): ::1

Updated by chucke (Tiago Cardoso) over 1 year ago

And more inconsistencies when trying to patch Net::HTTP's usage:

# forcing here "::1" so that I can open the socket
irb(main):015:0> conn = Net::HTTP.new("::1", 9292)
=> #<Net::HTTP ::1:9292 open=false>
irb(main):016:0> conn.set_debug_output($stderr)
=> #<IO:<STDERR>>
irb(main):017:0> conn.get("http://[::1]:9292")
opening connection to ::1:9292...
opened
<- "GET http://[::1]:9292 HTTP/1.1\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: ::1:9292\r\n\r\n"
-> "HTTP/1.1 200 OK\r\n"
-> "Connection: close\r\n"
-> "Content-Length: 19\r\n"
-> "\r\n"
reading 19 bytes...
-> "echoing it all out!"
read 19 bytes
Conn close
=> #<Net::HTTPOK 200 OK readbody=true>

Notable mentions here are the request status line (host leaked into path) and the Host header (should have been Host: [::1]:9292).

Here's the same request performed with curl:

curl http://[::1]:9292 -v
* Rebuilt URL to: http://[::1]:9292/
*   Trying ::1...
* TCP_NODELAY set
* Connected to ::1 (::1) port 9292 (#0)
> GET / HTTP/1.1
> Host: [::1]:9292
> User-Agent: curl/7.50.3
> Accept: */*
> 
< HTTP/1.1 200 OK
< Content-Length: 19
< 
* Curl_http_done: called premature == 0
* Connection #0 to host ::1 left intact
echoing it all out!

Updated by shevegen (Robert A. Heiler) over 1 year ago

if someone be so kind as to edit/replace the original description,
I'd be very thankful.

I think there may be a few who could modify it (not me); at the
least the title can be changed, but possibly also the body of
the message. For some reason, the original poster can not change
the first message, but can modify later replies. Perhaps it is
to preserve the original suggestion, but ideally I think people
could have a window of modification even for the first comment
in a thread; e. g. something like 1-2 hours, to correct any
typos or so. Not sure how easy this is to change via this bugtracker
though.

Updated by akr (Akira Tanaka) over 1 year ago

  • Status changed from Open to Rejected

Use URI::HTTP.hostname which unwraps the bracket.

  u = URI("http://[::1]/bar")
  p u.hostname      #=> "::1"
  p u.host          #=> "[::1]"

Also available in: Atom PDF