如何在Ruby中与IPv6地址建立HTTP连接?
解决Ruby中IPv6地址的REST请求连接问题
问题出在URI解析后返回的url.host包含IPv6地址的方括号,Net::HTTP直接将这个带括号的字符串作为主机名传递给底层解析器,导致getaddrinfo无法识别这是一个IPv6地址,从而抛出错误。
以下是两种可行的解决方案:
方案一:手动去除方括号并强制使用IPv6
修改代码,先移除主机名的方括号,再指定ipv6: true参数让Net::HTTP使用IPv6连接:
require 'ipaddr' require 'json' require 'net/http' require 'base64' require 'uri' request_uri = "https://[2002:cafe:cafe:cafe:100::1000]/path/to/service" url = URI(request_uri) # 提取方括号内的纯IPv6地址 host = url.host.gsub(/^\[(.*)\]$/, '\1') # 启动HTTP连接时开启SSL并指定IPv6 http = Net::HTTP.start(host, url.port, use_ssl: url.scheme == 'https', ipv6: true) # 后续构建POST请求示例 request = Net::HTTP::Post.new(url.path) request.body = JSON.generate(your_payload) response = http.request(request)
方案二:使用IPAddr对象处理IPv6地址
利用Ruby的IPAddr类解析地址,Net::HTTP可以直接识别IPAddr对象,自动处理IPv6连接:
require 'ipaddr' require 'json' require 'net/http' require 'base64' require 'uri' request_uri = "https://[2002:cafe:cafe:cafe:100::1000]/path/to/service" url = URI(request_uri) # 解析为IPAddr对象,自动处理方括号 ip_address = IPAddr.new(url.host) # 启动连接,开启SSL http = Net::HTTP.start(ip_address, url.port, use_ssl: url.scheme == 'https') # 构建并发送POST请求示例 request = Net::HTTP::Post.new(url.path) request.body = JSON.generate(your_payload) response = http.request(request)
补充说明
使用主机名可以正常请求的原因是:DNS解析主机名时会返回纯IPv6地址,Net::HTTP处理时不会携带方括号,因此底层解析器能正确识别。直接使用带方括号的地址字符串时,会被当作普通主机名而非IPv6地址解析,导致失败。
内容的提问来源于stack exchange,提问作者Chigzz
相关产品推荐
相关产品推荐

