class Badgify::HttpDecorator

lecklider.com/2016/09/decorating-ruby-s-net-http-for-fun-and-profit.html

Constants

CONTENT_TYPE_FORM
CONTENT_TYPE_JSON

Content-types

OPEN_TIMEOUT

Timeouts

READ_TIMEOUT

Public Class Methods

new(url) click to toggle source

CONTENT_TYPE_MULTIPART = “multipart/form-data; boundary=#{ Rack::Multipart::MULTIPART_BOUNDARY }”

# File lib/badgify/http_decorator.rb, line 21
def initialize(url)
  if Badgify.token.nil?
    raise AuthenticationError.new("No token provided")
  end

  # Build up our HTTP object
  uri = URI(url)
  @http = Net::HTTP.new(uri.hostname, uri.port)
  @http.use_ssl = true if uri.scheme == "https"
  @http.verify_mode = OpenSSL::SSL::VERIFY_NONE if uri.scheme == "https"
  @http.open_timeout = OPEN_TIMEOUT
  @http.read_timeout = READ_TIMEOUT

  # In local development we can log requests and responses to $stdout.
  #   DO NOT EVER do this in production. EVER.
  if ENV['RACK_ENV'] == 'development'
    @http.set_debug_output($stdout)
  end
end

Public Instance Methods

delete(path) click to toggle source

DELETE

# File lib/badgify/http_decorator.rb, line 91
def delete(path)
  request = Net::HTTP::Delete.new(path)

  parse fetch(request)
end
finish() click to toggle source

Clean up the connection if needed.

# File lib/badgify/http_decorator.rb, line 61
def finish
  @http.finish if @http.started?
end
get(path, params = {}) click to toggle source

GET

# File lib/badgify/http_decorator.rb, line 66
def get(path, params = {})
  uri       = URI.parse(path)
  uri.query = URI.encode_www_form(params) unless params.empty?
  request   = Net::HTTP::Get.new(uri.to_s)

  parse fetch(request)
end
multipart(path, params) click to toggle source

POST multipart

# File lib/badgify/http_decorator.rb, line 130
def multipart(path, params)
  request = Net::HTTP::Post.new(path)

  request.content_type = CONTENT_TYPE_MULTIPART
  request.body = Rack::Multipart::Generator.new(
    'file' => Rack::Multipart::UploadedFile.new(params['file'][:tempfile].path, params['file'][:type])
  ).dump

  parse fetch(request)
end
patch(path, params = {}, as: :form) click to toggle source

PATCH

# File lib/badgify/http_decorator.rb, line 98
def patch(path, params = {}, as: :form)
  request = Net::HTTP::Patch.new(path)

  case as
  when :json
    request.content_type = CONTENT_TYPE_JSON
    request.body = JSON.generate(params) unless params.empty?
  else
    request.content_type = CONTENT_TYPE_FORM
    request.body = URI.encode_www_form(params) unless params.empty?
  end

  parse fetch(request)
end
post(path, params = {}, as: :json) click to toggle source

POST

# File lib/badgify/http_decorator.rb, line 75
def post(path, params = {}, as: :json)
  request = Net::HTTP::Post.new(path)

  case as
  when :json
    request.content_type = CONTENT_TYPE_JSON
    request.body = JSON.generate(params) unless params.empty?
  else
    request.content_type = CONTENT_TYPE_FORM
    request.body = URI.encode_www_form(params) unless params.empty?
  end

  parse fetch(request)
end
put(path, params = {}, as: :json) click to toggle source

PUT

# File lib/badgify/http_decorator.rb, line 114
def put(path, params = {}, as: :json)
  request = Net::HTTP::Put.new(path)

  case as
  when :json
    request.content_type = CONTENT_TYPE_JSON
    request.body = JSON.generate(params) unless params.empty?
  else
    request.content_type = CONTENT_TYPE_FORM
    request.body = URI.encode_www_form(params) unless params.empty?
  end

  parse fetch(request)
end
start() { |self| ... } click to toggle source

Open a connection for multiple calls.

  • Accepts a block, otherwise just opens the connection.

  • You'll need to close the connection if you just open it.

# File lib/badgify/http_decorator.rb, line 44
def start
  if block_given?
    # Open the connection.
    @http.start unless @http.started?

    # Yield to the calling block.
    yield(self)

    # Clean up the connection.
    @http.finish if @http.started?
  else
    # Open the connection.
    @http.start unless @http.started?
  end
end

Private Instance Methods

fetch(request) click to toggle source

Perform the request.

# File lib/badgify/http_decorator.rb, line 144
def fetch(request)
  # Shore up default headers for the request.
  request['Accept'] = CONTENT_TYPE_JSON
  request['Connection'] = 'keep-alive'
  request['User-Agent'] =  "Badgify Ruby v#{Badgify::VERSION}"
  request["Authorization"] = "Token token=\"#{Badgify.token}\""

  # Actually make the request.
  response = @http.request(request)

  # Net::HTTPResponse.value will raise an error for non-200 responses.
  #   Simpler than trying to detect every possible exception.
  response.value || response
end
parse(response) click to toggle source
# File lib/badgify/http_decorator.rb, line 159
def parse(response)
  # Parse the response as JSON if possible.
  if response.content_type == CONTENT_TYPE_JSON
    JSON.parse(response.body)

  # Otherwise just return the response body.
  else
    response.body
  end
end