faraday 2.1.0 → 2.4.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: 2123a105dd09a93bec6fe115277fd7c58afa269bc1036524a422a3e45df2b40c
4
- data.tar.gz: bdd311dabe80e2ecd28f7bf941ea0e551840b2bc783dd781b56999842086a31f
3
+ metadata.gz: 3b9b61d836844815a4d9a5a1e9986c9a60416b8a9e9159d61f959e0c74ed52cc
4
+ data.tar.gz: 34fb0b4f2d4a8b22a72d56d0f3d4bfa884b2290c5012b1cdfe6de4b6886420a6
5
5
  SHA512:
6
- metadata.gz: 943a1dd4a67287874fc3724d3d9ec7e41540cd3a08b528201b1af806d5dd56bceb976f54df6d0394fb25bffeb0bcb224831700c9ef46c1daf24cb3e13fd2ad52
7
- data.tar.gz: 3ae115b30da8ec49253888f4a81522c14667a8da6b248b0d56192252b8d9bf9a6914f703530d467c2a83415a0862b73ccc17f799d9c1d0fba8289296b7cb0faf
6
+ metadata.gz: 9f0db04b8a845215b109b3491985dc6ce6ac60ced07874bcdcdd5bab5d935a40e51bda4feab6f93375889597185c295785e5a6d1119576762d006ca696033794
7
+ data.tar.gz: 45debf037f0d1d02cccc70e33042c68d76146bb6b58bc8de839a7745404cd58a4171b0e209c75b1384475f6432531317a9145959ebf3ffe60837b65469f20e2b
data/CHANGELOG.md CHANGED
@@ -1,5 +1,83 @@
1
1
  # Faraday Changelog
2
2
 
