faraday 1.0.1 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +104 -0
  3. data/LICENSE.md +1 -1
  4. data/README.md +3 -5
  5. data/examples/client_spec.rb +1 -1
  6. data/lib/faraday.rb +60 -41
  7. data/lib/faraday/adapter.rb +2 -12
  8. data/lib/faraday/autoload.rb +2 -10
  9. data/lib/faraday/connection.rb +14 -7
  10. data/lib/faraday/encoders/flat_params_encoder.rb +9 -2
  11. data/lib/faraday/encoders/nested_params_encoder.rb +7 -2
  12. data/lib/faraday/error.rb +20 -0
  13. data/lib/faraday/methods.rb +6 -0
  14. data/lib/faraday/middleware.rb +14 -4
  15. data/lib/faraday/options.rb +4 -8
  16. data/lib/faraday/options/proxy_options.rb +4 -0
  17. data/lib/faraday/rack_builder.rb +13 -12
  18. data/lib/faraday/request.rb +20 -10
  19. data/lib/faraday/request/multipart.rb +9 -2
  20. data/lib/faraday/request/retry.rb +2 -2
  21. data/lib/faraday/response.rb +0 -6
  22. data/lib/faraday/response/raise_error.rb +12 -1
  23. data/lib/faraday/utils.rb +2 -2
  24. data/lib/faraday/utils/headers.rb +2 -2
  25. data/lib/faraday/version.rb +5 -0
  26. data/spec/faraday/adapter/em_http_spec.rb +39 -37
  27. data/spec/faraday/adapter/em_synchrony_spec.rb +11 -9
  28. data/spec/faraday/adapter/test_spec.rb +260 -0
  29. data/spec/faraday/connection_spec.rb +45 -0
  30. data/spec/faraday/error_spec.rb +15 -0
  31. data/spec/faraday/middleware_spec.rb +32 -6
  32. data/spec/faraday/options/proxy_options_spec.rb +7 -0
  33. data/spec/faraday/params_encoders/flat_spec.rb +8 -0
  34. data/spec/faraday/params_encoders/nested_spec.rb +8 -0
  35. data/spec/faraday/rack_builder_spec.rb +149 -0
  36. data/spec/faraday/request/authorization_spec.rb +2 -2
  37. data/spec/faraday/request/multipart_spec.rb +41 -13
  38. data/spec/faraday/request/retry_spec.rb +1 -1
  39. data/spec/faraday/request_spec.rb +16 -5
  40. data/spec/faraday/response/raise_error_spec.rb +63 -0
  41. data/spec/support/shared_examples/adapter.rb +2 -1
  42. data/spec/support/shared_examples/request_method.rb +39 -11
  43. metadata +134 -16
  44. data/lib/faraday/adapter/em_http.rb +0 -286
  45. data/lib/faraday/adapter/em_http_ssl_patch.rb +0 -62
  46. data/lib/faraday/adapter/em_synchrony.rb +0 -150
  47. data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +0 -69
  48. data/lib/faraday/adapter/excon.rb +0 -124
  49. data/lib/faraday/adapter/httpclient.rb +0 -152
  50. data/lib/faraday/adapter/net_http.rb +0 -219
  51. data/lib/faraday/adapter/net_http_persistent.rb +0 -91
  52. data/lib/faraday/adapter/patron.rb +0 -132
  53. data/lib/faraday/adapter/rack.rb +0 -75
  54. data/spec/faraday/adapter/net_http_persistent_spec.rb +0 -57
data/lib/faraday/error.rb CHANGED
@@ -28,6 +28,18 @@ module Faraday
28
28
  %(#<#{self.class}#{inner}>)
29
29
  end
30
30
 
31
+ def response_status
32
+ @response[:status] if @response
33
+ end
34
+
35
+ def response_headers
36
+ @response[:headers] if @response
37
+ end
38
+
39
+ def response_body
40
+ @response[:body] if @response
41
+ end
42
+
31
43
  protected
32
44
 
33
45
  # Pulls out potential parent exception and response hash, storing them in
@@ -38,6 +50,14 @@ module Faraday
38
50
  # :headers - String key/value hash of HTTP response header
39
51
  # values.
40
52
  # :body - Optional string HTTP response body.
53
+ # :request - Hash
54
+ # :method - Symbol with the request HTTP method.
55
+ # :url_path - String with the url path requested.
56
+ # :params - String key/value hash of query params
57
+ # present in the request.
58
+ # :headers - String key/value hash of HTTP request
59
+ # header values.
60
+ # :body - String HTTP request body.
41
61
  #
42
62
  # If a subclass has to call this, then it should pass a string message
43
63
  # to `super`. See NilStatusError.
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Faraday
4
+ METHODS_WITH_QUERY = %w[get head delete trace].freeze
5
+ METHODS_WITH_BODY = %w[post put patch].freeze
6
+ end
@@ -6,15 +6,25 @@ module Faraday
6
6
  extend MiddlewareRegistry
7
7
  extend DependencyLoader
8
8
 
9
- def initialize(app = nil)
9
+ attr_reader :app, :options
10
+
11
+ def initialize(app = nil, options = {})
10
12
  @app = app
13
+ @options = options
14
+ end
15
+
16
+ def call(env)
17
+ on_request(env) if respond_to?(:on_request)
18
+ app.call(env).on_complete do |environment|
19
+ on_complete(environment) if respond_to?(:on_complete)
20
+ end
11
21
  end
12
22
 
13
23
  def close
14
- if @app.respond_to?(:close)
15
- @app.close
24
+ if app.respond_to?(:close)
25
+ app.close
16
26
  else
17
- warn "#{@app} does not implement \#close!"
27
+ warn "#{app} does not implement \#close!"
18
28
  end
19
29
  end
20
30
  end
@@ -103,12 +103,10 @@ module Faraday
103
103
  end
104
104
 
105
105
  # Public
106
- def each_key
106
+ def each_key(&block)
107
107
  return to_enum(:each_key) unless block_given?
108
108
 
109
- keys.each do |key|
110
- yield(key)
111
- end
109
+ keys.each(&block)
112
110
  end
113
111
 
114
112
  # Public
@@ -119,12 +117,10 @@ module Faraday
119
117
  alias has_key? key?
120
118
 
121
119
  # Public
122
- def each_value
120
+ def each_value(&block)
123
121
  return to_enum(:each_value) unless block_given?
124
122
 
125
- values.each do |value|
126
- yield(value)
127
- end
123
+ values.each(&block)
128
124
  end
129
125
 
130
126
  # Public
@@ -11,6 +11,9 @@ module Faraday
11
11
  def self.from(value)
12
12
  case value
13
13
  when String
14
+ # URIs without a scheme should default to http (like 'example:123').
15
+ # This fixes #1282 and prevents a silent failure in some adapters.
16
+ value = "http://#{value}" unless value.include?('://')
14
17
  value = { uri: Utils.URI(value) }
15
18
  when URI
16
19
  value = { uri: value }
@@ -19,6 +22,7 @@ module Faraday
19
22
  value[:uri] = Utils.URI(uri)
20
23
  end
21
24
  end
25
+
22
26
  super(value)
23
27
  end
24
28
 
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'ruby2_keywords'
3
4
  require 'faraday/adapter_registry'
4
5
 
5
6
  module Faraday
@@ -27,7 +28,7 @@ module Faraday
27
28
 
28
29
  attr_reader :name
29
30
 
30
- def initialize(klass, *args, &block)
31
+ ruby2_keywords def initialize(klass, *args, &block)
31
32
  @name = klass.to_s
32
33
  REGISTRY.set(klass) if klass.respond_to?(:name)
33
34
  @args = args
@@ -89,7 +90,7 @@ module Faraday
89
90
  @handlers.frozen?
90
91
  end
91
92
 
92
- def use(klass, *args, &block)
93
+ ruby2_keywords def use(klass, *args, &block)
93
94
  if klass.is_a? Symbol
94
95
  use_symbol(Faraday::Middleware, klass, *args, &block)
95
96
  else
@@ -99,15 +100,15 @@ module Faraday
99
100
  end
100
101
  end
101
102
 
102
- def request(key, *args, &block)
103
+ ruby2_keywords def request(key, *args, &block)
103
104
  use_symbol(Faraday::Request, key, *args, &block)
104
105
  end
105
106
 
106
- def response(key, *args, &block)
107
+ ruby2_keywords def response(key, *args, &block)
107
108
  use_symbol(Faraday::Response, key, *args, &block)
108
109
  end
109
110
 
110
- def adapter(klass = NO_ARGUMENT, *args, &block)
111
+ ruby2_keywords def adapter(klass = NO_ARGUMENT, *args, &block)
111
112
  return @adapter if klass == NO_ARGUMENT
112
113
 
113
114
  klass = Faraday::Adapter.lookup_middleware(klass) if klass.is_a?(Symbol)
@@ -116,7 +117,7 @@ module Faraday
116
117
 
117
118
  ## methods to push onto the various positions in the stack:
118
119
 
119
- def insert(index, *args, &block)
120
+ ruby2_keywords def insert(index, *args, &block)
120
121
  raise_if_locked
121
122
  index = assert_index(index)
122
123
  handler = self.class::Handler.new(*args, &block)
@@ -125,12 +126,12 @@ module Faraday
125
126
 
126
127
  alias insert_before insert
127
128
 
128
- def insert_after(index, *args, &block)
129
+ ruby2_keywords def insert_after(index, *args, &block)
129
130
  index = assert_index(index)
130
131
  insert(index + 1, *args, &block)
131
132
  end
132
133
 
133
- def swap(index, *args, &block)
134
+ ruby2_keywords def swap(index, *args, &block)
134
135
  raise_if_locked
135
136
  index = assert_index(index)
136
137
  @handlers.delete_at(index)
@@ -186,7 +187,7 @@ module Faraday
186
187
  end
187
188
 
188
189
  # ENV Keys
189
- # :method - a symbolized request method (:get, :post)
190
+ # :http_method - a symbolized request HTTP method (:get, :post)
190
191
  # :body - the request body that will eventually be converted to a string.
191
192
  # :url - URI instance for the current request.
192
193
  # :status - HTTP response status code
@@ -207,7 +208,7 @@ module Faraday
207
208
  request.options.params_encoder
208
209
  )
