Feature #11322
closedOpenUri: RuntimeError: HTTP redirection loop
Description
Trying to download this file from this website with OpenUri
fails with the runtime error "HTTP redirection loop".
Here is how I can reproduce the error:
> require 'open-uri'
=> true
> open('http://apps.london.ca/OpenData/ShapeFiles_Zipped/2010_skateboard_parks_shp.zip')
RuntimeError: HTTP redirection loop: http://apps.london.ca/uniquesig87fdc01fb86ce6f0fd235c713015d7d7/uniquesig0/InternalSite/StartApp.asp?resource_id=837A134B9EC24A2197B6AF5745B6CA55&login_type=0&site_name=appstrunk&secure=0&orig_url=http%3a%2f%2fapps.london.ca%2fOpenData%2fShapeFiles_Zipped%2f2010_skateboard_parks_shp.zip
from /home/john/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/open-uri.rb:232:in `open_loop'
from /home/john/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/open-uri.rb:150:in `open_uri'
from /home/john/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/open-uri.rb:716:in `open'
from /home/john/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/open-uri.rb:34:in `open'
from (irb):2
from /home/john/.rvm/rubies/ruby-2.2.2/bin/irb:11:in `<main>'
Files
Updated by 0x0dea (D.E. Akers) over 9 years ago
The problem is not specific to OpenURI
:
$ curl -L http://apps.london.ca/OpenData/ShapeFiles_Zipped/2010_skateboard_parks_shp.zip
curl: (47) Maximum (50) redirects followed
It seems the 302 Object Moved
handler on this server has not been properly configured; it expects the previous request to have set a few cookies and simply sends the client back if it doesn't find them.
OpenURI
appears to be incapable of handling such a circumstance, but Net::HTTP
can and isn't that much more complex. I've presented below a demonstration of how you might go about orchestrating the "handshake" in order to successfully obtain the file.
conn = Net::HTTP.new 'apps.london.ca'
file = '/OpenData/ShapeFiles_Zipped/2010_skateboard_parks_shp.zip'
resp = conn.get file
cookie = resp.get_fields('Set-Cookie').map { |c| c.split(';')[0] }.join(';')
resp = conn.get file, 'Cookie' => cookie
File.write File.basename(file), resp.body
Updated by tbsprs (Tobias Preuss) over 9 years ago
Dear D.E. Akers: Your workaround works like a charm. Thank you very much.
Updated by chaimann (Eugene Chaikin) over 8 years ago
i've had a similar issue with open('http://www.replayjeans.com/us/shop/product/women/jumpers-knitwear/neoprene-printed-sweatshirt/pc/48/c/61/sc/-1/1962')
which i solved modifying D.E. Akers workaround a bit:
url = 'http://www.replayjeans.com/us/shop/product/women/jumpers-knitwear/neoprene-printed-sweatshirt/pc/48/c/61/sc/-1/1962'
uri = URI(url)
res = Net::HTTP.get_response(uri)
cookie = res['Set-Cookie']
req = Net::HTTP::Get.new(uri)
req['Cookie'] = cookie
res = Net::HTTP.start(uri.hostname, uri.port) { |http| http.request(req) }
However there is another issue that i can't resolve.
Some requests don't end up in a redirection loop, but response has a status 302 Moved Temporarily
and open(url)
returns not the page i expect.
If I apply redirect loop workaround for this case, i get the correct page.
Tried to google but no avail so far.
Updated by shyouhei (Shyouhei Urabe) over 7 years ago
- Status changed from Open to Assigned
Updated by jeremyevans0 (Jeremy Evans) over 5 years ago
- File open_uri-redirect-cookie-11322.patch open_uri-redirect-cookie-11322.patch added
- Tracker changed from Bug to Feature
- ruby -v deleted (
ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]) - Backport deleted (
2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN)
I don't think this is a bug. As 0x0dea (D.E. Akers) pointed out, other programs work the same way. However, I think cookie handling in open_uri could be a useful feature. Attached is a patch that implements the necessary support.
I used this Roda app to test the cookie redirection support:
require 'roda'
Roda.plugin :cookies
Roda.route do |r|
r.root do
if r.cookies['foo'] == 'bar'
'Success!'
else
response.set_cookie('foo', 'bar')
r.redirect '/'
end
end
end
run Roda
Updated by jeremyevans0 (Jeremy Evans) about 4 years ago
I've submitted the patch as a pull request, with a test: https://github.com/ruby/open-uri/pull/1
Updated by hsbt (Hiroshi SHIBATA) about 1 year ago
https://github.com/ruby/open-uri/pull/18 is another approach with max_redirects
option.
Updated by akr (Akira Tanaka) about 1 year ago
I agree with max_redirects
option.
Updated by hsbt (Hiroshi SHIBATA) about 1 year ago
- Status changed from Assigned to Closed
I merged https://github.com/ruby/open-uri/pull/18. Thanks all.
Updated by tbsprs (Tobias Preuss) about 1 year ago
Thanks for following up.