faraday 0.17.3 → 1.0.0.pre.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.md +1 -1
  3. data/README.md +18 -358
  4. data/lib/faraday.rb +93 -174
  5. data/lib/faraday/adapter.rb +36 -22
  6. data/lib/faraday/adapter/em_http.rb +142 -99
  7. data/lib/faraday/adapter/em_http_ssl_patch.rb +23 -17
  8. data/lib/faraday/adapter/em_synchrony.rb +104 -60
  9. data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +18 -15
  10. data/lib/faraday/adapter/excon.rb +97 -57
  11. data/lib/faraday/adapter/httpclient.rb +61 -39
  12. data/lib/faraday/adapter/net_http.rb +104 -51
  13. data/lib/faraday/adapter/net_http_persistent.rb +49 -28
  14. data/lib/faraday/adapter/patron.rb +54 -35
  15. data/lib/faraday/adapter/rack.rb +28 -12
  16. data/lib/faraday/adapter/test.rb +86 -53
  17. data/lib/faraday/adapter/typhoeus.rb +4 -1
  18. data/lib/faraday/adapter_registry.rb +28 -0
  19. data/lib/faraday/autoload.rb +47 -36
  20. data/lib/faraday/connection.rb +321 -179
  21. data/lib/faraday/dependency_loader.rb +37 -0
  22. data/lib/faraday/encoders/flat_params_encoder.rb +94 -0
  23. data/lib/faraday/encoders/nested_params_encoder.rb +171 -0
  24. data/lib/faraday/error.rb +21 -79
  25. data/lib/faraday/logging/formatter.rb +92 -0
  26. data/lib/faraday/middleware.rb +4 -28
  27. data/lib/faraday/middleware_registry.rb +129 -0
  28. data/lib/faraday/options.rb +33 -184
  29. data/lib/faraday/options/connection_options.rb +22 -0
  30. data/lib/faraday/options/env.rb +181 -0
  31. data/lib/faraday/options/proxy_options.rb +28 -0
  32. data/lib/faraday/options/request_options.rb +21 -0
  33. data/lib/faraday/options/ssl_options.rb +59 -0
  34. data/lib/faraday/parameters.rb +4 -197
  35. data/lib/faraday/rack_builder.rb +66 -55
  36. data/lib/faraday/request.rb +68 -36
  37. data/lib/faraday/request/authorization.rb +42 -30
  38. data/lib/faraday/request/basic_authentication.rb +14 -7
  39. data/lib/faraday/request/instrumentation.rb +45 -27
  40. data/lib/faraday/request/multipart.rb +72 -49
  41. data/lib/faraday/request/retry.rb +197 -171
  42. data/lib/faraday/request/token_authentication.rb +15 -10
  43. data/lib/faraday/request/url_encoded.rb +41 -23
  44. data/lib/faraday/response.rb +22 -15
  45. data/lib/faraday/response/logger.rb +22 -69
  46. data/lib/faraday/response/raise_error.rb +36 -18
  47. data/lib/faraday/upload_io.rb +29 -18
  48. data/lib/faraday/utils.rb +28 -245
  49. data/lib/faraday/utils/headers.rb +139 -0
  50. data/lib/faraday/utils/params_hash.rb +61 -0
  51. data/spec/external_adapters/faraday_specs_setup.rb +14 -0
  52. metadata +25 -51
  53. data/CHANGELOG.md +0 -232
  54. data/Rakefile +0 -13
  55. data/lib/faraday/deprecate.rb +0 -107
  56. data/spec/faraday/deprecate_spec.rb +0 -69
  57. data/spec/faraday/error_spec.rb +0 -102
  58. data/spec/faraday/response/raise_error_spec.rb +0 -106
  59. data/spec/spec_helper.rb +0 -105
  60. data/test/adapters/default_test.rb +0 -14
  61. data/test/adapters/em_http_test.rb +0 -30
  62. data/test/adapters/em_synchrony_test.rb +0 -32
  63. data/test/adapters/excon_test.rb +0 -30
  64. data/test/adapters/httpclient_test.rb +0 -34
  65. data/test/adapters/integration.rb +0 -263
  66. data/test/adapters/logger_test.rb +0 -136
  67. data/test/adapters/net_http_persistent_test.rb +0 -114
  68. data/test/adapters/net_http_test.rb +0 -79
  69. data/test/adapters/patron_test.rb +0 -40
  70. data/test/adapters/rack_test.rb +0 -38
  71. data/test/adapters/test_middleware_test.rb +0 -157
  72. data/test/adapters/typhoeus_test.rb +0 -38
  73. data/test/authentication_middleware_test.rb +0 -65
  74. data/test/composite_read_io_test.rb +0 -109
  75. data/test/connection_test.rb +0 -738
  76. data/test/env_test.rb +0 -268
  77. data/test/helper.rb +0 -75
  78. data/test/live_server.rb +0 -67
  79. data/test/middleware/instrumentation_test.rb +0 -88
  80. data/test/middleware/retry_test.rb +0 -282
  81. data/test/middleware_stack_test.rb +0 -260
  82. data/test/multibyte.txt +0 -1
  83. data/test/options_test.rb +0 -333
  84. data/test/parameters_test.rb +0 -157
  85. data/test/request_middleware_test.rb +0 -126
  86. data/test/response_middleware_test.rb +0 -72
  87. data/test/strawberry.rb +0 -2
  88. data/test/utils_test.rb +0 -98
