2017-04-27 8 views
2

URL이 제공되는 일련의 이미지를 다운로드하려고합니다. 일부 URL은 공백이있는 URL로 리디렉션되어 OpenURI가 오류를 발생시킵니다.공백이있는 URL로 리디렉션되는 Ruby의 파일 다운로드

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 리디렉션을 이해할 수 있도록하는 방법이 있나요 :이 다운로드에 대한 책임이있는 코드에서 오류가 발생합니다?

관측 : 올바르게 그래서 같은 공간을 인코딩 후 OpenURI 처리 할 수있는 URL을 리디렉션 결과 : 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 제 편집을 확인하십시오. 리디렉션 URL은 미리 알 수 없습니다. 문제는 제공된 URL 리디렉션에 관계없이 단일 'open()'호출로 파일을 다운로드하는 방법입니다. – 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 옵션을 사용하고 리다이렉트 예외 (오픈 - URI는 리다이렉트 응답을 받았을 때 발생하고 그것을 수행하는 것이 허용되지 않음)에서 구출하여 수동으로 리디렉션을 처리하는 것입니다. 그런 다음 URL을 인코딩하고 다시 시도하십시오. 이런 식으로 뭔가가 :

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

좋아 보인다! –