faraday 0.11.0 → 1.4.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 (104) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +380 -0
  3. data/LICENSE.md +1 -1
  4. data/README.md +25 -229
  5. data/Rakefile +7 -0
  6. data/examples/client_spec.rb +65 -0
  7. data/examples/client_test.rb +79 -0
  8. data/lib/faraday/adapter/httpclient.rb +83 -59
  9. data/lib/faraday/adapter/patron.rb +92 -36
  10. data/lib/faraday/adapter/rack.rb +30 -13
  11. data/lib/faraday/adapter/test.rb +103 -62
  12. data/lib/faraday/adapter/typhoeus.rb +7 -115
  13. data/lib/faraday/adapter.rb +77 -22
  14. data/lib/faraday/adapter_registry.rb +30 -0
  15. data/lib/faraday/autoload.rb +42 -36
  16. data/lib/faraday/connection.rb +351 -167
  17. data/lib/faraday/dependency_loader.rb +37 -0
  18. data/lib/faraday/encoders/flat_params_encoder.rb +105 -0
  19. data/lib/faraday/encoders/nested_params_encoder.rb +176 -0
  20. data/lib/faraday/error.rb +127 -38
  21. data/lib/faraday/file_part.rb +128 -0
  22. data/lib/faraday/logging/formatter.rb +105 -0
  23. data/lib/faraday/methods.rb +6 -0
  24. data/lib/faraday/middleware.rb +19 -25
  25. data/lib/faraday/middleware_registry.rb +129 -0
  26. data/lib/faraday/options/connection_options.rb +22 -0
  27. data/lib/faraday/options/env.rb +181 -0
  28. data/lib/faraday/options/proxy_options.rb +32 -0
  29. data/lib/faraday/options/request_options.rb +22 -0
  30. data/lib/faraday/options/ssl_options.rb +59 -0
  31. data/lib/faraday/options.rb +58 -207
  32. data/lib/faraday/param_part.rb +53 -0
  33. data/lib/faraday/parameters.rb +4 -196
  34. data/lib/faraday/rack_builder.rb +84 -48
  35. data/lib/faraday/request/authorization.rb +44 -30
  36. data/lib/faraday/request/basic_authentication.rb +14 -7
  37. data/lib/faraday/request/instrumentation.rb +45 -27
  38. data/lib/faraday/request/multipart.rb +88 -45
  39. data/lib/faraday/request/retry.rb +211 -126
  40. data/lib/faraday/request/token_authentication.rb +15 -10
  41. data/lib/faraday/request/url_encoded.rb +43 -23
  42. data/lib/faraday/request.rb +94 -32
  43. data/lib/faraday/response/logger.rb +22 -69
  44. data/lib/faraday/response/raise_error.rb +49 -14
  45. data/lib/faraday/response.rb +27 -23
  46. data/lib/faraday/utils/headers.rb +139 -0
  47. data/lib/faraday/utils/params_hash.rb +61 -0
  48. data/lib/faraday/utils.rb +38 -238
  49. data/lib/faraday/version.rb +5 -0
  50. data/lib/faraday.rb +124 -187
  51. data/spec/external_adapters/faraday_specs_setup.rb +14 -0
  52. data/spec/faraday/adapter/em_http_spec.rb +47 -0
  53. data/spec/faraday/adapter/em_synchrony_spec.rb +16 -0
  54. data/spec/faraday/adapter/excon_spec.rb +49 -0
  55. data/spec/faraday/adapter/httpclient_spec.rb +73 -0
  56. data/spec/faraday/adapter/net_http_spec.rb +64 -0
  57. data/spec/faraday/adapter/patron_spec.rb +18 -0
  58. data/spec/faraday/adapter/rack_spec.rb +8 -0
  59. data/spec/faraday/adapter/test_spec.rb +260 -0
  60. data/spec/faraday/adapter/typhoeus_spec.rb +7 -0
  61. data/spec/faraday/adapter_registry_spec.rb +28 -0
  62. data/spec/faraday/adapter_spec.rb +55 -0
  63. data/spec/faraday/composite_read_io_spec.rb +80 -0
  64. data/spec/faraday/connection_spec.rb +736 -0
  65. data/spec/faraday/error_spec.rb +60 -0
  66. data/spec/faraday/middleware_spec.rb +52 -0
  67. data/spec/faraday/options/env_spec.rb +70 -0
  68. data/spec/faraday/options/options_spec.rb +297 -0
  69. data/spec/faraday/options/proxy_options_spec.rb +44 -0
  70. data/spec/faraday/options/request_options_spec.rb +19 -0
  71. data/spec/faraday/params_encoders/flat_spec.rb +42 -0
  72. data/spec/faraday/params_encoders/nested_spec.rb +142 -0
  73. data/spec/faraday/rack_builder_spec.rb +345 -0
  74. data/spec/faraday/request/authorization_spec.rb +88 -0
  75. data/spec/faraday/request/instrumentation_spec.rb +76 -0
  76. data/spec/faraday/request/multipart_spec.rb +302 -0
  77. data/spec/faraday/request/retry_spec.rb +242 -0
  78. data/spec/faraday/request/url_encoded_spec.rb +83 -0
  79. data/spec/faraday/request_spec.rb +120 -0
  80. data/spec/faraday/response/logger_spec.rb +220 -0
  81. data/spec/faraday/response/middleware_spec.rb +68 -0
  82. data/spec/faraday/response/raise_error_spec.rb +169 -0
  83. data/spec/faraday/response_spec.rb +75 -0
  84. data/spec/faraday/utils/headers_spec.rb +82 -0
  85. data/spec/faraday/utils_spec.rb +56 -0
  86. data/spec/faraday_spec.rb +37 -0
  87. data/spec/spec_helper.rb +132 -0
  88. data/spec/support/disabling_stub.rb +14 -0
  89. data/spec/support/fake_safe_buffer.rb +15 -0
  90. data/spec/support/helper_methods.rb +133 -0
  91. data/spec/support/shared_examples/adapter.rb +105 -0
  92. data/spec/support/shared_examples/params_encoder.rb +18 -0
  93. data/spec/support/shared_examples/request_method.rb +262 -0
  94. data/spec/support/streaming_response_checker.rb +35 -0
  95. data/spec/support/webmock_rack_app.rb +68 -0
  96. metadata +164 -16
  97. data/lib/faraday/adapter/em_http.rb +0 -243
  98. data/lib/faraday/adapter/em_http_ssl_patch.rb +0 -56
  99. data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +0 -66
  100. data/lib/faraday/adapter/em_synchrony.rb +0 -106
  101. data/lib/faraday/adapter/excon.rb +0 -80
  102. data/lib/faraday/adapter/net_http.rb +0 -135
  103. data/lib/faraday/adapter/net_http_persistent.rb +0 -50
  104. data/lib/faraday/upload_io.rb +0 -67
data/lib/faraday/utils.rb CHANGED
@@ -1,184 +1,12 @@
1
- require 'thread'
1
+ # frozen_string_literal: true
2
+
3
+ require 'faraday/utils/headers'
4
+ require 'faraday/utils/params_hash'
2
5
 
3
6
  module Faraday
7
+ # Utils contains various static helper methods.
4
8
  module Utils
5
- extend self
6
-
7
- # Adapted from Rack::Utils::HeaderHash
8
- class Headers < ::Hash
9
- def self.from(value)
10
- new(value)
11
- end
12
-
13
- def initialize(hash = nil)
14
- super()
15
- @names = {}
16
- self.update(hash || {})
17
- end
18
-
19
- # on dup/clone, we need to duplicate @names hash
20
- def initialize_copy(other)
21
- super
22
- @names = other.names.dup
23
- end
24
-
25
- # need to synchronize concurrent writes to the shared KeyMap
26
- keymap_mutex = Mutex.new
27
-
28
- # symbol -> string mapper + cache
29
- KeyMap = Hash.new do |map, key|
30
- value = if key.respond_to?(:to_str)
31
- key
32
- else
33
- key.to_s.split('_'). # :user_agent => %w(user agent)
34
- each { |w| w.capitalize! }. # => %w(User Agent)
35
- join('-') # => "User-Agent"
36
- end
37
- keymap_mutex.synchronize { map[key] = value }
38
- end
39
- KeyMap[:etag] = "ETag"
40
-
41
- def [](k)
42
- k = KeyMap[k]
43
- super(k) || super(@names[k.downcase])
44
- end
45
-
46
- def []=(k, v)
47
- k = KeyMap[k]
48
- k = (@names[k.downcase] ||= k)
49
- # join multiple values with a comma
50
- v = v.to_ary.join(', ') if v.respond_to? :to_ary
51
- super(k, v)
52
- end
53
-
54
- def fetch(k, *args, &block)
55
- k = KeyMap[k]
56
- key = @names.fetch(k.downcase, k)
57
- super(key, *args, &block)
58
- end
59
-
60
- def delete(k)
61
- k = KeyMap[k]
62
- if k = @names[k.downcase]
63
- @names.delete k.downcase
64
- super(k)
65
- end
66
- end
67
-
68
- def include?(k)
69
- @names.include? k.downcase
70
- end
71
-
72
- alias_method :has_key?, :include?
73
- alias_method :member?, :include?
74
- alias_method :key?, :include?
75
-
76
- def merge!(other)
77
- other.each { |k, v| self[k] = v }
78
- self
79
- end
80
- alias_method :update, :merge!
81
-
82
- def merge(other)
83
- hash = dup
84
- hash.merge! other
85
- end
86
-
87
- def replace(other)
88
- clear
89
- @names.clear
90
- self.update other
91
- self
92
- end
93
-
94
- def to_hash() ::Hash.new.update(self) end
95
-
96
- def parse(header_string)
97
- return unless header_string && !header_string.empty?
98
- header_string.split(/\r\n/).
99
- tap { |a| a.shift if a.first.index('HTTP/') == 0 }. # drop the HTTP status line
100
- map { |h| h.split(/:\s*/, 2) }.reject { |p| p[0].nil? }. # split key and value, ignore blank lines
101
- each { |key, value|
102
- # join multiple values with a comma
103
- if self[key]
104
- self[key] << ', ' << value
105
- else
106
- self[key] = value
107
- end
108
- }
109
- end
110
-
111
- def init_with(coder)
112
- @names = coder['names']
113
- end
114
-
115
- def encode_with(coder)
116
- coder['names'] = @names
117
- end
118
-
119
- protected
120
-
121
- def names
122
- @names
123
- end
124
- end
125
-
126
- # hash with stringified keys
127
- class ParamsHash < Hash
128
- def [](key)
129
- super(convert_key(key))
130
- end
131
-
132
- def []=(key, value)
133
- super(convert_key(key), value)
134
- end
135
-
136
- def delete(key)
137
- super(convert_key(key))
138
- end
139
-
140
- def include?(key)
141
- super(convert_key(key))
142
- end
143
-
144
- alias_method :has_key?, :include?
145
- alias_method :member?, :include?
146
- alias_method :key?, :include?
147
-
148
- def update(params)
149
- params.each do |key, value|
150
- self[key] = value
151
- end
152
- self
153
- end
154
- alias_method :merge!, :update
155
-
156
- def merge(params)
157
- dup.update(params)
158
- end
159
-
160
- def replace(other)
161
- clear
162
- update(other)
163
- end
164
-
165
- def merge_query(query, encoder = nil)
166
- if query && !query.empty?
167
- update((encoder || Utils.default_params_encoder).decode(query))
168
- end
169
- self
170
- end
171
-
172
- def to_query(encoder = nil)
173
- (encoder || Utils.default_params_encoder).encode(self)
174
- end
175
-
176
- private
177
-
178
- def convert_key(key)
179
- key.to_s
180
- end
181
- end
9
+ module_function
182
10
 
183
11
  def build_query(params)
184
12
  FlatParamsEncoder.encode(params)
@@ -188,17 +16,27 @@ module Faraday
188
16
  NestedParamsEncoder.encode(params)
189
17
  end
190
18
 
191
- ESCAPE_RE = /[^a-zA-Z0-9 .~_-]/
19
+ def default_space_encoding
20
+ @default_space_encoding ||= '+'
21
+ end
22
+
23
+ class << self
24
+ attr_writer :default_space_encoding
25
+ end
26
+
27
+ ESCAPE_RE = /[^a-zA-Z0-9 .~_-]/.freeze
192
28
 
193
- def escape(s)
194
- s.to_s.gsub(ESCAPE_RE) {|match|
195
- '%' + match.unpack('H2' * match.bytesize).join('%').upcase
196
- }.tr(' ', '+')
29
+ def escape(str)
30
+ str.to_s.gsub(ESCAPE_RE) do |match|
31
+ "%#{match.unpack('H2' * match.bytesize).join('%').upcase}"
32
+ end.gsub(' ', default_space_encoding)
197
33
  end
198
34
 
199
- def unescape(s) CGI.unescape s.to_s end
35
+ def unescape(str)
36
+ CGI.unescape str.to_s
37
+ end
200
38
 
201
- DEFAULT_SEP = /[&;] */n
39
+ DEFAULT_SEP = /[&;] */n.freeze
202
40
 
203
41
  # Adapted from Rack
204
42
  def parse_query(query)
@@ -217,55 +55,18 @@ module Faraday
217
55
  attr_writer :default_params_encoder
218
56
  end
219
57
 
220
- # Stolen from Rack
221
- def normalize_params(params, name, v = nil)
222
- name =~ %r(\A[\[\]]*([^\[\]]+)\]*)
223
- k = $1 || ''
224
- after = $' || ''
225
-
226
- return if k.empty?
227
-
228
- if after == ""
229
- if params[k]
230
- params[k] = Array[params[k]] unless params[k].kind_of?(Array)
231
- params[k] << v
232
- else
233
- params[k] = v
234
- end
235
- elsif after == "[]"
236
- params[k] ||= []
237
- raise TypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
238
- params[k] << v
239
- elsif after =~ %r(^\[\]\[([^\[\]]+)\]$) || after =~ %r(^\[\](.+)$)
240
- child_key = $1
241
- params[k] ||= []
242
- raise TypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
243
- if params[k].last.is_a?(Hash) && !params[k].last.key?(child_key)
244
- normalize_params(params[k].last, child_key, v)
245
- else
246
- params[k] << normalize_params({}, child_key, v)
247
- end
248
- else
249
- params[k] ||= {}
250
- raise TypeError, "expected Hash (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Hash)
251
- params[k] = normalize_params(params[k], after, v)
252
- end
253
-
254
- return params
255
- end
256
-
257
58
  # Normalize URI() behavior across Ruby versions
258
59
  #
259
60
  # url - A String or URI.
260
61
  #
261
62
  # Returns a parsed URI.
262
- def URI(url)
63
+ def URI(url) # rubocop:disable Naming/MethodName
263
64
  if url.respond_to?(:host)
264
65
  url
265
66
  elsif url.respond_to?(:to_str)
266
67
  default_uri_parser.call(url)
267
68
  else
268
- raise ArgumentError, "bad argument (expected URI object or URI string)"
69
+ raise ArgumentError, 'bad argument (expected URI object or URI string)'
269
70
  end
270
71
  end
271
72
 
@@ -278,27 +79,28 @@ module Faraday
278
79
 
279
80
  def default_uri_parser=(parser)
280
81
  @default_uri_parser = if parser.respond_to?(:call) || parser.nil?
281
- parser
282
- else
283
- parser.method(:parse)
284
- end
82
+ parser
83
+ else
84
+ parser.method(:parse)
85
+ end
285
86
  end
286
87
 
287
- # Receives a String or URI and returns just the path with the query string sorted.
88
+ # Receives a String or URI and returns just
89
+ # the path with the query string sorted.
288
90
  def normalize_path(url)
289
91
  url = URI(url)
290
- (url.path.start_with?('/') ? url.path : '/' + url.path) +
291
- (url.query ? "?#{sort_query_params(url.query)}" : "")
92
+ (url.path.start_with?('/') ? url.path : "/#{url.path}") +
93
+ (url.query ? "?#{sort_query_params(url.query)}" : '')
292
94
  end
293
95
 
294
96
  # Recursive hash update
295
97
  def deep_merge!(target, hash)
296
98
  hash.each do |key, value|
297
- if Hash === value and Hash === target[key]
298
- target[key] = deep_merge(target[key], value)
299
- else
300
- target[key] = value
301
- end
99
+ target[key] = if value.is_a?(Hash) && target[key].is_a?(Hash)
100
+ deep_merge(target[key], value)
101
+ else
102
+ value
103
+ end
302
104
  end
303
105
  target
304
106
  end
@@ -308,8 +110,6 @@ module Faraday
308
110
  deep_merge!(source.dup, hash)
309
111
  end
310
112
 
311
- protected
312
-
313
113
  def sort_query_params(query)
314
114
  query.split('&').sort.join('&')
315
115
  end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Faraday
4
+ VERSION = '1.4.3'
5
+ end