simple-http 0.3.2 → 0.3.3

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: c7bdabbc5ad9589138ddf4724fb952870d18da4f4f96d957fdc51a145d86adaf
4
- data.tar.gz: 6a4842332bc30e54c0271cb70177efc5d6283197230eaf1e0c382f1528835574
3
+ metadata.gz: b513811215ed8543923236fd40336bd3989771cc85f7da2a2d6ecfff869c7bd4
4
+ data.tar.gz: 0a0718c191e4102a8a06162e92d295dcd519aaeb22fbb4997ee45a8b3a4e7a26
5
5
  SHA512:
6
- metadata.gz: e8844fa1eb87462695fc7a82329e18055fa2bdf3ecf0dc251872fdec5c640fda6a532e86e82ca1048d5e78a5f7993769d4494ceca7973e51f310dd9cfac794c5
7
- data.tar.gz: c37bedd490d573c8da46484d990ccb197dead457c00569e0b87eaa374f6cf36b39ef80941b5069406f8ab88dde2a74abd14ba12b168512019a30a27c052ac33c
6
+ metadata.gz: 2b304ffa55e45fdcc8c5c68b52d379dae57d38d07404c817a04de80409c0e161c75c6c94dff0cdbad81506ffee3e61e0569b33d1e20fd8fba77880e420694650
7
+ data.tar.gz: 429e91c1b979b1750cf4896b2ebf2a13cf072bb4e0418268573615273dd1a5785ef5eb6f9927851d55531eb41703d748d57fe9a8c59533c750e463147d486848
data/lib/simple-http.rb CHANGED
@@ -1 +1,2 @@
1
+ # rubocop:disable Naming/FileName
1
2
  require "simple/http"
data/lib/simple/http.rb CHANGED
@@ -2,21 +2,23 @@
2
2
  # Copyright:: Copyright (c) 2011-2015 radiospiel
3
3
  # License:: Distributes under the terms of the Modified BSD License, see LICENSE.BSD for details.
4
4
 
5
- require "net/http"
5
+ # rubocop:disable Metrics/ClassLength
6
+
6
7
  require "json"
7
- require "logger"
8
+ require "expectation"
8
9
 
9
10
  module Simple; end
10
11
  class Simple::HTTP; end
11
12
 
12
13
  require_relative "http/version"
14
+ require_relative "http/helpers"
13
15
  require_relative "http/caching"
14
16
  require_relative "http/errors"
17
+ require_relative "http/logger"
15
18
  require_relative "http/headers"
16
19
  require_relative "http/request"
17
20
  require_relative "http/response"
18
-
19
- require "openssl"
21
+ require_relative "http/checked_response"
20
22
 
21
23
  #
22
24
  # A very simple, Net::HTTP-based HTTP client.
@@ -25,10 +27,6 @@ require "openssl"
25
27
  # requests are jsonized, and all data in responses are parsed as JSON if
26
28
  # the Content-Type header is set to "application/json".
27
29
  class Simple::HTTP
28
- #
29
- # The logger instance.
30
- attr_accessor :logger
31
-
32
30
  #
33
31
  # The base URL when set, all requests that do not start with http: or
34
32
  # https: are done relative to this base URL.
@@ -40,44 +38,67 @@ class Simple::HTTP
40
38
  # error - which is probably only useful when testing an interface.
41
39
  attr_accessor :follows_redirections
42
40
 
41
+ #
42
+ # Always send these headers.
43
+ attr_reader :default_headers
44
+
45
+ def default_headers=(default_headers)
46
+ expect! default_params => [Hash, nil]
47
+ @default_headers = default_headers
48
+ end
49
+
43
50
  #
44
51
  # When set, appends this to all request URLs
45
- attr_accessor :default_params
52
+ attr_reader :default_params
53
+
54
+ def default_params=(default_params)
55
+ expect! default_params => [Hash, String, nil]
56
+ @default_params = default_params
57
+ end
46
58
 
47
59
  #
48
60
  # When set, sets Authorization headers to all requests. Must be an
49
61
  # array [ username, password ].
50
62
  attr_accessor :basic_auth
51
63
 
52
- def initialize
64
+ def initialize(base_url: nil)
65
+ self.default_headers = {}
66
+ self.default_params = nil
67
+ self.base_url = base_url
53
68
  self.follows_redirections = true
54
- self.logger = Logger.new(STDERR, level: :warn)
55
69
  end
56
70
 
57
71
  def head(url, headers = {})
58
- perform_request! :HEAD, url, nil, headers
72
+ perform_request!(:HEAD, url, nil, headers)
73
+ end
74
+
75
+ def head!(url, headers = {})
76
+ perform_request!(:HEAD, url, nil, headers)
59
77
  end
60
78
 
61
79
  def get(url, headers = {})
62
- perform_request! :GET, url, nil, headers
80
+ perform_request!(:GET, url, nil, headers)
63
81
  end
64
82
 
65
83
  def options(url, headers = {})
66
- perform_request! :OPTIONS, url, nil, headers
84
+ perform_request!(:OPTIONS, url, nil, headers)
67
85
  end
68
86
 
69
87
  def post(url, body = nil, headers = {})
70
- perform_request! :POST, url, body, headers
88
+ perform_request!(:POST, url, body, headers)
71
89
  end
72
90
 
73
91
  def put(url, body = nil, headers = {})
74
- perform_request! :PUT, url, body, headers
92
+ perform_request!(:PUT, url, body, headers)
75
93
  end
76
94
 
77
95
  def delete(url, headers = {})
78
- perform_request! :DELETE, url, nil, headers
96
+ perform_request!(:DELETE, url, nil, headers)
79
97
  end
80
98
 
99
+ # adds get!, post!; etc.
100
+ include CheckedResponse
101
+
81
102
  #
82
103
  # -- Caching ----------------------------------------------------------------
83
104
 
@@ -94,18 +115,18 @@ class Simple::HTTP
94
115
  url = File.join(base_url, url)
95
116
  end
96
117
 
97
- uri = URI.parse(url)
98
- unless uri.is_a?(URI::HTTP)
99
- raise ArgumentError, "Invalid URL: #{url}"
118
+ expect! url => /^http|https/
119
+
120
+ if default_headers
121
+ headers = headers.merge(default_headers)
100
122
  end
101
123
 
102
- # append default_params, if set
103
- if default_params
104
- url.concat(url.include?("?") ? "&" : "?")
105
- url.concat default_params
124
+ case default_params
125
+ when Hash then url = ::Simple::HTTP.build_url(url, default_params)
126
+ when String then url = url + (url.include?("?") ? "&" : "?") + default_params
106
127
  end
107
128
 
108
- request = Request.new(verb: verb, url: url, body: body, headers: headers)
129
+ request = Request.build(verb: verb, url: url, body: body, headers: headers)
109
130
 
110
131
  execute_request(request)
111
132
  end
@@ -120,7 +141,7 @@ class Simple::HTTP
120
141
 
121
142
  raise ::Simple::HTTP::TooManyRedirections, response if max_redirections <= 0
122
143
 
123
- request = ::Simple::HTTP::Request.new(verb: :GET, url: response.headers["Location"], headers: {})
144
+ request = ::Simple::HTTP::Request.build(verb: :GET, url: response.headers["Location"], headers: {})
124
145
  execute_request(request, max_redirections: max_redirections - 1)
125
146
  end
126
147
 
@@ -144,18 +165,54 @@ class Simple::HTTP
144
165
  def execute_request_w_logging(request)
145
166
  started_at = Time.now
146
167
 
147
- response = driver.execute_request(request, client: self)
148
- response.send(:set_request, request)
168
+ Simple::HTTP.logger.debug do
169
+ "> #{request}, w/headers #{request.headers}"
170
+ end
171
+
172
+ response_hsh = driver.execute_request(request, client: self)
173
+
174
+ status, message, headers, body = response_hsh.values_at :status, :message, :headers, :body
175
+
176
+ response = ::Simple::HTTP::Response.build request: request,
177
+ status: status,
178
+ message: message,
179
+ body: body,
180
+ headers: headers
149
181
 
