faraday 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.md +1 -1
  3. data/README.md +3 -4
  4. data/examples/client_spec.rb +1 -1
  5. data/lib/faraday/adapter/em_http.rb +3 -2
  6. data/lib/faraday/adapter/excon.rb +2 -2
  7. data/lib/faraday/adapter/httpclient.rb +2 -1
  8. data/lib/faraday/adapter/net_http.rb +18 -8
  9. data/lib/faraday/adapter/typhoeus.rb +1 -1
  10. data/lib/faraday/adapter.rb +1 -0
  11. data/lib/faraday/adapter_registry.rb +3 -1
  12. data/lib/faraday/autoload.rb +1 -1
  13. data/lib/faraday/connection.rb +3 -3
  14. data/lib/faraday/dependency_loader.rb +3 -1
  15. data/lib/faraday/encoders/flat_params_encoder.rb +9 -2
  16. data/lib/faraday/encoders/nested_params_encoder.rb +7 -2
  17. data/lib/faraday/error.rb +8 -0
  18. data/lib/faraday/options.rb +4 -8
  19. data/lib/faraday/rack_builder.rb +13 -12
  20. data/lib/faraday/request/authorization.rb +3 -1
  21. data/lib/faraday/request/multipart.rb +10 -3
  22. data/lib/faraday/request/url_encoded.rb +3 -1
  23. data/lib/faraday/request.rb +20 -10
  24. data/lib/faraday/response/raise_error.rb +12 -1
  25. data/lib/faraday/response.rb +4 -1
  26. data/lib/faraday/utils/headers.rb +2 -2
  27. data/lib/faraday/utils.rb +11 -3
  28. data/lib/faraday.rb +2 -2
  29. data/spec/faraday/adapter/em_http_spec.rb +1 -1
  30. data/spec/faraday/adapter/em_synchrony_spec.rb +1 -1
  31. data/spec/faraday/adapter/patron_spec.rb +1 -1
  32. data/spec/faraday/adapter/test_spec.rb +260 -0
  33. data/spec/faraday/params_encoders/flat_spec.rb +8 -0
  34. data/spec/faraday/params_encoders/nested_spec.rb +8 -0
  35. data/spec/faraday/rack_builder_spec.rb +150 -1
  36. data/spec/faraday/request/authorization_spec.rb +2 -2
  37. data/spec/faraday/request/multipart_spec.rb +41 -13
  38. data/spec/faraday/request/url_encoded_spec.rb +13 -0
  39. data/spec/faraday/request_spec.rb +16 -5
  40. data/spec/faraday/response/middleware_spec.rb +16 -0
  41. data/spec/faraday/response/raise_error_spec.rb +33 -0
  42. data/spec/support/shared_examples/request_method.rb +3 -3
  43. metadata +21 -6
  44. data/UPGRADING.md +0 -55
@@ -31,4 +31,12 @@ RSpec.describe Faraday::FlatParamsEncoder do
31
31
  params = { a: [] }
32
32
  expect(subject.encode(params)).to eq('a=')
33
33
  end
34
+
35
+ it 'encodes unsorted when asked' do
36
+ params = { b: false, a: true }
37
+ expect(subject.encode(params)).to eq('a=true&b=false')
38
+ Faraday::FlatParamsEncoder.sort_params = false
39
+ expect(subject.encode(params)).to eq('b=false&a=true')
40
+ Faraday::FlatParamsEncoder.sort_params = true
41
+ end
34
42
  end
@@ -94,6 +94,14 @@ RSpec.describe Faraday::NestedParamsEncoder do
94
94
  expect(subject.encode(params)).to eq('a%5B%5D=true&a%5B%5D=false')
95
95
  end
96
96
 
97
+ it 'encodes unsorted when asked' do
98
+ params = { b: false, a: true }
99
+ expect(subject.encode(params)).to eq('a=true&b=false')
100
+ Faraday::NestedParamsEncoder.sort_params = false
101
+ expect(subject.encode(params)).to eq('b=false&a=true')
102
+ Faraday::NestedParamsEncoder.sort_params = true
103
+ end
104
+
97
105
  shared_examples 'a wrong decoding' do
98
106
  it do
99
107
  expect { subject.decode(query) }.to raise_error(TypeError) do |e|
@@ -189,8 +189,157 @@ RSpec.describe Faraday::RackBuilder do
189
189
 
190
190
  it 'raises an error while making a request' do
191
191
  expect { conn.get('/') }.to raise_error(RuntimeError) do |err|
192
- expect(err.message).to eq('missing dependency for Broken: cannot load such file -- zomg/i_dont/exist')
192
+ expect(err.message).to match(%r{missing dependency for Broken: .+ -- zomg/i_dont/exist})
193
193
  end
194
194
  end
195
195
  end
196
+
197
+ context 'when middleware is added with named arguments' do
198
+ let(:conn) { Faraday::Connection.new {} }
199
+
200
+ let(:dog_middleware) do
201
+ Class.new(Faraday::Middleware) do
202
+ attr_accessor :name
203
+
204
+ def initialize(app, name:)
205
+ super(app)
206
+ @name = name
207
+ end
208
+ end
209
+ end
210
+ let(:dog) do
211
+ subject.handlers.find { |handler| handler == dog_middleware }.build
212
+ end
213
+
214
+ it 'adds a handler to construct middleware with options passed to use' do
215
+ subject.use dog_middleware, name: 'Rex'
216
+ expect { dog }.to_not output(
217
+ /warning: Using the last argument as keyword parameters is deprecated/
218
+ ).to_stderr
219
+ expect(dog.name).to eq('Rex')
220
+ end
221
+ end
222
+
223
+ context 'when a request adapter is added with named arguments' do
224
+ let(:conn) { Faraday::Connection.new {} }
225
+
226
+ let(:cat_request) do
227
+ Class.new(Faraday::Middleware) do
228
+ attr_accessor :name
229
+
230
+ def initialize(app, name:)
231
+ super(app)
232
+ @name = name
233
+ end
234
+ end
235
+ end
236
+ let(:cat) do
237
+ subject.handlers.find { |handler| handler == cat_request }.build
238
+ end
239
+
240
+ it 'adds a handler to construct request adapter with options passed to request' do
241
+ Faraday::Request.register_middleware cat_request: cat_request
242
+ subject.request :cat_request, name: 'Felix'
243
+ expect { cat }.to_not output(
244
+ /warning: Using the last argument as keyword parameters is deprecated/
245
+ ).to_stderr
246
+ expect(cat.name).to eq('Felix')
247
+ end
248
+ end
249
+
250
+ context 'when a response adapter is added with named arguments' do
251
+ let(:conn) { Faraday::Connection.new {} }
252
+
253
+ let(:fish_response) do
254
+ Class.new(Faraday::Response::Middleware) do
255
+ attr_accessor :name
256
+
257
+ def initialize(app, name:)
258
+ super(app)
259
+ @name = name
260
+ end
261
+ end
262
+ end
263
+ let(:fish) do
264
+ subject.handlers.find { |handler| handler == fish_response }.build
265
+ end
266
+
267
+ it 'adds a handler to construct response adapter with options passed to response' do
268
+ Faraday::Response.register_middleware fish_response: fish_response
269
+ subject.response :fish_response, name: 'Bubbles'
270
+ expect { fish }.to_not output(
271
+ /warning: Using the last argument as keyword parameters is deprecated/
272
+ ).to_stderr
273
+ expect(fish.name).to eq('Bubbles')
274
+ end
275
+ end
276
+
277
+ context 'when a plain adapter is added with named arguments' do
278
+ let(:conn) { Faraday::Connection.new {} }
279
+
280
+ let(:rabbit_adapter) do
281
+ Class.new(Faraday::Adapter) do
282
+ attr_accessor :name
283
+
284
+ def initialize(app, name:)
285
+ super(app)
286
+ @name = name
287
+ end
288
+ end
289
+ end
290
+ let(:rabbit) do
291
+ subject.adapter.build
292
+ end
293
+
294
+ it 'adds a handler to construct adapter with options passed to adapter' do
295
+ Faraday::Adapter.register_middleware rabbit_adapter: rabbit_adapter
296
+ subject.adapter :rabbit_adapter, name: 'Thumper'
297
+ expect { rabbit }.to_not output(
298
+ /warning: Using the last argument as keyword parameters is deprecated/
299
+ ).to_stderr
300
+ expect(rabbit.name).to eq('Thumper')
301
+ end
302
+ end
303
+
304
+ context 'when handlers are directly added or updated' do
305
+ let(:conn) { Faraday::Connection.new {} }
306
+
307
+ let(:rock_handler) do
308
+ Class.new do
309
+ attr_accessor :name
310
+
311
+ def initialize(_app, name:)
312
+ @name = name
313
+ end
314
+ end
315
+ end
316
+ let(:rock) do
317
+ subject.handlers.find { |handler| handler == rock_handler }.build
318
+ end
319
+
320
+ it 'adds a handler to construct adapter with options passed to insert' do
321
+ subject.insert 0, rock_handler, name: 'Stony'
322
+ expect { rock }.to_not output(
323
+ /warning: Using the last argument as keyword parameters is deprecated/
324
+ ).to_stderr
325
+ expect(rock.name).to eq('Stony')
326
+ end
327
+
328
+ it 'adds a handler with options passed to insert_after' do
329
+ subject.insert_after 0, rock_handler, name: 'Rocky'
330
+ expect { rock }.to_not output(
331
+ /warning: Using the last argument as keyword parameters is deprecated/
332
+ ).to_stderr
333
+ expect(rock.name).to eq('Rocky')
334
+ end
335
+
336
+ it 'adds a handler with options passed to swap' do
337
+ subject.insert 0, rock_handler, name: 'Flint'
338
+ subject.swap 0, rock_handler, name: 'Chert'
339
+ expect { rock }.to_not output(
340
+ /warning: Using the last argument as keyword parameters is deprecated/
341
+ ).to_stderr
342
+ expect(rock.name).to eq('Chert')
343
+ end
344
+ end
196
345
  end
@@ -56,7 +56,7 @@ RSpec.describe Faraday::Request::Authorization do
56
56
  end
57
57
 
58
58
  context 'when other values are provided' do
59
- let(:auth_config) { ['baz', foo: 42] }
59
+ let(:auth_config) { ['baz', { foo: 42 }] }
60
60
 
61
61
  it { expect(response.body).to match(/^Token /) }
62
62
  it { expect(response.body).to match(/token="baz"/) }
@@ -78,7 +78,7 @@ RSpec.describe Faraday::Request::Authorization do
78
78
  end
79
79
 
80
80
  context 'when passed a string and a hash' do
81
- let(:auth_config) { ['baz', foo: 42] }
81
+ let(:auth_config) { ['baz', { foo: 42 }] }
82
82
 
83
83
  it { expect(response.body).to eq('baz foo="42"') }
84
84
 
@@ -1,9 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  RSpec.describe Faraday::Request::Multipart do
4
+ let(:options) { {} }
4
5
  let(:conn) do
5
6
  Faraday.new do |b|
6
- b.request :multipart
7
+ b.request :multipart, options
7
8
  b.request :url_encoded
8
9
  b.adapter :test do |stub|
9
10
  stub.post('/echo') do |env|
@@ -54,9 +55,10 @@ RSpec.describe Faraday::Request::Multipart do
54
55
  part_bc, body_bc = result.part('b[c]')
55
56
  expect(part_bc).to_not be_nil
56
57
  expect(part_bc.filename).to eq('multipart_spec.rb')
57
- expect(part_bc.headers['content-disposition']).to eq(
58
- 'form-data; foo=1; name="b[c]"; filename="multipart_spec.rb"'
59
- )
58
+ expect(part_bc.headers['content-disposition'])
59
+ .to eq(
60
+ 'form-data; foo=1; name="b[c]"; filename="multipart_spec.rb"'
61
+ )
60
62
  expect(part_bc.headers['content-type']).to eq('text/x-ruby')
61
63
  expect(part_bc.headers['content-transfer-encoding']).to eq('binary')
62
64
  expect(body_bc).to eq(File.read(__FILE__))
