lib/down/net_http.rb in down-4.0.1 vs lib/down/net_http.rb in down-4.1.0

- old
+ new

@@ -10,11 +10,11 @@ require "cgi" module Down class NetHttp < Backend def initialize(options = {}) - @options = options + @options = { "User-Agent" => "Down/#{Down::VERSION}" }.merge(options) end def download(uri, options = {}) options = @options.merge(options) @@ -22,11 +22,10 @@ max_redirects = options.delete(:max_redirects) || 2 progress_proc = options.delete(:progress_proc) content_length_proc = options.delete(:content_length_proc) open_uri_options = { - "User-Agent" => "Down/#{VERSION}", content_length_proc: proc { |size| if size && max_size && size > max_size raise Down::TooLarge, "file is too large (max is #{max_size/1024/1024}MB)" end content_length_proc.call(size) if content_length_proc @@ -60,13 +59,11 @@ tries = max_redirects + 1 begin uri = URI(uri) - if uri.class != URI::HTTP && uri.class != URI::HTTPS - raise Down::InvalidUrl, "URL scheme needs to be http or https" - end + fail Down::InvalidUrl, "URL scheme needs to be http or https" unless uri.is_a?(URI::HTTP) if uri.user || uri.password open_uri_options[:http_basic_authentication] ||= [uri.user, uri.password] uri.user = nil uri.password = nil @@ -81,11 +78,11 @@ open_uri_options["Cookie"] = exception.io.meta["set-cookie"] end retry else - raise Down::TooManyRedirects, "too many redirects" + fail Down::TooManyRedirects, "too many redirects" end rescue OpenURI::HTTPError => exception code, message = exception.io.status response_class = Net::HTTPResponse::CODE_TO_OBJ.fetch(code) response = response_class.new(nil, code, message) @@ -105,25 +102,19 @@ # does. open_uri_file = downloaded_file downloaded_file = copy_to_tempfile(uri.path, open_uri_file) OpenURI::Meta.init downloaded_file, open_uri_file - downloaded_file.extend DownloadedFile + downloaded_file.extend Down::NetHttp::DownloadedFile downloaded_file end def open(uri, options = {}) options = @options.merge(options) + uri = URI(uri) - begin - uri = URI(uri) - if uri.class != URI::HTTP && uri.class != URI::HTTPS - raise Down::InvalidUrl, "URL scheme needs to be http or https" - end - rescue URI::InvalidURIError - raise Down::InvalidUrl, "URL was invalid" - end + fail Down::InvalidUrl, "URL scheme needs to be http or https" unless uri.is_a?(URI::HTTP) http_class = Net::HTTP if options[:proxy] proxy = URI(options[:proxy]) @@ -150,10 +141,12 @@ http.read_timeout = options[:read_timeout] if options.key?(:read_timeout) http.open_timeout = options[:open_timeout] if options.key?(:open_timeout) request_headers = options.select { |key, value| key.is_a?(String) } + request_headers["Accept-Encoding"] = "" # otherwise FiberError can be raised + get = Net::HTTP::Get.new(uri.request_uri, request_headers) get.basic_auth(uri.user, uri.password) if uri.user || uri.password request = Fiber.new do http.start do @@ -162,20 +155,24 @@ response.instance_variable_set("@read", true) end end end - begin - response = request.resume + response = request.resume - response_error!(response) unless (200..299).cover?(response.code.to_i) - rescue => exception - request_error!(exception) + response_error!(response) unless (200..299).cover?(response.code.to_i) + + body_chunks = Enumerator.new do |yielder| + begin + response.read_body { |chunk| yielder << chunk } + rescue => exception + request_error!(exception) + end end Down::ChunkedIO.new( - chunks: response.enum_for(:read_body), + chunks: body_chunks, size: response["Content-Length"] && response["Content-Length"].to_i, encoding: response.type_params["charset"], rewindable: options.fetch(:rewindable, true), on_close: -> { request.resume }, # close HTTP connnection data: { @@ -185,10 +182,12 @@ headers.merge!(name => value) }, response: response, }, ) + rescue => exception + request_error!(exception) end private def copy_to_tempfile(basename, io) @@ -233,12 +232,10 @@ Errno::EHOSTUNREACH raise Down::ConnectionError, exception.message when SocketError raise Down::ConnectionError, "domain name could not be resolved" when Errno::ETIMEDOUT, - Timeout::Error, - Net::OpenTimeout, - Net::ReadTimeout + Timeout::Error raise Down::TimeoutError, "request timed out" when defined?(OpenSSL) && OpenSSL::SSL::SSLError raise Down::SSLError, exception.message else raise exception