5

我正在使用 Ruby 1.9.3 并正在运行以下命令:

open("ftp://user name:password@datafeeds.domain.com/1234/1234.txt.gz")

返回:

URI::InvalidURIError: bad URI(不是 URI?)

对用户名进行编码(用 %20 替换空格)也不起作用:

Net::FTPPermError: 530 无效的用户名/密码

URI 在所有经过测试的浏览器和 FTP 客户端中都能正常工作——只是在使用 OpenURI 时不行。此外,使用 Net::FTP(由 OpenURI 包装)也可以正常工作:

require 'net/ftp'
ftp = Net::FTP.new
ftp.connect("datafeeds.domain.com", 21)
ftp.login("user name", "password")
ftp.getbinaryfile("/1234/1234.txt.gz")

知道为什么 OpenURI 方法不起作用,而 Net::FTP 方法起作用吗?谢谢。

4

3 回答 3

2

根据规范中定义,URL 用户名只允许使用以下字符:

user                   alphanum2 [ user ]
[...]
alphanum2              alpha | digit | - | _ | . | +  

浏览器因忽略规范而臭名昭著,因此说它们支持它并不是一个很好的证明。他们不应该按照规范。

如果 cURL 支持它们,那么使用Curb gem 看看是否可以让你使用它们。

于 2013-06-27T20:17:40.103 回答
1

根据这个 StackOverflow 答案,您应该能够转义用户名和密码中的特殊字符。您可以执行以下操作:

login = URI.escape('user name') + ':' + URI.escape('password')
open("ftp://#{login}@datafeeds.domain.com/1234/1234.txt.gz")
于 2013-06-27T20:53:16.630 回答
1

open-uri在这件事上似乎被打破了。我对包含#字符的密码有类似的问题。

通过直接设置URI的实例变量,我最终绕过了set_password不允许#密码中的字符。@password

uri = URI.parse(...)
if uri.password
  uri.instance_variable_set "@password", "password_with_#_char"
end
open(uri) # now this works fine

它很hacky,但可以完成工作。

于 2017-04-21T14:41:58.080 回答