@@ -135,9 +137,10 @@ RSpec.describe Faraday::Request::Multipart do
135
137
  part_bc, body_bc = result.part('b[][c]')
136
138
  expect(part_bc).to_not be_nil
137
139
  expect(part_bc.filename).to eq('multipart_spec.rb')
138
- expect(part_bc.headers['content-disposition']).to eq(
139
- 'form-data; name="b[][c]"; filename="multipart_spec.rb"'
140
- )
140
+ expect(part_bc.headers['content-disposition'])
141
+ .to eq(
142
+ 'form-data; name="b[][c]"; filename="multipart_spec.rb"'
143
+ )
141
144
  expect(part_bc.headers['content-type']).to eq('text/x-ruby')
142
145
  expect(part_bc.headers['content-transfer-encoding']).to eq('binary')
143
146
  expect(body_bc).to eq(File.read(__FILE__))
@@ -177,9 +180,10 @@ RSpec.describe Faraday::Request::Multipart do
177
180
  part_bc, body_bc = result.part('b[c]')
178
181
  expect(part_bc).to_not be_nil
179
182
  expect(part_bc.filename).to eq('multipart_spec.rb')
180
- expect(part_bc.headers['content-disposition']).to eq(
181
- 'form-data; foo=1; name="b[c]"; filename="multipart_spec.rb"'
182
- )
183
+ expect(part_bc.headers['content-disposition'])
184
+ .to eq(
185
+ 'form-data; foo=1; name="b[c]"; filename="multipart_spec.rb"'
186
+ )
183
187
  expect(part_bc.headers['content-type']).to eq('text/x-ruby')
184
188
  expect(part_bc.headers['content-transfer-encoding']).to eq('binary')
185
189
  expect(body_bc).to eq(File.read(__FILE__))
@@ -258,9 +262,10 @@ RSpec.describe Faraday::Request::Multipart do
258
262
  part_bc, body_bc = result.part('b[][c]')
259
263
  expect(part_bc).to_not be_nil
260
264
  expect(part_bc.filename).to eq('multipart_spec.rb')
261
- expect(part_bc.headers['content-disposition']).to eq(
262
- 'form-data; name="b[][c]"; filename="multipart_spec.rb"'
263
- )
265
+ expect(part_bc.headers['content-disposition'])
266
+ .to eq(
267
+ 'form-data; name="b[][c]"; filename="multipart_spec.rb"'
268
+ )
264
269
  expect(part_bc.headers['content-type']).to eq('text/x-ruby')
265
270
  expect(part_bc.headers['content-transfer-encoding']).to eq('binary')
266
271
  expect(body_bc).to eq(File.read(__FILE__))
@@ -271,4 +276,27 @@ RSpec.describe Faraday::Request::Multipart do
271
276
  expect(body_bd).to eq('2')
272
277
  end
273
278
  end
279
+
280
+ context 'when passing flat_encode=true option' do
281
+ let(:options) { { flat_encode: true } }
282
+ let(:io) { StringIO.new('io-content') }
283
+ let(:payload) do
284
+ {
285
+ a: 1,
286
+ b: [
287
+ Faraday::UploadIO.new(io, 'application/pdf'),
288
+ Faraday::UploadIO.new(io, 'application/pdf')
289
+ ]
290
+ }
291
+ end
292
+
293
+ it_behaves_like 'a multipart request'
294
+
295
+ it 'encode params using flat encoder' do
296
+ response = conn.post('/echo', payload)
297
+
298
+ expect(response.body).to include('name="b"')
299
+ expect(response.body).not_to include('name="b[]"')
300
+ end
301
+ end
274
302
  end
@@ -67,4 +67,17 @@ RSpec.describe Faraday::Request::UrlEncoded do
67
67
  response = conn.post('/echo', 'a' => { 'b' => { 'c' => ['d'] } })
68
68
  expect(response.body).to eq('a%5Bb%5D%5Bc%5D%5B%5D=d')
69
69
  end
