faraday 0.9.1 → 0.17.3

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 (74) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +212 -0
  3. data/LICENSE.md +1 -1
  4. data/README.md +203 -28
  5. data/Rakefile +6 -64
  6. data/lib/faraday/adapter/em_http.rb +17 -11
  7. data/lib/faraday/adapter/em_http_ssl_patch.rb +1 -1
  8. data/lib/faraday/adapter/em_synchrony.rb +19 -5
  9. data/lib/faraday/adapter/excon.rb +13 -11
  10. data/lib/faraday/adapter/httpclient.rb +31 -9
  11. data/lib/faraday/adapter/net_http.rb +36 -14
  12. data/lib/faraday/adapter/net_http_persistent.rb +37 -17
  13. data/lib/faraday/adapter/patron.rb +44 -21
  14. data/lib/faraday/adapter/rack.rb +1 -1
  15. data/lib/faraday/adapter/test.rb +79 -28
  16. data/lib/faraday/adapter/typhoeus.rb +4 -115
  17. data/lib/faraday/adapter.rb +10 -1
  18. data/lib/faraday/autoload.rb +1 -1
  19. data/lib/faraday/connection.rb +72 -20
  20. data/lib/faraday/deprecate.rb +107 -0
  21. data/lib/faraday/error.rb +132 -27
  22. data/lib/faraday/options.rb +45 -22
  23. data/lib/faraday/parameters.rb +56 -39
  24. data/lib/faraday/rack_builder.rb +29 -4
  25. data/lib/faraday/request/authorization.rb +1 -2
  26. data/lib/faraday/request/multipart.rb +7 -2
  27. data/lib/faraday/request/retry.rb +84 -19
  28. data/lib/faraday/request.rb +22 -0
  29. data/lib/faraday/response/logger.rb +29 -8
  30. data/lib/faraday/response/raise_error.rb +7 -3
  31. data/lib/faraday/response.rb +9 -5
  32. data/lib/faraday/utils.rb +32 -3
  33. data/lib/faraday.rb +15 -36
  34. data/spec/faraday/deprecate_spec.rb +69 -0
  35. data/spec/faraday/error_spec.rb +102 -0
  36. data/spec/faraday/response/raise_error_spec.rb +106 -0
  37. data/spec/spec_helper.rb +105 -0
  38. data/test/adapters/em_http_test.rb +10 -0
  39. data/test/adapters/em_synchrony_test.rb +22 -10
  40. data/test/adapters/excon_test.rb +10 -0
  41. data/test/adapters/httpclient_test.rb +14 -1
  42. data/test/adapters/integration.rb +17 -8
  43. data/test/adapters/logger_test.rb +65 -11
  44. data/test/adapters/net_http_persistent_test.rb +96 -2
  45. data/test/adapters/net_http_test.rb +67 -2
  46. data/test/adapters/patron_test.rb +28 -8
  47. data/test/adapters/rack_test.rb +8 -1
  48. data/test/adapters/test_middleware_test.rb +46 -3
  49. data/test/adapters/typhoeus_test.rb +19 -9
  50. data/test/composite_read_io_test.rb +16 -18
  51. data/test/connection_test.rb +294 -78
  52. data/test/env_test.rb +55 -5
  53. data/test/helper.rb +11 -17
  54. data/test/middleware/retry_test.rb +115 -10
  55. data/test/middleware_stack_test.rb +97 -10
  56. data/test/options_test.rb +97 -16
  57. data/test/parameters_test.rb +94 -1
  58. data/test/request_middleware_test.rb +24 -40
  59. data/test/response_middleware_test.rb +4 -4
  60. data/test/utils_test.rb +40 -0
  61. metadata +21 -66
  62. data/.document +0 -6
  63. data/CONTRIBUTING.md +0 -36
  64. data/Gemfile +0 -25
  65. data/faraday.gemspec +0 -34
  66. data/script/cached-bundle +0 -46
  67. data/script/console +0 -7
  68. data/script/generate_certs +0 -42
  69. data/script/package +0 -7
  70. data/script/proxy-server +0 -42
  71. data/script/release +0 -17
  72. data/script/s3-put +0 -71
  73. data/script/server +0 -36
  74. data/script/test +0 -172
@@ -10,11 +10,105 @@ module Adapters
10
10
  if defined?(Net::HTTP::Persistent)
11
11
  # work around problems with mixed SSL certificates
12
12
  # https://github.com/drbrain/net-http-persistent/issues/45
13
- http = Net::HTTP::Persistent.new('Faraday')
14
- http.ssl_cleanup(4)
13
+ if Net::HTTP::Persistent.instance_method(:initialize).parameters.first == [:key, :name]
14
+ Net::HTTP::Persistent.new(name: 'Faraday').reconnect_ssl
15
+ else
16
+ Net::HTTP::Persistent.new('Faraday').ssl_cleanup(4)
17
+ end
15
18
  end
16
19
  end if ssl_mode?
20
+
21
+ def test_reuses_tcp_sockets
22
+ # Ensure that requests are not reused from previous tests
23
+ Thread.current.keys
24
+ .select { |key| key.to_s =~ /\Anet_http_persistent_Faraday_/ }
25
+ .each { |key| Thread.current[key] = nil }
26
+
27
+ sockets = []
28
+ tcp_socket_open_wrapped = Proc.new do |*args, &block|
29
+ socket = TCPSocket.__minitest_stub__open(*args, &block)
30
+ sockets << socket
31
+ socket
32
+ end
33
+
34
+ TCPSocket.stub :open, tcp_socket_open_wrapped do
35
+ conn = create_connection
36
+ conn.post("/echo", :foo => "bar")
37
+ conn.post("/echo", :foo => "baz")
38
+ end
39
+
40
+ assert_equal 1, sockets.count
41
+ end
42
+
43
+ def test_does_not_reuse_tcp_sockets_when_proxy_changes
44
+ # Ensure that requests are not reused from previous tests
45
+ Thread.current.keys
46
+ .select { |key| key.to_s =~ /\Anet_http_persistent_Faraday_/ }
47
+ .each { |key| Thread.current[key] = nil }
48
+
49
+ sockets = []
50
+ tcp_socket_open_wrapped = Proc.new do |*args, &block|
51
+ socket = TCPSocket.__minitest_stub__open(*args, &block)
52
+ sockets << socket
53
+ socket
54
+ end
55
+
56
+ TCPSocket.stub :open, tcp_socket_open_wrapped do
57
+ conn = create_connection
58
+ conn.post("/echo", :foo => "bar")
59
+ conn.proxy = URI(ENV["LIVE_PROXY"])
60
+ conn.post("/echo", :foo => "bar")
61
+ end
62
+
63
+ assert_equal 2, sockets.count
64
+ end
17
65
  end
18
66
 
67
+ def test_without_custom_connection_config
68
+ url = URI('https://example.com:1234')
69
+
70
+ adapter = Faraday::Adapter::NetHttpPersistent.new
71
+
72
+ http = adapter.send(:net_http_connection, :url => url, :request => {})
73
+
74
+ # `pool` is only present in net_http_persistent >= 3.0
75
+ assert http.pool.size != nil if http.respond_to?(:pool)
76
+ end
77
+
78
+ def test_custom_connection_config
79
+ url = URI('https://example.com:1234')
80
+
81
+ adapter = Faraday::Adapter::NetHttpPersistent.new(nil, {pool_size: 5})
82
+
83
+ http = adapter.send(:net_http_connection, :url => url, :request => {})
84
+
85
+ # `pool` is only present in net_http_persistent >= 3.0
86
+ assert_equal 5, http.pool.size if http.respond_to?(:pool)
87
+ end
88
+
89
+ def test_custom_adapter_config
90
+ url = URI('https://example.com:1234')
91
+
92
+ adapter = Faraday::Adapter::NetHttpPersistent.new do |http|
93
+ http.idle_timeout = 123
94
+ end
95
+
96
+ http = adapter.send(:net_http_connection, :url => url, :request => {})
97
+ adapter.send(:configure_request, http, {})
98
+
99
+ assert_equal 123, http.idle_timeout
100
+ end
101
+
102
+ def test_max_retries
103
+ url = URI('http://example.com')
104
+
105
+ adapter = Faraday::Adapter::NetHttpPersistent.new
106
+
107
+ http = adapter.send(:net_http_connection, :url => url, :request => {})
108
+ adapter.send(:configure_request, http, {})
109
+
110
+ # `max_retries=` is only present in Ruby 2.5
111
+ assert_equal 0, http.max_retries if http.respond_to?(:max_retries=)
112
+ end
19
113
  end
20
114
  end
@@ -1,14 +1,79 @@
1
1
  require File.expand_path('../integration', __FILE__)
2
+ require 'ostruct'
3
+ require 'uri'
2
4
 
3
5
  module Adapters
4
6
  class NetHttpTest < Faraday::TestCase
5
7
 
6
8
  def adapter() :net_http end
7
9
 
8
- behaviors = [:NonParallel]
9
- behaviors << :Compression if RUBY_VERSION >= '1.9'
10
+ behaviors = [:NonParallel, :Compression]
10
11
 
11
12
  Integration.apply(self, *behaviors)
12
13
 
14
+ def test_no_explicit_http_port_number
15
+ url = URI('http://example.com')
16
+ url.port = nil
17
+
18
+ adapter = Faraday::Adapter::NetHttp.new
19
+ http = adapter.send(:net_http_connection, :url => url, :request => {})
20
+
21
+ assert_equal 80, http.port
22
+ end
23
+
24
+ def test_no_explicit_https_port_number
25
+ url = URI('https://example.com')
26
+ url.port = nil
27
+
28
+ adapter = Faraday::Adapter::NetHttp.new
29
+ http = adapter.send(:net_http_connection, :url => url, :request => {})
30
+
31
+ assert_equal 443, http.port
32
+ end
33
+
34
+ def test_explicit_port_number
35
+ url = URI('https://example.com:1234')
36
+
37
+ adapter = Faraday::Adapter::NetHttp.new
38
+ http = adapter.send(:net_http_connection, :url => url, :request => {})
39
+
40
+ assert_equal 1234, http.port
41
+ end
42
+
43
+ def test_custom_adapter_config
44
+ url = URI('https://example.com:1234')
45
+
46
+ adapter = Faraday::Adapter::NetHttp.new do |http|
47
+ http.continue_timeout = 123
48
+ end
49
+
50
+ http = adapter.send(:net_http_connection, :url => url, :request => {})
51
+ adapter.send(:configure_request, http, {})
52
+
53
+ assert_equal 123, http.continue_timeout
54
+ end
55
+
56
+ def test_no_retries
57
+ url = URI('http://example.com')
58
+
59
+ adapter = Faraday::Adapter::NetHttp.new
60
+
61
+ http = adapter.send(:net_http_connection, :url => url, :request => {})
62
+ adapter.send(:configure_request, http, {})
63
+
64
+ # `max_retries=` is only present in Ruby 2.5
65
+ assert_equal 0, http.max_retries if http.respond_to?(:max_retries=)
66
+ end
67
+
68
+ def test_write_timeout
69
+ url = URI('http://example.com')
70
+
71
+ adapter = Faraday::Adapter::NetHttp.new
72
+
73
+ http = adapter.send(:net_http_connection, :url => url, :request => {})
74
+ adapter.send(:configure_request, http, { write_timeout: 10 })
75
+
76
+ assert_equal 10, http.write_timeout if http.respond_to?(:write_timeout=)
77
+ end
13
78
  end
14
79
  end
@@ -5,16 +5,36 @@ module Adapters
5
5
 
6
6
  def adapter() :patron end
7
7
 
8
- Integration.apply(self, :NonParallel) do
9
- # https://github.com/toland/patron/issues/34
10
- undef :test_PATCH_send_url_encoded_params
8
+ unless jruby?
9
+ Integration.apply(self, :NonParallel) do
10
+ # https://github.com/toland/patron/issues/34
11
+ undef :test_PATCH_send_url_encoded_params
11
12
 
12
- # https://github.com/toland/patron/issues/52
13
- undef :test_GET_with_body
13
+ # https://github.com/toland/patron/issues/52
14
+ undef :test_GET_with_body
14
15
 
15
- # no support for SSL peer verification
16
- undef :test_GET_ssl_fails_with_bad_cert if ssl_mode?
17
- end unless jruby?
16
+ # no support for SSL peer verification
17
+ undef :test_GET_ssl_fails_with_bad_cert if ssl_mode?
18
+ end
18
19
 
20
+ def test_custom_adapter_config
21
+ conn = create_connection do |session|
22
+ assert_kind_of ::Patron::Session, session
23
+ session.max_redirects = 10
24
+ throw :config_block_called
25
+ end
26
+
27
+ assert_throws(:config_block_called) do
28
+ conn.get 'http://8.8.8.8:88'
29
+ end
30
+ end
31
+
32
+ def test_connection_timeout
33
+ conn = create_connection(:request => {:timeout => 10, :open_timeout => 1})
34
+ assert_raises Faraday::ConnectionFailed do
35
+ conn.get 'http://8.8.8.8:88'
36
+ end
37
+ end
38
+ end
19
39
  end
20
40
  end
@@ -14,12 +14,19 @@ module Adapters
14
14
  include Integration::Common
15
15
  include Integration::NonParallel
16
16
 
17
+ # Rack::MockResponse doesn't provide any way to access the reason phrase,
18
+ # so override the shared test from Common.
19
+ def test_GET_reason_phrase
20
+ response = get('echo')
21
+ assert_nil response.reason_phrase
22
+ end
23
+
17
24
  # not using shared test because error is swallowed by Sinatra
18
25
  def test_timeout
19
26
  conn = create_connection(:request => {:timeout => 1, :open_timeout => 1})
20
27
  begin
21
28
  conn.get '/slow'
22
- rescue Faraday::Error::ClientError
29
+ rescue Faraday::TimeoutError
23
30
  end
24
31
  end
25
32
 
@@ -4,11 +4,32 @@ module Adapters
4
4
  class TestMiddleware < Faraday::TestCase
5
5
  Stubs = Faraday::Adapter.lookup_middleware(:test)::Stubs
6
6
  def setup
7
- @stubs = Stubs.new
7
+ @stubs = Stubs.new do |stub|
8
+ stub.get('/hello') do
9
+ [200, {'Content-Type' => 'text/html'}, 'hello']
10
+ end
11
+ stub.get('/method-echo') do |env|
12
+ [200, {'Content-Type' => 'text/html'}, env[:method].to_s]
13
+ end
14
+ stub.get(/\A\/resources\/\d+(?:\?|\z)/) do
15
+ [200, {'Content-Type' => 'text/html'}, 'show']
16
+ end
17
+ stub.get(/\A\/resources\/(specified)\z/) do |env, meta|
18
+ [200, {'Content-Type' => 'text/html'}, "show #{meta[:match_data][1]}"]
19
+ end
20
+ stub.get('http://domain.test/hello') do
21
+ [200, {'Content-Type' => 'text/html'}, 'domain: hello']
22
+ end
23
+ stub.get('http://wrong.test/hello') do
24
+ [200, {'Content-Type' => 'text/html'}, 'wrong: hello']
25
+ end
26
+ stub.get('http://wrong.test/bait') do
27
+ [404, {'Content-Type' => 'text/html'}]
28
+ end
29
+ end
8
30
  @conn = Faraday.new do |builder|
9
31
  builder.adapter :test, @stubs
10
32
  end
11
- @stubs.get('/hello') { [200, {'Content-Type' => 'text/html'}, 'hello'] }
12
33
  @resp = @conn.get('/hello')
13
34
  end
14
35
 
@@ -24,8 +45,24 @@ module Adapters
24
45
  assert_equal 'hello', @resp.body
25
46
  end
26
47
 
48
+ def test_middleware_with_host_points_to_the_right_stub
49
+ assert_equal 'domain: hello', @conn.get('http://domain.test/hello').body
50
+ end
51
+
27
52
  def test_middleware_can_be_called_several_times
28
- assert_equal 'hello', @conn.get("/hello").body
53
+ assert_equal 'hello', @conn.get('/hello').body
54
+ end
55
+
56
+ def test_middleware_can_handle_regular_expression_path
57
+ assert_equal 'show', @conn.get('/resources/1').body
58
+ end
59
+
60
+ def test_middleware_can_handle_single_parameter_block
61
+ assert_equal 'get', @conn.get('/method-echo').body
62
+ end
63
+
64
+ def test_middleware_can_handle_regular_expression_path_with_captured_result
65
+ assert_equal 'show specified', @conn.get('/resources/specified').body
29
66
  end
30
67
 
31
68
  def test_middleware_with_get_params
@@ -104,6 +141,12 @@ module Adapters
104
141
  end
105
142
  end
106
143
 
144
+ def test_raises_an_error_if_no_stub_is_found_for_specified_host
145
+ assert_raises Stubs::NotFound do
146
+ @conn.get('http://domain.test/bait')
147
+ end
148
+ end
149
+
107
150
  def test_raises_an_error_if_no_stub_is_found_for_request_without_this_header
108
151
  @stubs.get('/yo', { 'X-HELLO' => 'hello' }) { [200, {}, 'a'] }
109
152
  assert_raises Faraday::Adapter::Test::Stubs::NotFound do
@@ -6,23 +6,33 @@ module Adapters
6
6
  def adapter() :typhoeus end
7
7
 
8
8
  Integration.apply(self, :Parallel) do
9
- # https://github.com/dbalatero/typhoeus/issues/75
10
- undef :test_GET_with_body
11
-
12
- # Not a Typhoeus bug, but WEBrick inability to handle "100-continue"
13
- # which libcurl seems to generate for this particular request:
14
- undef :test_POST_sends_files
15
-
16
9
  # inconsistent outcomes ranging from successful response to connection error
17
10
  undef :test_proxy_auth_fail if ssl_mode?
18
11
 
12
+ # Typhoeus adapter not supporting Faraday::SSLError
13
+ undef :test_GET_ssl_fails_with_bad_cert if ssl_mode?
14
+
19
15
  def test_binds_local_socket
20
16
  host = '1.2.3.4'
21
17
  conn = create_connection :request => { :bind => { :host => host } }
22
18
  assert_equal host, conn.options[:bind][:host]
23
19
  end
24
20
 
25
- end unless jruby?
21
+ # Typhoeus::Response doesn't provide an easy way to access the reason phrase,
22
+ # so override the shared test from Common.
23
+ def test_GET_reason_phrase
24
+ response = get('echo')
25
+ assert_nil response.reason_phrase
26
+ end
27
+ end
28
+
29
+ def test_custom_adapter_config
30
+ adapter = Faraday::Adapter::Typhoeus.new(nil, { :forbid_reuse => true, :maxredirs => 1 })
31
+
32
+ request = adapter.method(:typhoeus_request).call({})
33
+
34
+ assert_equal true, request.options[:forbid_reuse]
35
+ assert_equal 1, request.options[:maxredirs]
36
+ end
26
37
  end
27
38
  end
28
-
@@ -40,22 +40,22 @@ class CompositeReadIOTest < Faraday::TestCase
40
40
  assert_equal "abc", io.read(3)
41
41
  assert_equal "d12", io.read(3)
42
42
  assert_equal "34", io.read(3)
43
- assert_equal nil, io.read(3)
44
- assert_equal nil, io.read(3)
43
+ assert_nil io.read(3)
44
+ assert_nil io.read(3)
45
45
  end
46
46
 
47
47
  def test_multipart_read_limited_size_larger_than_part
48
48
  io = composite_io(part("abcd"), part("1234"))
49
49
  assert_equal "abcd12", io.read(6)
50
50
  assert_equal "34", io.read(6)
51
- assert_equal nil, io.read(6)
51
+ assert_nil io.read(6)
52
52
  end
53
53
 
54
54
  def test_multipart_read_with_blank_parts
55
55
  io = composite_io(part(""), part("abcd"), part(""), part("1234"), part(""))
56
56
  assert_equal "abcd12", io.read(6)
57
57
  assert_equal "34", io.read(6)
58
- assert_equal nil, io.read(6)
58
+ assert_nil io.read(6)
59
59
  end
60
60
 
61
61
  def test_multipart_rewind
@@ -65,7 +65,7 @@ class CompositeReadIOTest < Faraday::TestCase
65
65
  io.rewind
66
66
  assert_equal "abc", io.read(3)
67
67
  assert_equal "d1234", io.read(5)
68
- assert_equal nil, io.read(3)
68
+ assert_nil io.read(3)
69
69
  io.rewind
70
70
  assert_equal "ab", io.read(2)
71
71
  end
@@ -86,21 +86,19 @@ class CompositeReadIOTest < Faraday::TestCase
86
86
  end
87
87
  end
88
88
 
89
- unless RUBY_VERSION < '1.9'
90
- def test_read_from_multibyte
91
- File.open(File.dirname(__FILE__) + '/multibyte.txt') do |utf8|
92
- io = composite_io(part("\x86"), Part.new(utf8))
93
- assert_equal bin("\x86\xE3\x83\x95\xE3\x82\xA1\xE3\x82\xA4\xE3\x83\xAB\n"), io.read
94
- end
89
+ def test_read_from_multibyte
90
+ File.open(File.dirname(__FILE__) + '/multibyte.txt') do |utf8|
91
+ io = composite_io(part("\x86"), Part.new(utf8))
92
+ assert_equal bin("\x86\xE3\x83\x95\xE3\x82\xA1\xE3\x82\xA4\xE3\x83\xAB\n"), io.read
95
93
  end
94
+ end
96
95
 
97
- def test_limited_from_multibyte
98
- File.open(File.dirname(__FILE__) + '/multibyte.txt') do |utf8|
99
- io = composite_io(part("\x86"), Part.new(utf8))
100
- assert_equal bin("\x86\xE3\x83"), io.read(3)
101
- assert_equal bin("\x95\xE3\x82"), io.read(3)
102
- assert_equal bin("\xA1\xE3\x82\xA4\xE3\x83\xAB\n"), io.read(8)
103
- end
96
+ def test_limited_from_multibyte
97
+ File.open(File.dirname(__FILE__) + '/multibyte.txt') do |utf8|
98
+ io = composite_io(part("\x86"), Part.new(utf8))
99
+ assert_equal bin("\x86\xE3\x83"), io.read(3)
100
+ assert_equal bin("\x95\xE3\x82"), io.read(3)
101
+ assert_equal bin("\xA1\xE3\x82\xA4\xE3\x83\xAB\n"), io.read(8)
104
102
  end
105
103
  end
106
104