class Resync::Client::HTTPHelper

Utility class simplifying GET requests for HTTP/HTTPS resources.

Constants

DEFAULT_MAX_REDIRECTS

The default number of redirects to follow before erroring out.

Attributes

redirect_limit[RW]

@!attribute [rw] redirect_limit

@return [Integer] the number of redirects to follow before erroring out
user_agent[RW]

@!attribute [rw] user_agent

@return [String] the User-Agent string to send when making requests

Public Class Methods

new(user_agent:, redirect_limit: DEFAULT_MAX_REDIRECTS) click to toggle source

Creates a new HTTPHelper

@param user_agent [String] the User-Agent string to send when making requests @param redirect_limit [Integer] the number of redirects to follow before erroring out

(defaults to {DEFAULT_MAX_REDIRECTS})
# File lib/resync/client/http_helper.rb, line 36
def initialize(user_agent:, redirect_limit: DEFAULT_MAX_REDIRECTS)
  @user_agent = user_agent
  @redirect_limit = redirect_limit
end

Public Instance Methods

fetch(uri:, limit: redirect_limit) click to toggle source

Gets the content of the specified URI as a string. @param uri [URI] the URI to download @param limit [Integer] the number of redirects to follow (defaults to {#redirect_limit}) @return [String] the content of the URI

# File lib/resync/client/http_helper.rb, line 48
def fetch(uri:, limit: redirect_limit)
  make_request(uri, limit) do |success|
    # not 100% clear why we need an explicit return here; it
    # doesn't show up in unit tests but it does in example.rb
    return success.body
  end
end
fetch_to_file(uri:, path: nil, limit: redirect_limit) click to toggle source

Gets the content of the specified URI and saves it to a file. If no file path is provided, saves it to a temporary file. @param uri [URI] the URI to download @param path [String] the path to save the download to (optional) @return [String] the path to the downloaded file

# File lib/resync/client/http_helper.rb, line 61
def fetch_to_file(uri:, path: nil, limit: redirect_limit)
  make_request(uri, limit) do |success|
    file = path ? File.new(path, 'w+') : Tempfile.new(['resync-client', ".#{extension_for(success)}"])
    open file, 'w' do |out|
      success.read_body { |chunk| out.write(chunk) }
    end
    return file.path
  end
end

Private Instance Methods

extension_for(response) click to toggle source
# File lib/resync/client/http_helper.rb, line 93
def extension_for(response)
  content_type = response['Content-Type']
  mime_type = MIME::Types[content_type].first || MIME::Types['application/octet-stream'].first
  mime_type.preferred_extension || 'bin'
end
make_request(uri, limit) { |response| ... } click to toggle source

Private methods

# File lib/resync/client/http_helper.rb, line 76
def make_request(uri, limit, &block) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
  raise "Redirect limit (#{redirect_limit}) exceeded retrieving URI #{uri}" if limit <= 0
  req = Net::HTTP::Get.new(uri, 'User-Agent' => user_agent)
  Net::HTTP.start(uri.hostname, uri.port, use_ssl: (uri.scheme == 'https')) do |http|
    http.request(req) do |response|
      case response
      when Net::HTTPSuccess
        yield(response)
      when Net::HTTPInformation, Net::HTTPRedirection
        make_request(redirect_uri_for(response, uri), limit - 1, &block)
      else
        raise "Error #{response.code}: #{response.message} retrieving URI #{uri}"
      end
    end
  end
end
redirect_uri_for(response, original_uri) click to toggle source
# File lib/resync/client/http_helper.rb, line 99
def redirect_uri_for(response, original_uri)
  if response.is_a?(Net::HTTPInformation)
    original_uri
  else
    location = response['location']
    new_uri = URI(location)
    new_uri.relative? ? original_uri + location : new_uri
  end
end