70
+
71
+ context 'customising default_space_encoding' do
72
+ around do |example|
73
+ Faraday::Utils.default_space_encoding = '%20'
74
+ example.run
75
+ Faraday::Utils.default_space_encoding = nil
76
+ end
77
+
78
+ it 'uses the custom character to encode spaces' do
79
+ response = conn.post('/echo', str: 'apple banana')
80
+ expect(response.body).to eq('str=apple%20banana')
81
+ end
82
+ end
70
83
  end
@@ -6,20 +6,31 @@ RSpec.describe Faraday::Request do
6
6
  headers: { 'Mime-Version' => '1.0' },
7
7
  request: { oauth: { consumer_key: 'anonymous' } })
8
8
  end
9
- let(:method) { :get }
9
+ let(:http_method) { :get }
10
10
  let(:block) { nil }
11
11
 
12
- subject { conn.build_request(method, &block) }
12
+ subject { conn.build_request(http_method, &block) }
13
13
 
14
14
  context 'when nothing particular is configured' do
15
- it { expect(subject.method).to eq(:get) }
15
+ it { expect(subject.http_method).to eq(:get) }
16
16
  it { expect(subject.to_env(conn).ssl.verify).to be_falsey }
17
17
  end
18
18
 
19
- context 'when method is post' do
20
- let(:method) { :post }
19
+ context 'when HTTP method is post' do
20
+ let(:http_method) { :post }
21
+
22
+ it { expect(subject.http_method).to eq(:post) }
23
+ end
24
+
25
+ describe 'deprecate method for HTTP method' do
26
+ let(:http_method) { :post }
27
+ let(:expected_warning) do
28
+ %r{WARNING: `Faraday::Request#method` is deprecated; use `#http_method` instead. It will be removed in or after version 2.0.\n`Faraday::Request#method` called from .+/spec/faraday/request_spec.rb:\d+.}
29
+ end
21
30
 
22
31
  it { expect(subject.method).to eq(:post) }
32
+
33
+ it { expect { subject.method }.to output(expected_warning).to_stderr }
23
34
  end
24
35
 
25
36
  context 'when setting the url on setup with a URI' do
@@ -26,6 +26,22 @@ RSpec.describe Faraday::Response::Middleware do
26
26
  end
27
27
  end
28
28
 
29
+ context 'with a custom ResponseMiddleware and private parse' do
30
+ let(:custom_middleware) do
31
+ Class.new(Faraday::Response::Middleware) do
32
+ private
33
+
34
+ def parse(body)
35
+ body.upcase
36
+ end
37
+ end
38
+ end
39
+
40
+ it 'parses the response' do
41
+ expect(conn.get('ok').body).to eq('<BODY></BODY>')
42
+ end
43
+ end
44
+
29
45
  context 'with a custom ResponseMiddleware but empty response' do
30
46
  let(:custom_middleware) do
31
47
  Class.new(Faraday::Response::Middleware) do
@@ -103,4 +103,37 @@ RSpec.describe Faraday::Response::RaiseError do
103
103
  expect(ex.response[:status]).to eq(500)
104
104
  end
105
105
  end
106
+
107
+ describe 'request info' do
108
+ let(:conn) do
109
+ Faraday.new do |b|
110
+ b.response :raise_error
111
+ b.adapter :test do |stub|
112
+ stub.post('request?full=true', request_body, request_headers) do
113
+ [400, { 'X-Reason' => 'because' }, 'keep looking']
114
+ end
115
+ end
116
+ end
117
+ end
118
+ let(:request_body) { JSON.generate({ 'item' => 'sth' }) }
119
+ let(:request_headers) { { 'Authorization' => 'Basic 123' } }
120
+
121
+ subject(:perform_request) do
122
+ conn.post 'request' do |req|
123
+ req.headers['Authorization'] = 'Basic 123'
124
+ req.params[:full] = true
125
+ req.body = request_body
126
+ end
127
+ end
128
+
129
+ it 'returns the request info in the exception' do
130
+ expect { perform_request }.to raise_error(Faraday::BadRequestError) do |ex|
131
+ expect(ex.response[:request][:method]).to eq(:post)
132
+ expect(ex.response[:request][:url_path]).to eq('/request')
133
+ expect(ex.response[:request][:params]).to eq({ 'full' => 'true' })
134
+ expect(ex.response[:request][:headers]).to match(a_hash_including(request_headers))
135
+ expect(ex.response[:request][:body]).to eq(request_body)
136
+ end
137
+ end
138
+ end
106
139
  end
