我正在尝试使用 Ruby std 完成一些 RESTful 的事情。库、“uri”和“net/https”。我想通过明确指定的传出接口(interface)访问链路本地 IPv6 地址,例如 fe80::cba7:32b1:741d:5c41%ens192
。
当我尝试创建新的 URI 实例时 - 我仍然收到相同的错误(对于下面的两个示例):
URI("https://[fe80::cba7:32b1:741d:5c41%ens192]/")
URI("https://[fe80::cba7:32b1:741d:5c41%25ens192]/")
返回
URI::InvalidURIError: bad URI(is not URI?)
请问您知道如何处理这些 IPv6 链路本地地址吗? 仅供引用,我尝试发出一个简单的 HTTP 请求,它有效。所以一般来说,Ruby 对于 IPv6 没有问题:)
require 'net/https'
request = Net::HTTP.new('fe80::cba7:32b1:741d:5c41%ens192', 443)
request.use_ssl = true
request.verify_mode = OpenSSL::SSL::VERIFY_NONE
request.get('/')
提前致谢!
最佳答案
我刚刚找到答案...URI 规范 RFC3986 不支持 IPv6 范围寻址区域。 Ruby URI 实现遵循标准。所以这就是为什么 :) 唯一的办法是:
- 创建一个新的 URI 解析器 https://www.packetizer.com/rfc/rfc6874/
- 在您的代码中需要它
- 设置 URI::DEFAULT_PARSER 即
URI::DEFAULT_PARSER = URI::RFC6874_Parser.new
我发现了这个标准。 Go 库 net/url 支持 RFC6874,因此至少对 Ruby RFC6874_Parser
的编码有一些启发:)
package main
import (
"fmt"
"log"
"net/url"
)
func main() {
fmt.Println("Hello, playground")
u, err := url.Parse("https://[fe80::250:56ff:fe9e:76d9%25ens192]")
if err != nil {
log.Fatal(err)
}
fmt.Println(u.Hostname())
}
返回
fe80::250:56ff:fe9e:76d9%ens192
关于Ruby URI 无法处理具有显式指定传出接口(interface)的链接本地 IPv6 地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44796588/