faraday 0.8.11 → 0.9.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 (68) hide show
  1. checksums.yaml +4 -4
  2. data/.document +6 -0
  3. data/CHANGELOG.md +15 -0
  4. data/CONTRIBUTING.md +36 -0
  5. data/Gemfile +10 -3
  6. data/LICENSE.md +1 -1
  7. data/README.md +17 -51
  8. data/Rakefile +2 -18
  9. data/faraday.gemspec +34 -0
  10. data/lib/faraday/adapter/em_http.rb +34 -0
  11. data/lib/faraday/adapter/em_http_ssl_patch.rb +56 -0
  12. data/lib/faraday/adapter/em_synchrony.rb +11 -24
  13. data/lib/faraday/adapter/excon.rb +12 -2
  14. data/lib/faraday/adapter/httpclient.rb +106 -0
  15. data/lib/faraday/adapter/net_http.rb +10 -6
  16. data/lib/faraday/adapter/patron.rb +2 -8
  17. data/lib/faraday/adapter/rack.rb +0 -2
  18. data/lib/faraday/adapter/test.rb +39 -39
  19. data/lib/faraday/adapter/typhoeus.rb +12 -3
  20. data/lib/faraday/adapter.rb +20 -35
  21. data/lib/faraday/autoload.rb +85 -0
  22. data/lib/faraday/connection.rb +232 -125
  23. data/lib/faraday/error.rb +42 -34
  24. data/lib/faraday/options.rb +350 -0
  25. data/lib/faraday/parameters.rb +193 -0
  26. data/lib/faraday/{builder.rb → rack_builder.rb} +79 -22
  27. data/lib/faraday/request/authorization.rb +7 -5
  28. data/lib/faraday/request/basic_authentication.rb +1 -1
  29. data/lib/faraday/request/instrumentation.rb +36 -0
  30. data/lib/faraday/request/multipart.rb +10 -9
  31. data/lib/faraday/request/retry.rb +99 -4
  32. data/lib/faraday/request/token_authentication.rb +2 -2
  33. data/lib/faraday/request/url_encoded.rb +7 -6
  34. data/lib/faraday/request.rb +21 -30
  35. data/lib/faraday/response/logger.rb +4 -4
  36. data/lib/faraday/response/raise_error.rb +4 -2
  37. data/lib/faraday/response.rb +17 -23
  38. data/lib/faraday/utils.rb +81 -71
  39. data/lib/faraday.rb +187 -68
  40. data/script/console +7 -0
  41. data/script/proxy-server +1 -0
  42. data/script/release +6 -3
  43. data/script/test +4 -2
  44. data/test/adapters/em_http_test.rb +6 -1
  45. data/test/adapters/em_synchrony_test.rb +7 -1
  46. data/test/adapters/httpclient_test.rb +21 -0
  47. data/test/adapters/integration.rb +23 -8
  48. data/test/adapters/logger_test.rb +1 -1
  49. data/test/adapters/net_http_persistent_test.rb +10 -1
  50. data/test/adapters/net_http_test.rb +0 -31
  51. data/test/adapters/patron_test.rb +4 -1
  52. data/test/adapters/test_middleware_test.rb +48 -4
  53. data/test/adapters/typhoeus_test.rb +8 -1
  54. data/test/authentication_middleware_test.rb +2 -2
  55. data/test/connection_test.rb +160 -84
  56. data/test/env_test.rb +51 -24
  57. data/test/helper.rb +13 -13
  58. data/test/live_server.rb +8 -0
  59. data/test/middleware/instrumentation_test.rb +88 -0
  60. data/test/middleware/retry_test.rb +88 -35
  61. data/test/middleware_stack_test.rb +13 -12
  62. data/test/options_test.rb +252 -0
  63. data/test/request_middleware_test.rb +11 -1
  64. data/test/response_middleware_test.rb +2 -4
  65. data/test/strawberry.rb +2 -0
  66. data/test/utils_test.rb +34 -6
  67. metadata +71 -11
  68. data/test/parameters_test.rb +0 -24
@@ -1,5 +1,6 @@
1
1
  require 'forwardable'
2
2
  require File.expand_path("../../helper", __FILE__)
3
+ Faraday.require_lib 'autoload'
3
4
 
4
5
  module Adapters
5
6
  # Adapter integration tests. To use, implement two methods:
@@ -11,6 +12,7 @@ module Adapters
11
12
  if base.live_server?
12
13
  features = [:Common]
13
14
  features.concat extra_features
15
+ features << :SSL if base.ssl_mode?
14
16
  features.each {|name| base.send(:include, self.const_get(name)) }
15
17
  yield if block_given?
16
18
  elsif !defined? @warned
@@ -61,6 +63,17 @@ module Adapters
61
63
  end
62
64
  end
63
65
 
66
+ module SSL
67
+ def test_GET_ssl_fails_with_bad_cert
68
+ ca_file = 'tmp/faraday-different-ca-cert.crt'
69
+ conn = create_connection(:ssl => {:ca_file => ca_file})
70
+ err = assert_raises Faraday::SSLError do
71
+ conn.get('/ssl')
72
+ end
73
+ assert_includes err.message, "certificate"
74
+ end
75
+ end
76
+
64
77
  module Common
65
78
  extend Forwardable
66
79
  def_delegators :create_connection, :get, :head, :put, :post, :patch, :delete, :run_request
@@ -143,8 +156,7 @@ module Adapters
143
156
  end
144
157
 
145
158
  def test_HEAD_retrieves_no_response_body
146
- # FIXME: some adapters return empty string, some nil
147
- assert_equal '', head('echo').body.to_s
159
+ assert_equal '', head('echo').body
148
160
  end
149
161
 
150
162
  def test_HEAD_retrieves_the_response_headers
@@ -161,13 +173,13 @@ module Adapters
161
173
 
162
174
  def test_timeout
163
175
  conn = create_connection(:request => {:timeout => 1, :open_timeout => 1})
164
- assert_raise Faraday::Error::TimeoutError do
176
+ assert_raises Faraday::Error::TimeoutError do
165
177
  conn.get '/slow'
166
178
  end
167
179
  end
168
180
 
169
181
  def test_connection_error
170
- assert_raise Faraday::Error::ConnectionFailed do
182
+ assert_raises Faraday::Error::ConnectionFailed do
171
183
  get 'http://localhost:4'
172
184
  end
173
185
  end
@@ -190,18 +202,21 @@ module Adapters
190
202
  proxy_uri.password = 'WRONG'
191
203
  conn = create_connection(:proxy => proxy_uri)
192
204
 
193
- err = assert_raise Faraday::Error::ConnectionFailed do
205
+ err = assert_raises Faraday::Error::ConnectionFailed do
194
206
  conn.get '/echo'
195
207
  end
196
208
 
197
- unless self.class.ssl_mode? && (self.class.jruby? ||
198
- adapter == :em_http || adapter == :em_synchrony)
209
+ unless self.class.ssl_mode? && self.class.jruby?
199
210
  # JRuby raises "End of file reached" which cannot be distinguished from a 407
200
- # EM raises "connection closed by server" due to https://github.com/igrigorik/em-socksify/pull/19
201
211
  assert_equal %{407 "Proxy Authentication Required "}, err.message
202
212
  end
203
213
  end
204
214
 
215
+ def test_empty_body_response_represented_as_blank_string
216
+ response = get('204')
217
+ assert_equal '', response.body
218
+ end
219
+
205
220
  def adapter
206
221
  raise NotImplementedError.new("Need to override #adapter")
207
222
  end
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '..', 'helper'))
1
+ require File.expand_path('../../helper', __FILE__)
2
2
  require 'stringio'
3
3
  require 'logger'
4
4
 
@@ -5,7 +5,16 @@ module Adapters
5
5
 
6
6
  def adapter() :net_http_persistent end
7
7
 
8
- Integration.apply(self, :NonParallel)
8
+ Integration.apply(self, :NonParallel) do
9
+ def setup
10
+ if defined?(Net::HTTP::Persistent)
11
+ # work around problems with mixed SSL certificates
12
+ # https://github.com/drbrain/net-http-persistent/issues/45
13
+ http = Net::HTTP::Persistent.new('Faraday')
14
+ http.ssl_cleanup(4)
15
+ end
16
+ end if ssl_mode?
17
+ end
9
18
 
10
19
  end
11
20
  end
@@ -1,6 +1,4 @@
1
1
  require File.expand_path('../integration', __FILE__)
2
- require 'ostruct'
3
- require 'uri'
4
2
 
5
3
  module Adapters
6
4
  class NetHttpTest < Faraday::TestCase
@@ -12,34 +10,5 @@ module Adapters
12
10
 
13
11
  Integration.apply(self, *behaviors)
14
12
 
15
- def test_no_explicit_http_port_number
16
- url = URI('http://example.com')
17
- url.port = nil
18
-
19
- adapter = Faraday::Adapter::NetHttp.new
20
- http = adapter.net_http_connection(:url => url, :request => {})
21
-
22
- assert_equal 80, http.port
23
- end
24
-
25
- def test_no_explicit_https_port_number
26
- url = URI('https://example.com')
27
- url.port = nil
28
-
29
- adapter = Faraday::Adapter::NetHttp.new
30
- http = adapter.net_http_connection(:url => url, :request => {})
31
-
32
- assert_equal 443, http.port
33
- end
34
-
35
- def test_explicit_port_number
36
- url = URI('https://example.com:1234')
37
-
38
- adapter = Faraday::Adapter::NetHttp.new
39
- http = adapter.net_http_connection(:url => url, :request => {})
40
-
41
- assert_equal 1234, http.port
42
- end
43
-
44
13
  end
45
14
  end
@@ -11,7 +11,10 @@ module Adapters
11
11
 
12
12
  # https://github.com/toland/patron/issues/52
13
13
  undef :test_GET_with_body
14
- end unless RUBY_VERSION < '1.9' or jruby?
14
+
15
+ # no support for SSL peer verification
16
+ undef :test_GET_ssl_fails_with_bad_cert if ssl_mode?
17
+ end unless jruby?
15
18
 
16
19
  end
17
20
  end
@@ -1,9 +1,10 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '..', 'helper'))
1
+ require File.expand_path('../../helper', __FILE__)
2
2
 
3
3
  module Adapters
4
4
  class TestMiddleware < Faraday::TestCase
5
+ Stubs = Faraday::Adapter.lookup_middleware(:test)::Stubs
5
6
  def setup
6
- @stubs = Faraday::Adapter::Test::Stubs.new
7
+ @stubs = Stubs.new
7
8
  @conn = Faraday.new do |builder|
8
9
  builder.adapter :test, @stubs
9
10
  end
@@ -36,11 +37,18 @@ module Adapters
36
37
  @stubs.get('/optional?a=1') { [200, {}, 'a'] }
37
38
  assert_equal 'a', @conn.get('/optional?a=1&b=1').body
38
39
  assert_equal 'a', @conn.get('/optional?a=1').body
39
- assert_raise Faraday::Adapter::Test::Stubs::NotFound do
40
+ assert_raises Faraday::Adapter::Test::Stubs::NotFound do
40
41
  @conn.get('/optional')
41
42
  end
42
43
  end
43
44
 
45
+ def test_middleware_with_http_headers
46
+ @stubs.get('/yo', { 'X-HELLO' => 'hello' }) { [200, {}, 'a'] }
47
+ @stubs.get('/yo') { [200, {}, 'b'] }
48
+ assert_equal 'a', @conn.get('/yo') { |env| env.headers['X-HELLO'] = 'hello' }.body
49
+ assert_equal 'b', @conn.get('/yo').body
50
+ end
51
+
44
52
  def test_middleware_allow_different_outcomes_for_the_same_request
45
53
  @stubs.get('/hello') { [200, {'Content-Type' => 'text/html'}, 'hello'] }
46
54
  @stubs.get('/hello') { [200, {'Content-Type' => 'text/html'}, 'world'] }
@@ -61,10 +69,46 @@ module Adapters
61
69
  assert_equal 'a', @conn.get('http://foo.com/hello?a=1').body
62
70
  end
63
71
 
72
+ def test_parses_params_with_default_encoder
73
+ @stubs.get '/hello' do |env|
74
+ assert_equal '1', env[:params]['a']['b']
75
+ [200, {}, 'a']
76
+ end
77
+
78
+ assert_equal 'a', @conn.get('http://foo.com/hello?a[b]=1').body
79
+ end
80
+
81
+ def test_parses_params_with_nested_encoder
82
+ @stubs.get '/hello' do |env|
83
+ assert_equal '1', env[:params]['a']['b']
84
+ [200, {}, 'a']
85
+ end
86
+
87
+ @conn.options.params_encoder = Faraday::NestedParamsEncoder
88
+ assert_equal 'a', @conn.get('http://foo.com/hello?a[b]=1').body
89
+ end
90
+
91
+ def test_parses_params_with_flat_encoder
92
+ @stubs.get '/hello' do |env|
93
+ assert_equal '1', env[:params]['a[b]']
94
+ [200, {}, 'a']
95
+ end
96
+
97
+ @conn.options.params_encoder = Faraday::FlatParamsEncoder
98
+ assert_equal 'a', @conn.get('http://foo.com/hello?a[b]=1').body
99
+ end
100
+
64
101
  def test_raises_an_error_if_no_stub_is_found_for_request
65
- assert_raise Faraday::Adapter::Test::Stubs::NotFound do
102
+ assert_raises Stubs::NotFound do
66
103
  @conn.get('/invalid'){ [200, {}, []] }
67
104
  end
68
105
  end
106
+
107
+ def test_raises_an_error_if_no_stub_is_found_for_request_without_this_header
108
+ @stubs.get('/yo', { 'X-HELLO' => 'hello' }) { [200, {}, 'a'] }
109
+ assert_raises Faraday::Adapter::Test::Stubs::NotFound do
110
+ @conn.get('/yo')
111
+ end
112
+ end
69
113
  end
70
114
  end
@@ -15,7 +15,14 @@ module Adapters
15
15
 
16
16
  # inconsistent outcomes ranging from successful response to connection error
17
17
  undef :test_proxy_auth_fail if ssl_mode?
18
- end unless jruby? or ruby_22_plus?
19
18
 
19
+ def test_binds_local_socket
20
+ host = '1.2.3.4'
21
+ conn = create_connection :request => { :bind => { :host => host } }
22
+ assert_equal host, conn.options[:bind][:host]
23
+ end
24
+
25
+ end unless jruby?
20
26
  end
21
27
  end
28
+
@@ -1,9 +1,9 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
1
+ require File.expand_path('../helper', __FILE__)
2
2
 
3
3
  class AuthenticationMiddlewareTest < Faraday::TestCase
4
4
  def conn
5
5
  Faraday::Connection.new('http://example.net/') do |builder|
6
- yield builder
6
+ yield(builder)
7
7
  builder.adapter :test do |stub|
8
8
  stub.get('/auth-echo') do |env|
9
9
  [200, {}, env[:request_headers]['Authorization']]