@@ -13,8 +13,8 @@ shared_examples 'a request method' do |http_method|
13
13
  end
14
14
 
15
15
  it 'handles headers with multiple values' do
16
- request_stub.to_return(headers: { 'Set-Cookie' => 'one, two' })
17
- expect(response.headers['set-cookie']).to eq('one, two')
16
+ request_stub.to_return(headers: { 'Set-Cookie' => 'name=value' })
17
+ expect(response.headers['set-cookie']).to eq('name=value')
18
18
  end
19
19
 
20
20
  it 'retrieves the response headers' do
@@ -119,7 +119,7 @@ shared_examples 'a request method' do |http_method|
119
119
  request_stub.with(headers: { 'Content-Type' => %r{\Amultipart/form-data} }) do |request|
120
120
  # WebMock does not support matching body for multipart/form-data requests yet :(
121
121
  # https://github.com/bblimke/webmock/issues/623
122
- request.body =~ /RubyMultipartPost/
122
+ request.body.include?('RubyMultipartPost')
123
123
  end
124
124
  conn.public_send(http_method, '/', payload)
125
125
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: faraday
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - "@technoweenie"
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2020-01-01 00:00:00.000000000 Z
13
+ date: 2020-10-17 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: multipart-post
@@ -32,6 +32,20 @@ dependencies:
32
32
  - - "<"
33
33
  - !ruby/object:Gem::Version
34
34
  version: '3'
35
+ - !ruby/object:Gem::Dependency
36
+ name: ruby2_keywords
37
+ requirement: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ type: :runtime
43
+ prerelease: false
44
+ version_requirements: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
35
49
  description:
36
50
  email: technoweenie@gmail.com
37
51
  executables: []
@@ -42,7 +56,6 @@ files:
42
56
  - LICENSE.md
43
57
  - README.md
44
58
  - Rakefile
45
- - UPGRADING.md
46
59
  - examples/client_spec.rb
47
60
  - examples/client_test.rb
48
61
  - lib/faraday.rb
@@ -102,6 +115,7 @@ files:
102
115
  - spec/faraday/adapter/net_http_spec.rb
103
116
  - spec/faraday/adapter/patron_spec.rb
104
117
  - spec/faraday/adapter/rack_spec.rb
118
+ - spec/faraday/adapter/test_spec.rb
105
119
  - spec/faraday/adapter/typhoeus_spec.rb
106
120
  - spec/faraday/adapter_registry_spec.rb
107
121
  - spec/faraday/adapter_spec.rb
@@ -143,25 +157,26 @@ licenses:
143
157
  - MIT
144
158
  metadata:
145
159
  homepage_uri: https://lostisland.github.io/faraday
146
- changelog_uri: https://github.com/lostisland/faraday/releases/tag/v1.0.0
160
+ changelog_uri: https://github.com/lostisland/faraday/releases/tag/v1.1.0
147
161
  source_code_uri: https://github.com/lostisland/faraday
148
162
  bug_tracker_uri: https://github.com/lostisland/faraday/issues
149
163
  post_install_message:
150
164
  rdoc_options: []
151
165
  require_paths:
152
166
  - lib
167
+ - spec/external_adapters
153
168
  required_ruby_version: !ruby/object:Gem::Requirement
154
169
  requirements:
155
170
  - - ">="
156
171
  - !ruby/object:Gem::Version
157
- version: '2.3'
172
+ version: '2.4'
158
173
  required_rubygems_version: !ruby/object:Gem::Requirement
159
174
  requirements:
160
175
  - - ">="
161
176
  - !ruby/object:Gem::Version
162
177
  version: '0'
163
178
  requirements: []
164
- rubygems_version: 3.1.2
179
+ rubygems_version: 3.0.3
165
180
  signing_key:
166
181
  specification_version: 4
167
182
  summary: HTTP/REST API client library.