faraday 0.9.1 → 0.16.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 (98) hide show
  1. checksums.yaml +5 -5
  2. data/LICENSE.md +1 -1
  3. data/README.md +30 -195
  4. data/lib/faraday/adapter/em_http.rb +148 -99
  5. data/lib/faraday/adapter/em_http_ssl_patch.rb +24 -18
  6. data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +18 -15
  7. data/lib/faraday/adapter/em_synchrony.rb +107 -49
  8. data/lib/faraday/adapter/excon.rb +102 -55
  9. data/lib/faraday/adapter/httpclient.rb +80 -36
  10. data/lib/faraday/adapter/net_http.rb +119 -44
  11. data/lib/faraday/adapter/net_http_persistent.rb +68 -27
  12. data/lib/faraday/adapter/patron.rb +76 -34
  13. data/lib/faraday/adapter/rack.rb +28 -12
  14. data/lib/faraday/adapter/test.rb +136 -52
  15. data/lib/faraday/adapter/typhoeus.rb +7 -115
  16. data/lib/faraday/adapter.rb +43 -20
  17. data/lib/faraday/adapter_registry.rb +28 -0
  18. data/lib/faraday/autoload.rb +47 -36
  19. data/lib/faraday/connection.rb +359 -165
  20. data/lib/faraday/dependency_loader.rb +37 -0
  21. data/lib/faraday/encoders/flat_params_encoder.rb +94 -0
  22. data/lib/faraday/encoders/nested_params_encoder.rb +171 -0
  23. data/lib/faraday/error.rb +71 -24
  24. data/lib/faraday/file_part.rb +128 -0
  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/connection_options.rb +22 -0
  29. data/lib/faraday/options/env.rb +181 -0
  30. data/lib/faraday/options/proxy_options.rb +28 -0
  31. data/lib/faraday/options/request_options.rb +21 -0
  32. data/lib/faraday/options/ssl_options.rb +59 -0
  33. data/lib/faraday/options.rb +57 -185
  34. data/lib/faraday/param_part.rb +53 -0
  35. data/lib/faraday/parameters.rb +4 -180
  36. data/lib/faraday/rack_builder.rb +74 -38
  37. data/lib/faraday/request/authorization.rb +42 -31
  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 +81 -45
  41. data/lib/faraday/request/retry.rb +212 -121
  42. data/lib/faraday/request/token_authentication.rb +15 -10
  43. data/lib/faraday/request/url_encoded.rb +41 -23
  44. data/lib/faraday/request.rb +84 -30
  45. data/lib/faraday/response/logger.rb +22 -48
  46. data/lib/faraday/response/raise_error.rb +36 -14
  47. data/lib/faraday/response.rb +29 -18
  48. data/lib/faraday/utils/headers.rb +139 -0
  49. data/lib/faraday/utils/params_hash.rb +61 -0
  50. data/lib/faraday/utils.rb +28 -216
  51. data/lib/faraday.rb +102 -204
  52. data/spec/external_adapters/faraday_specs_setup.rb +14 -0
  53. metadata +24 -94
  54. data/.document +0 -6
  55. data/CHANGELOG.md +0 -20
  56. data/CONTRIBUTING.md +0 -36
  57. data/Gemfile +0 -25
  58. data/Rakefile +0 -71
  59. data/faraday.gemspec +0 -34
  60. data/lib/faraday/upload_io.rb +0 -67
  61. data/script/cached-bundle +0 -46
  62. data/script/console +0 -7
  63. data/script/generate_certs +0 -42
  64. data/script/package +0 -7
  65. data/script/proxy-server +0 -42
  66. data/script/release +0 -17
  67. data/script/s3-put +0 -71
  68. data/script/server +0 -36
  69. data/script/test +0 -172
  70. data/test/adapters/default_test.rb +0 -14
  71. data/test/adapters/em_http_test.rb +0 -20
  72. data/test/adapters/em_synchrony_test.rb +0 -20
  73. data/test/adapters/excon_test.rb +0 -20
  74. data/test/adapters/httpclient_test.rb +0 -21
  75. data/test/adapters/integration.rb +0 -254
  76. data/test/adapters/logger_test.rb +0 -82
  77. data/test/adapters/net_http_persistent_test.rb +0 -20
  78. data/test/adapters/net_http_test.rb +0 -14
  79. data/test/adapters/patron_test.rb +0 -20
  80. data/test/adapters/rack_test.rb +0 -31
  81. data/test/adapters/test_middleware_test.rb +0 -114
  82. data/test/adapters/typhoeus_test.rb +0 -28
  83. data/test/authentication_middleware_test.rb +0 -65
  84. data/test/composite_read_io_test.rb +0 -111
  85. data/test/connection_test.rb +0 -522
  86. data/test/env_test.rb +0 -218
  87. data/test/helper.rb +0 -81
  88. data/test/live_server.rb +0 -67
  89. data/test/middleware/instrumentation_test.rb +0 -88
  90. data/test/middleware/retry_test.rb +0 -177
  91. data/test/middleware_stack_test.rb +0 -173
  92. data/test/multibyte.txt +0 -1
  93. data/test/options_test.rb +0 -252
  94. data/test/parameters_test.rb +0 -64
  95. data/test/request_middleware_test.rb +0 -142
  96. data/test/response_middleware_test.rb +0 -72
  97. data/test/strawberry.rb +0 -2
  98. data/test/utils_test.rb +0 -58
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Faraday
2
4
  # Subclasses Struct with some special helpers for converting from a Hash to