150
- logger.info do
151
- "#{request}: #{response}, #{"%.3f secs" % (Time.now - started_at)}"
182
+ ::Simple::HTTP.logger.info do
183
+ # FIXME: for some reason the status message might contain a trailing space?
184
+ message = response.message.gsub(/ $/, "")
185
+ "#{request} #{response.status} #{"%.3f" % (Time.now - started_at)} secs: #{message}"
152
186
  end
153
187
 
154
188
  response
155
189
  end
156
190
 
191
+ def determine_driver
192
+ "default"
193
+
194
+ # require "faraday"
195
+ # "faraday"
196
+ # rescue LoadError
197
+ # "default"
198
+ end
199
+
157
200
  def driver
158
- require "simple/http/driver/default"
159
- ::Simple::HTTP::Driver::Default
201
+ @driver ||= begin
202
+ driver_name = determine_driver
203
+ Simple::HTTP.logger.debug "simple-http: Using #{driver_name} driver"
204
+ driver_name
205
+ end
206
+
207
+ case @driver
208
+ when "faraday"
209
+ require "simple/http/driver/faraday"
210
+ ::Simple::HTTP::Driver::Faraday
211
+ when "default"
212
+ require "simple/http/driver/default"
213
+ ::Simple::HTTP::Driver::Default
214
+ else
215
+ raise "Internal error"
216
+ end
160
217
  end
161
218
  end
@@ -0,0 +1,28 @@
1
+ module Simple::HTTP::CheckedResponse
2
+ SELF = self
3
+
4
+ def get!(url, headers = {}, into: nil)
5
+ response = perform_request!(:GET, url, nil, headers)
6
+ response.checked_content(into: into)
7
+ end
8
+
9
+ def options!(url, headers = {}, into: nil)
10
+ response = perform_request!(:OPTIONS, url, nil, headers)
11
+ response.checked_content(into: into)
12
+ end
13
+
14
+ def post!(url, body = nil, headers = {}, into: nil)
15
+ response = perform_request!(:POST, url, body, headers)
16
+ response.checked_content(into: into)
17
+ end
18
+
19
+ def put!(url, body = nil, headers = {}, into: nil)
20
+ response = perform_request!(:PUT, url, body, headers)
21
+ response.checked_content(into: into)
22
+ end
23
+
24
+ def delete!(url, headers = {}, into: nil)
25
+ response = perform_request!(:DELETE, url, nil, headers)
26
+ response.checked_content(into: into)
27
+ end
28
+ end
@@ -1,4 +1,7 @@
1
- # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
1
+ # rubocop:disable Metrics/AbcSize
2
+
3
+ require "net/http"
4
+ require "openssl"
2
5
 
3
6
  module Simple::HTTP::Driver
4
7
  end
@@ -6,9 +9,7 @@ end
6
9
  module Simple::HTTP::Driver::Default
7
10
  extend self
8
11
 
9
- #
10
- # do a HTTP request, return its response or, when not successful,
11
- # raise an error.
12
+ # does an HTTP request and returns its response.
12
13
  def execute_request(request, client:)
13
14
  verb, url, body, headers =
14
15
  request.verb, request.url, request.body, request.headers
@@ -20,12 +21,14 @@ module Simple::HTTP::Driver::Default
20
21
 
21
22
  # execute request
22
23
  net_http = load_net_http(uri.scheme, uri.host, uri.port)
23
- resp = net_http.request(net_request)
24
+ response = net_http.request(net_request)
24
25
 
25
- ::Simple::HTTP::Response.new status: Integer(resp.code),
26
- message: resp.message,
27
- headers: Simple::HTTP::Headers.new(resp),
28
- body: resp.body
26
+ {
27
+ status: Integer(response.code),
28
+ message: response.message,
29
+ headers: Simple::HTTP::Headers.new(response),
30
+ body: response.body
31
+ }
29
32
  end
30
33
 
31
34
  private
@@ -39,10 +42,11 @@ module Simple::HTTP::Driver::Default
39
42
  :PUT => Net::HTTP::Put,
