2017-04-27 38 views
2

我試圖下載一組圖像,並提供其URL。一些URL重定向到包含空格的URL,這會導致OpenURI引發錯誤。使用Ruby下載重定向到帶有空格的URL的文件

即我提供的http://www.example.com/upload/comercial%20(2).jpg重定向到https://www.example.com/upload/comercial (2).jpg。這導致代碼中的錯誤負責下載:

url = 'http://www.example.com/upload/comercial%20(2).jpg' 
download = open(url, {ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE, allow_redirections: :all}) 

OpenURI::HTTPError: 302 Redirect (Invalid Location URI) 

有沒有辦法讓OpenURI瞭解重定向?

觀察: 產生的重定向URL可以通過OpenURI編碼,像這樣的空間後,正確處理:直到open()呼叫由

redirected = 'https://www.example.com/upload/comercial (2).jpg' 
encoded = URI.escape(redirected) 
# https://www.example.com/upload/comercial%20(2).jpg 

download = open(encoded, {ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE, allow_redirections: :all}) 
# Success 

顯然重定向URL是未知的。

+0

@AndreyDeineko請檢查我的編輯 - 重定向網址事先不知道。問題是如何使用單個'open()'調用下載文件,而不管提供的URL是否重定向。 – mrt

+0

FWIW問題在這裏:https://github.com/ruby/ruby/blob/52c738408e7624d1f6ebb8c62a7497fed2684bf5/lib/open-uri.rb#L356-L360當OpenURI命中重定向時,它會調用URL上的URI.parse 。 'URI.parse'遵守[RFC-3986](https://tools.ietf.org/html/rfc3986),它不允許有空格。如果你想使用OpenURI,我想不出比Sergio的更好的解決方案。 –

回答

3

你可以做的是手動處理重定向,通過使用redirect: false選項並從重定向異常中恢復(open-uri在獲得重定向響應時引發,並且不允許執行它)。然後你編碼的網址,然後再試一次。類似這樣的:

begin 
    open(uri, redirect: false) 
rescue OpenURI::HTTPRedirect => redirect 
    uri = redirect.uri # assigned from the "Location" response header 
    escaped = URI.escape(redirected) 
    open(escaped, redirect: false) 
end 

你可以在方法中隱藏這個邏輯,它將對它的調用者「一次調用」。抽象是好的。

+1

@JordanRunning:'OpenURI :: HTTPRedirect'是特定的錯誤。在這種情況下,由於'redirect:false',它由open-uri本身引發。可能有其他http錯誤,不是由重定向引起的。這些情況可能需要不同的處理(例如,來自遠程服務器的http 500) –

+0

@JordanRunning:不,這行代碼不在這裏。它終止[在其他地方](https://github.com/ruby/ruby/blob/52c738408e7624d1f6ebb8c62a7497fed2684bf5/lib/open-uri.rb#L221-L223)。 –

+0

看起來不錯! –