3
5
  # a Struct.
@@ -10,6 +12,7 @@ module Faraday
10
12
  # Public
11
13
  def each
12
14
  return to_enum(:each) unless block_given?
15
+
13
16
  members.each do |key|
14
17
  yield(key.to_sym, send(key))
15
18
  end
@@ -18,23 +21,20 @@ module Faraday
18
21
  # Public
19
22
  def update(obj)
20
23
  obj.each do |key, value|
21
- if sub_options = self.class.options_for(key)
22
- value = sub_options.from(value) if value
23
- elsif Hash === value
24
- hash = {}
25
- value.each do |hash_key, hash_value|
26
- hash[hash_key] = hash_value
27
- end
28
- value = hash
24
+ sub_options = self.class.options_for(key)
25
+ if sub_options
26
+ new_value = sub_options.from(value) if value
27
+ elsif value.is_a?(Hash)
28
+ new_value = value.dup
29
+ else
30
+ new_value = value
29
31
  end
30
32
 
31
- self.send("#{key}=", value) unless value.nil?
33
+ send("#{key}=", new_value) unless new_value.nil?
32
34
  end
33
35
  self
34
36
  end
35
37
 
36
- alias merge! update
37
-
38
38
  # Public
39
39
  def delete(key)
40
40
  value = send(key)
@@ -48,18 +48,38 @@ module Faraday
48
48
  end
49
49
 
50
50
  # Public
51
- def merge(value)
52
- dup.update(value)
51
+ def merge!(other)
52
+ other.each do |key, other_value|
53
+ self_value = send(key)
54
+ sub_options = self.class.options_for(key)
55
+ new_value = if self_value && sub_options && other_value
56
+ self_value.merge(other_value)
57
+ else
58
+ other_value
59
+ end
60
+ send("#{key}=", new_value) unless new_value.nil?
61
+ end
62
+ self
63
+ end
64
+
65
+ # Public
66
+ def merge(other)
67
+ dup.merge!(other)
68
+ end
69
+
70
+ # Public
71
+ def deep_dup
72
+ self.class.from(self)
53
73
  end
54
74
 
55
75
  # Public
56
76
  def fetch(key, *args)
57
77
  unless symbolized_key_set.include?(key.to_sym)
58
78
  key_setter = "#{key}="
59
- if args.size > 0
79
+ if !args.empty?
60
80
  send(key_setter, args.first)
61
81
  elsif block_given?
