Skip to content

Instantly share code, notes, and snippets.

@myobie
Last active November 12, 2018 05:15
Show Gist options
  • Save myobie/eb677383ec84357bcd2c to your computer and use it in GitHub Desktop.
Save myobie/eb677383ec84357bcd2c to your computer and use it in GitHub Desktop.
Request / Response for easier Net::HTTP usage in ruby
require 'net/http'
require 'json'
require_relative 'response'
class Request
AlreadyComplete = Class.new(StandardError)
VERBS = {
head: Net::HTTP::Head,
get: Net::HTTP::Get,
post: Net::HTTP::Post,
put: Net::HTTP::Put,
patch: Net::HTTP::Patch,
delete: Net::HTTP::Delete
}.freeze
BODIES = [:post, :put, :patch].freeze
attr_reader :token, :verb, :body, :headers, :original_response, :response, :uri
def initialize(token: nil, uri:, verb:, body: nil, headers: {})
@state = :pending
@token = token
@uri = uri
@verb = verb
@body = body
@headers = headers
end
def complete?
@state == :complete
end
def to_curl
o = "curl"
o << " -H 'Authorization: #{token}'" if token
o << " -H 'Accept: application/json'"
headers.each do |k, v|
o << " -H '#{k}: #{v}'"
end
if BODIES.include?(verb)
o << " -H 'Content-type: application/json'"
o << " -d '#{body}'"
end
o << " '#{uri}'"
end
private def make_request
Net::HTTP.start(uri.host, uri.port, use_ssl: (uri.scheme == 'https')) do |http|
request = VERBS[verb].new uri
request["Authorization"] = token if token
request["Accept"] = "application/json"
headers.each do |k, v|
request[k] = v
end
if BODIES.include?(verb) && body
request["Content-type"] = "application/json"
request.body = if String === body then body else JSON.generate(body) end
end
@original_response = http.request request
end
@response = Response.new({
request: self,
code: original_response.code,
body: original_response.body,
headers: original_response.to_hash
}).freeze
rescue => e
@original_response = nil
response_body = JSON.generate({
type: "exception",
exception: {
message: e.message,
backtrace: e.backtrace
}
})
response_code = if Errno::ETIMEDOUT === e then "504" else "599" end
@response = Response.new({
request: self,
code: response_code,
body: response_body,
headers: {}
})
end
def call
fail AlreadyComplete if @state == :complete
make_request
@state = :complete
end
end
class Response
attr_reader :request, :code, :body, :headers
def initialize(request: nil, code:, body: nil, headers: {})
@request = request
@code = code
@body = body
@headers = headers
end
def status
code.to_i
end
def parsed_body
unless body.nil? || body.empty?
@parsed_body ||= JSON.parse(body)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment