net-hippie 0.3.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b39c735df32d765a6146802cfed8d0dc6cf6140363b55b84b08d6b691b9613fa
4
- data.tar.gz: cc061070fc681973b97833836867d489cabb1db950d29e9561a9bdac8c566a1e
3
+ metadata.gz: ca969a22c79466a3c517f262f6a7c72137a62304b358b2f1caeec7849e222357
4
+ data.tar.gz: e9faffeec00a494e39f795d5ab3d32c7f58e9027e3ec79106256ae2b7b70d6f0
5
5
  SHA512:
6
- metadata.gz: dedf2965ae930705d3e3a4cc5aacd29bb5210d17097c4699660ad2bb3562cbd4d9cba70450a6fd3646741ae0c55a6bc49ce0fa26e799193294bda05ba29d6ccf
7
- data.tar.gz: df77476f60696ab864520b689dde126289fc3b9aa9df94bf5e816aa6cb479dff1cdcc33673d3be78a4391685c72d7fa465b261aa712e4b1f84220f1f25b715e9
6
+ metadata.gz: 035f5e34f31997473705d0556ee16e3e038c004fff44065c7ac86c1ffa2abd659cf0eb7ef1ff44baf51f31c7113e623621d627fd5fbccc478616585a10b59aa0
7
+ data.tar.gz: f86f16b3fa730239cf81683a1087a275633b88cee991358e7ad282db965b18f9293fc4bf8de6c991dee7ad2921de5413bcbcd6abdb178a42d2f77c2da523fcc1
@@ -5,11 +5,13 @@ on: [push, pull_request]
5
5
  jobs:
6
6
  test:
7
7
  runs-on: ubuntu-latest
8
+ strategy:
9
+ matrix:
10
+ ruby: [ '2.5', '2.6', '2.7' ]
8
11
  steps:
9
12
  - uses: actions/checkout@v1
10
- - name: Set up Ruby
11
- uses: actions/setup-ruby@v1
13
+ - uses: actions/setup-ruby@v1
12
14
  with:
13
- version: 2.7.x
14
- - name: Build and test
15
+ ruby-version: ${{ matrix.ruby }}
16
+ - name: cibuild
15
17
  run: bin/cibuild
@@ -5,7 +5,8 @@ AllCops:
5
5
  - 'test/**/*'
6
6
  - 'tmp/**/*'
7
7
  - 'vendor/**/*'
8
- TargetRubyVersion: 2.4
8
+ NewCops: enable
9
+ TargetRubyVersion: 2.5
9
10
 
10
11
  Layout/ParameterAlignment:
11
12
  EnforcedStyle: with_fixed_indentation
@@ -1,4 +1,4 @@
1
- Version 0.3.2
1
+ Version 1.0.0
2
2
 
3
3
  # Changelog
4
4
  All notable changes to this project will be documented in this file.
@@ -7,7 +7,22 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
7
7
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
8
8
 
9
9
  ## [Unreleased]
10
- - nil
10
+
11
+ ## [1.0.0] - 2020-07-31
12
+ ### Added
13
+ - Add simpler API to remove the need to instantiate a `Client` directly.
14
+ - Default to 3 retries using simple API.
15
+ - Re-use client connection for connections to the same scheme, host, and port.
16
+
17
+ ### Removed
18
+ - Remove support for Ruby 2.4
19
+ - Remove legacy `Api` class.
20
+
21
+ ### Changed
22
+ - Limit mutable options on Client.
23
+ - Change default `read_timeout` to 10 seconds.
24
+ - Change default `open_timeout` to 10 seconds.
25
+ - Log to `STDERR` by default instead of `STDOUT`.
11
26
 
12
27
  ## [0.3.2] - 2020-01-28
13
28
  ### Fixed
@@ -54,7 +69,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
54
69
  - with\_retry.https://www.mokhan.ca/%F0%9F%92%8E/2018/11/10/net-hippie-0-2-0.html
55
70
  - authorization header helpers
56
71
 
57
- [Unreleased]: https://github.com/mokhan/net-hippie/compare/v0.3.2...HEAD
72
+ [Unreleased]: https://github.com/mokhan/net-hippie/compare/v1.0.0...HEAD
73
+ [1.0.0]: https://github.com/mokhan/net-hippie/compare/v0.3.2...v1.0.0
58
74
  [0.3.2]: https://github.com/mokhan/net-hippie/compare/v0.3.1...v0.3.2
59
75
  [0.3.1]: https://github.com/mokhan/net-hippie/compare/v0.3.0...v0.3.1
60
76
  [0.3.0]: https://github.com/mokhan/net-hippie/compare/v0.2.7...v0.3.0
data/Gemfile CHANGED
@@ -2,7 +2,5 @@
2
2
 
3
3
  source 'https://rubygems.org'
4
4
 
5
- git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
-
7
5
  # Specify your gem's dependencies in net-hippie.gemspec
8
6
  gemspec
data/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # Net::Hippie
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/net-hippie.svg)](https://rubygems.org/gems/net-hippie)
4
- [![Build Status](https://travis-ci.org/mokhan/net-hippie.svg?branch=master)](https://travis-ci.org/mokhan/net-hippie)
4
+ [![Build Status](https://github.com/mokhan/net-hippie/workflows/Test/badge.svg)](https://github.com/mokhan/net-hippie/actions)
5
5
 
6
- Net::Hippie is a light weight wrapper around `net/http` that defaults to
7
- sending JSON messages.
6
+ `Net::Hippie` is a light weight wrapper around `net/http` that defaults to
7
+ sending `JSON` messages.
8
8
 
9
9
  ## Installation
10
10
 
@@ -27,23 +27,22 @@ Or install it yourself as:
27
27
  ```ruby
28
28
  require 'net/hippie'
29
29
 
30
- Net::Hippie.logger = Rails.logger
31
-
32
- client = Net::Hippie::Client.new
30
+ Net::Hippie.logger = Logger.new(STDERR)
33
31
 
34
32
  headers = {
35
33
  'Accept' => 'application/vnd.haveibeenpwned.v2+json'
36
34
  }
37
35
 
38
- uri = URI.parse('https://haveibeenpwned.com/api/breaches')
39
- response = client.get(uri, headers: headers)
36
+ uri = 'https://haveibeenpwned.com/api/breaches'
37
+ response = Net::Hippie.get(uri, headers: headers)
40
38
  puts JSON.parse(response.body)
41
39
  ```
42
40
 
43
41
  ```ruby
44
- client = Net::Hippie::Client.new
45
- body = { user: { name: 'hippie' } }
46
- response = client.post(URI.parse('https://example.org'), body: body)
42
+ response = Net::Hippie.post(
43
+ 'https://example.org',
44
+ body: { name: 'hippie' }
45
+ )
47
46
  puts JSON.parse(response.body)
48
47
  ```
49
48
 
@@ -69,24 +68,30 @@ client = Net::Hippie::Client.new(
69
68
  ### Basic Auth
70
69
 
71
70
  ```ruby
72
- client = Net::Hippie::Client.new
73
- headers = { 'Authorization' => Net::Hippie.basic_auth('username', 'password') }
74
- client.get('https://www.example.org', headers: headers)
71
+ Net::Hippie.get(
72
+ 'https://www.example.org',
73
+ headers: {
74
+ 'Authorization' => Net::Hippie.basic_auth('username', 'password')
75
+ }
76
+ )
75
77
  ```
76
78
 
77
79
  ### Bearer Auth
78
80
 
79
81
  ```ruby
80
- client = Net::Hippie::Client.new
81
82
  headers = { 'Authorization' => Net::Hippie.bearer_auth('token') }
82
- client.get('https://www.example.org', headers: headers)
83
+ Net::Hippie.get('https://www.example.org', headers: headers)
83
84
  ```
84
85
 
85
86
  ## Development
86
87
 
87
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
88
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/test` to run the tests.
89
+ You can also run `bin/console` for an interactive prompt that will allow you to experiment.
88
90
 
89
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
91
+ To install this gem onto your local machine, run `bundle exec rake install`.
92
+ To release a new version, update the version number in `version.rb`,
93
+ and then run `bin/shipit`, which will create a git tag for the version,
94
+ push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
90
95
 
91
96
  ## Contributing
92
97
 
data/Rakefile CHANGED
@@ -6,7 +6,7 @@ require 'rubocop/rake_task'
6
6
 
7
7
  Rake::TestTask.new(:test) do |t|
8
8
  t.libs << 'test'
9
- t.libs << 'lib'
9
+ t.verbose = true
10
10
  t.test_files = FileList['test/**/*_test.rb']
11
11
  end
12
12
  RuboCop::RakeTask.new(:rubocop)
@@ -1,15 +1,10 @@
1
1
  #!/bin/sh
2
2
 
3
- # script/cibuild: Setup environment for CI to run tests. This is primarily
4
- # designed to run on the continuous integration server.
5
-
6
3
  set -e
4
+ [ -z "$DEBUG" ] || set -x
7
5
 
8
6
  cd "$(dirname "$0")/.."
9
7
 
10
- echo [$(date "+%H:%M:%S")] "==> Started at…"
11
-
12
- # GC customizations
13
8
  export RUBY_GC_MALLOC_LIMIT=79000000
14
9
  export RUBY_GC_HEAP_INIT_SLOTS=800000
15
10
  export RUBY_HEAP_FREE_MIN=100000
@@ -17,7 +12,11 @@ export RUBY_HEAP_SLOTS_INCREMENT=400000
17
12
  export RUBY_HEAP_SLOTS_GROWTH_FACTOR=1
18
13
  export CIBUILD=1
19
14
 
20
- ruby -v
21
- gem install bundler:2.0.1 --conservative
15
+ echo "[$(date "+%H:%M:%S")] ==> Running setup…"
16
+ bin/setup
17
+
18
+ echo "[$(date "+%H:%M:%S")] ==> Running tests…"
22
19
  bin/test
20
+
21
+ echo "[$(date "+%H:%M:%S")] ==> Running linters…"
23
22
  bin/lint
data/bin/lint CHANGED
@@ -2,7 +2,4 @@
2
2
 
3
3
  set -e
4
4
 
5
- [ -z "$DEBUG" ] || set -x
6
-
7
- echo [$(date "+%H:%M:%S")] "==> Running linters…"
8
5
  bundle exec rake lint
data/bin/setup CHANGED
@@ -1,8 +1,7 @@
1
1
  #!/usr/bin/env bash
2
2
  set -euo pipefail
3
3
  IFS=$'\n\t'
4
- set -vx
5
4
 
5
+ ruby -v
6
+ gem install bundler -v '~> 2.0'
6
7
  bundle install
7
-
8
- # Do any other automated setup that you need to do here
data/bin/test CHANGED
@@ -1,17 +1,7 @@
1
1
  #!/bin/sh
2
2
 
3
- # script/test: Run test suite for application. Optionally pass in a path to an
4
- # individual test file to run a single test.
5
-
6
-
7
3
  set -e
8
4
 
9
5
  cd "$(dirname "$0")/.."
10
6
 
11
- [ -z "$DEBUG" ] || set -x
12
-
13
- echo [$(date "+%H:%M:%S")] "==> Running setup…"
14
- bin/setup
15
-
16
- echo [$(date "+%H:%M:%S")] "==> Running tests…"
17
7
  bundle exec rake test
@@ -6,10 +6,10 @@ require 'logger'
6
6
  require 'net/http'
7
7
  require 'openssl'
8
8
 
9
- require 'net/hippie/version'
10
- require 'net/hippie/content_type_mapper'
11
9
  require 'net/hippie/client'
12
- require 'net/hippie/api'
10
+ require 'net/hippie/connection'
11
+ require 'net/hippie/content_type_mapper'
12
+ require 'net/hippie/version'
13
13
 
14
14
  module Net
15
15
  # net/http for hippies.
@@ -31,7 +31,7 @@ module Net
31
31
  ].freeze
32
32
 
33
33
  def self.logger
34
- @logger ||= Logger.new(STDOUT)
34
+ @logger ||= Logger.new(STDERR)
35
35
  end
36
36
 
37
37
  def self.logger=(logger)
@@ -53,5 +53,19 @@ module Net
53
53
  def self.bearer_auth(token)
54
54
  "Bearer #{token}"
55
55
  end
56
+
57
+ def self.method_missing(symbol, *args)
58
+ default_client.with_retry(retries: 3) do |client|
59
+ client.public_send(symbol, *args)
60
+ end || super
61
+ end
62
+
63
+ def self.respond_to_missing?(name, _include_private = false)
64
+ Client.public_instance_methods.include?(name.to_sym)
65
+ end
66
+
67
+ def self.default_client
68
+ @default_client ||= Client.new(follow_redirects: 3, logger: logger)
69
+ end
56
70
  end
57
71
  end
@@ -10,27 +10,25 @@ module Net
10
10
  'User-Agent' => "net/hippie #{Net::Hippie::VERSION}"
11
11
  }.freeze
12
12
 
13
- attr_accessor :mapper, :read_timeout, :open_timeout, :logger
14
- attr_accessor :follow_redirects
15
-
16
- def initialize(certificate: nil, headers: DEFAULT_HEADERS,
17
- key: nil, passphrase: nil, verify_mode: Net::Hippie.verify_mode)
18
- @certificate = certificate
19
- @default_headers = headers
20
- @key = key
21
- @mapper = ContentTypeMapper.new
22
- @passphrase = passphrase
23
- @read_timeout = 30
24
- @verify_mode = verify_mode
25
- @logger = Net::Hippie.logger
26
- @follow_redirects = 0
13
+ attr_reader :mapper, :logger, :follow_redirects
14
+
15
+ def initialize(options = {})
16
+ @options = options
17
+ @mapper = options.fetch(:mapper, ContentTypeMapper.new)
18
+ @logger = options.fetch(:logger, Net::Hippie.logger)
19
+ @follow_redirects = options.fetch(:follow_redirects, 0)
20
+ @default_headers = options.fetch(:headers, DEFAULT_HEADERS)
21
+ @connections = Hash.new do |hash, key|
22
+ scheme, host, port = key
23
+ hash[key] = Connection.new(scheme, host, port, options)
24
+ end
27
25
  end
28
26
 
29
27
  def execute(uri, request, limit: follow_redirects, &block)
30
- http = http_for(uri)
31
- response = http.request(request)
28
+ connection = connection_for(uri)
29
+ response = connection.run(request)
32
30
  if limit.positive? && response.is_a?(Net::HTTPRedirection)
33
- url = build_url_for(http, response['location'])
31
+ url = connection.build_url_for(response['location'])
34
32
  request = request_for(Net::HTTP::Get, url)
35
33
  execute(url, request, limit: limit - 1, &block)
36
34
  else
@@ -78,8 +76,7 @@ module Net
78
76
 
79
77
  private
80
78
 
81
- attr_reader :default_headers, :verify_mode
82
- attr_reader :certificate, :key, :passphrase
79
+ attr_reader :default_headers
83
80
 
84
81
  def attempt(attempt, max)
85
82
  yield
@@ -91,46 +88,21 @@ module Net
91
88
  sleep delay
92
89
  end
93
90
 
94
- def http_for(uri)
95
- uri = URI.parse(uri.to_s)
96
- http = Net::HTTP.new(uri.host, uri.port)
97
- http.read_timeout = read_timeout
98
- http.open_timeout = open_timeout if open_timeout
99
- http.use_ssl = uri.scheme == 'https'
100
- http.verify_mode = verify_mode
101
- http.set_debug_output(logger)
102
- apply_client_tls_to(http)
103
- http
104
- end
105
-
106
91
  def request_for(type, uri, headers: {}, body: {})
107
92
  final_headers = default_headers.merge(headers)
108
- uri = URI.parse(uri.to_s)
109
- type.new(uri, final_headers).tap do |x|
93
+ type.new(URI.parse(uri.to_s), final_headers).tap do |x|
110
94
  x.body = mapper.map_from(final_headers, body) unless body.empty?
111
95
  end
112
96
  end
113
97
 
114
- def private_key(type = OpenSSL::PKey::RSA)
115
- passphrase ? type.new(key, passphrase) : type.new(key)
116
- end
117
-
118
- def apply_client_tls_to(http)
119
- return if certificate.nil? || key.nil?
120
-
121
- http.cert = OpenSSL::X509::Certificate.new(certificate)
122
- http.key = private_key
123
- end
124
-
125
98
  def run(uri, http_method, headers, body, &block)
126
99
  request = request_for(http_method, uri, headers: headers, body: body)
127
100
  execute(uri, request, &block)
128
101
  end
129
102
 
130
- def build_url_for(http, path)
131
- return path if path.start_with?('http')
132
-
133
- "#{http.use_ssl? ? 'https' : 'http'}://#{http.address}#{path}"
103
+ def connection_for(uri)
104
+ uri = URI.parse(uri.to_s)
105
+ @connections[[uri.scheme, uri.host, uri.port]]
134
106
  end
135
107
  end
136
108
  end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Net
4
+ module Hippie
5
+ # A connection to a specific host
6
+ class Connection
7
+ def initialize(scheme, host, port, options = {})
8
+ http = Net::HTTP.new(host, port)
9
+ http.read_timeout = options.fetch(:read_timeout, 10)
10
+ http.open_timeout = options.fetch(:open_timeout, 10)
11
+ http.use_ssl = scheme == 'https'
12
+ http.verify_mode = options.fetch(:verify_mode, Net::Hippie.verify_mode)
13
+ http.set_debug_output(options.fetch(:logger, Net::Hippie.logger))
14
+ apply_client_tls_to(http, options)
15
+ @http = http
16
+ end
17
+
18
+ def run(request)
19
+ @http.request(request)
20
+ end
21
+
22
+ def build_url_for(path)
23
+ return path if path.start_with?('http')
24
+
25
+ "#{@http.use_ssl? ? 'https' : 'http'}://#{@http.address}#{path}"
26
+ end
27
+
28
+ private
29
+
30
+ def apply_client_tls_to(http, options)
31
+ return if options[:certificate].nil? || options[:key].nil?
32
+
33
+ http.cert = OpenSSL::X509::Certificate.new(options[:certificate])
34
+ http.key = private_key(options[:key], options[:passphrase])
35
+ end
36
+
37
+ def private_key(key, passphrase, type = OpenSSL::PKey::RSA)
38
+ passphrase ? type.new(key, passphrase) : type.new(key)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -5,6 +5,8 @@ module Net
5
5
  # Converts a ruby hash into a JSON string
6
6
  class ContentTypeMapper
7
7
  def map_from(headers, body)
8
+ return body if body.is_a?(String)
9
+
8
10
  content_type = headers['Content-Type'] || ''
9
11
  return JSON.generate(body) if content_type.include?('json')
10
12
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Net
4
4
  module Hippie
5
- VERSION = '0.3.2'
5
+ VERSION = '1.0.0'
6
6
  end
7
7
  end
@@ -21,11 +21,11 @@ Gem::Specification.new do |spec|
21
21
  spec.bindir = 'exe'
22
22
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
23
  spec.require_paths = ['lib']
24
- spec.required_ruby_version = '~> 2.4'
24
+ spec.required_ruby_version = '~> 2.5'
25
25
 
26
26
  spec.add_development_dependency 'minitest', '~> 5.0'
27
27
  spec.add_development_dependency 'rake', '~> 13.0'
28
28
  spec.add_development_dependency 'rubocop', '~> 0.55'
29
- spec.add_development_dependency 'vcr', '~> 4.0'
29
+ spec.add_development_dependency 'vcr', '~> 6.0'
30
30
  spec.add_development_dependency 'webmock', '~> 3.4'
31
31
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: net-hippie
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - mo
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-01-28 00:00:00.000000000 Z
11
+ date: 2020-08-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '4.0'
61
+ version: '6.0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '4.0'
68
+ version: '6.0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: webmock
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -92,7 +92,6 @@ files:
92
92
  - ".gitignore"
93
93
  - ".gitlab-ci.yml"
94
94
  - ".rubocop.yml"
95
- - ".travis.yml"
96
95
  - CHANGELOG.md
97
96
  - Gemfile
98
97
  - LICENSE.txt
@@ -106,8 +105,8 @@ files:
106
105
  - bin/test
107
106
  - exe/net-hippie
108
107
  - lib/net/hippie.rb
109
- - lib/net/hippie/api.rb
110
108
  - lib/net/hippie/client.rb
109
+ - lib/net/hippie/connection.rb
111
110
  - lib/net/hippie/content_type_mapper.rb
112
111
  - lib/net/hippie/version.rb
113
112
  - net-hippie.gemspec
@@ -123,14 +122,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
123
122
  requirements:
124
123
  - - "~>"
125
124
  - !ruby/object:Gem::Version
126
- version: '2.4'
125
+ version: '2.5'
127
126
  required_rubygems_version: !ruby/object:Gem::Requirement
128
127
  requirements:
129
128
  - - ">="
130
129
  - !ruby/object:Gem::Version
131
130
  version: '0'
132
131
  requirements: []
133
- rubygems_version: 3.1.2
132
+ rubygems_version: 3.1.4
134
133
  signing_key:
135
134
  specification_version: 4
136
135
  summary: net/http for hippies. ☮️
@@ -1,9 +0,0 @@
1
- sudo: false
2
- language: ruby
3
- rvm:
4
- - 2.4.9
5
- - 2.5.7
6
- - 2.6.5
7
- - 2.7.0
8
- script:
9
- - bin/cibuild
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Net
4
- module Hippie
5
- # A no nonsense class to perform HTTP requests.
6
- class Api
7
- attr_reader :uri, :verify_mode
8
-
9
- def initialize(url, verify_none: false)
10
- @uri = URI.parse(url)
11
- @verify_mode = OpenSSL::SSL::VERIFY_NONE if verify_none
12
- end
13
-
14
- def get
15
- client.get(uri).body
16
- end
17
-
18
- def execute(request)
19
- client.execute(uri, request)
20
- end
21
-
22
- private
23
-
24
- def client
25
- @client ||= Client.new(headers: {}, verify_mode: verify_mode)
26
- end
27
- end
28
- end
29
- end