require "open-uri" unless defined?(OpenURI) module OpenURI class << self # # The is a bug in Ruby's implementation of OpenURI that prevents redirects # from HTTP -> HTTPS. That should totally be a valid redirect, so we # override that method here and call it a day. # # Note: this does NOT permit HTTPS -> HTTP redirects, as that would be a # major security hole in the fabric of space-time! # def default_redirectable?(uri1, uri2) a, b = uri1.scheme.downcase, uri2.scheme.downcase a == b || (a == "http" && b == "https") end alias_method :redirectable?, :default_redirectable? # # Permit all redirects. # # Note: this DOES permit HTTP -> HTTP redirects, and that is a major # security hole! # # @return [true] # def unsafe_redirectable?(uri1, uri2) a, b = uri1.scheme.downcase, uri2.scheme.downcase a == b || (a == "http" && b == "https") || (a == "https" && b == "http") end # # Override the default open_uri method to search for our custom option to # permit unsafe redirects. # # @example # open('http://example.com', allow_unsafe_redirects: true) # alias_method :original_open_uri, :open_uri def open_uri(name, *rest, &block) options = rest.find { |arg| arg.is_a?(Hash) } || {} if options.delete(:allow_unsafe_redirects) class << self alias_method :redirectable?, :unsafe_redirectable? end end original_open_uri(name, *rest, &block) ensure class << self alias_method :redirectable?, :default_redirectable? end end end # # Force Kernel#open to always return a Tempfile. This works around the fact # that the OpenURI-provided Kernel#open returns a StringIO OR a Tempfile # instances depending on the size of the data being downloaded. In the case # of Omnibus we always want a Tempfile. # # @see http://winstonyw.com/2013/10/02/openuris_open_tempfile_and_stringio/ # # rubocop:disable Naming/ConstantName class Buffer remove_const :StringMax StringMax = 0 end end