40
43
  :DELETE => Net::HTTP::Delete
41
44
  }.freeze #:nodoc:
45
+ # rubocop:enable Style/HashSyntax, Layout/AlignHash
42
46
 
43
47
  #
44
48
  # build a HTTP request object.
45
- def build_request(method, uri, body, _headers, client:)
49
+ def build_request(method, uri, body, headers, client:)
46
50
  klass = REQUEST_CLASSES.fetch(method)
47
51
  request = klass.new(uri.request_uri)
48
52
 
@@ -52,21 +56,12 @@ module Simple::HTTP::Driver::Default
52
56
  request.basic_auth(*client.basic_auth)
53
57
  end
54
58
 
55
- # set request headers
56
- # unless headers && !headers.empty?
57
- # # TODO: set headers
58
- # # set_request_headers request, headers
59
- # end
60
-
61
- # set request body
62
- if request.request_body_permitted? && body
63
- request.content_type = "application/json"
64
- if body.is_a?(Hash) || body.is_a?(Array)
65
- body = JSON.generate(body)
66
- end
67
- request.body = body
59
+ if headers && !headers.empty?
60
+ headers.each { |key, value| request[key] = value }
68
61
  end
69
62
 
63
+ request.body = body if body
64
+
70
65
  request
71
66
  end
72
67
 
@@ -0,0 +1,44 @@
1
+ # rubocop:disable Metrics/AbcSize
2
+
3
+ module Simple::HTTP::Driver
4
+ end
5
+
6
+ module Simple::HTTP::Driver::Faraday
7
+ extend self
8
+
9
+ URI_KLASSES = {
10
+ "http" => URI::HTTP,
11
+ "https" => URI::HTTPS
12
+ }
13
+
14
+ # does an HTTP request and returns its response.
15
+ def execute_request(request, client:)
16
+ connection = build_connection(request.url, client: client)
17
+
18
+ headers = request.headers.dup
19
+
20
+ body = request.body
21
+
22
+ resp = connection.run_request(request.verb.downcase, request.url, body, headers)
23
+
24
+ {
25
+ status: Integer(resp.status),
26
+ message: resp.reason_phrase,
27
+ headers: Simple::HTTP::Headers.new(resp.headers.to_hash),
28
+ body: resp.body
29
+ }
30
+ end
31
+
32
+ private
33
+
34
+ def build_connection(url, client:)
35
+ ::Faraday.new.tap do |connection|
36
+ uri = URI.parse(url)
37
+ if uri.user
38
+ connection.basic_auth(uri.user, uri.password)
39
+ elsif client.basic_auth
40
+ connection.basic_auth(*client.basic_auth)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -22,14 +22,32 @@ class Simple::HTTP::Error < RuntimeError
22
22
  end
23
23
 
24
24
  def verb
25
- request.class::METHOD
25
+ request.verb
26
26
  end
27
27
 
28
28
  def message
29
- "#{verb} #{request.uri} ##{status} #{response.message}"
29
+ "#{verb} #{request.url} ##{status} #{response.message}"
30
30
  end
31
31
  end
32
32
 
33
+ class Simple::HTTP::StatusError < Simple::HTTP::Error
34
+ def self.raise(response:)
35
+ error_klass = case response.status
36
+ when 400..499 then ::Simple::HTTP::Status4XXError
37
+ when 500..599 then ::Simple::HTTP::Status5XXError
38
+ else ::Simple::HTTP::StatusError
39
+ end
40
+
41
+ Kernel.raise error_klass.new(response)
42
+ end
43
+ end
44
+
45
+ class Simple::HTTP::Status4XXError < Simple::HTTP::StatusError
46
+ end
47
+
48
+ class Simple::HTTP::Status5XXError < Simple::HTTP::StatusError
49
+ end
50
+
33
51
  class Simple::HTTP::TooManyRedirections < Simple::HTTP::Error
34
52
  def location
35
53
  response["Location"]