3
+ ## The changelog has moved!
4
+
5
+ This file is not being updated anymore. Instead, please check the [Releases](https://github.com/lostisland/faraday/releases) page.
6
+
7
+ ## [2.2.0](https://github.com/lostisland/faraday/compare/v2.1.0...v2.2.0) (2022-02-03)
8
+
9
+ * Reintroduce the possibility to register middleware with symbols, strings or procs in [#1391](https://github.com/lostisland/faraday/pull/1391)
10
+
11
+ ## [2.1.0](https://github.com/lostisland/faraday/compare/v2.0.1...v2.1.0) (2022-01-15)
12
+
13
+ * Fix test adapter thread safety by @iMacTia in [#1380](https://github.com/lostisland/faraday/pull/1380)
14
+ * Add default adapter options by @hirasawayuki in [#1382](https://github.com/lostisland/faraday/pull/1382)
15
+ * CI: Add Ruby 3.1 to matrix by @petergoldstein in [#1374](https://github.com/lostisland/faraday/pull/1374)
16
+ * docs: fix regex pattern in logger.md examples by @hirasawayuki in [#1378](https://github.com/lostisland/faraday/pull/1378)
17
+
18
+ ## [2.0.1](https://github.com/lostisland/faraday/compare/v2.0.0...v2.0.1) (2022-01-05)
19
+
20
+ * Re-add `faraday-net_http` as default adapter by @iMacTia in [#1366](https://github.com/lostisland/faraday/pull/1366)
21
+ * Updated sample format in UPGRADING.md by @vimutter in [#1361](https://github.com/lostisland/faraday/pull/1361)
22
+ * docs: Make UPGRADING examples more copyable by @olleolleolle in [#1363](https://github.com/lostisland/faraday/pull/1363)
23
+
24
+ ## [2.0.0](https://github.com/lostisland/faraday/compare/v1.8.0...v2.0.0) (2022-01-04)
25
+
26
+ The next major release is here, and it comes almost 2 years after the release of v1.0!
27
+
28
+ This release changes the way you use Faraday and embraces a new paradigm of Faraday as an ecosystem, rather than a library.
29
+
30
+ What does that mean? It means that Faraday is less of a bundled tool and more of a framework for the community to build on top of.
31
+
32
+ As a result, all adapters and some middleware have moved out and are now shipped as standalone gems 🙌!
33
+
34
+ But this doesn't mean that upgrading from Faraday 1.x to Faraday 2.0 should be hard, in fact we've listed everything you need to do in the [UPGRADING.md](https://github.com/lostisland/faraday/blob/main/UPGRADING.md) doc.
35
+
36
+ Moreover, we've setup a new [awesome-faraday](https://github.com/lostisland/awesome-faraday) repository that will showcase a curated list of adapters and middleware 😎.
37
+
38
+ This release was the result of the efforts of the core team and all the contributors, new and old, that have helped achieve this milestone 👏.
39
+
40
+ ## What's Changed
41
+
42
+ * Autoloading, dependency loading and middleware registry cleanup by @iMacTia in [#1301](https://github.com/lostisland/faraday/pull/1301)
43
+ * Move JSON middleware (request and response) from faraday_middleware by @iMacTia in [#1300](https://github.com/lostisland/faraday/pull/1300)
44
+ * Remove deprecated `Faraday::Request#method` by @olleolleolle in [#1303](https://github.com/lostisland/faraday/pull/1303)
45
+ * Remove deprecated `Faraday::UploadIO` by @iMacTia in [#1307](https://github.com/lostisland/faraday/pull/1307)
46
+ * [1.x] Deprecate Authorization helpers in `Faraday::Connection` by @iMacTia in [#1306](https://github.com/lostisland/faraday/pull/1306)
47
+ * Drop deprecated auth helpers from Connection and refactor auth middleware by @iMacTia in [#1308](https://github.com/lostisland/faraday/pull/1308)
48
+ * Add Faraday 1.x examples in authentication.md docs by @iMacTia in [#1320](https://github.com/lostisland/faraday/pull/1320)
49
+ * Fix passing a URL with embedded basic auth by @iMacTia in [#1324](https://github.com/lostisland/faraday/pull/1324)
50
+ * Register JSON middleware by @mollerhoj in [#1331](https://github.com/lostisland/faraday/pull/1331)
51
+ * Retry middleware should handle string exception class name consistently by @jrochkind in [#1334](https://github.com/lostisland/faraday/pull/1334)
52
+ * Improve request info in exceptions raised by RaiseError Middleware by @willianzocolau in [#1335](https://github.com/lostisland/faraday/pull/1335)
53
+ * Remove net-http adapter and update docs by @iMacTia in [#1336](https://github.com/lostisland/faraday/pull/1336)
54
+ * Explain plan for faraday_middleware in UPGRADING.md by @iMacTia in [#1339](https://github.com/lostisland/faraday/pull/1339)
55
+ * Scripts folder cleanup by @iMacTia in [#1340](https://github.com/lostisland/faraday/pull/1340)
56
+ * Replace `Hash#merge` with `Utils#deep_merge` for connection options by @xkwd in [#1343](https://github.com/lostisland/faraday/pull/1343)
57
+ * Callable authorizers by @sled in [#1345](https://github.com/lostisland/faraday/pull/1345)
58
+ * Default value for exc error by @DariuszMusielak in [#1351](https://github.com/lostisland/faraday/pull/1351)
59
+ * Don't call `retry_block` unless a retry is going to happen by @jrochkind in [#1350](https://github.com/lostisland/faraday/pull/1350)
60
+ * Improve documentation for v2 by @iMacTia in [#1353](https://github.com/lostisland/faraday/pull/1353)
61
+ * Remove default `default_adapter` (yes, you read that right) by @iMacTia in [#1354](https://github.com/lostisland/faraday/pull/1354)
62
+ * Remove retry middleware by @iMacTia in [#1356](https://github.com/lostisland/faraday/pull/1356)
63
+ * Remove multipart middleware and all its documentation and tests by @iMacTia in [#1357](https://github.com/lostisland/faraday/pull/1357)
64
+
65
+ ## [1.9.3](https://github.com/lostisland/faraday/compare/v1.9.2...v1.9.3) (2022-01-06)
66
+
67
+ * Re-add support for Ruby 2.4+ by @iMacTia in [#1371](https://github.com/lostisland/faraday/pull/1371)
68
+
69
+ ## [1.9.2](https://github.com/lostisland/faraday/compare/v1.9.1...v1.9.2) (2022-01-06)
70
+
71
+ * Add alias with legacy name to gemified middleware by @iMacTia in [#1372](https://github.com/lostisland/faraday/pull/1372)
72
+
73
+ ## [1.9.1](https://github.com/lostisland/faraday/compare/v1.9.0...v1.9.1) (2022-01-06)
74
+
75
+ * Update adapter dependencies in Gemspec by @iMacTia in [#1370](https://github.com/lostisland/faraday/pull/1370)
76
+
77
+ ## [1.9.0](https://github.com/lostisland/faraday/compare/v1.8.0...v1.9.0) (2022-01-06)
78
+
79
+ * Use external multipart and retry middleware by @iMacTia in [#1367](https://github.com/lostisland/faraday/pull/1367)
80
+
3
81
  ## [1.8.0](https://github.com/lostisland/faraday/releases/tag/v1.8.0) (2021-09-18)
4
82
 
5
83
  ### Features
@@ -65,7 +143,7 @@
65
143
 
66
144
  ### Highlights
67
145
 
68
- With this release, we continue the work of gradually moving out adapters into their own gems 🎉
146
+ With this release, we continue the work of gradually moving out adapters into their own gems 🎉
69
147
  Thanks to @MikeRogers0 for helping the Faraday team in progressing with this quest 👏
70
148
 
71
149
  And thanks to @olleolleolle efforts, Faraday is becoming more inclusive than ever 🤗
@@ -112,7 +190,7 @@ Checkout the "Misc" section below for more details 🙌 !
112
190
  ## [v1.3.0](https://github.com/lostisland/faraday/releases/tag/v1.3.0) (2020-12-31)
113
191
 
114
192
  ### Highlights
115
- Faraday v1.3.0 is the first release to officially support Ruby 3.0 in the CI pipeline 🎉 🍾!
193
+ Faraday v1.3.0 is the first release to officially support Ruby 3.0 in the CI pipeline 🎉 🍾!
116
194
 
117
195
  This is also the first release with a previously "included" adapter (Net::HTTP) being isolated into a [separate gem](https://github.com/lostisland/faraday-net_http) 🎊!
118
196
  The new adapter is added to Faraday as a dependency for now, so that means full backwards-compatibility, but just to be safe be careful when upgrading!
@@ -203,7 +281,7 @@ Many thanks to the Faraday Team, @JanDintel and everyone who attended the [ROSS
203
281
  * Allows `parse` method to be private/protected in response middleware (#1123)
204
282
  * Encode Spaces in Query Strings as '%20' Instead of '+' (#1125)
205
283
  * Limits rack to v2.0.x (#1127)
206
- * Adapter Registry reads also use mutex (#1136)
284
+ * Adapter Registry reads also use mutex (#1136)
207
285
 
208
286
  ### Documentation
209
287
 
data/LICENSE.md CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2009-2020 Rick Olson, Zack Hobson
1
+ Copyright (c) 2009-2022 Rick Olson, Zack Hobson
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -10,11 +10,6 @@ adapters (such as Net::HTTP) and embraces the concept of Rack middleware when pr
10
10
  You probably don't want to use Faraday directly in your project, as it will lack an actual client library to perform
11
11
  requests. Instead, you probably want to have a look at [Awesome Faraday][awesome] for a list of available adapters.
12
12
 
13
- ## FARADAY 2.0
14
-
15
- You're reading the README and looking at the code of our upcoming v2.0 release (the `main` branch, currently in alpha).
16
- If you're here to read about our latest v1.x release, then please head over to the [1.x branch](https://github.com/lostisland/faraday/tree/1.x).
17
-
18
13
  ## Getting Started
19
14
 
20
15
  The best starting point is the [Faraday Website][website], with its introduction and explanation.
@@ -47,7 +42,7 @@ Open the issues page and check for the `help wanted` label!
47
42
  But before you start coding, please read our [Contributing Guide][contributing]
48
43
 
49
44
  ## Copyright
50
- © 2009 - 2021, the [Faraday Team][faraday_team]. Website and branding design by [Elena Lo Piccolo](https://elelopic.design).
45
+ © 2009 - 2022, the [Faraday Team][faraday_team]. Website and branding design by [Elena Lo Piccolo](https://elelopic.design).
51
46
 
52
47
  [awesome]: https://github.com/lostisland/awesome-faraday/#adapters
53
48
  [website]: https://lostisland.github.io/faraday
@@ -12,10 +12,15 @@ class Client
12
12
  @conn = conn
13
13
  end
14
14
 
15
- def sushi(jname, params: {})
15
+ def httpbingo(jname, params: {})
16
16
  res = @conn.get("/#{jname}", params)
17
17
  data = JSON.parse(res.body)
18
- data['name']
18
+ data['origin']
19
+ end
20
+
21
+ def foo(params)
22
+ res = @conn.post('/foo', JSON.dump(params))
23
+ res.status
19
24
  end
20
25
  end
21
26
 
@@ -24,42 +29,42 @@ RSpec.describe Client do
24
29
  let(:conn) { Faraday.new { |b| b.adapter(:test, stubs) } }
25
30
  let(:client) { Client.new(conn) }
26
31
 
27
- it 'parses name' do
28
- stubs.get('/ebi') do |env|
32
+ it 'parses origin' do
33
+ stubs.get('/ip') do |env|
29
34
  # optional: you can inspect the Faraday::Env
30
- expect(env.url.path).to eq('/ebi')
35
+ expect(env.url.path).to eq('/ip')
31
36
  [
32
37
  200,
33
38
  { 'Content-Type': 'application/javascript' },
34
- '{"name": "shrimp"}'
39
+ '{"origin": "127.0.0.1"}'
35
40
  ]
36
41
  end
37
42
 
38
43
  # uncomment to trigger stubs.verify_stubbed_calls failure
39
44
  # stubs.get('/unused') { [404, {}, ''] }
40
45
 
41
- expect(client.sushi('ebi')).to eq('shrimp')
46
+ expect(client.httpbingo('ip')).to eq('127.0.0.1')
42
47
  stubs.verify_stubbed_calls
43
48
  end
44
49
 
45
50
  it 'handles 404' do
46
- stubs.get('/ebi') do
51
+ stubs.get('/api') do
47
52
  [
48
53
  404,
49
54
  { 'Content-Type': 'application/javascript' },
50
55
  '{}'
51
56
  ]
52
57
  end
53
- expect(client.sushi('ebi')).to be_nil
58
+ expect(client.httpbingo('api')).to be_nil
54
59
  stubs.verify_stubbed_calls
55
60
  end
56
61
 
57
62
  it 'handles exception' do
58
- stubs.get('/ebi') do
63
+ stubs.get('/api') do
59
64
  raise Faraday::ConnectionFailed
60
65
  end
61
66
 
62
- expect { client.sushi('ebi') }.to raise_error(Faraday::ConnectionFailed)
67
+ expect { client.httpbingo('api') }.to raise_error(Faraday::ConnectionFailed)
63
68
  stubs.verify_stubbed_calls
64
69
  end
65
70
 
@@ -67,17 +72,17 @@ RSpec.describe Client do
67
72
  let(:stubs) { Faraday::Adapter::Test::Stubs.new(strict_mode: true) }
68
73
 
69
74
  it 'verifies the all parameter values are identical' do
70
- stubs.get('/ebi?abc=123') do
75
+ stubs.get('/api?abc=123') do
71
76
  [
72
77
  200,
73
78
  { 'Content-Type': 'application/javascript' },
74
- '{"name": "shrimp"}'
79
+ '{"origin": "127.0.0.1"}'
75
80
  ]
76
81
  end
77
82
 
78
83
  # uncomment to raise Stubs::NotFound
79
- # expect(client.sushi('ebi', params: { abc: 123, foo: 'Kappa' })).to eq('shrimp')
80
- expect(client.sushi('ebi', params: { abc: 123 })).to eq('shrimp')
84
+ # expect(client.httpbingo('api', params: { abc: 123, foo: 'Kappa' })).to eq('127.0.0.1')
85
+ expect(client.httpbingo('api', params: { abc: 123 })).to eq('127.0.0.1')
81
86
  stubs.verify_stubbed_calls
82
87
  end
83
88
  end
@@ -86,11 +91,28 @@ RSpec.describe Client do
86
91
  let(:conn) { Faraday.new(request: { params_encoder: Faraday::FlatParamsEncoder }) { |b| b.adapter(:test, stubs) } }
87
92
 
88
93
  it 'handles the same multiple URL parameters' do
89
- stubs.get('/ebi?a=x&a=y&a=z') { [200, { 'Content-Type' => 'application/json' }, '{"name": "shrimp"}'] }
94
+ stubs.get('/api?a=x&a=y&a=z') { [200, { 'Content-Type' => 'application/json' }, '{"origin": "127.0.0.1"}'] }
90
95
 
91
96
  # uncomment to raise Stubs::NotFound
92
- # expect(client.sushi('ebi', params: { a: %w[x y] })).to eq('shrimp')
93
- expect(client.sushi('ebi', params: { a: %w[x y z] })).to eq('shrimp')
97
+ # expect(client.httpbingo('api', params: { a: %w[x y] })).to eq('127.0.0.1')
98
+ expect(client.httpbingo('api', params: { a: %w[x y z] })).to eq('127.0.0.1')
99
+ stubs.verify_stubbed_calls
100
+ end
101
+ end
102
+
103
+ context 'When you want to test the body, you can use a proc as well as string' do
104
+ it 'tests with a string' do
105
+ stubs.post('/foo', '{"name":"YK"}') { [200, {}, ''] }
106
+
107
+ expect(client.foo(name: 'YK')).to eq 200
108
+ stubs.verify_stubbed_calls
109
+ end
110
+
111
+ it 'tests with a proc' do
112
+ check = ->(request_body) { JSON.parse(request_body).slice('name') == { 'name' => 'YK' } }
113
+ stubs.post('/foo', check) { [200, {}, ''] }
114
+
115
+ expect(client.foo(name: 'YK', created_at: Time.now)).to eq 200
94
116
  stubs.verify_stubbed_calls
95
117
  end
96
118
  end
@@ -13,24 +13,29 @@ class Client
13
13
  @conn = conn
14
14
  end
15
15
 
16
- def sushi(jname, params: {})
16
+ def httpbingo(jname, params: {})
17
17
  res = @conn.get("/#{jname}", params)
18
18
  data = JSON.parse(res.body)
19
- data['name']
19
+ data['origin']
20
+ end
21
+
22
+ def foo(params)
23
+ res = @conn.post('/foo', JSON.dump(params))
24
+ res.status
20
25
  end
21
26
  end
22
27
 
23
28
  # Example API client test
24
29
  class ClientTest < Test::Unit::TestCase
25
- def test_sushi_name
30
+ def test_httpbingo_name
26
31
  stubs = Faraday::Adapter::Test::Stubs.new
27
- stubs.get('/ebi') do |env|
32
+ stubs.get('/api') do |env|
28
33
  # optional: you can inspect the Faraday::Env
29
- assert_equal '/ebi', env.url.path
34
+ assert_equal '/api', env.url.path
30
35
  [
31
36
  200,
32
37
  { 'Content-Type': 'application/javascript' },
33
- '{"name": "shrimp"}'
38
+ '{"origin": "127.0.0.1"}'
34
39
  ]
35
40
  end
36
41
 
@@ -38,13 +43,13 @@ class ClientTest < Test::Unit::TestCase
38
43
  # stubs.get('/unused') { [404, {}, ''] }
39
44
 
40
45
  cli = client(stubs)
41
- assert_equal 'shrimp', cli.sushi('ebi')
46
+ assert_equal '127.0.0.1', cli.httpbingo('api')
42
47
  stubs.verify_stubbed_calls
43
48
  end
44
49
 
45
- def test_sushi_not_found
50
+ def test_httpbingo_not_found
46
51
  stubs = Faraday::Adapter::Test::Stubs.new
47
- stubs.get('/ebi') do
52
+ stubs.get('/api') do
48
53
  [
49
54
  404,
50
55
  { 'Content-Type': 'application/javascript' },
@@ -53,48 +58,48 @@ class ClientTest < Test::Unit::TestCase
53
58
  end
54
59
 
55
60
  cli = client(stubs)
56
- assert_nil cli.sushi('ebi')
61
+ assert_nil cli.httpbingo('api')
57
62
  stubs.verify_stubbed_calls
58
63
  end
59
64
 
60
- def test_sushi_exception
65
+ def test_httpbingo_exception
61
66
  stubs = Faraday::Adapter::Test::Stubs.new
62
- stubs.get('/ebi') do
67
+ stubs.get('/api') do
63
68
  raise Faraday::ConnectionFailed
64
69
  end
65
70
 
66
71
  cli = client(stubs)
67
72
  assert_raise Faraday::ConnectionFailed do
68
- cli.sushi('ebi')
73
+ cli.httpbingo('api')
69
74
  end
70
75
  stubs.verify_stubbed_calls
71
76
  end
72
77
 
73
78
  def test_strict_mode
74
79
  stubs = Faraday::Adapter::Test::Stubs.new(strict_mode: true)
75
- stubs.get('/ebi?abc=123') do
80
+ stubs.get('/api?abc=123') do
76
81
  [
77
82
  200,
78
83
  { 'Content-Type': 'application/javascript' },
79
- '{"name": "shrimp"}'
84
+ '{"origin": "127.0.0.1"}'
80
85
  ]
81
86
  end
82
87
 
83
88
  cli = client(stubs)
84
- assert_equal 'shrimp', cli.sushi('ebi', params: { abc: 123 })
89
+ assert_equal '127.0.0.1', cli.httpbingo('api', params: { abc: 123 })
85
90
 
86
91
  # uncomment to raise Stubs::NotFound
87
- # assert_equal 'shrimp', cli.sushi('ebi', params: { abc: 123, foo: 'Kappa' })
92
+ # assert_equal '127.0.0.1', cli.httpbingo('api', params: { abc: 123, foo: 'Kappa' })
88
93
  stubs.verify_stubbed_calls
89
94
  end
90
95
 
91
96
  def test_non_default_params_encoder
92
97
  stubs = Faraday::Adapter::Test::Stubs.new(strict_mode: true)
93
- stubs.get('/ebi?a=x&a=y&a=z') do
98
+ stubs.get('/api?a=x&a=y&a=z') do
94
99
  [
95
100
  200,
96
101
  { 'Content-Type': 'application/javascript' },
97
- '{"name": "shrimp"}'
102
+ '{"origin": "127.0.0.1"}'
98
103
  ]
99
104
  end
100
105
  conn = Faraday.new(request: { params_encoder: Faraday::FlatParamsEncoder }) do |builder|
@@ -102,10 +107,31 @@ class ClientTest < Test::Unit::TestCase
102
107
  end
103
108
 
104
109
  cli = Client.new(conn)
105
- assert_equal 'shrimp', cli.sushi('ebi', params: { a: %w[x y z] })
110
+ assert_equal '127.0.0.1', cli.httpbingo('api', params: { a: %w[x y z] })
106
111
 
107
112
  # uncomment to raise Stubs::NotFound
108
- # assert_equal 'shrimp', cli.sushi('ebi', params: { a: %w[x y] })
113
+ # assert_equal '127.0.0.1', cli.httpbingo('api', params: { a: %w[x y] })
114
+ stubs.verify_stubbed_calls
115
+ end
116
+
117
+ def test_with_string_body
118
+ stubs = Faraday::Adapter::Test::Stubs.new do |stub|
119
+ stub.post('/foo', '{"name":"YK"}') { [200, {}, ''] }
120
+ end
121
+ cli = client(stubs)
122
+ assert_equal 200, cli.foo(name: 'YK')
123
+
124
+ stubs.verify_stubbed_calls
125
+ end
126
+
127
+ def test_with_proc_body
128
+ stubs = Faraday::Adapter::Test::Stubs.new do |stub|
129
+ check = ->(request_body) { JSON.parse(request_body).slice('name') == { 'name' => 'YK' } }
130
+ stub.post('/foo', check) { [200, {}, ''] }
131
+ end
132
+ cli = client(stubs)
133
+ assert_equal 200, cli.foo(name: 'YK', created_at: Time.now)
134
+
109
135
  stubs.verify_stubbed_calls
110
136
  end
111
137
 
@@ -26,6 +26,15 @@ module Faraday
26
26
  # ]
27
27
  # end
28
28
  #
29
+ # # Test the request body is the same as the stubbed body
30
+ # stub.post('/bar', 'name=YK&word=call') { [200, {}, ''] }
31
+ #
32
+ # # You can pass a proc as a stubbed body and check the request body in your way.
33
+ # # In this case, the proc should return true or false.
34
+ # stub.post('/foo', ->(request_body) do
35
+ # JSON.parse(request_body).slice('name') == { 'name' => 'YK' } }) { [200, {}, '']
36
+ # end
37
+ #
29
38
  # # You can set strict_mode to exactly match the stubbed requests.
30
39
  # stub.strict_mode = true
31
40
  # end
@@ -42,6 +51,12 @@ module Faraday
42
51
  #
43
52
  # resp = test.get '/items/2'
44
53
  # resp.body # => 'showing item: 2'
54
+ #
55
+ # resp = test.post '/bar', 'name=YK&word=call'
56
+ # resp.status # => 200
57
+ #
58
+ # resp = test.post '/foo', JSON.dump(name: 'YK', created_at: Time.now)
59
+ # resp.status # => 200
45
60
  class Test < Faraday::Adapter
46
61
  attr_accessor :stubs
47
62
 
@@ -181,7 +196,7 @@ module Faraday
181
196
  [(host.nil? || host == request_host) &&
182
197
  path_match?(request_path, meta) &&
183
198
  params_match?(env) &&
184
- (body.to_s.size.zero? || request_body == body) &&
199
+ body_match?(request_body) &&
185
200
  headers_match?(request_headers), meta]
186
201
  end
187
202
 
@@ -222,6 +237,17 @@ module Faraday
222
237
  end
223
238
  end
224
239
 
240
+ def body_match?(request_body)
241
+ return true if body.to_s.size.zero?
242
+
243
+ case body
244
+ when Proc
245
+ body.call(request_body)
246
+ else
247
+ request_body == body
248
+ end
249
+ end
250
+
225
251
  def to_s
226
252
  "#{path} #{body}"
227
253
  end
@@ -6,9 +6,9 @@ module Faraday
6
6
  #
7
7
  # @example
8
8
  #
9
- # conn = Faraday::Connection.new 'http://sushi.com'
9
+ # conn = Faraday::Connection.new 'http://httpbingo.org'
10
10
  #
11
- # # GET http://sushi.com/nigiri
11
+ # # GET http://httpbingo.org/nigiri
12
12
  # conn.get 'nigiri'
13
13
  # # => #<Faraday::Response>
14
14
  #
@@ -349,11 +349,11 @@ module Faraday
349
349
  # @example
350
350
  #
351
351
  # conn = Faraday::Connection.new { ... }
352
- # conn.url_prefix = "https://sushi.com/api"
352
+ # conn.url_prefix = "https://httpbingo.org/api"
353
353
  # conn.scheme # => https
354
354
  # conn.path_prefix # => "/api"
355
355
  #
356
- # conn.get("nigiri?page=2") # accesses https://sushi.com/api/nigiri
356
+ # conn.get("nigiri?page=2") # accesses https://httpbingo.org/api/nigiri
357
357
  def url_prefix=(url, encoder = nil)
358
358
  uri = @url_prefix = Utils.URI(url)
359
359
  self.path_prefix = uri.path
@@ -395,15 +395,15 @@ module Faraday
395
395
  #
396
396
  # @example
397
397
  # conn = Faraday::Connection.new { ... }
398
- # conn.url_prefix = "https://sushi.com/api?token=abc"
398
+ # conn.url_prefix = "https://httpbingo.org/api?token=abc"
399
399
  # conn.scheme # => https
400
400
  # conn.path_prefix # => "/api"
401
401
  #
402
402
  # conn.build_url("nigiri?page=2")
403
- # # => https://sushi.com/api/nigiri?token=abc&page=2
403
+ # # => https://httpbingo.org/api/nigiri?token=abc&page=2
404
404
  #
405
405
  # conn.build_url("nigiri", page: 2)
406
- # # => https://sushi.com/api/nigiri?token=abc&page=2
406
+ # # => https://httpbingo.org/api/nigiri?token=abc&page=2
407
407
  #
408
408
  def build_url(url = nil, extra_params = nil)
409
409
  uri = build_exclusive_url(url)
@@ -62,11 +62,17 @@ module Faraday
62
62
  end
63
63
 
64
64
  def encode_array(parent, value)
65
- new_parent = "#{parent}%5B%5D"
66
- return new_parent if value.empty?
65
+ return "#{parent}%5B%5D" if value.empty?
67
66
 
68
67
  buffer = +''
69
- value.each { |val| buffer << "#{encode_pair(new_parent, val)}&" }
68
+ value.each_with_index do |val, index|
69
+ new_parent = if @array_indices
70
+ "#{parent}%5B#{index}%5D"
71
+ else
72
+ "#{parent}%5B%5D"
73
+ end
74
+ buffer << "#{encode_pair(new_parent, val)}&"
75
+ end
70
76
  buffer.chop
71
77
  end
72
78
  end
@@ -161,7 +167,7 @@ module Faraday
161
167
  # for your requests.
162
168
  module NestedParamsEncoder
163
169
  class << self
164
- attr_accessor :sort_params
170
+ attr_accessor :sort_params, :array_indices
165
171
 
166
172
  extend Forwardable
167
173
  def_delegators :'Faraday::Utils', :escape, :unescape
@@ -169,6 +175,7 @@ module Faraday
169
175
 
170
176
  # Useful default for OAuth and caching.
171
177
  @sort_params = true
178
+ @array_indices = false
172
179
 
173
180
  extend EncodeMethods
174
181
  extend DecodeMethods
@@ -53,13 +53,31 @@ module Faraday
53
53
  # Faraday::Middleware.lookup_middleware(:foo)
54
54
  # # => Faraday::Whatever
55
55
  def lookup_middleware(key)
56
- registered_middleware[key] ||
56
+ load_middleware(key) ||
57
57
  raise(Faraday::Error, "#{key.inspect} is not registered on #{self}")
58
58
  end
59
59
 
60
+ private
61
+
60
62
  def middleware_mutex(&block)
61
63
  @middleware_mutex ||= Monitor.new
62
64
  @middleware_mutex.synchronize(&block)
63
65
  end
66
+
67
+ def load_middleware(key)
68
+ value = registered_middleware[key]
69
+ case value
70
+ when Module
71
+ value
72
+ when Symbol, String
73
+ middleware_mutex do
74
+ @registered_middleware[key] = const_get(value)
75
+ end
76
+ when Proc
77
+ middleware_mutex do
78
+ @registered_middleware[key] = value.call
79
+ end
80
+ end
81
+ end
64
82
  end
65
83
  end
@@ -6,6 +6,10 @@ module Faraday
6
6
  # @!attribute verify
7
7
  # @return [Boolean] whether to verify SSL certificates or not
8
8
  #
9
+ # @!attribute verify_hostname
10
+ # @return [Boolean] whether to enable hostname verification on server certificates
11
+ # during the handshake or not (see https://github.com/ruby/openssl/pull/60)
12
+ #
9
13
  # @!attribute ca_file
10
14
  # @return [String] CA file
11
15
  #
@@ -41,7 +45,8 @@ module Faraday
41
45
  #
42
46
  # @!attribute max_version
43
47
  # @return [String, Symbol] maximum SSL version (see https://ruby-doc.org/stdlib-2.5.1/libdoc/openssl/rdoc/OpenSSL/SSL/SSLContext.html#method-i-max_version-3D)
44
- class SSLOptions < Options.new(:verify, :ca_file, :ca_path, :verify_mode,
48
+ class SSLOptions < Options.new(:verify, :verify_hostname,
49
+ :ca_file, :ca_path, :verify_mode,
45
50
  :cert_store, :client_cert, :client_key,
46
51
  :certificate, :private_key, :verify_depth,
47
52
  :version, :min_version, :max_version)
@@ -55,5 +60,10 @@ module Faraday
55
60
  def disable?
56
61
  !verify?
57
62
  end
63
+
64
+ # @return [Boolean] true if should verify_hostname
65
+ def verify_hostname?
66
+ verify_hostname != false
67
+ end
58
68
  end
59
69
  end
@@ -8,7 +8,7 @@ module Faraday
8
8
  # middleware stack (heavily inspired by Rack).
9
9
  #
10
10
  # @example
11
- # Faraday::Connection.new(url: 'http://sushi.com') do |builder|
11
+ # Faraday::Connection.new(url: 'http://httpbingo.org') do |builder|
12
12
  # builder.request :url_encoded # Faraday::Request::UrlEncoded
13
13
  # builder.adapter :net_http # Faraday::Adapter::NetHttp
14
14
  # end
@@ -31,7 +31,9 @@ module Faraday
31
31
  return unless process_request?(env)
32
32
 
33
33
  env.request_headers[CONTENT_TYPE] ||= self.class.mime_type
34
- yield(env.body) unless env.body.respond_to?(:to_str)
34
+ return if env.body.respond_to?(:to_str) || env.body.respond_to?(:read)
35
+
36
+ yield(env.body)
35
37
  end
36
38
 
37
39
  # @param env [Faraday::Env]
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Faraday
4
- VERSION = '2.1.0'
4
+ VERSION = '2.4.0'
5
5
  end
data/lib/faraday.rb CHANGED
@@ -47,7 +47,7 @@ module Faraday
47
47
 
48
48
  # @overload default_adapter
49
49
  # Gets the Symbol key identifying a default Adapter to use
50
- # for the default {Faraday::Connection}. Defaults to `:test`.
50
+ # for the default {Faraday::Connection}. Defaults to `:net_http`.
51
51
  # @return [Symbol] the default adapter
52
52
  # @overload default_adapter=(adapter)
53
53
  # Updates default adapter while resetting {.default_connection}.
@@ -373,5 +373,41 @@ RSpec.describe Faraday::Adapter::Test do
373
373
  it_behaves_like 'does not raise NotFound even when headers do not satisfy the strict check', '/with_user_agent', { authorization: 'Bearer m_ck', user_agent: 'My Agent' }
374
374
  it_behaves_like 'does not raise NotFound even when headers do not satisfy the strict check', '/with_user_agent', { authorization: 'Bearer m_ck', user_agent: 'My Agent', x_special: 'special' }
375
375
  end
376
+
377
+ describe 'body_match?' do
378
+ let(:stubs) do
379
+ described_class::Stubs.new do |stubs|
380
+ stubs.post('/no_check') { [200, {}, 'ok'] }
381
+ stubs.post('/with_string', 'abc') { [200, {}, 'ok'] }
382
+ stubs.post(
383
+ '/with_proc',
384
+ ->(request_body) { JSON.parse(request_body, symbolize_names: true) == { x: '!', a: [{ m: [{ a: true }], n: 123 }] } },
385
+ { content_type: 'application/json' }
386
+ ) do
387
+ [200, {}, 'ok']
388
+ end
389
+ end
390
+ end
391
+
392
+ context 'when trying without any args for body' do
393
+ subject(:without_body) { connection.post('/no_check') }
394
+
395
+ it { expect(without_body.status).to eq 200 }
396
+ end
397
+
398
+ context 'when trying with string body stubs' do
399
+ subject(:with_string) { connection.post('/with_string', 'abc') }
400
+
401
+ it { expect(with_string.status).to eq 200 }
402
+ end
403
+
404
+ context 'when trying with proc body stubs' do
405
+ subject(:with_proc) do
406
+ connection.post('/with_proc', JSON.dump(a: [{ n: 123, m: [{ a: true }] }], x: '!'), { 'Content-Type' => 'application/json' })
407
+ end
408
+
409
+ it { expect(with_proc.status).to eq 200 }
410
+ end
411
+ end
376
412
  end
377
413
  end
@@ -12,9 +12,9 @@ end
12
12
 
13
13
  shared_examples 'initializer with url' do
14
14
  context 'with simple url' do
15
- let(:address) { 'http://sushi.com' }
15
+ let(:address) { 'http://httpbingo.org' }
16
16
 
17
- it { expect(subject.host).to eq('sushi.com') }
17
+ it { expect(subject.host).to eq('httpbingo.org') }
18
18
  it { expect(subject.port).to eq(80) }
19
19
  it { expect(subject.scheme).to eq('http') }
20
20
  it { expect(subject.path_prefix).to eq('/') }
@@ -22,7 +22,7 @@ shared_examples 'initializer with url' do
22
22
  end
23
23
 
24
24
  context 'with complex url' do
25
- let(:address) { 'http://sushi.com:815/fish?a=1' }
25
+ let(:address) { 'http://httpbingo.org:815/fish?a=1' }
26
26
 
27
27
  it { expect(subject.port).to eq(815) }
28
28
  it { expect(subject.path_prefix).to eq('/fish') }
@@ -41,17 +41,17 @@ shared_examples 'default connection options' do
41
41
  after { Faraday.default_connection_options = nil }
42
42
 
43
43
  it 'works with implicit url' do
44
- conn = Faraday.new 'http://sushi.com/foo'
44
+ conn = Faraday.new 'http://httpbingo.org/foo'
45
45
  expect(conn.options.timeout).to eq(10)
46
46
  end
47
47
 
48
48
  it 'works with option url' do
49
- conn = Faraday.new url: 'http://sushi.com/foo'
49
+ conn = Faraday.new url: 'http://httpbingo.org/foo'
50
50
  expect(conn.options.timeout).to eq(10)
51
51
  end
52
52
 
53
53
  it 'works with instance connection options' do
54
- conn = Faraday.new 'http://sushi.com/foo', request: { open_timeout: 1 }
54
+ conn = Faraday.new 'http://httpbingo.org/foo', request: { open_timeout: 1 }
55
55
  expect(conn.options.timeout).to eq(10)
56
56
  expect(conn.options.open_timeout).to eq(1)
57
57
  end
@@ -61,7 +61,7 @@ shared_examples 'default connection options' do
61
61
  conn.options.timeout = 1
62
62
  expect(Faraday.default_connection_options.request.timeout).to eq(10)
63
63
 
64
- other = Faraday.new url: 'https://sushi.com/foo'
64
+ other = Faraday.new url: 'https://httpbingo.org/foo'
65
65
  other.options.timeout = 1
66
66
 
67
67
  expect(Faraday.default_connection_options.request.timeout).to eq(10)
@@ -81,14 +81,14 @@ RSpec.describe Faraday::Connection do
81
81
  subject { conn }
82
82
 
83
83
  context 'with implicit url param' do
84
- # Faraday::Connection.new('http://sushi.com')
84
+ # Faraday::Connection.new('http://httpbingo.org')
85
85
  let(:url) { address }
86
86
 
87
87
  it_behaves_like 'initializer with url'
88
88
  end
89
89
 
90
90
  context 'with explicit url param' do
91
- # Faraday::Connection.new(url: 'http://sushi.com')
91
+ # Faraday::Connection.new(url: 'http://httpbingo.org')
92
92
  let(:url) { { url: address } }
93
93
 
94
94
  it_behaves_like 'initializer with url'
@@ -108,13 +108,13 @@ RSpec.describe Faraday::Connection do
108
108
  end
109
109
 
110
110
  context 'with custom params and params in url' do
111
- let(:url) { 'http://sushi.com/fish?a=1&b=2' }
111
+ let(:url) { 'http://httpbingo.org/fish?a=1&b=2' }
112
112
  let(:options) { { params: { a: 3 } } }
113
113
  it { expect(subject.params).to eq('a' => 3, 'b' => '2') }
114
114
  end
115
115
 
116
116
  context 'with basic_auth in url' do
117
- let(:url) { 'http://Aladdin:open%20sesame@sushi.com/fish' }
117
+ let(:url) { 'http://Aladdin:open%20sesame@httpbingo.org/fish' }
118
118
 
119
119
  it { expect(subject.headers['Authorization']).to eq('Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==') }
120
120
  end
@@ -131,6 +131,12 @@ RSpec.describe Faraday::Connection do
131
131
  it { expect(subject.ssl.verify?).to be_falsey }
132
132
  end
133
133
 
134
+ context 'with verify_hostname false' do
135
+ let(:options) { { ssl: { verify_hostname: false } } }
136
+
137
+ it { expect(subject.ssl.verify_hostname?).to be_falsey }
138
+ end
139
+
134
140
  context 'with empty block' do
135
141
  let(:conn) { Faraday::Connection.new {} }
136
142
 
@@ -141,7 +147,7 @@ RSpec.describe Faraday::Connection do
141
147
  let(:conn) do
142
148
  Faraday::Connection.new(params: { 'a' => '1' }) do |faraday|
143
149
  faraday.adapter :test
144
- faraday.url_prefix = 'http://sushi.com/omnom'
150
+ faraday.url_prefix = 'http://httpbingo.org/omnom'
145
151
  end
146
152
  end
147
153
 
@@ -165,8 +171,8 @@ RSpec.describe Faraday::Connection do
165
171
  subject { conn.build_exclusive_url('sake.html') }
166
172
 
167
173
  it 'uses connection host as default host' do
168
- conn.host = 'sushi.com'
169
- expect(subject.host).to eq('sushi.com')
174
+ conn.host = 'httpbingo.org'
175
+ expect(subject.host).to eq('httpbingo.org')
170
176
  expect(subject.scheme).to eq('http')
171
177
  end
172
178
 
@@ -203,10 +209,10 @@ RSpec.describe Faraday::Connection do
203
209
  end
204
210
 
205
211
  context 'with complete url' do
206
- subject { conn.build_exclusive_url('http://sushi.com/sake.html?a=1') }
212
+ subject { conn.build_exclusive_url('http://httpbingo.org/sake.html?a=1') }
207
213
 
208
214
  it { expect(subject.scheme).to eq('http') }
209
- it { expect(subject.host).to eq('sushi.com') }
215
+ it { expect(subject.host).to eq('httpbingo.org') }
210
216
  it { expect(subject.port).to eq(80) }
211
217
  it { expect(subject.path).to eq('/sake.html') }
212
218
  it { expect(subject.query).to eq('a=1') }
@@ -214,35 +220,35 @@ RSpec.describe Faraday::Connection do
214
220
 
215
221
  it 'overrides connection port for absolute url' do
216
222
  conn.port = 23
217
- uri = conn.build_exclusive_url('http://sushi.com')
223
+ uri = conn.build_exclusive_url('http://httpbingo.org')
218
224
  expect(uri.port).to eq(80)
219
225
  end
220
226
 
221
227
  it 'does not add ending slash given nil url' do
222
- conn.url_prefix = 'http://sushi.com/nigiri'
228
+ conn.url_prefix = 'http://httpbingo.org/nigiri'
223
229
  uri = conn.build_exclusive_url
224
230
  expect(uri.path).to eq('/nigiri')
225
231
  end
226
232
 
227
233
  it 'does not add ending slash given empty url' do
228
- conn.url_prefix = 'http://sushi.com/nigiri'
234
+ conn.url_prefix = 'http://httpbingo.org/nigiri'
229
235
  uri = conn.build_exclusive_url('')
230
236
  expect(uri.path).to eq('/nigiri')
231
237
  end
232
238
 
233
239
  it 'does not use connection params' do
234
- conn.url_prefix = 'http://sushi.com/nigiri'
240
+ conn.url_prefix = 'http://httpbingo.org/nigiri'
235
241
  conn.params = { a: 1 }
236
- expect(conn.build_exclusive_url.to_s).to eq('http://sushi.com/nigiri')
242
+ expect(conn.build_exclusive_url.to_s).to eq('http://httpbingo.org/nigiri')
237
243
  end
238
244
 
239
245
  it 'allows to provide params argument' do
240
- conn.url_prefix = 'http://sushi.com/nigiri'
246
+ conn.url_prefix = 'http://httpbingo.org/nigiri'
241
247
  conn.params = { a: 1 }
242
248
  params = Faraday::Utils::ParamsHash.new
243
249
  params[:a] = 2
244
250
  uri = conn.build_exclusive_url(nil, params)
245
- expect(uri.to_s).to eq('http://sushi.com/nigiri?a=2')
251
+ expect(uri.to_s).to eq('http://httpbingo.org/nigiri?a=2')
246
252
  end
247
253
 
248
254
  it 'handles uri instances' do
@@ -251,34 +257,34 @@ RSpec.describe Faraday::Connection do
251
257
  end
252
258
 
253
259
  it 'always returns new URI instance' do
254
- conn.url_prefix = 'http://sushi.com'
260
+ conn.url_prefix = 'http://httpbingo.org'
255
261
  uri1 = conn.build_exclusive_url(nil)
256
262
  uri2 = conn.build_exclusive_url(nil)
257
263
  expect(uri1).not_to equal(uri2)
258
264
  end
259
265
 
260
266
  context 'with url_prefixed connection' do
261
- let(:url) { 'http://sushi.com/sushi/' }
267
+ let(:url) { 'http://httpbingo.org/get/' }
262
268
 
263
269
  it 'parses url and changes scheme' do
264
270
  conn.scheme = 'https'
265
271
  uri = conn.build_exclusive_url('sake.html')
266
- expect(uri.to_s).to eq('https://sushi.com/sushi/sake.html')
272
+ expect(uri.to_s).to eq('https://httpbingo.org/get/sake.html')
267
273
  end
268
274
 
269
275
  it 'joins url to base with ending slash' do
270
276
  uri = conn.build_exclusive_url('sake.html')
271
- expect(uri.to_s).to eq('http://sushi.com/sushi/sake.html')
277
+ expect(uri.to_s).to eq('http://httpbingo.org/get/sake.html')
272
278
  end
273
279
 
274
280
  it 'used default base with ending slash' do
275
281
  uri = conn.build_exclusive_url
276
- expect(uri.to_s).to eq('http://sushi.com/sushi/')
282
+ expect(uri.to_s).to eq('http://httpbingo.org/get/')
277
283
  end
278
284
 
279
285
  it 'overrides base' do
280
286
  uri = conn.build_exclusive_url('/sake/')
281
- expect(uri.to_s).to eq('http://sushi.com/sake/')
287
+ expect(uri.to_s).to eq('http://httpbingo.org/sake/')
282
288
  end
283
289
  end
284
290
 
@@ -307,22 +313,22 @@ RSpec.describe Faraday::Connection do
307
313
  end
308
314
 
309
315
  describe '#build_url' do
310
- let(:url) { 'http://sushi.com/nigiri' }
316
+ let(:url) { 'http://httpbingo.org/nigiri' }
311
317
 
312
318
  it 'uses params' do
313
319
  conn.params = { a: 1, b: 1 }
314
- expect(conn.build_url.to_s).to eq('http://sushi.com/nigiri?a=1&b=1')
320
+ expect(conn.build_url.to_s).to eq('http://httpbingo.org/nigiri?a=1&b=1')
315
321
  end
316
322
 
317
323
  it 'merges params' do
318
324
  conn.params = { a: 1, b: 1 }
319
325
  url = conn.build_url(nil, b: 2, c: 3)
320
- expect(url.to_s).to eq('http://sushi.com/nigiri?a=1&b=2&c=3')
326
+ expect(url.to_s).to eq('http://httpbingo.org/nigiri?a=1&b=2&c=3')
321
327
  end
322
328
  end
323
329
 
324
330
  describe '#build_request' do
325
- let(:url) { 'https://asushi.com/sake.html' }
331
+ let(:url) { 'https://ahttpbingo.org/sake.html' }
326
332
  let(:request) { conn.build_request(:get) }
327
333
 
328
334
  before do
@@ -339,7 +345,7 @@ RSpec.describe Faraday::Connection do
339
345
  describe '#to_env' do
340
346
  subject { conn.build_request(:get).to_env(conn).url }
341
347
 
342
- let(:url) { 'http://sushi.com/sake.html' }
348
+ let(:url) { 'http://httpbingo.org/sake.html' }
343
349
  let(:options) { { params: @params } }
344
350
 
345
351
  it 'parses url params into query' do
@@ -592,7 +598,7 @@ RSpec.describe Faraday::Connection do
592
598
  describe '#dup' do
593
599
  subject { conn.dup }
594
600
 
595
- let(:url) { 'http://sushi.com/foo' }
601
+ let(:url) { 'http://httpbingo.org/foo' }
596
602
  let(:options) do
597
603
  {
598
604
  ssl: { verify: :none },
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Faraday::MiddlewareRegistry do
4
+ before do
5
+ stub_const('CustomMiddleware', custom_middleware_klass)
6
+ end
7
+ let(:custom_middleware_klass) { Class.new(Faraday::Middleware) }
8
+ let(:dummy) { Class.new { extend Faraday::MiddlewareRegistry } }
9
+
10
+ after { dummy.unregister_middleware(:custom) }
11
+
12
+ it 'allows to register with constant' do
13
+ dummy.register_middleware(custom: custom_middleware_klass)
14
+ expect(dummy.lookup_middleware(:custom)).to eq(custom_middleware_klass)
15
+ end
16
+
17
+ it 'allows to register with symbol' do
18
+ dummy.register_middleware(custom: :CustomMiddleware)
19
+ expect(dummy.lookup_middleware(:custom)).to eq(custom_middleware_klass)
20
+ end
21
+
22
+ it 'allows to register with string' do
23
+ dummy.register_middleware(custom: 'CustomMiddleware')
24
+ expect(dummy.lookup_middleware(:custom)).to eq(custom_middleware_klass)
25
+ end
26
+
27
+ it 'allows to register with Proc' do
28
+ dummy.register_middleware(custom: -> { custom_middleware_klass })
29
+ expect(dummy.lookup_middleware(:custom)).to eq(custom_middleware_klass)
30
+ end
31
+ end
@@ -27,6 +27,12 @@ RSpec.describe Faraday::Env do
27
27
  expect(ssl.fetch(:verify, true)).to be_falsey
28
28
  end
29
29
 
30
+ it 'handle verify_hostname when fetching' do
31
+ ssl = Faraday::SSLOptions.new
32
+ ssl.verify_hostname = true
33
+ expect(ssl.fetch(:verify_hostname, false)).to be_truthy
34
+ end
35
+
30
36
  it 'retains custom members' do
31
37
  env[:foo] = 'custom 1'
32
38
  env[:bar] = :custom2
@@ -102,6 +102,14 @@ RSpec.describe Faraday::NestedParamsEncoder do
102
102
  Faraday::NestedParamsEncoder.sort_params = true
103
103
  end
104
104
 
105
+ it 'encodes arrays indices when asked' do
106
+ params = { a: [0, 1, 2] }
107
+ expect(subject.encode(params)).to eq('a%5B%5D=0&a%5B%5D=1&a%5B%5D=2')
108
+ Faraday::NestedParamsEncoder.array_indices = true
109
+ expect(subject.encode(params)).to eq('a%5B0%5D=0&a%5B1%5D=1&a%5B2%5D=2')
110
+ Faraday::NestedParamsEncoder.array_indices = false
111
+ end
112
+
105
113
  shared_examples 'a wrong decoding' do
106
114
  it do
107
115
  expect { subject.decode(query) }.to raise_error(TypeError) do |e|
@@ -110,18 +110,6 @@ RSpec.describe Faraday::RackBuilder do
110
110
  end
111
111
  end
112
112
 
113
- context 'with custom registered middleware' do
114
- let(:conn) { Faraday::Connection.new {} }
115
-
116
- after { Faraday::Middleware.unregister_middleware(:apple) }
117
-
118
- it 'allows to register with constant' do
119
- Faraday::Middleware.register_middleware(apple: Apple)
120
- subject.use(:apple)
121
- expect(subject.handlers).to eq([Apple])
122
- end
123
- end
124
-
125
113
  context 'when having two handlers' do
126
114
  let(:conn) { Faraday::Connection.new {} }
127
115
 
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'stringio'
4
+
3
5
  RSpec.describe Faraday::Request::UrlEncoded do
4
6
  let(:conn) do
5
7
  Faraday.new do |b|
@@ -7,7 +9,11 @@ RSpec.describe Faraday::Request::UrlEncoded do
7
9
  b.adapter :test do |stub|
8
10
  stub.post('/echo') do |env|
9
11
  posted_as = env[:request_headers]['Content-Type']
10
- [200, { 'Content-Type' => posted_as }, env[:body]]
12
+ body = env[:body]
13
+ if body.respond_to?(:read)
14
+ body = body.read
15
+ end
16
+ [200, { 'Content-Type' => posted_as }, body]
11
17
  end
12
18
  end
13
19
  end
@@ -67,6 +73,11 @@ RSpec.describe Faraday::Request::UrlEncoded do
67
73
  expect(response.body).to eq('a%5Bb%5D%5Bc%5D%5B%5D=d')
68
74
  end
69
75
 
76
+ it 'works with files' do
77
+ response = conn.post('/echo', StringIO.new('str=apple'))
78
+ expect(response.body).to eq('str=apple')
79
+ end
80
+
70
81
  context 'customising default_space_encoding' do
71
82
  around do |example|
72
83
  Faraday::Utils.default_space_encoding = '%20'
@@ -2,7 +2,7 @@
2
2
 
3
3
  RSpec.describe Faraday::Request do
4
4
  let(:conn) do
5
- Faraday.new(url: 'http://sushi.com/api',
5
+ Faraday.new(url: 'http://httpbingo.org/api',
6
6
  headers: { 'Mime-Version' => '1.0' },
7
7
  request: { oauth: { consumer_key: 'anonymous' } })
8
8
  end
@@ -14,6 +14,7 @@ RSpec.describe Faraday::Request do
14
14
  context 'when nothing particular is configured' do
15
15
  it { expect(subject.http_method).to eq(:get) }
16
16
  it { expect(subject.to_env(conn).ssl.verify).to be_falsey }
17
+ it { expect(subject.to_env(conn).ssl.verify_hostname).to be_falsey }
17
18
  end
18
19
 
19
20
  context 'when HTTP method is post' do
@@ -27,7 +28,7 @@ RSpec.describe Faraday::Request do
27
28
 
28
29
  it { expect(subject.path).to eq(URI.parse('foo.json')) }
29
30
  it { expect(subject.params).to eq('a' => '1') }
30
- it { expect(subject.to_env(conn).url.to_s).to eq('http://sushi.com/api/foo.json?a=1') }
31
+ it { expect(subject.to_env(conn).url.to_s).to eq('http://httpbingo.org/api/foo.json?a=1') }
31
32
  end
32
33
 
33
34
  context 'when setting the url on setup with a string path and params' do
@@ -35,7 +36,7 @@ RSpec.describe Faraday::Request do
35
36
 
36
37
  it { expect(subject.path).to eq('foo.json') }
37
38
  it { expect(subject.params).to eq('a' => 1) }
38
- it { expect(subject.to_env(conn).url.to_s).to eq('http://sushi.com/api/foo.json?a=1') }
39
+ it { expect(subject.to_env(conn).url.to_s).to eq('http://httpbingo.org/api/foo.json?a=1') }
39
40
  end
40
41
 
41
42
  context 'when setting the url on setup with a path including params' do
@@ -43,7 +44,7 @@ RSpec.describe Faraday::Request do
43
44
 
44
45
  it { expect(subject.path).to eq('foo.json') }
45
46
  it { expect(subject.params).to eq('a' => '1', 'b' => '2') }
46
- it { expect(subject.to_env(conn).url.to_s).to eq('http://sushi.com/api/foo.json?a=1&b=2') }
47
+ it { expect(subject.to_env(conn).url.to_s).to eq('http://httpbingo.org/api/foo.json?a=1&b=2') }
47
48
  end
48
49
 
49
50
  context 'when setting a header on setup with []= syntax' do
@@ -68,9 +68,9 @@ RSpec.describe Faraday::Utils::Headers do
68
68
  end
69
69
 
70
70
  context 'when response headers values include a colon' do
71
- let(:headers) { "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nLocation: http://sushi.com/\r\n\r\n" }
71
+ let(:headers) { "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nLocation: http://httpbingo.org/\r\n\r\n" }
72
72
 
73
- it { expect(subject['location']).to eq('http://sushi.com/') }
73
+ it { expect(subject['location']).to eq('http://httpbingo.org/') }
74
74
  end
75
75
 
76
76
  context 'when response headers include a blank line' do
@@ -102,7 +102,8 @@ RSpec.describe Faraday::Utils do
102
102
  verify_depth: nil,
103
103
  version: '2',
104
104
  min_version: nil,
105
- max_version: nil
105
+ max_version: nil,
106
+ verify_hostname: nil
106
107
  }
107
108
  end
108
109
 
@@ -38,6 +38,7 @@ shared_examples 'adapter examples' do |**options|
38
38
  let(:conn) do
39
39
  conn_options[:ssl] ||= {}
40
40
  conn_options[:ssl][:ca_file] ||= ENV['SSL_FILE']
41
+ conn_options[:ssl][:verify_hostname] ||= ENV['SSL_VERIFY_HOSTNAME'] == 'yes'
41
42
 
42
43
  Faraday.new(remote, conn_options) do |conn|
43
44
  conn.request :url_encoded
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: 2.1.0
4
+ version: 2.4.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: 2022-01-15 00:00:00.000000000 Z
13
+ date: 2022-07-28 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: faraday-net_http
@@ -91,6 +91,7 @@ files:
91
91
  - spec/faraday/adapter_spec.rb
92
92
  - spec/faraday/connection_spec.rb
93
93
  - spec/faraday/error_spec.rb
94
+ - spec/faraday/middleware_registry_spec.rb
94
95
  - spec/faraday/middleware_spec.rb
95
96
  - spec/faraday/options/env_spec.rb
96
97
  - spec/faraday/options/options_spec.rb
@@ -124,7 +125,7 @@ licenses:
124
125
  - MIT
125
126
  metadata:
126
127
  homepage_uri: https://lostisland.github.io/faraday
127
- changelog_uri: https://github.com/lostisland/faraday/releases/tag/v2.1.0
128
+ changelog_uri: https://github.com/lostisland/faraday/releases/tag/v2.4.0
128
129
  source_code_uri: https://github.com/lostisland/faraday
129
130
  bug_tracker_uri: https://github.com/lostisland/faraday/issues
130
131
  post_install_message: