Sha256: 863397391620bce839c16e24b83d228feba70a23e21d3d46a1812427a446d389

Contents?: true

Size: 1.28 KB

Versions: 6

Compression:

Stored size: 1.28 KB

Contents

require 'uri'
require 'net/http'

module Saviour
  class UrlSource
    MAX_REDIRECTS = 10

    def initialize(url)
      @uri = wrap_uri_string(url)
    end

    def read(*args)
      stringio.read(*args)
    end

    def rewind
      stringio.rewind
    end

    def original_filename
      ::File.basename(@uri.path)
    end


    private

    def stringio
      @stringio ||= StringIO.new(raw_data)
    end

    def raw_data
      @raw_data ||= with_retry(3) { resolve(@uri) }
    end

    def resolve(uri, max_redirects = MAX_REDIRECTS)
      raise RuntimeError, "Max number of allowed redirects reached (#{MAX_REDIRECTS}) when resolving #{uri}" if max_redirects == 0

      response = Net::HTTP.get_response(uri)

      case response
        when Net::HTTPSuccess
          response.body
        when Net::HTTPRedirection
          resolve(wrap_uri_string(response['location']), max_redirects - 1)
        else
          false
      end
    end

    def wrap_uri_string(url)
      begin
        URI(url)
      rescue URI::InvalidURIError
        raise ArgumentError, "'#{url}' is not a valid URI"
      end
    end

    def with_retry(n = 3, &block)
      raise(RuntimeError, "Connection to #{@uri} failed after 3 attempts.") if n == 0

      block.call || with_retry(n - 1, &block)
    end
  end
end

Version data entries

6 entries across 6 versions & 1 rubygems

Version Path
saviour-0.4.5 lib/saviour/url_source.rb
saviour-0.4.4 lib/saviour/url_source.rb
saviour-0.4.3 lib/saviour/url_source.rb
saviour-0.4.2 lib/saviour/url_source.rb
saviour-0.4.1 lib/saviour/url_source.rb
saviour-0.4.0 lib/saviour/url_source.rb