@@ -0,0 +1,24 @@
1
+ module Simple::HTTP::Helpers
2
+ module BuildURL
3
+ def build_url(base, *args)
4
+ option_args, string_args = args.partition { |arg| arg.is_a?(Hash) }
5
+ options = option_args.inject({}) { |hsh, option| hsh.update option }
6
+
7
+ url = File.join([base] + string_args)
8
+
9
+ query = build_query(options)
10
+ url += url.index("?") ? "&#{query}" : "?#{query}" if query
11
+
12
+ url
13
+ end
14
+
15
+ private
16
+
17
+ def build_query(params)
18
+ params = params.reject { |_k, v| v.blank? }
19
+ return nil if params.blank?
20
+
21
+ params.map { |k, value| "#{k}=#{escape(value.to_s)}" }.join("&")
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,8 @@
1
+ require "logger"
2
+
3
+ class Simple::HTTP
4
+ class << self
5
+ attr_accessor :logger
6
+ end
7
+ self.logger = Logger.new(STDERR, level: :warn)
8
+ end
@@ -1,10 +1,38 @@
1
1
  class Simple::HTTP::Request
2
2
  attr_reader :verb, :url, :body, :headers
3
3
 
4
- def initialize(verb:, url:, body: nil, headers:)
4
+ class << self
5
+ def build(verb:, url:, body: nil, headers:)
6
+ if body_permitted?(verb) && !headers.key?("Content-Type")
7
+ if body.is_a?(Hash) || body.is_a?(Array)
8
+ headers["Content-Type"] = "application/json"
9
+ body = JSON.generate(body)
10
+ end
11
+ end
12
+
13
+ new verb, url, body, headers
14
+ end
15
+
16
+ private
17
+
18
+ def body_permitted?(verb)
19
+ return false if verb == :GET
20
+ return false if verb == :HEAD
21
+ return false if verb == :DELETE
22
+ return false if verb == :OPTIONS
23
+
24
+ true
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def initialize(verb, url, body, headers)
5
31
  @verb, @url, @body, @headers = verb, url, body, headers
6
32
  end
7
33
 
34
+ public
35
+
8
36
  def to_s
9
37
  scrubbed_url = url.gsub(/\/\/(.*):(.*)@/) { |_| "//#{$1}:xxxxxx@" }
10
38
  "#{verb} #{scrubbed_url}"
@@ -1,6 +1,23 @@
1
1
  require_relative "./body_builder"
2
2
 
3
3
  class Simple::HTTP::Response
4
+ class << self
5
+ def build(request:, body:, headers:, status:, message:)
6
+ unless body_permitted?(request.verb)
7
+ body = nil
8
+ end
9
+
10
+ new request, body, headers, status, message
11
+ end
12
+
13
+ def body_permitted?(verb)
14
+ return false if verb == :HEAD
15
+ return false if verb == :OPTIONS
16
+
17
+ true
18
+ end
19
+ end
20
+
4
21
  BodyBuilder = Simple::HTTP::BodyBuilder
5
22
 
6
23
  attr_reader :request
@@ -9,7 +26,10 @@ class Simple::HTTP::Response
9
26
  attr_reader :headers
10
27
  attr_reader :original_body
11
28
 
12
- def initialize(body:, headers:, status:, message:)
29
+ private
30
+
31
+ def initialize(request, body, headers, status, message)
32
+ @request = request
13
33
  @headers = headers
14
34
  @status = status
15
35
  @message = message
@@ -23,12 +43,6 @@ class Simple::HTTP::Response
23
43
  end
24
44
  end
25
45
 
26
- private
27
-
28
- def set_request(request)
29
- @request = request
30
- end
31
-
32
46
  public
33
47
 
34
48
  # e.g "text/plain"
@@ -45,28 +59,58 @@ class Simple::HTTP::Response
45
59
  end
46
60
 
47
61
  def bytes
48
- @original_body&.byte_size || 0
62
+ @original_body&.bytesize || 0
49
63
  end
50
64
 
51
65
  def to_s
52
66
  "#{status} #{message.gsub(/\s+$/, "")} (#{bytes} byte)"
53
67
  end
54
68
 
