faraday 0.9.1 → 0.17.1

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 +196 -0
  3. data/LICENSE.md +1 -1
  4. data/README.md +192 -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 +101 -0
  21. data/lib/faraday/error.rb +90 -24
  22. data/lib/faraday/options.rb +43 -20
  23. data/lib/faraday/parameters.rb +56 -39
  24. data/lib/faraday/rack_builder.rb +27 -2
  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 +14 -34
  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 +95 -0
  37. data/spec/spec_helper.rb +104 -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
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'faraday'
4
+
5
+ # This file was generated by the `rspec --init` command. Conventionally, all
6
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
7
+ # The generated `.rspec` file contains `--require spec_helper` which will cause
8
+ # this file to always be loaded, without a need to explicitly require it in any
9
+ # files.
10
+ #
11
+ # Given that it is always loaded, you are encouraged to keep this file as
12
+ # light-weight as possible. Requiring heavyweight dependencies from this file
13
+ # will add to the boot time of your test suite on EVERY test run, even for an
14
+ # individual file that may not need all of that loaded. Instead, consider making
15
+ # a separate helper file that requires the additional dependencies and performs
16
+ # the additional setup, and require it from the spec files that actually need
17
+ # it.
18
+ #
19
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
20
+ RSpec.configure do |config|
21
+ # rspec-expectations config goes here. You can use an alternate
22
+ # assertion/expectation library such as wrong or the stdlib/minitest
23
+ # assertions if you prefer.
24
+ config.expect_with :rspec do |expectations|
25
+ # This option will default to `true` in RSpec 4. It makes the `description`
26
+ # and `failure_message` of custom matchers include text for helper methods
27
+ # defined using `chain`, e.g.:
28
+ # be_bigger_than(2).and_smaller_than(4).description
29
+ # # => "be bigger than 2 and smaller than 4"
30
+ # ...rather than:
31
+ # # => "be bigger than 2"
32
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
33
+ end
34
+
35
+ # rspec-mocks config goes here. You can use an alternate test double
36
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
37
+ config.mock_with :rspec do |mocks|
38
+ # Prevents you from mocking or stubbing a method that does not exist on
39
+ # a real object. This is generally recommended, and will default to
40
+ # `true` in RSpec 4.
41
+ mocks.verify_partial_doubles = true
42
+ end
43
+
44
+ # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
45
+ # have no way to turn it off -- the option exists only for backwards
46
+ # compatibility in RSpec 3). It causes shared context metadata to be
47
+ # inherited by the metadata hash of host groups and examples, rather than
48
+ # triggering implicit auto-inclusion in groups with matching metadata.
49
+ config.shared_context_metadata_behavior = :apply_to_host_groups
50
+
51
+ # Run specs in random order to surface order dependencies. If you find an
52
+ # order dependency and want to debug it, you can fix the order by providing
53
+ # the seed, which is printed after each run.
54
+ # --seed 1234
55
+ config.order = :random
56
+
57
+ # Seed global randomization in this process using the `--seed` CLI option.
58
+ # Setting this allows you to use `--seed` to deterministically reproduce
59
+ # test failures related to randomization by passing the same `--seed` value
60
+ # as the one that triggered the failure.
61
+ Kernel.srand config.seed
62
+
63
+ # Limits the available syntax to the non-monkey patched syntax that is
64
+ # recommended. For more details, see:
65
+ # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
66
+ # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
67
+ # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
68
+ config.disable_monkey_patching!
69
+
70
+ # The settings below are suggested to provide a good initial experience
71
+ # with RSpec, but feel free to customize to your heart's content.
72
+ =begin
73
+ # This allows you to limit a spec run to individual examples or groups
74
+ # you care about by tagging them with `:focus` metadata. When nothing
75
+ # is tagged with `:focus`, all examples get run. RSpec also provides
76
+ # aliases for `it`, `describe`, and `context` that include `:focus`
77
+ # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
78
+ config.filter_run_when_matching :focus
79
+
80
+ # Allows RSpec to persist some state between runs in order to support
81
+ # the `--only-failures` and `--next-failure` CLI options. We recommend
82
+ # you configure your source control system to ignore this file.
83
+ config.example_status_persistence_file_path = "spec/examples.txt"
84
+
85
+ # This setting enables warnings. It's recommended, but in some cases may
86
+ # be too noisy due to issues in dependencies.
87
+ config.warnings = true
88
+
89
+ # Many RSpec users commonly either run the entire suite or an individual
90
+ # file, and it's useful to allow more verbose output when running an
91
+ # individual spec file.
92
+ if config.files_to_run.one?
93
+ # Use the documentation formatter for detailed output,
94
+ # unless a formatter has already been configured
95
+ # (e.g. via a command-line flag).
96
+ config.default_formatter = "doc"
97
+ end
98
+
99
+ # Print the 10 slowest examples and example groups at the
100
+ # end of the spec run, to help surface which specs are running
101
+ # particularly slow.
102
+ config.profile_examples = 10
103
+ =end
104
+ end
@@ -16,5 +16,15 @@ module Adapters
16
16
  end
17
17
  end unless jruby? and ssl_mode?
18
18
  # https://github.com/eventmachine/eventmachine/issues/180
19
+
20
+ def test_custom_adapter_config
21
+ url = URI('https://example.com:1234')
22
+
23
+ adapter = Faraday::Adapter::EMHttp.new nil, inactivity_timeout: 20
24
+
25
+ req = adapter.create_request(url: url, request: {})
26
+
27
+ assert_equal 20, req.connopts.inactivity_timeout
28
+ end
19
29
  end
20
30
  end
@@ -5,16 +5,28 @@ module Adapters
5
5
 
6
6
  def adapter() :em_synchrony end
7
7
 
8
- Integration.apply(self, :Parallel) do
9
- # https://github.com/eventmachine/eventmachine/pull/289
10
- undef :test_timeout
11
-
12
- def test_binds_local_socket
13
- host = '1.2.3.4'
14
- conn = create_connection :request => { :bind => { :host => host } }
15
- #put conn.get('/who-am-i').body
16
- assert_equal host, conn.options[:bind][:host]
8
+ unless jruby?
9
+ Integration.apply(self, :Parallel) do
10
+ # https://github.com/eventmachine/eventmachine/pull/289
11
+ undef :test_timeout
12
+
13
+ def test_binds_local_socket
14
+ host = '1.2.3.4'
15
+ conn = create_connection :request => { :bind => { :host => host } }
16
+ #put conn.get('/who-am-i').body
17
+ assert_equal host, conn.options[:bind][:host]
18
+ end
17
19
  end
18
- end unless RUBY_VERSION < '1.9' or jruby?
20
+ end
21
+
22
+ def test_custom_adapter_config
23
+ url = URI('https://example.com:1234')
24
+
25
+ adapter = Faraday::Adapter::EMSynchrony.new nil, inactivity_timeout: 20
26
+
27
+ req = adapter.create_request(url: url, request: {})
28
+
29
+ assert_equal 20, req.connopts.inactivity_timeout
30
+ end
19
31
  end
20
32
  end
@@ -16,5 +16,15 @@ module Adapters
16
16
  # https://github.com/geemus/excon/issues/358
17
17
  undef :test_connection_error if RUBY_VERSION >= '2.1.0'
18
18
  end
19
+
20
+ def test_custom_adapter_config
21
+ url = URI('https://example.com:1234')
22
+
23
+ adapter = Faraday::Adapter::Excon.new nil, debug_request: true
24
+
25
+ conn = adapter.create_connection({url: url}, {})
26
+
27
+ assert_equal true, conn.data[:debug_request]
28
+ end
19
29
  end
20
30
  end
@@ -5,7 +5,7 @@ module Adapters
5
5
 
6
6
  def adapter() :httpclient end
7
7
 
8
- Integration.apply(self, :NonParallel) do
8
+ Integration.apply(self, :NonParallel, :Compression) do
9
9
  def setup
10
10
  require 'httpclient' unless defined?(HTTPClient)
11
11
  HTTPClient::NO_PROXY_HOSTS.delete('localhost')
@@ -16,6 +16,19 @@ module Adapters
16
16
  conn = create_connection :request => { :bind => { :host => host } }
17
17
  assert_equal host, conn.options[:bind][:host]
18
18
  end
19
+
20
+ def test_custom_adapter_config
21
+ adapter = Faraday::Adapter::HTTPClient.new do |client|
22
+ client.keep_alive_timeout = 20
23
+ client.ssl_config.timeout = 25
24
+ end
25
+
26
+ client = adapter.client
27
+ adapter.configure_client
28
+
29
+ assert_equal 20, client.keep_alive_timeout
30
+ assert_equal 25, client.ssl_config.timeout
31
+ end
19
32
  end
20
33
  end
21
34
  end
@@ -9,7 +9,7 @@ module Adapters
9
9
  # `#adapter_options` optional. extra arguments for building an adapter
10
10
  module Integration
11
11
  def self.apply(base, *extra_features)
12
- if base.live_server?
12
+ if base.live_server
13
13
  features = [:Common]
14
14
  features.concat extra_features
15
15
  features << :SSL if base.ssl_mode?
@@ -18,6 +18,7 @@ module Adapters
18
18
  elsif !defined? @warned
19
19
  warn "Warning: Not running integration tests against a live server."
20
20
  warn "Start the server `ruby test/live_server.rb` and set the LIVE=1 env variable."
21
+ warn "See CONTRIBUTING for usage."
21
22
  @warned = true
22
23
  end
23
24
  end
@@ -59,7 +60,8 @@ module Adapters
59
60
  module Compression
60
61
  def test_GET_handles_compression
61
62
  res = get('echo_header', :name => 'accept-encoding')
62
- assert_match(/gzip;.+\bdeflate\b/, res.body)
63
+ assert_match(/\bgzip\b/, res.body)
64
+ assert_match(/\bdeflate\b/, res.body)
63
65
  end
64
66
  end
65
67
 
@@ -113,6 +115,11 @@ module Adapters
113
115
  assert_equal expected, get('ssl').body
114
116
  end
115
117
 
118
+ def test_GET_reason_phrase
119
+ response = get('echo')
120
+ assert_equal "OK", response.reason_phrase
121
+ end
122
+
116
123
  def test_POST_send_url_encoded_params
117
124
  assert_equal %(post {"name"=>"zack"}), post('echo', :name => 'zack').body
118
125
  end
@@ -173,13 +180,13 @@ module Adapters
173
180
 
174
181
  def test_timeout
175
182
  conn = create_connection(:request => {:timeout => 1, :open_timeout => 1})
176
- assert_raises Faraday::Error::TimeoutError do
183
+ assert_raises Faraday::TimeoutError do
177
184
  conn.get '/slow'
178
185
  end
179
186
  end
180
187
 
181
188
  def test_connection_error
182
- assert_raises Faraday::Error::ConnectionFailed do
189
+ assert_raises Faraday::ConnectionFailed do
183
190
  get 'http://localhost:4'
184
191
  end
185
192
  end
@@ -202,12 +209,14 @@ module Adapters
202
209
  proxy_uri.password = 'WRONG'
203
210
  conn = create_connection(:proxy => proxy_uri)
204
211
 
205
- err = assert_raises Faraday::Error::ConnectionFailed do
212
+ err = assert_raises Faraday::ConnectionFailed do
206
213
  conn.get '/echo'
207
214
  end
208
215
 
209
- unless self.class.ssl_mode? && self.class.jruby?
216
+ unless self.class.ssl_mode? && (self.class.jruby? ||
217
+ adapter == :em_http || adapter == :em_synchrony)
210
218
  # JRuby raises "End of file reached" which cannot be distinguished from a 407
219
+ # EM raises "connection closed by server" due to https://github.com/igrigorik/em-socksify/pull/19
211
220
  assert_equal %{407 "Proxy Authentication Required "}, err.message
212
221
  end
213
222
  end
@@ -226,14 +235,14 @@ module Adapters
226
235
  []
227
236
  end
228
237
 
229
- def create_connection(options = {})
238
+ def create_connection(options = {}, &optional_connection_config_blk)
230
239
  if adapter == :default
231
240
  builder_block = nil
232
241
  else
233
242
  builder_block = Proc.new do |b|
234
243
  b.request :multipart
235
244
  b.request :url_encoded
236
- b.adapter adapter, *adapter_options
245
+ b.adapter adapter, *adapter_options, &optional_connection_config_blk
237
246
  end
238
247
  end
239
248
 
@@ -8,13 +8,20 @@ module Adapters
8
8
  rubbles = ['Barney', 'Betty', 'Bam Bam']
9
9
 
10
10
  Faraday.new do |b|
11
- b.response :logger, logger, logger_options
11
+ b.response :logger, @logger, logger_options do | logger |
12
+ logger.filter(/(soylent green is) (.+)/,'\1 tasty')
13
+ logger.filter(/(api_key:).*"(.+)."/,'\1[API_KEY]')
14
+ logger.filter(/(password)=(.+)/,'\1=[HIDDEN]')
15
+ end
12
16
  b.adapter :test do |stubs|
13
17
  stubs.get('/hello') { [200, {'Content-Type' => 'text/html'}, 'hello'] }
14
18
  stubs.post('/ohai') { [200, {'Content-Type' => 'text/html'}, 'fred'] }
15
- stubs.get('/ohno') { [200, {'Content-Type' => 'text/html'}, 'wilma'] }
16
19
  stubs.post('/ohyes') { [200, {'Content-Type' => 'text/html'}, 'pebbles'] }
17
20
  stubs.get('/rubbles') { [200, {'Content-Type' => 'application/json'}, rubbles] }
21
+ stubs.get('/filtered_body') { [200, {'Content-Type' => 'text/html'}, 'soylent green is people'] }
22
+ stubs.get('/filtered_headers') { [200, {'Content-Type' => 'text/html'}, 'headers response'] }
23
+ stubs.get('/filtered_params') { [200, {'Content-Type' => 'text/html'}, 'params response'] }
24
+ stubs.get('/filtered_url') { [200, {'Content-Type' => 'text/html'}, 'url response'] }
18
25
  end
19
26
  end
20
27
  end
@@ -25,25 +32,45 @@ module Adapters
25
32
  @logger.level = Logger::DEBUG
26
33
 
27
34
  @conn = conn(@logger)
28
- @resp = @conn.get '/hello', nil, :accept => 'text/html'
29
35
  end
30
36
 
31
37
  def test_still_returns_output
32
- assert_equal 'hello', @resp.body
38
+ resp = @conn.get '/hello', nil, :accept => 'text/html'
39
+ assert_equal 'hello', resp.body
33
40
  end
34
41
 
35
42
  def test_logs_method_and_url
36
- assert_match "get http:/hello", @io.string
43
+ @conn.get '/hello', nil, :accept => 'text/html'
44
+ assert_match 'request: GET http:/hello', @io.string
45
+ end
46
+
47
+ def test_logs_status_code
48
+ @conn.get '/hello', nil, :accept => 'text/html'
49
+ assert_match 'response: Status 200', @io.string
37
50
  end
38
51
 
39
- def test_logs_request_headers
52
+ def test_logs_request_headers_by_default
53
+ @conn.get '/hello', nil, :accept => 'text/html'
40
54
  assert_match %(Accept: "text/html), @io.string
41
55
  end
42
56
 
43
- def test_logs_response_headers
57
+ def test_logs_response_headers_by_default
58
+ @conn.get '/hello', nil, :accept => 'text/html'
44
59
  assert_match %(Content-Type: "text/html), @io.string
45
60
  end
46
61
 
62
+ def test_does_not_log_request_headers_if_option_is_false
63
+ app = conn(@logger, :headers => { :request => false })
64
+ app.get '/hello', nil, :accept => 'text/html'
65
+ refute_match %(Accept: "text/html), @io.string
66
+ end
67
+
68
+ def test_does_log_response_headers_if_option_is_false
69
+ app = conn(@logger, :headers => { :response => false })
70
+ app.get '/hello', nil, :accept => 'text/html'
71
+ refute_match %(Content-Type: "text/html), @io.string
72
+ end
73
+
47
74
  def test_does_not_log_request_body_by_default
48
75
  @conn.post '/ohai', 'name=Unagi', :accept => 'text/html'
49
76
  refute_match %(name=Unagi), @io.string
@@ -54,16 +81,18 @@ module Adapters
54
81
  refute_match %(fred), @io.string
55
82
  end
56
83
 
57
- def test_log_request_body
84
+ def test_log_only_request_body
58
85
  app = conn(@logger, :bodies => { :request => true })
59
86
  app.post '/ohyes', 'name=Tamago', :accept => 'text/html'
60
87
  assert_match %(name=Tamago), @io.string
88
+ refute_match %(pebbles), @io.string
61
89
  end
62
90
 
63
- def test_log_response_body
91
+ def test_log_only_response_body
64
92
  app = conn(@logger, :bodies => { :response => true })
65
- app.get '/ohno', :accept => 'text/html'
66
- assert_match %(wilma), @io.string
93
+ app.post '/ohyes', 'name=Hamachi', :accept => 'text/html'
94
+ assert_match %(pebbles), @io.string
95
+ refute_match %(name=Hamachi), @io.string
67
96
  end
68
97
 
69
98
  def test_log_request_and_response_body
@@ -78,5 +107,30 @@ module Adapters
78
107
  app.get '/rubbles', nil, :accept => 'text/html'
79
108
  assert_match %([\"Barney\", \"Betty\", \"Bam Bam\"]\n), @io.string
80
109
  end
110
+
111
+ def test_logs_filter_body
112
+ app = conn(@logger, :bodies => true)
113
+ app.get '/filtered_body', nil, :accept => 'text/html'
114
+ assert_match %(soylent green is), @io.string
115
+ assert_match %(tasty), @io.string
116
+ refute_match %(people), @io.string
117
+ end
118
+
119
+ def test_logs_filter_headers
120
+ app = conn(@logger)
121
+ app.headers = {'api_key' => 'ABC123'}
122
+ app.get '/filtered_headers', nil, :accept => 'text/html'
123
+ assert_match %(api_key:), @io.string
124
+ assert_match %([API_KEY]), @io.string
125
+ refute_match %(ABC123), @io.string
126
+ end
127
+
128
+ def test_logs_filter_url
129
+ app = conn(@logger)
130
+ app.get '/filtered_url?password=hunter2', nil, :accept => 'text/html'
131
+ assert_match %(password=[HIDDEN]), @io.string
132
+ refute_match %(hunter2), @io.string
133
+ end
134
+
81
135
  end
82
136
  end
@@ -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