209
210
 
210
- Env.new(request.method, request.body, exclusive_url,
211
+ Env.new(request.http_method, request.body, exclusive_url,
211
212
  request.options, request.headers, connection.ssl,
212
213
  connection.parallel_manager)
213
214
  end
@@ -231,10 +232,10 @@ module Faraday
231
232
  end
232
233
 
233
234
  def is_adapter?(klass) # rubocop:disable Naming/PredicateName
234
- klass.ancestors.include?(Faraday::Adapter)
235
+ klass <= Faraday::Adapter
235
236
  end
236
237
 
237
- def use_symbol(mod, key, *args, &block)
238
+ ruby2_keywords def use_symbol(mod, key, *args, &block)
238
239
  use(mod.lookup_middleware(key), *args, &block)
239
240
  end
240
241
 
@@ -12,7 +12,7 @@ module Faraday
12
12
  # req.body = 'abc'
13
13
  # end
14
14
  #
15
- # @!attribute method
15
+ # @!attribute http_method
16
16
  # @return [Symbol] the HTTP method of the Request
17
17
  # @!attribute path
18
18
  # @return [URI, String] the path
@@ -26,7 +26,9 @@ module Faraday
26
26
  # @return [RequestOptions] options
27
27
  #
28
28
  # rubocop:disable Style/StructInheritance
29
- class Request < Struct.new(:method, :path, :params, :headers, :body, :options)
29
+ class Request < Struct.new(
30
+ :http_method, :path, :params, :headers, :body, :options
31
+ )
30
32
  # rubocop:enable Style/StructInheritance
31
33
 
32
34
  extend MiddlewareRegistry
@@ -56,6 +58,14 @@ module Faraday
56
58
  end
57
59
  end
58
60
 
61
+ def method
62
+ warn <<~TEXT
63
+ WARNING: `Faraday::Request##{__method__}` is deprecated; use `#http_method` instead. It will be removed in or after version 2.0.
64
+ `Faraday::Request##{__method__}` called from #{caller_locations(1..1).first}
65
+ TEXT
66
+ http_method
67
+ end
68
+
59
69
  # Replace params, preserving the existing hash type.
60
70
  #
61
71
  # @param hash [Hash] new params
@@ -116,7 +126,7 @@ module Faraday
116
126
  # @return [Hash] the hash ready to be serialized in Marshal.
117
127
  def marshal_dump
118
128
  {
119
- method: method,
129
+ http_method: http_method,
120
130
  body: body,
121
131
  headers: headers,
122
132
  path: path,
@@ -129,17 +139,17 @@ module Faraday
129
139
  # Restores the instance variables according to the +serialised+.
130
140
  # @param serialised [Hash] the serialised object.
131
141
  def marshal_load(serialised)
132
- self.method = serialised[:method]
133
- self.body = serialised[:body]
134
- self.headers = serialised[:headers]
135
- self.path = serialised[:path]
136
- self.params = serialised[:params]
137
- self.options = serialised[:options]
142
+ self.http_method = serialised[:http_method]
143
+ self.body = serialised[:body]
144
+ self.headers = serialised[:headers]
145
+ self.path = serialised[:path]
146
+ self.params = serialised[:params]
147
+ self.options = serialised[:options]
138
148
  end
139
149
 
140
150
  # @return [Env] the Env for this Request
141
151
  def to_env(connection)
142
- Env.new(method, body, connection.build_exclusive_url(path, params),
152
+ Env.new(http_method, body, connection.build_exclusive_url(path, params),
143
153
  options, headers, connection.ssl, connection.parallel_manager)
144
154
  end
145
155
  end
@@ -12,6 +12,11 @@ module Faraday
12
12
  DEFAULT_BOUNDARY_PREFIX = '-----------RubyMultipartPost'
13
13
  end
14
14
 
15
+ def initialize(app = nil, options = {})
16
+ super(app)
17
+ @options = options
18
+ end
19
+
15
20
  # Checks for files in the payload, otherwise leaves everything untouched.
16
21
  #
17
22
  # @param env [Faraday::Env]
@@ -30,7 +35,7 @@ module Faraday
30
35
  type = request_type(env)
31
36
  env.body.respond_to?(:each_key) && !env.body.empty? && (
32
37
  (type.empty? && has_multipart?(env.body)) ||
33
- (type == self.class.mime_type)
38
+ (type == self.class.mime_type)
34
39
  )
35
40
  end
36
41
 
@@ -79,7 +84,9 @@ module Faraday
79
84
  # @param pieces [Array]
80
85
  def process_params(params, prefix = nil, pieces = nil, &block)
81
86
  params.inject(pieces || []) do |all, (key, value)|
82
- key = "#{prefix}[#{key}]" if prefix
87
+ if prefix
88
+ key = @options[:flat_encode] ? prefix.to_s : "#{prefix}[#{key}]"
89
+ end
83
90
 
84
91
  case value
85
92
  when Array
@@ -21,7 +21,7 @@ module Faraday
21
21
  # end
22
22
  #
23
23
  # This example will result in a first interval that is random between 0.05
24
- # and 0.075 and a second interval that is random between 0.1 and 0.15.
24
+ # and 0.075 and a second interval that is random between 0.1 and 0.125.
25
25
  class Retry < Faraday::Middleware
26
26
  DEFAULT_EXCEPTIONS = [
27
27
  Errno::ETIMEDOUT, 'Timeout::Error',
@@ -112,7 +112,7 @@ module Faraday
112
112
  # not independent of the retry count. This would be useful
113
113
  # if the exception produced is non-recoverable or if the
114
114
  # the HTTP method called is not idempotent.
115
- # @option options [Block] :retry_block block that is executed after
115
+ # @option options [Block] :retry_block block that is executed before
116
116
  # every retry. Request environment, middleware options, current number
117
117
  # of retries and the exception is passed to the block as parameters.
118
118
  # @option options [Array] :retry_statuses Array of Integer HTTP status
@@ -7,12 +7,6 @@ module Faraday
7
7
  class Response
8
8
  # Used for simple response middleware.
9
9
  class Middleware < Faraday::Middleware
10
- def call(env)
11
- @app.call(env).on_complete do |environment|
12
- on_complete(environment)
13
- end
14
- end
15
-
16
10
  # Override this to modify the environment after the response has finished.
17
11
  # Calls the `parse` method if defined
18
12
  # `parse` method can be defined as private, public and protected
@@ -38,7 +38,18 @@ module Faraday
38
38
  end
39
39
 
40
40
  def response_values(env)
41
- { status: env.status, headers: env.response_headers, body: env.body }
41
+ {
42
+ status: env.status,
43
+ headers: env.response_headers,
44
+ body: env.body,
45
+ request: {
46
+ method: env.method,
47
+ url_path: env.url.path,
48
+ params: env.params,
49
+ headers: env.request_headers,
50
+ body: env.request_body
51
+ }
52
+ }
42
53
  end
43
54
  end
44
55
  end
data/lib/faraday/utils.rb CHANGED
@@ -28,7 +28,7 @@ module Faraday
28
28
 
29
29
  def escape(str)
30
30
  str.to_s.gsub(ESCAPE_RE) do |match|
31
- '%' + match.unpack('H2' * match.bytesize).join('%').upcase
31
+ "%#{match.unpack('H2' * match.bytesize).join('%').upcase}"
32
32
  end.gsub(' ', default_space_encoding)
33
33
  end
34
34
 
@@ -89,7 +89,7 @@ module Faraday
89
89
  # the path with the query string sorted.
90
90
  def normalize_path(url)
91
91
  url = URI(url)
92
- (url.path.start_with?('/') ? url.path : '/' + url.path) +
92
+ (url.path.start_with?('/') ? url.path : "/#{url.path}") +
93
93
  (url.query ? "?#{sort_query_params(url.query)}" : '')
94
94
  end
95
95
 
@@ -105,7 +105,7 @@ module Faraday
105
105
  end
106
106
 
107
107
  def to_hash
108
- ::Hash.new.update(self)
108
+ {}.update(self)
109
109
  end
110
110
 
111
111
  def parse(header_string)
@@ -114,7 +114,7 @@ module Faraday
114
114
  headers = header_string.split(/\r\n/)
115
115
 
116
116
  # Find the last set of response headers.
117
- start_index = headers.rindex { |x| x.match(%r{^HTTP/}) } || 0
117
+ start_index = headers.rindex { |x| x.start_with?('HTTP/') } || 0
118
118
  last_response = headers.slice(start_index, headers.size)
119
119
 
120
120
  last_response
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Faraday
4
+ VERSION = '1.6.0'
5
+ end
@@ -1,47 +1,49 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- RSpec.describe Faraday::Adapter::EMHttp, unless: defined?(JRUBY_VERSION) do
4
- features :request_body_on_query_methods, :reason_phrase_parse, :trace_method,
5
- :skip_response_body_on_head, :parallel, :local_socket_binding
3
+ unless defined?(JRUBY_VERSION)
4
+ RSpec.describe Faraday::Adapter::EMHttp do
5
+ features :request_body_on_query_methods, :reason_phrase_parse, :trace_method,
6
+ :skip_response_body_on_head, :parallel, :local_socket_binding
6
7
 
7
- it_behaves_like 'an adapter'
8
+ it_behaves_like 'an adapter'
8
9
 
9
- it 'allows to provide adapter specific configs' do
10
- url = URI('https://example.com:1234')
11
- adapter = described_class.new nil, inactivity_timeout: 20
12
- req = adapter.create_request(url: url, request: {})
10
+ it 'allows to provide adapter specific configs' do
11
+ url = URI('https://example.com:1234')
12
+ adapter = described_class.new nil, inactivity_timeout: 20
13
+ req = adapter.create_request(url: url, request: {})
13
14
 
14
- expect(req.connopts.inactivity_timeout).to eq(20)
15
- end
16
-
17
- context 'Options' do
18
- let(:request) { Faraday::RequestOptions.new }
19
- let(:env) { { request: request } }
20
- let(:options) { {} }
21
- let(:adapter) { Faraday::Adapter::EMHttp.new }
22
-
23
- it 'configures timeout' do
24
- request.timeout = 5
25
- adapter.configure_timeout(options, env)
26
- expect(options[:inactivity_timeout]).to eq(5)
27
- expect(options[:connect_timeout]).to eq(5)
28
- end
29
-
30
- it 'configures timeout and open_timeout' do
31
- request.timeout = 5
32
- request.open_timeout = 1
33
- adapter.configure_timeout(options, env)
34
- expect(options[:inactivity_timeout]).to eq(5)
35
- expect(options[:connect_timeout]).to eq(1)
15
+ expect(req.connopts.inactivity_timeout).to eq(20)
36
16
  end
37
17
 
38
- it 'configures all timeout settings' do
39
- request.timeout = 5
40
- request.read_timeout = 3
41
- request.open_timeout = 1
42
- adapter.configure_timeout(options, env)
43
- expect(options[:inactivity_timeout]).to eq(3)
44
- expect(options[:connect_timeout]).to eq(1)
18
+ context 'Options' do
19
+ let(:request) { Faraday::RequestOptions.new }
20
+ let(:env) { { request: request } }
21
+ let(:options) { {} }
22
+ let(:adapter) { Faraday::Adapter::EMHttp.new }
23
+
24
+ it 'configures timeout' do
25
+ request.timeout = 5
26
+ adapter.configure_timeout(options, env)
27
+ expect(options[:inactivity_timeout]).to eq(5)
28
+ expect(options[:connect_timeout]).to eq(5)
29
+ end
30
+
31
+ it 'configures timeout and open_timeout' do
32
+ request.timeout = 5
33
+ request.open_timeout = 1
34
+ adapter.configure_timeout(options, env)
35
+ expect(options[:inactivity_timeout]).to eq(5)
36
+ expect(options[:connect_timeout]).to eq(1)
37
+ end
38
+
39
+ it 'configures all timeout settings' do
40
+ request.timeout = 5
41
+ request.read_timeout = 3
42
+ request.open_timeout = 1
43
+ adapter.configure_timeout(options, env)
44
+ expect(options[:inactivity_timeout]).to eq(3)
45
+ expect(options[:connect_timeout]).to eq(1)
46
+ end
45
47
  end
46
48
  end
47
49
  end