55
- # evaluate and potentially parses response body.
56
- # raises an Simple::Http::Error if the result code is not a 2xx
57
- def content!
58
- raise Error, self unless status >= 200 && status <= 299
69
+ # evaluate and potentially parse response
70
+ def content(into: nil)
71
+ return parsed_content if into.nil?
59
72
 
60
- content
73
+ if parsed_content.is_a?(Array)
74
+ parsed_content.map { |entry| into.new entry }
75
+ else
76
+ into.new parsed_content
77
+ end
61
78
  end
62
79
 
63
- # evaluate and potentially parse response
64
- def content
65
- case media_type
66
- when "application/json"
67
- JSON.parse(body) unless body.empty?
68
- else
69
- body
80
+ private
81
+
82
+ def parsed_content
83
+ return @parsed_content if defined? @parsed_content
84
+
85
+ @parsed_content = case media_type
86
+ when "application/json"
87
+ body.empty? ? nil : JSON.parse(body)
88
+ else
89
+ body
70
90
  end
71
91
  end
92
+
93
+ public
94
+
95
+ def checked_content(into:)
96
+ check_response_status!
97
+ content(into: into)
98
+ end
99
+
100
+ private
101
+
102
+ SUCCESSFUL_STATUS_CODES = 200..299
103
+
104
+ def check_response_status!
105
+ return if SUCCESSFUL_STATUS_CODES.include?(status)
106
+
107
+ Simple::HTTP.logger.warn do
108
+ msg = "#{request}: HTTP request failed w/#{self}"
109
+ msg += "\nheaders: #{headers}" if Simple::HTTP.logger.debug?
110
+ msg += "\nresponse body: #{body}" if body && Simple::HTTP.logger.info?
111
+ msg
112
+ end
113
+
114
+ ::Simple::HTTP::StatusError.raise(response: self)
115
+ end
72
116
  end
data/test/test_helper.rb CHANGED
@@ -32,8 +32,9 @@ class Simple::HTTP::TestCase < Test::Unit::TestCase
32
32
 
33
33
  # The command to start the server must reset the BUNDLE_GEMFILE environment
34
34
  # setting.
35
- command = "cd ../simple-httpd/ && BUNDLE_GEMFILE= PORT=12345 bin/simple-httpd #{httpd_root} -q"
36
- command = "#{command} 2> log/simple-httpd.log"
35
+ # command = "cd ../simple-httpd/ && BUNDLE_GEMFILE= PORT=12345 bin/simple-httpd start #{httpd_root} -q"
36
+ command = "PORT=12345 bundle exec simple-httpd start #{httpd_root}"
37
+ command = "#{command} -q 2> log/simple-httpd.log"
37
38
 
38
39
  ::RSpec::Httpd::Server.start! port: PORT, command: command
39
40
  end
metadata CHANGED
@@ -1,15 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple-http
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - radiospiel
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-11-29 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2019-12-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: expectation
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.1'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.1.1
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '1.1'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.1.1
13
33
  description: Simple code for simple HTTP requests
14
34
  email: eno@radiospiel.org
15
35
  executables: []
@@ -21,9 +41,13 @@ files:
21
41
  - lib/simple/http.rb
22
42
  - lib/simple/http/body_builder.rb
23
43
  - lib/simple/http/caching.rb
44
+ - lib/simple/http/checked_response.rb
24
45
  - lib/simple/http/driver/default.rb
46
+ - lib/simple/http/driver/faraday.rb
25
47
  - lib/simple/http/errors.rb
26
48
  - lib/simple/http/headers.rb
49
+ - lib/simple/http/helpers.rb
50
+ - lib/simple/http/logger.rb
27
51
  - lib/simple/http/request.rb
28
52
  - lib/simple/http/response.rb
29
53
  - lib/simple/http/version.rb
@@ -54,7 +78,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
54
78
  - !ruby/object:Gem::Version
55
79
  version: '0'
56
80
  requirements: []
57
- rubygems_version: 3.0.4
81
+ rubygems_version: 3.0.6
58
82
  signing_key:
59
83
  specification_version: 4
60
84
  summary: Simple code for simple HTTP requests