Ruby 打开“不支持用户信息”:具有基本身份验证的 URL

23t*_*tux 5 ruby ftp basic-authentication

我有很多以下格式的网址

当我尝试使用 ruby​​ 的open方法加载图像时,它会引发以下错误https,但适用于ftp

open(URI.parse("ftp://user:pass@example.com/some_image.jpg")) # works
open(URI.parse("https://user:pass@example.com/some_image.jpg")) # throws error:

# ArgumentError: userinfo not supported.  [RFC3986]
Run Code Online (Sandbox Code Playgroud)

我发现(来自需要用户名和密码的远程 URL 的 JSON 解析)您可以提供这样open的基本身份验证参数

url = URI.parse(url)
open(url, http_basic_authentication: [url.user,url.password])
Run Code Online (Sandbox Code Playgroud)

但这仍然会引发错误,因为 url 仍然包含用户/密码信息。

那么,从 url 解析出用户/密码信息的简单方法是什么?我通过像这样自己连接 URL 的部分来尝试它:

uri = URI.parse(url)
uri_base = "#{uri.scheme}://#{uri.host}:#{uri.port}#{uri.path}"
uri_base += "?#{uri.query}" if uri.query
open(uri_base, http_basic_authentication: [uri.user,uri.password])
Run Code Online (Sandbox Code Playgroud)

但这对 FTP 不起作用,它会引发Net::FTPPermError: 530 User _ftp denied by SACL.错误。

那么,有没有一种简单的方法来支持open具有可选的用于HTTP基本身份验证httpsftp

更新

我想出了以下解决方案,但它看起来有点笨拙,我认为必须有更好的方法:

  def download url
    opts = {}
    uri = URI.parse(url)

    uri_base = "#{uri.scheme}://"
    if uri.scheme=="ftp"
      uri_base += "#{uri.user}:#{uri.password}@" if uri.user
    else
      opts[:http_basic_authentication] = [uri.user,uri.password] if uri.user
    end
    uri_base += "#{uri.host}:#{uri.port}/#{uri.path}"
    uri_base += "?#{uri.query}" if uri.query
    open(uri_base, opts)
  end
Run Code Online (Sandbox Code Playgroud)