Commit d98902a
Changed files (8)
lib
net
test
lib/net/hippie/client.rb
@@ -10,26 +10,24 @@ module Net
'User-Agent' => "net/hippie #{Net::Hippie::VERSION}"
}.freeze
- attr_accessor :mapper, :read_timeout, :open_timeout, :logger
- attr_accessor :follow_redirects
- attr_accessor :certificate, :key, :passphrase
+ attr_reader :mapper, :logger
+ attr_reader :follow_redirects
def initialize(options = {})
- @default_headers = options.fetch(:headers, DEFAULT_HEADERS)
+ @options = options
@mapper = options.fetch(:mapper, ContentTypeMapper.new)
- @read_timeout = options.fetch(:read_timeout, 10)
- @open_timeout = options.fetch(:open_timeout, 10)
- @verify_mode = options.fetch(:verify_mode, Net::Hippie.verify_mode)
@logger = options.fetch(:logger, Net::Hippie.logger)
@follow_redirects = options.fetch(:follow_redirects, 0)
- @certificate = options[:certificate]
- @key = options[:key]
- @passphrase = options[:passphrase]
- @connections = {}
+ @http_connections = Hash.new do |hash, key|
+ uri = URI.parse(key.to_s)
+ build_http_for(uri).tap do |http|
+ hash[key] = http
+ end
+ end
end
def execute(uri, request, limit: follow_redirects, &block)
- http = http_for(uri)
+ http = @http_connections[uri]
response = http.request(request)
if limit.positive? && response.is_a?(Net::HTTPRedirection)
url = build_url_for(http, response['location'])
@@ -80,7 +78,9 @@ module Net
private
- attr_reader :default_headers, :verify_mode
+ def default_headers
+ @options.fetch(:headers, DEFAULT_HEADERS)
+ end
def attempt(attempt, max)
yield
@@ -92,38 +92,33 @@ module Net
sleep delay
end
- def http_for(uri)
- @connections.fetch(uri.to_s) do |key|
- uri = URI.parse(uri.to_s)
- http = Net::HTTP.new(uri.host, uri.port)
- http.read_timeout = read_timeout
- http.open_timeout = open_timeout
- http.use_ssl = uri.scheme == 'https'
- http.verify_mode = verify_mode
- http.set_debug_output(logger)
- apply_client_tls_to(http)
- @connections[key] = http
- http
- end
+ def build_http_for(uri)
+ http = Net::HTTP.new(uri.host, uri.port)
+ http.read_timeout = @options.fetch(:read_timeout, 10)
+ http.open_timeout = @options.fetch(:open_timeout, 10)
+ http.use_ssl = uri.scheme == 'https'
+ http.verify_mode = @options.fetch(:verify_mode, Net::Hippie.verify_mode)
+ http.set_debug_output(logger)
+ apply_client_tls_to(http)
+ http
end
def request_for(type, uri, headers: {}, body: {})
final_headers = default_headers.merge(headers)
- uri = URI.parse(uri.to_s)
- type.new(uri, final_headers).tap do |x|
+ type.new(URI.parse(uri.to_s), final_headers).tap do |x|
x.body = mapper.map_from(final_headers, body) unless body.empty?
end
end
- def private_key(type = OpenSSL::PKey::RSA)
+ def private_key(key, passphrase, type = OpenSSL::PKey::RSA)
passphrase ? type.new(key, passphrase) : type.new(key)
end
def apply_client_tls_to(http)
- return if certificate.nil? || key.nil?
+ return if @options[:certificate].nil? || @options[:key].nil?
- http.cert = OpenSSL::X509::Certificate.new(certificate)
- http.key = private_key
+ http.cert = OpenSSL::X509::Certificate.new(@options[:certificate])
+ http.key = private_key(@options[:key], @options[:passphrase])
end
def run(uri, http_method, headers, body, &block)
lib/net/hippie/content_type_mapper.rb
@@ -5,6 +5,8 @@ module Net
# Converts a ruby hash into a JSON string
class ContentTypeMapper
def map_from(headers, body)
+ return body if body.is_a?(String)
+
content_type = headers['Content-Type'] || ''
return JSON.generate(body) if content_type.include?('json')
lib/net/hippie/version.rb
@@ -2,6 +2,6 @@
module Net
module Hippie
- VERSION = '0.3.2'
+ VERSION = '1.0.0'
end
end
lib/net/hippie.rb
@@ -56,11 +56,15 @@ module Net
def self.method_missing(symbol, *args)
default_client.with_retry(retries: 3) do |client|
client.public_send(symbol, *args)
- end
+ end || super
+ end
+
+ def self.respond_to_missing?(name, _include_private = false)
+ Client.public_instance_methods.include?(name.to_sym)
end
def self.default_client
- @subject ||= Client.new
+ @default_client ||= Client.new(follow_redirects: 3, logger: logger)
end
end
end
test/net/client_test.rb
@@ -6,7 +6,6 @@ class ClientTest < Minitest::Test
def initialize(*args)
super
@subject = Net::Hippie::Client.new
- @subject.logger = ENV['CIBUILD'] ? Logger.new('/dev/null') : Logger.new(STDOUT)
end
def test_get
@@ -27,7 +26,7 @@ class ClientTest < Minitest::Test
https://pypi.org/pypi/pytz/2019.2/json
https://pypi.org/pypi/requests/2.5.3/json
}.each do |url|
- subject.follow_redirects = 3
+ subject = Net::Hippie::Client.new(follow_redirects: 3)
response = subject.get(url)
refute_nil response
assert_equal Net::HTTPOK, response.class
@@ -38,7 +37,7 @@ class ClientTest < Minitest::Test
def test_does_not_follow_redirect
VCR.use_cassette('does_not_follow_redirect') do
- subject.follow_redirects = 0
+ subject = Net::Hippie::Client.new(follow_redirects: 0)
response = subject.get('https://pypi.org/pypi/django/1.11.3/json')
refute_nil response
assert_kind_of Net::HTTPRedirection, response
@@ -48,7 +47,7 @@ class ClientTest < Minitest::Test
def test_does_follow_redirects
VCR.use_cassette('does_follow_redirects') do
- subject.follow_redirects = 10
+ subject = Net::Hippie::Client.new(follow_redirects: 10)
response = subject.get('https://pypi.org/pypi/django/1.11.3/json')
refute_nil response
assert_kind_of Net::HTTPOK, response
@@ -58,7 +57,7 @@ class ClientTest < Minitest::Test
def test_follow_redirects_with_relative_paths
VCR.use_cassette('follow_redirects_with_relative_paths') do
- subject.follow_redirects = 10
+ subject = Net::Hippie::Client.new(follow_redirects: 10)
response = subject.get("http://go.microsoft.com/fwlink/?LinkId=329770")
refute_nil response
assert_kind_of Net::HTTPOK, response
@@ -76,7 +75,7 @@ class ClientTest < Minitest::Test
.then
.to_return(status: 200, body: { success: true }.to_json)
- subject.follow_redirects = n
+ subject = Net::Hippie::Client.new(follow_redirects: n)
response = subject.get(url)
refute_nil response
assert_equal Net::HTTPOK, response.class
@@ -304,10 +303,4 @@ class ClientTest < Minitest::Test
end
assert(@called)
end
-
- def test_open_timeout_setting
- assert_equal subject.open_timeout, 10
- @subject.open_timeout = 5
- assert_equal subject.open_timeout, 5
- end
end
test/test_helper.rb
@@ -7,6 +7,8 @@ require 'securerandom'
require 'vcr'
require 'webmock'
+Net::Hippie.logger = ENV['CIBUILD'] ? Logger.new('/dev/null') : Logger.new(STDERR)
+
VCR.configure do |config|
config.cassette_library_dir = 'test/fixtures'
config.hook_into :webmock
.rubocop.yml
@@ -5,7 +5,7 @@ AllCops:
- 'test/**/*'
- 'tmp/**/*'
- 'vendor/**/*'
- TargetRubyVersion: 2.4
+ TargetRubyVersion: 2.5
Layout/ParameterAlignment:
EnforcedStyle: with_fixed_indentation
net-hippie.gemspec
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
spec.bindir = 'exe'
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ['lib']
- spec.required_ruby_version = '~> 2.4'
+ spec.required_ruby_version = '~> 2.5'
spec.add_development_dependency 'minitest', '~> 5.0'
spec.add_development_dependency 'rake', '~> 13.0'