OpenURI 无法遵循具有 %20 的 URL
OpenURI fails to follow URLs that have %20
我在使用 Ruby 的 OpenURI 跟随重定向功能时遇到一些问题。
当转到其中包含 %20
的 URL 并使用 30x 重定向时,Ruby 的 OpenURI 失败。
- 完全相同的 URL,用
+
而不是 %20
可以工作。
%20
和 +
版本都可以与 curl -L
一起正常工作(跟随)。
代码
require 'open-uri'
base = "http://software-engineering-handbook.com/Handbook"
puts "===> PASS: URI Open +"
result = open "#{base}/Video+Series"
p result.status
puts "===> PASS: Curl +"
puts `curl -LIsS "#{base}/Video+Series" | grep HTTP`
puts "===> PASS: Curl %20"
puts `curl -LIsS "#{base}/Video%20Series" | grep HTTP`
puts "===> FAIL: URI Open %20"
begin
result = open "#{base}/Video%20Series"
p result.status
rescue => e
puts "#{e.class} #{e.message}"
end
输出
===> PASS: URI Open +
["200", "OK"]
===> PASS: Curl +
HTTP/1.1 200 OK
===> PASS: Curl %20
HTTP/1.1 303 See Other
HTTP/1.1 200 OK
===> FAIL: URI Open %20
OpenURI::HTTPError 302 Found (Invalid Location URI)
我不确定这里发生了什么。尝试过 HTTParty(虽然我知道它只是一个包装器),希望看到不同的行为,但也失败了。
服务器正在响应一个指向无效 URI 的重定向。 curl
松懈,但 Ruby 严格。
如果我们打印出 e.cause
,我们将获得更多信息。
#<URI::InvalidURIError: bad URI(is not URI?): "http://software-engineering-handbook.com/Handbook/Video Series/">
并且还通过查看 curl -I 'http://software-engineering-handbook.com/Handbook/Video%20Series'
中的 headers...
HTTP/1.1 303 See Other
Server: Cowboy
Date: Sat, 28 Dec 2019 21:41:28 GMT
Connection: keep-alive
Content-Type: text/html;charset=utf-8
Location: http://software-engineering-handbook.com/Handbook/Video Series/
事实上,服务器正在返回无效的 URI。 URI path 中不允许有空格。 Ruby 的 URI class 不会解析它。
> URI("http://software-engineering-handbook.com/Handbook/Video Series/")
URI::InvalidURIError: bad URI(is not URI?): "http://software-engineering-handbook.com/Handbook/Video Series/"
from /Users/schwern/.rvm/rubies/ruby-2.6.5/lib/ruby/2.6.0/uri/rfc3986_parser.rb:67:in `split'
我在使用 Ruby 的 OpenURI 跟随重定向功能时遇到一些问题。
当转到其中包含 %20
的 URL 并使用 30x 重定向时,Ruby 的 OpenURI 失败。
- 完全相同的 URL,用
+
而不是%20
可以工作。 %20
和+
版本都可以与curl -L
一起正常工作(跟随)。
代码
require 'open-uri'
base = "http://software-engineering-handbook.com/Handbook"
puts "===> PASS: URI Open +"
result = open "#{base}/Video+Series"
p result.status
puts "===> PASS: Curl +"
puts `curl -LIsS "#{base}/Video+Series" | grep HTTP`
puts "===> PASS: Curl %20"
puts `curl -LIsS "#{base}/Video%20Series" | grep HTTP`
puts "===> FAIL: URI Open %20"
begin
result = open "#{base}/Video%20Series"
p result.status
rescue => e
puts "#{e.class} #{e.message}"
end
输出
===> PASS: URI Open +
["200", "OK"]
===> PASS: Curl +
HTTP/1.1 200 OK
===> PASS: Curl %20
HTTP/1.1 303 See Other
HTTP/1.1 200 OK
===> FAIL: URI Open %20
OpenURI::HTTPError 302 Found (Invalid Location URI)
我不确定这里发生了什么。尝试过 HTTParty(虽然我知道它只是一个包装器),希望看到不同的行为,但也失败了。
服务器正在响应一个指向无效 URI 的重定向。 curl
松懈,但 Ruby 严格。
如果我们打印出 e.cause
,我们将获得更多信息。
#<URI::InvalidURIError: bad URI(is not URI?): "http://software-engineering-handbook.com/Handbook/Video Series/">
并且还通过查看 curl -I 'http://software-engineering-handbook.com/Handbook/Video%20Series'
中的 headers...
HTTP/1.1 303 See Other
Server: Cowboy
Date: Sat, 28 Dec 2019 21:41:28 GMT
Connection: keep-alive
Content-Type: text/html;charset=utf-8
Location: http://software-engineering-handbook.com/Handbook/Video Series/
事实上,服务器正在返回无效的 URI。 URI path 中不允许有空格。 Ruby 的 URI class 不会解析它。
> URI("http://software-engineering-handbook.com/Handbook/Video Series/")
URI::InvalidURIError: bad URI(is not URI?): "http://software-engineering-handbook.com/Handbook/Video Series/"
from /Users/schwern/.rvm/rubies/ruby-2.6.5/lib/ruby/2.6.0/uri/rfc3986_parser.rb:67:in `split'