module OpenURI

Patch to allow open-uri to follow safe (http to https) and unsafe redirections (https to http).

Original gist URL: gist.github.com/1271420

Relevant issue: redmine.ruby-lang.org/issues/3719

Source here: github.com/ruby/ruby/blob/trunk/lib/open-uri.rb

Thread-safe implementation adapted from: github.com/obfusk/open_uri_w_redirect_to_https

Public Class Methods

open_uri(name, *rest, &block) click to toggle source

Patches the original open_uri method, so that it accepts the :allow_redirections argument with these options:

* :safe will allow HTTP => HTTPS redirections.
* :all  will allow HTTP => HTTPS and HTTPS => HTTP redirections.

OpenURI::open can receive different kinds of arguments, like a string for the mode or an integer for the permissions, and then a hash with options like UserAgent, etc.

To find the :allow_redirections option, we look for this options hash.

# File lib/ext/scraper.rb, line 134
def self.open_uri(name, *rest, &block)
  Thread.current[:__open_uri_redirections__] = allow_redirections(rest)

  block2 = lambda do |io|
    Thread.current[:__open_uri_redirections__] = nil
    block[io]
  end

  begin
    open_uri_original name, *rest, &(block ? block2 : nil)
  ensure
    Thread.current[:__open_uri_redirections__] = nil
  end
end
Also aliased as: open_uri_original
open_uri_original(name, *rest, &block)
Alias for: open_uri
redirectable?(uri1, uri2) click to toggle source
# File lib/ext/scraper.rb, line 101
def redirectable?(uri1, uri2)
  case Thread.current[:__open_uri_redirections__]
  when :safe
    redirectable_safe? uri1, uri2
  when :all
    redirectable_all? uri1, uri2
  else
    redirectable_cautious? uri1, uri2
  end
end
Also aliased as: redirectable_cautious?
redirectable_all?(uri1, uri2) click to toggle source
# File lib/ext/scraper.rb, line 116
def redirectable_all?(uri1, uri2)
  redirectable_safe?(uri1, uri2) || https_to_http?(uri1, uri2)
end
redirectable_cautious?(uri1, uri2)
Alias for: redirectable?
redirectable_safe?(uri1, uri2) click to toggle source
# File lib/ext/scraper.rb, line 112
def redirectable_safe?(uri1, uri2)
  redirectable_cautious?(uri1, uri2) || http_to_https?(uri1, uri2)
end

Private Class Methods

allow_redirections(args) click to toggle source
# File lib/ext/scraper.rb, line 151
def self.allow_redirections(args)
  options = first_hash_argument(args)
  options.delete :allow_redirections if options
end
first_hash_argument(arguments) click to toggle source
# File lib/ext/scraper.rb, line 156
def self.first_hash_argument(arguments)
  arguments.select { |arg| arg.is_a? Hash }.first
end
http_to_https?(uri1, uri2) click to toggle source
# File lib/ext/scraper.rb, line 160
def self.http_to_https?(uri1, uri2)
  schemes_from([uri1, uri2]) == %w(http https)
end
https_to_http?(uri1, uri2) click to toggle source
# File lib/ext/scraper.rb, line 164
def self.https_to_http?(uri1, uri2)
  schemes_from([uri1, uri2]) == %w(https http)
end
schemes_from(uris) click to toggle source
# File lib/ext/scraper.rb, line 168
def self.schemes_from(uris)
  uris.map { |u| u.scheme.downcase }
end