@@ -1,5 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Faraday
2
4
  class Adapter
5
+ # Patron adapter.
3
6
  class Patron < Faraday::Adapter
4
7
  dependency 'patron'
5
8
 
@@ -9,46 +12,60 @@ module Faraday
9
12
  env[:body] = env[:body].read if env[:body].respond_to? :read
10
13
 
11
14
  session = ::Patron::Session.new
12
- @config_block.call(session) if @config_block
13
- configure_ssl(session, env[:ssl]) if env[:url].scheme == 'https' and env[:ssl]
15
+ @config_block&.call(session)
16
+ if (env[:url].scheme == 'https') && env[:ssl]
17
+ configure_ssl(session, env[:ssl])
18
+ end
14
19
 
15
- if req = env[:request]
16
- session.timeout = session.connect_timeout = req[:timeout] if req[:timeout]
17
- session.connect_timeout = req[:open_timeout] if req[:open_timeout]
20
+ if (req = env[:request])
21
+ if req[:timeout]
22
+ session.timeout = session.connect_timeout = req[:timeout]
23
+ end
24
+ session.connect_timeout = req[:open_timeout] if req[:open_timeout]
18
25
 
19
- if proxy = req[:proxy]
26
+ if (proxy = req[:proxy])
20
27
  proxy_uri = proxy[:uri].dup
21
- proxy_uri.user = proxy[:user] && Utils.escape(proxy[:user]).gsub('+', '%20')
22
- proxy_uri.password = proxy[:password] && Utils.escape(proxy[:password]).gsub('+', '%20')
28
+ proxy_uri.user = proxy[:user] &&
29
+ Utils.escape(proxy[:user]).gsub('+', '%20')
30
+ proxy_uri.password = proxy[:password] &&
31
+ Utils.escape(proxy[:password]).gsub('+', '%20')
23
32
  session.proxy = proxy_uri.to_s
24
33
  end
25
34
  end
26
35
 
27
36
  response = begin
28
37
  data = env[:body] ? env[:body].to_s : nil
29
- session.request(env[:method], env[:url].to_s, env[:request_headers], :data => data)
30
- rescue Errno::ECONNREFUSED, ::Patron::ConnectionFailed
31
- raise Faraday::ConnectionFailed, $!
38
+ session.request(env[:method], env[:url].to_s,
39
+ env[:request_headers], data: data)
40
+ rescue Errno::ECONNREFUSED, ::Patron::ConnectionFailed
41
+ raise Faraday::ConnectionFailed, $ERROR_INFO
32
42
  end
