Created
December 5, 2015 14:18
-
-
Save sergeych/b3bc51acc3acc08c1318 to your computer and use it in GitHub Desktop.
Easy took to perform http request with pool and keep-alive support
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'net/http' | |
require 'uri' | |
require 'json' | |
require 'hashie' | |
# Simple HTTP access, with embed JSON parsing, pooling and keep-alive support. Especially useful | |
# for API access over https. Requires json support and gem 'hashie'. | |
# | |
# v2 by [email protected] | |
# | |
# Synopsis: | |
# | |
# connection = Httpick.new(url) | |
# connection.get path, [ ,headers: [] ], **params | |
# | |
# also available methods: post, put, patch, delete and head | |
# | |
# For more control see #request | |
# | |
class Httpick | |
@@connections = {} | |
# Create Httpick to acces a given host. Actual http connection will be either | |
# taken from a pool or created (to use keep-alive at its best) | |
def initialize uri | |
uri.is_a?(URI) or uri = URI.parse(uri) | |
@conn = @@connections[uri.host] ||= begin | |
c = Net::HTTP.new(uri.host, uri.port) | |
c.use_ssl = uri.scheme == 'https' | |
c.start | |
end | |
@uri = uri | |
end | |
# Perform a request on the current connection, to use when the method could vary. | |
# | |
# @param [Object] method | |
# @param [Object] path if not set, used uri passed on initialization | |
# @param [Hash] headers | |
# @param [Hash] params | |
# @return [Httpick] instance, so you can chain it like httpick.request().json or like | |
def request method, path: nil, headers: {}, params: {} | |
path = path || @uri.path | |
if method == 'GET' && params.size > 0 | |
path = path + '?' + params.map { |k, v| "#{k}=#{CGI::escape(v.to_s)}" }.join('&') | |
end | |
@req = case method | |
when 'GET' | |
Net::HTTP::Get.new(path) | |
when 'PUT' | |
Net::HTTP::Put.new(path) | |
when 'POST' | |
Net::HTTP::Post.new(path) | |
when 'PATCH' | |
Net::HTTP::Patch.new(path) | |
when 'DELETE' | |
Net::HTTP::Delete.new(path) | |
when 'HEAD' | |
Net::HTTP::Head.new(path) | |
else | |
raise ArgumentError, "unknown http method #{method}" | |
end | |
headers.each { |k, v| | |
@req[k.to_s] = v.to_s | |
} | |
# p [:r, method, @uri.to_s, path, params] | |
if method != 'GET' && params && params.size > 0 | |
@req.set_form_data params | |
end | |
@response = @conn.request @req | |
self | |
end | |
# Perfrom request using connection pool/keep alive as possible | |
# (userful to speed up sequences of https calls) | |
def self.request uri, method: :get, headers: {}, params: {} | |
method = method.to_s.upcase | |
uri.is_a?(String) and uri = URI.parse(uri) | |
h = HttpUtil.new uri | |
h.request method, headers: headers, params: params | |
end | |
# response body | |
def body | |
@response.body | |
end | |
# Parse body that should be JSON | |
# @return [Hashie::Mash] parsed body | |
def json | |
b = @response.body || "{}" | |
Hashie::Mash.new JSON.parse(b) | |
end | |
# Same as #status | |
def code | |
@response.code.to_i | |
end | |
# response status as an integer value | |
def status | |
code | |
end | |
%w[get post put delete patch head].each do |m| | |
Httpick.class_eval <<-End | |
def #{m}(path, headers:{}, **params) | |
request '#{m.upcase}', path: path, headers: headers, params: params | |
end | |
End | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment