faraday 0.15.0 → 1.10.0

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