33
43
 
44
+ if (req = env[:request]).stream_response?
45
+ warn "Streaming downloads for #{self.class.name} " \
46
+ 'are not yet implemented.'
47
+ req.on_data.call(response.body, response.body.bytesize)
48
+ end
34
49
  # Remove the "HTTP/1.1 200", leaving just the reason phrase
35
50
  reason_phrase = response.status_line.gsub(/^.* \d{3} /, '')
36
51
 
37
- save_response(env, response.status, response.body, response.headers, reason_phrase)
52
+ save_response(env, response.status, response.body,
53
+ response.headers, reason_phrase)
38
54
 
39
55
  @app.call env
40
- rescue ::Patron::TimeoutError => err
41
- if connection_timed_out_message?(err.message)
42
- raise Faraday::ConnectionFailed, err
43
- else
44
- raise Faraday::TimeoutError, err
56
+ rescue ::Patron::TimeoutError => e
57
+ if connection_timed_out_message?(e.message)
58
+ raise Faraday::ConnectionFailed, e
45
59
  end
46
- rescue ::Patron::Error => err
47
- if err.message.include?("code 407")
48
- raise Faraday::ConnectionFailed, %{407 "Proxy Authentication Required "}
49
- else
50
- raise Faraday::ConnectionFailed, err
60
+
61
+ raise Faraday::TimeoutError, e
62
+ rescue ::Patron::Error => e
63
+ if e.message.include?('code 407')
64
+ raise Faraday::ConnectionFailed,
65
+ %(407 "Proxy Authentication Required ")
51
66
  end
67
+
68
+ raise Faraday::ConnectionFailed, e
52
69
  end
53
70
 
54
71
  if loaded? && defined?(::Patron::Request::VALID_ACTIONS)
@@ -60,8 +77,8 @@ module Faraday
60
77
  actions << :options unless actions.include? :options
61
78
  else
62
79
  # Patron 0.4.20 and up
63
- actions << "PATCH" unless actions.include? "PATCH"
64
- actions << "OPTIONS" unless actions.include? "OPTIONS"
80
+ actions << 'PATCH' unless actions.include? 'PATCH'
81
+ actions << 'OPTIONS' unless actions.include? 'OPTIONS'
65
82
  end
66
83
  end
67
84
  end
@@ -76,20 +93,22 @@ module Faraday
76
93
 
77
94
  private
78
95
 
79
- CURL_TIMEOUT_MESSAGES = [ "Connection time-out",
80
- "Connection timed out",
81
- "Timed out before name resolve",
82
- "server connect has timed out",
83
- "Resolving timed out",
84
- "name lookup timed out",
85
- "timed out before SSL",
86
- "connect() timed out"
87
- ].freeze
96
+ CURL_TIMEOUT_MESSAGES = [
97
+ 'Connection time-out',
98
+ 'Connection timed out',
99
+ 'Timed out before name resolve',
100
+ 'server connect has timed out',
101
+ 'Resolving timed out',
102
+ 'name lookup timed out',
103
+ 'timed out before SSL',
104
+ 'connect() timed out'
105
+ ].freeze
88
106
 
89
107
  def connection_timed_out_message?(message)
90
- CURL_TIMEOUT_MESSAGES.any? { |curl_message| message.include?(curl_message) }
108
+ CURL_TIMEOUT_MESSAGES.any? do |curl_message|
109
+ message.include?(curl_message)
110
+ end
91
111
  end
92
-
93
112
  end
94
113
  end
95
114
  end
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Faraday
2
4
  class Adapter
3
5
  # Sends requests to a Rack app.
4
6
  #
5
- # Examples
7
+ # @example
6
8
  #
7
9
  # class MyRackApp
8
10
  # def call(env)
@@ -17,7 +19,7 @@ module Faraday
17
19
  dependency 'rack/test'
18
20
 
19
21
  # not prefixed with "HTTP_"