62
- send(key_setter, Proc.new.call(key))
82
+ send(key_setter, yield(key))
63
83
  else
64
84
  raise self.class.fetch_error_class, "key not found: #{key.inspect}"
65
85
  end
@@ -85,6 +105,7 @@ module Faraday
85
105
  # Public
86
106
  def each_key
87
107
  return to_enum(:each_key) unless block_given?
108
+
88
109
  keys.each do |key|
89
110
  yield(key)
90
111
  end
@@ -100,6 +121,7 @@ module Faraday
100
121
  # Public
101
122
  def each_value
102
123
  return to_enum(:each_value) unless block_given?
124
+
103
125
  values.each do |value|
104
126
  yield(value)
105
127
  end
@@ -129,9 +151,9 @@ module Faraday
129
151
  value = send(member)
130
152
  values << "#{member}=#{value.inspect}" if value
131
153
  end
132
- values = values.empty? ? ' (empty)' : (' ' << values.join(", "))
154
+ values = values.empty? ? '(empty)' : values.join(', ')
133
155
 
134
- %(#<#{self.class}#{values}>)
156
+ %(#<#{self.class} #{values}>)
135
157
  end
136
158
 
137
159
  # Internal
@@ -149,8 +171,12 @@ module Faraday
149
171
  @attribute_options ||= {}
150
172
  end
151
173
 
152
- def self.memoized(key)
153
- memoized_attributes[key.to_sym] = Proc.new
174
+ def self.memoized(key, &block)
175
+ unless block_given?
176
+ raise ArgumentError, '#memoized must be called with a block'
177
+ end
178
+
179
+ memoized_attributes[key.to_sym] = block
154
180
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
155
181
  def #{key}() self[:#{key}]; end
156
182
  RUBY
@@ -162,7 +188,7 @@ module Faraday
162
188
 
163
189
  def [](key)
164
190
  key = key.to_sym
165
- if method = self.class.memoized_attributes[key]
191
+ if (method = self.class.memoized_attributes[key])
166
192
  super(key) || (self[key] = instance_eval(&method))
167
193
  else
168
194
  super
@@ -170,7 +196,7 @@ module Faraday
170
196
  end
171
197
 
172
198
  def symbolized_key_set
173
- @symbolized_key_set ||= Set.new(keys.map { |k| k.to_sym })
199
+ @symbolized_key_set ||= Set.new(keys.map(&:to_sym))
174
200
  end
175
201
 
176
202
  def self.inherited(subclass)
@@ -181,170 +207,16 @@ module Faraday
181
207
 
182
208
  def self.fetch_error_class
183
209
  @fetch_error_class ||= if Object.const_defined?(:KeyError)
184
- ::KeyError
185
- else
186
- ::IndexError
187
- end
188
- end
189
- end
190
-
191
- class RequestOptions < Options.new(:params_encoder, :proxy, :bind,
192
- :timeout, :open_timeout, :boundary,
193
- :oauth)
194
-
195
- def []=(key, value)
196
- if key && key.to_sym == :proxy
197
- super(key, value ? ProxyOptions.from(value) : nil)
198
- else
199
- super(key, value)
200
- end
201
- end
202
- end
203
-
204
- class SSLOptions < Options.new(:verify, :ca_file, :ca_path, :verify_mode,
205
- :cert_store, :client_cert, :client_key, :certificate, :private_key, :verify_depth, :version)
206
-
207
- def verify?
208
- verify != false
209
- end
210
-
211
- def disable?
212
- !verify?
213
- end
214
- end
215
-
216
- class ProxyOptions < Options.new(:uri, :user, :password)
217
- extend Forwardable
218
- def_delegators :uri, :scheme, :scheme=, :host, :host=, :port, :port=, :path, :path=
219
-
220
- def self.from(value)
221
- case value
222
- when String
223
- value = {:uri => Utils.URI(value)}
224
- when URI
225
- value = {:uri => value}
226
- when Hash, Options
227
- if uri = value.delete(:uri)
228
- value[:uri] = Utils.URI(uri)
229
- end
230
- end
231
- super(value)
232
- end
233
-
234
- memoized(:user) { uri.user && Utils.unescape(uri.user) }
235
- memoized(:password) { uri.password && Utils.unescape(uri.password) }
236
- end
237
-
238
- class ConnectionOptions < Options.new(:request, :proxy, :ssl, :builder, :url,
239
- :parallel_manager, :params, :headers, :builder_class)
240
-
241
- options :request => RequestOptions, :ssl => SSLOptions
242
-
243
- memoized(:request) { self.class.options_for(:request).new }
244
-
245
- memoized(:ssl) { self.class.options_for(:ssl).new }
246
-
247
- memoized(:builder_class) { RackBuilder }
248
-
249
- def new_builder(block)
250
- builder_class.new(&block)
251
- end
252
- end
253
-
254
- class Env < Options.new(:method, :body, :url, :request, :request_headers,
255
- :ssl, :parallel_manager, :params, :response, :response_headers, :status)
256
-
257
- ContentLength = 'Content-Length'.freeze
258
- StatusesWithoutBody = Set.new [204, 304]
259
- SuccessfulStatuses = 200..299
260
-
261
- # A Set of HTTP verbs that typically send a body. If no body is set for
262
- # these requests, the Content-Length header is set to 0.
263
- MethodsWithBodies = Set.new [:post, :put, :patch, :options]
264
-
265
- options :request => RequestOptions,
266
- :request_headers => Utils::Headers, :response_headers => Utils::Headers
267
-
268
- extend Forwardable
269
-
270
- def_delegators :request, :params_encoder
271
-
272
- # Public
273
- def [](key)
274
- if in_member_set?(key)
275
- super(key)
276
- else
277
- custom_members[key]
278
- end
279
- end
280
-
281
- # Public
282
- def []=(key, value)
283
- if in_member_set?(key)
284
- super(key, value)
285
- else
286
- custom_members[key] = value
287
- end
288
- end
289
-
290
- # Public
291
- def success?
292
- SuccessfulStatuses.include?(status)
293
- end
294
-
295
- # Public
296
- def needs_body?
297
- !body && MethodsWithBodies.include?(method)
298
- end
299
-
300
- # Public
301
- def clear_body
302
- request_headers[ContentLength] = '0'
303
- self.body = ''
304
- end
305
-
306
- # Public
307
- def parse_body?
308
- !StatusesWithoutBody.include?(status)
309
- end
310
-
311
- # Public
312
- def parallel?
313
- !!parallel_manager
314
- end
315
-
316
- def inspect
317
- attrs = [nil]
318
- members.each do |mem|
319
- if value = send(mem)
320
- attrs << "@#{mem}=#{value.inspect}"
321
- end
322
- end
323
- if !custom_members.empty?
324
- attrs << "@custom=#{custom_members.inspect}"
325
- end
326
- %(#<#{self.class}#{attrs.join(" ")}>)
327
- end
328
-
329
- # Internal
330
- def custom_members
331
- @custom_members ||= {}
332
- end
333
-
334
- # Internal
335
- if members.first.is_a?(Symbol)
336
- def in_member_set?(key)
337
- self.class.member_set.include?(key.to_sym)
338
- end
339
- else
340
- def in_member_set?(key)
341
- self.class.member_set.include?(key.to_s)
342
- end
343
- end
344
-
345
- # Internal
346
- def self.member_set
347
- @member_set ||= Set.new(members)
210
+ ::KeyError
211
+ else
212
+ ::IndexError
213
+ end
348
214
  end
349
215
  end
350
216
  end
217
+
218
+ require 'faraday/options/request_options'
219
+ require 'faraday/options/ssl_options'
220
+ require 'faraday/options/proxy_options'
221
+ require 'faraday/options/connection_options'
222
+ require 'faraday/options/env'
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Faraday
4
+ # Multipart value used to POST data with a content type.
5
+ class ParamPart
6
+ # @param value [String] Uploaded content as a String.
7
+ # @param content_type [String] String content type of the value.
8
+ # @param content_id [String] Optional String of this value's Content-ID.
9
+ #
10
+ # @return [Faraday::ParamPart]
11
+ def initialize(value, content_type, content_id = nil)
12
+ @value = value
13
+ @content_type = content_type
14
+ @content_id = content_id
15
+ end
16
+
17
+ # Converts this value to a form part.
18
+ #
19
+ # @param boundary [String] String multipart boundary that must not exist in
20
+ # the content exactly.
21
+ # @param key [String] String key name for this value.
22
+ #
23
+ # @return [Faraday::Parts::Part]
24
+ def to_part(boundary, key)
25
+ Faraday::Parts::Part.new(boundary, key, value, headers)
26
+ end
27
+
28
+ # Returns a Hash of String key/value pairs.
29
+ #
30
+ # @return [Hash]
31
+ def headers
32
+ {
33
+ 'Content-Type' => content_type,
34
+ 'Content-ID' => content_id
35
+ }
36
+ end
37
+
38
+ # The content to upload.
39
+ #
40
+ # @return [String]
41
+ attr_reader :value
42
+
43
+ # The value's content type.
44
+ #
45
+ # @return [String]
46
+ attr_reader :content_type
47
+
48
+ # The value's content ID, if given.
49
+ #
50
+ # @return [String, nil]
51
+ attr_reader :content_id
52
+ end
53
+ end
@@ -1,181 +1,5 @@
1
- require "forwardable"
1
+ # frozen_string_literal: true
2
2
 
3
- module Faraday
4
- module NestedParamsEncoder
5
- class << self
6
- extend Forwardable
7
- def_delegators :'Faraday::Utils', :escape, :unescape
8
- end
9
-
10
- def self.encode(params)
11
- return nil if params == nil
12
-
13
- if !params.is_a?(Array)
14
- if !params.respond_to?(:to_hash)
15
- raise TypeError,
16
- "Can't convert #{params.class} into Hash."
17
- end
18
- params = params.to_hash
19
- params = params.map do |key, value|
20
- key = key.to_s if key.kind_of?(Symbol)
21
- [key, value]
22
- end
23
- # Useful default for OAuth and caching.
24
- # Only to be used for non-Array inputs. Arrays should preserve order.
25
- params.sort!
26
- end
27
-
28
- # Helper lambda
29
- to_query = lambda do |parent, value|
30
- if value.is_a?(Hash)
31
- value = value.map do |key, val|
32
- key = escape(key)
33
- [key, val]
34
- end
35
- value.sort!
36
- buffer = ""
37
- value.each do |key, val|
38
- new_parent = "#{parent}%5B#{key}%5D"
39
- buffer << "#{to_query.call(new_parent, val)}&"
40
- end
41
- return buffer.chop
42
- elsif value.is_a?(Array)
43
- buffer = ""
44
- value.each_with_index do |val, i|
45
- new_parent = "#{parent}%5B%5D"
46
- buffer << "#{to_query.call(new_parent, val)}&"
47
- end
48
- return buffer.chop
49
- else
50
- encoded_value = escape(value)
51
- return "#{parent}=#{encoded_value}"
52
- end
53
- end
54
-
55
- # The params have form [['key1', 'value1'], ['key2', 'value2']].
56
- buffer = ''
57
- params.each do |parent, value|
58
- encoded_parent = escape(parent)
59
- buffer << "#{to_query.call(encoded_parent, value)}&"
60
- end
61
- return buffer.chop
62
- end
63
-
64
- def self.decode(query)
65
- return nil if query == nil
66
- # Recursive helper lambda
67
- dehash = lambda do |hash|
68
- hash.each do |(key, value)|
69
- if value.kind_of?(Hash)
70
- hash[key] = dehash.call(value)
71
- end
72
- end
73
- # Numeric keys implies an array
74
- if hash != {} && hash.keys.all? { |key| key =~ /^\d+$/ }
75
- hash.sort.inject([]) do |accu, (_, value)|
76
- accu << value; accu
77
- end
78
- else
79
- hash
80
- end
81
- end
82
-
83
- empty_accumulator = {}
84
- return ((query.split('&').map do |pair|
85
- pair.split('=', 2) if pair && !pair.empty?
86
- end).compact.inject(empty_accumulator.dup) do |accu, (key, value)|
87
- key = unescape(key)
88
- if value.kind_of?(String)
89
- value = unescape(value.gsub(/\+/, ' '))
90
- end
91
-
92
- array_notation = !!(key =~ /\[\]$/)
93
- subkeys = key.split(/[\[\]]+/)
94
- current_hash = accu
95
- for i in 0...(subkeys.size - 1)
96
- subkey = subkeys[i]
97
- current_hash[subkey] = {} unless current_hash[subkey]
98
- current_hash = current_hash[subkey]
99
- end
100
- if array_notation
101
- current_hash[subkeys.last] = [] unless current_hash[subkeys.last]
102
- current_hash[subkeys.last] << value
103
- else
104
- current_hash[subkeys.last] = value
105
- end
106
- accu
107
- end).inject(empty_accumulator.dup) do |accu, (key, value)|
108
- accu[key] = value.kind_of?(Hash) ? dehash.call(value) : value
109
- accu
110
- end
111
- end
112
- end
113
-
114
- module FlatParamsEncoder
115
- class << self
116
- extend Forwardable
117
- def_delegators :'Faraday::Utils', :escape, :unescape
118
- end
119
-
120
- def self.encode(params)
121
- return nil if params == nil
122
-
123
- if !params.is_a?(Array)
124
- if !params.respond_to?(:to_hash)
125
- raise TypeError,
126
- "Can't convert #{params.class} into Hash."
127
- end
128
- params = params.to_hash
129
- params = params.map do |key, value|
130
- key = key.to_s if key.kind_of?(Symbol)
131
- [key, value]
132
- end
133
- # Useful default for OAuth and caching.
134
- # Only to be used for non-Array inputs. Arrays should preserve order.
135
- params.sort!
136
- end
137
-
138
- # The params have form [['key1', 'value1'], ['key2', 'value2']].
139
- buffer = ''
140
- params.each do |key, value|
141
- encoded_key = escape(key)
142
- value = value.to_s if value == true || value == false
143
- if value == nil
144
- buffer << "#{encoded_key}&"
145
- elsif value.kind_of?(Array)
146
- value.each do |sub_value|
147
- encoded_value = escape(sub_value)
148
- buffer << "#{encoded_key}=#{encoded_value}&"
149
- end
150
- else
151
- encoded_value = escape(value)
152
- buffer << "#{encoded_key}=#{encoded_value}&"
153
- end
154
- end
155
- return buffer.chop
156
- end
157
-
158
- def self.decode(query)
159
- empty_accumulator = {}
160
- return nil if query == nil
161
- split_query = (query.split('&').map do |pair|
162
- pair.split('=', 2) if pair && !pair.empty?
163
- end).compact
164
- return split_query.inject(empty_accumulator.dup) do |accu, pair|
165
- pair[0] = unescape(pair[0])
166
- pair[1] = true if pair[1].nil?
167
- if pair[1].respond_to?(:to_str)
168
- pair[1] = unescape(pair[1].to_str.gsub(/\+/, " "))
169
- end
170
- if accu[pair[0]].kind_of?(Array)
171
- accu[pair[0]] << pair[1]
172
- elsif accu[pair[0]]
173
- accu[pair[0]] = [accu[pair[0]], pair[1]]
174
- else
175
- accu[pair[0]] = pair[1]
176
- end
177
- accu
178
- end
179
- end
180
- end
181
- end
3
+ require 'forwardable'
4
+ require 'faraday/encoders/nested_params_encoder'
5
+ require 'faraday/encoders/flat_params_encoder'