20
- SPECIAL_HEADERS = %w[ CONTENT_LENGTH CONTENT_TYPE ]
22
+ SPECIAL_HEADERS = %w[CONTENT_LENGTH CONTENT_TYPE].freeze
21
23
 
22
24
  def initialize(faraday_app, rack_app)
23
25
  super(faraday_app)
@@ -27,32 +29,46 @@ module Faraday
27
29
 
28
30
  def call(env)
29
31
  super
30
- rack_env = {
31
- :method => env[:method],
32
- :input => env[:body].respond_to?(:read) ? env[:body].read : env[:body],
33
- 'rack.url_scheme' => env[:url].scheme
34
- }
32
+ rack_env = build_rack_env(env)
35
33
 
36
- env[:request_headers].each do |name, value|
34
+ env[:request_headers]&.each do |name, value|
37
35
  name = name.upcase.tr('-', '_')
38
36
  name = "HTTP_#{name}" unless SPECIAL_HEADERS.include? name
39
37
  rack_env[name] = value
40
- end if env[:request_headers]
38
+ end
41
39
 
42
40
  timeout = env[:request][:timeout] || env[:request][:open_timeout]
43
41
  response = if timeout
44
- Timer.timeout(timeout, Faraday::TimeoutError) { execute_request(env, rack_env) }
45
- else
46
- execute_request(env, rack_env)
42
+ Timer.timeout(timeout, Faraday::TimeoutError) do
43
+ execute_request(env, rack_env)
44
+ end
45
+ else
46
+ execute_request(env, rack_env)
47
+ end
48
+
49
+ if (req = env[:request]).stream_response?
50
+ warn "Streaming downloads for #{self.class.name} " \
51
+ 'are not yet implemented.'
52
+ req.on_data.call(response.body, response.body.bytesize)
47
53
  end
48
54
 
49
55
  save_response(env, response.status, response.body, response.headers)
50
56
  @app.call env
51
57
  end
52
58
 
59
+ private
60
+
53
61
  def execute_request(env, rack_env)
54
62
  @session.request(env[:url].to_s, rack_env)
55
63
  end
64
+
65
+ def build_rack_env(env)
66
+ {
67
+ method: env[:method],
68
+ input: env[:body].respond_to?(:read) ? env[:body].read : env[:body],
69
+ 'rack.url_scheme' => env[:url].scheme
70
+ }
71
+ end
56
72
  end
57
73
  end
58
74
  end
@@ -1,51 +1,56 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Faraday
2
4
  class Adapter
3
- # Examples
4
- #
5
+ # @example
5
6
  # test = Faraday::Connection.new do
6
7
  # use Faraday::Adapter::Test do |stub|
7
- # # simply define matcher to match the request
8
+ # # Define matcher to match the request
8
9
  # stub.get '/resource.json' do
9
10
  # # return static content
10
11
  # [200, {'Content-Type' => 'application/json'}, 'hi world']
11
12
  # end
12
- #
13
+ #
13
14
  # # response with content generated based on request
14
15
  # stub.get '/showget' do |env|
15
16
  # [200, {'Content-Type' => 'text/plain'}, env[:method].to_s]
16
17
  # end
17
- #
18
- # # regular expression can be used as matching filter
18
+ #
19
+ # # A regular expression can be used as matching filter
19
20
  # stub.get /\A\/items\/(\d+)\z/ do |env, meta|
20
- # # in case regular expression is used an instance of MatchData can be received
21
- # [200, {'Content-Type' => 'text/plain'}, "showing item: #{meta[:match_data][1]}"]
21
+ # # in case regular expression is used, an instance of MatchData
22
+ # # can be received
23
+ # [200,
24
+ # {'Content-Type' => 'text/plain'},
25
+ # "showing item: #{meta[:match_data][1]}"
26
+ # ]
22
27
  # end
23
28
  # end
24
29
  # end
25
- #
30
+ #
26
31
  # resp = test.get '/resource.json'
27
32
  # resp.body # => 'hi world'
28
- #
33
+ #
29
34
  # resp = test.get '/showget'
30
35
  # resp.body # => 'get'
31
- #
36
+ #
32
37
  # resp = test.get '/items/1'
33
38
  # resp.body # => 'showing item: 1'
34
- #
39
+ #
35
40
  # resp = test.get '/items/2'
36
41
  # resp.body # => 'showing item: 2'
37
- #
38
-
39
42
  class Test < Faraday::Adapter
40
43
  attr_accessor :stubs
41
44
 
45
+ # A stack of Stubs
42
46
  class Stubs
43
47
  class NotFound < StandardError
44
48
  end
45
49
 
46
50
  def initialize
47
- # {:get => [Stub, Stub]}
48
- @stack, @consumed = {}, {}
51
+ # { get: [Stub, Stub] }
52
+ @stack = {}
53
+ @consumed = {}
49
54
  yield(self) if block_given?
50
55
  end
51
56
 
@@ -54,7 +59,8 @@ module Faraday
54
59
  end
55
60
 
56
61
  def match(request_method, host, path, headers, body)
57
- return false if !@stack.key?(request_method)
62
+ return false unless @stack.key?(request_method)
63
+
58
64
  stack = @stack[request_method]
59
65
  consumed = (@consumed[request_method] ||= [])
60
66
 
@@ -74,15 +80,15 @@ module Faraday
74
80
  new_stub(:head, path, headers, &block)
75
81
  end
76
82
 
77
- def post(path, body=nil, headers = {}, &block)
83
+ def post(path, body = nil, headers = {}, &block)
78
84
  new_stub(:post, path, headers, body, &block)
79
85
  end
80
86
 
81
- def put(path, body=nil, headers = {}, &block)
87
+ def put(path, body = nil, headers = {}, &block)
82
88
  new_stub(:put, path, headers, body, &block)
83
89
  end
84
90
 
85
- def patch(path, body=nil, headers = {}, &block)
91
+ def patch(path, body = nil, headers = {}, &block)
86
92
  new_stub(:patch, path, headers, body, &block)
87
93
  end
88
94
 
@@ -98,26 +104,32 @@ module Faraday
98
104
  def verify_stubbed_calls
99
105
  failed_stubs = []
100
106
  @stack.each do |method, stubs|
101
- unless stubs.size == 0
102
- failed_stubs.concat(stubs.map {|stub|
107
+ next if stubs.empty?
108
+
109
+ failed_stubs.concat(
110
+ stubs.map do |stub|
103
111
  "Expected #{method} #{stub}."
104
- })
105
- end
112
+ end
113
+ )
106
114
  end
107
- raise failed_stubs.join(" ") unless failed_stubs.size == 0
115
+ raise failed_stubs.join(' ') unless failed_stubs.empty?
108
116
  end
109
117
 
110
118
  protected
111
119
 
112
- def new_stub(request_method, path, headers = {}, body=nil, &block)
120
+ def new_stub(request_method, path, headers = {}, body = nil, &block)
113
121
  normalized_path, host =
114
122
  if path.is_a?(Regexp)
115
123
  path
116
124
  else
117
- [Faraday::Utils.normalize_path(path), Faraday::Utils.URI(path).host]
125
+ [
126
+ Faraday::Utils.normalize_path(path),
127
+ Faraday::Utils.URI(path).host
128
+ ]
118
129
  end
119
130
 
120
- (@stack[request_method] ||= []) << Stub.new(host, normalized_path, headers, body, block)
131
+ stub = Stub.new(host, normalized_path, headers, body, block)
132
+ (@stack[request_method] ||= []) << stub
121
133
  end
122
134
 
123
135
  def matches?(stack, host, path, headers, body)
@@ -129,32 +141,42 @@ module Faraday
129
141
  end
130
142
  end
131
143
 
144
+ # Stub request
145
+ # rubocop:disable Style/StructInheritance
132
146
  class Stub < Struct.new(:host, :path, :params, :headers, :body, :block)
147
+ # rubocop:enable Style/StructInheritance
133
148
  def initialize(host, full, headers, body, block)
134
- path, query = full.respond_to?(:split) ? full.split("?") : full
135
- params = query ?
136
- Faraday::Utils.parse_nested_query(query) :
137
- {}
149
+ path, query = full.respond_to?(:split) ? full.split('?') : full
150
+ params =
151
+ if query
152
+ Faraday::Utils.parse_nested_query(query)
153
+ else
154
+ {}
155
+ end
156
+
138
157
  super(host, path, params, headers, body, block)
139
158
  end
140
159
 
141
160
  def matches?(request_host, request_uri, request_headers, request_body)
142
161
  request_path, request_query = request_uri.split('?')
143
- request_params = request_query ?
144
- Faraday::Utils.parse_nested_query(request_query) :
145
- {}
146
- # meta is a hash use as carrier
162
+ request_params =
163
+ if request_query
164
+ Faraday::Utils.parse_nested_query(request_query)
165
+ else
166
+ {}
167
+ end
168
+ # meta is a hash used as carrier
147
169
  # that will be yielded to consumer block
148
170
  meta = {}
149
- return (host.nil? || host == request_host) &&
171
+ [(host.nil? || host == request_host) &&
150
172
  path_match?(request_path, meta) &&
151
173
  params_match?(request_params) &&
152
174
  (body.to_s.size.zero? || request_body == body) &&
153
- headers_match?(request_headers), meta
175
+ headers_match?(request_headers), meta]
154
176
  end
155
177
 
156
178
  def path_match?(request_path, meta)
157
- if path.is_a? Regexp
179
+ if path.is_a?(Regexp)
158
180
  !!(meta[:match_data] = path.match(request_path))
159
181
  else
160
182
  path == request_path
@@ -178,7 +200,7 @@ module Faraday
178
200
  end
179
201
  end
180
202
 
181
- def initialize(app, stubs=nil, &block)
203
+ def initialize(app, stubs = nil, &block)
182
204
  super(app)
183
205
  @stubs = stubs || Stubs.new
184
206
  configure(&block) if block
@@ -192,20 +214,31 @@ module Faraday
192
214
  super
193
215
  host = env[:url].host
194
216
  normalized_path = Faraday::Utils.normalize_path(env[:url])
195
- params_encoder = env.request.params_encoder || Faraday::Utils.default_params_encoder
196
-
197
- stub, meta = stubs.match(env[:method], host, normalized_path, env.request_headers, env[:body])
198
- if stub
199
- env[:params] = (query = env[:url].query) ?
200
- params_encoder.decode(query) : {}
201
- block_arity = stub.block.arity
202
- status, headers, body = (block_arity >= 0) ?
203
- stub.block.call(*[env, meta].take(block_arity)) :
217
+ params_encoder = env.request.params_encoder ||
218
+ Faraday::Utils.default_params_encoder
219
+
220
+ stub, meta = stubs.match(env[:method], host, normalized_path,
221
+ env.request_headers, env[:body])
222
+
223
+ unless stub
224
+ raise Stubs::NotFound, "no stubbed request for #{env[:method]} "\
225
+ "#{normalized_path} #{env[:body]}"
226
+ end
227
+
228
+ env[:params] = if (query = env[:url].query)
229
+ params_encoder.decode(query)
230
+ else
231
+ {}
232
+ end
233
+ block_arity = stub.block.arity
234
+ status, headers, body =
235
+ if block_arity >= 0
236
+ stub.block.call(*[env, meta].take(block_arity))
237
+ else
204
238
  stub.block.call(env, meta)
205
- save_response(env, status, body, headers)
206
- else
207
- raise Stubs::NotFound, "no stubbed request for #{env[:method]} #{normalized_path} #{env[:body]}"
208
- end
239
+ end
240
+ save_response(env, status, body, headers)
241
+
209
242
  @app.call(env)
210
243
  end
211
244
  end