faraday 0.12.2 → 1.3.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 (105) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +350 -0
  3. data/LICENSE.md +1 -1
  4. data/README.md +22 -325
  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.rb +120 -188
  9. data/lib/faraday/adapter.rb +84 -22
  10. data/lib/faraday/adapter/em_http.rb +150 -104
  11. data/lib/faraday/adapter/em_http_ssl_patch.rb +24 -18
  12. data/lib/faraday/adapter/em_synchrony.rb +110 -63
  13. data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +18 -15
  14. data/lib/faraday/adapter/excon.rb +98 -54
  15. data/lib/faraday/adapter/httpclient.rb +83 -59
  16. data/lib/faraday/adapter/net_http_persistent.rb +68 -27
  17. data/lib/faraday/adapter/patron.rb +86 -37
  18. data/lib/faraday/adapter/rack.rb +30 -13
  19. data/lib/faraday/adapter/test.rb +103 -62
  20. data/lib/faraday/adapter/typhoeus.rb +7 -115
  21. data/lib/faraday/adapter_registry.rb +30 -0
  22. data/lib/faraday/autoload.rb +46 -36
  23. data/lib/faraday/connection.rb +336 -177
  24. data/lib/faraday/dependency_loader.rb +37 -0
  25. data/lib/faraday/encoders/flat_params_encoder.rb +105 -0
  26. data/lib/faraday/encoders/nested_params_encoder.rb +176 -0
  27. data/lib/faraday/error.rb +126 -37
  28. data/lib/faraday/file_part.rb +128 -0
  29. data/lib/faraday/logging/formatter.rb +105 -0
  30. data/lib/faraday/methods.rb +6 -0
  31. data/lib/faraday/middleware.rb +19 -25
  32. data/lib/faraday/middleware_registry.rb +129 -0
  33. data/lib/faraday/options.rb +39 -193
  34. data/lib/faraday/options/connection_options.rb +22 -0
  35. data/lib/faraday/options/env.rb +181 -0
  36. data/lib/faraday/options/proxy_options.rb +28 -0
  37. data/lib/faraday/options/request_options.rb +22 -0
  38. data/lib/faraday/options/ssl_options.rb +59 -0
  39. data/lib/faraday/param_part.rb +53 -0
  40. data/lib/faraday/parameters.rb +4 -196
  41. data/lib/faraday/rack_builder.rb +77 -63
  42. data/lib/faraday/request.rb +94 -32
  43. data/lib/faraday/request/authorization.rb +44 -30
  44. data/lib/faraday/request/basic_authentication.rb +14 -7
  45. data/lib/faraday/request/instrumentation.rb +45 -27
  46. data/lib/faraday/request/multipart.rb +86 -48
  47. data/lib/faraday/request/retry.rb +209 -134
  48. data/lib/faraday/request/token_authentication.rb +15 -10
  49. data/lib/faraday/request/url_encoded.rb +43 -23
  50. data/lib/faraday/response.rb +27 -23
  51. data/lib/faraday/response/logger.rb +22 -69
  52. data/lib/faraday/response/raise_error.rb +49 -14
  53. data/lib/faraday/utils.rb +38 -247
  54. data/lib/faraday/utils/headers.rb +139 -0
  55. data/lib/faraday/utils/params_hash.rb +61 -0
  56. data/lib/faraday/version.rb +5 -0
  57. data/spec/external_adapters/faraday_specs_setup.rb +14 -0
  58. data/spec/faraday/adapter/em_http_spec.rb +47 -0
  59. data/spec/faraday/adapter/em_synchrony_spec.rb +16 -0
  60. data/spec/faraday/adapter/excon_spec.rb +49 -0
  61. data/spec/faraday/adapter/httpclient_spec.rb +73 -0
  62. data/spec/faraday/adapter/net_http_persistent_spec.rb +57 -0
  63. data/spec/faraday/adapter/net_http_spec.rb +64 -0
  64. data/spec/faraday/adapter/patron_spec.rb +18 -0
  65. data/spec/faraday/adapter/rack_spec.rb +8 -0
  66. data/spec/faraday/adapter/test_spec.rb +260 -0
  67. data/spec/faraday/adapter/typhoeus_spec.rb +7 -0
  68. data/spec/faraday/adapter_registry_spec.rb +28 -0
  69. data/spec/faraday/adapter_spec.rb +55 -0
  70. data/spec/faraday/composite_read_io_spec.rb +80 -0
  71. data/spec/faraday/connection_spec.rb +691 -0
  72. data/spec/faraday/error_spec.rb +60 -0
  73. data/spec/faraday/middleware_spec.rb +52 -0
  74. data/spec/faraday/options/env_spec.rb +70 -0
  75. data/spec/faraday/options/options_spec.rb +297 -0
  76. data/spec/faraday/options/proxy_options_spec.rb +37 -0
  77. data/spec/faraday/options/request_options_spec.rb +19 -0
  78. data/spec/faraday/params_encoders/flat_spec.rb +42 -0
  79. data/spec/faraday/params_encoders/nested_spec.rb +142 -0
  80. data/spec/faraday/rack_builder_spec.rb +345 -0
  81. data/spec/faraday/request/authorization_spec.rb +88 -0
  82. data/spec/faraday/request/instrumentation_spec.rb +76 -0
  83. data/spec/faraday/request/multipart_spec.rb +302 -0
  84. data/spec/faraday/request/retry_spec.rb +242 -0
  85. data/spec/faraday/request/url_encoded_spec.rb +83 -0
  86. data/spec/faraday/request_spec.rb +120 -0
  87. data/spec/faraday/response/logger_spec.rb +220 -0
  88. data/spec/faraday/response/middleware_spec.rb +68 -0
  89. data/spec/faraday/response/raise_error_spec.rb +169 -0
  90. data/spec/faraday/response_spec.rb +75 -0
  91. data/spec/faraday/utils/headers_spec.rb +82 -0
  92. data/spec/faraday/utils_spec.rb +56 -0
  93. data/spec/faraday_spec.rb +37 -0
  94. data/spec/spec_helper.rb +132 -0
  95. data/spec/support/disabling_stub.rb +14 -0
  96. data/spec/support/fake_safe_buffer.rb +15 -0
  97. data/spec/support/helper_methods.rb +133 -0
  98. data/spec/support/shared_examples/adapter.rb +105 -0
  99. data/spec/support/shared_examples/params_encoder.rb +18 -0
  100. data/spec/support/shared_examples/request_method.rb +262 -0
  101. data/spec/support/streaming_response_checker.rb +35 -0
  102. data/spec/support/webmock_rack_app.rb +68 -0
  103. metadata +109 -10
  104. data/lib/faraday/adapter/net_http.rb +0 -135
  105. data/lib/faraday/upload_io.rb +0 -67
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Faraday
4
+ # ConnectionOptions contains the configurable properties for a Faraday
5
+ # connection object.
6
+ class ConnectionOptions < Options.new(:request, :proxy, :ssl, :builder, :url,
7
+ :parallel_manager, :params, :headers,
8
+ :builder_class)
9
+
10
+ options request: RequestOptions, ssl: SSLOptions
11
+
12
+ memoized(:request) { self.class.options_for(:request).new }
13
+
14
+ memoized(:ssl) { self.class.options_for(:ssl).new }
15
+
16
+ memoized(:builder_class) { RackBuilder }
17
+
18
+ def new_builder(block)
19
+ builder_class.new(&block)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,181 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Faraday
4
+ # @!attribute method
5
+ # @return [Symbol] HTTP method (`:get`, `:post`)
6
+ #
7
+ # @!attribute body
8
+ # @return [String] The request body that will eventually be converted to a
9
+ # string.
10
+ #
11
+ # @!attribute url
12
+ # @return [URI] URI instance for the current request.
13
+ #
14
+ # @!attribute request
15
+ # @return [Hash] options for configuring the request.
16
+ # Options for configuring the request.
17
+ #
18
+ # - `:timeout` open/read timeout Integer in seconds
19
+ # - `:open_timeout` - read timeout Integer in seconds
20
+ # - `:on_data` - Proc for streaming
21
+ # - `:proxy` - Hash of proxy options
22
+ # - `:uri` - Proxy Server URI
23
+ # - `:user` - Proxy server username
24
+ # - `:password` - Proxy server password
25
+ #
26
+ # @!attribute request_headers
27
+ # @return [Hash] HTTP Headers to be sent to the server.
28
+ #
29
+ # @!attribute ssl
30
+ # @return [Hash] options for configuring SSL requests
31
+ #
32
+ # @!attribute parallel_manager
33
+ # @return [Object] sent if the connection is in parallel mode
34
+ #
35
+ # @!attribute params
36
+ # @return [Hash]
37
+ #
38
+ # @!attribute response
39
+ # @return [Response]
40
+ #
41
+ # @!attribute response_headers
42
+ # @return [Hash] HTTP headers from the server
43
+ #
44
+ # @!attribute status
45
+ # @return [Integer] HTTP response status code
46
+ #
47
+ # @!attribute reason_phrase
48
+ # @return [String]
49
+ class Env < Options.new(:method, :request_body, :url, :request,
50
+ :request_headers, :ssl, :parallel_manager, :params,
51
+ :response, :response_headers, :status,
52
+ :reason_phrase, :response_body)
53
+
54
+ # rubocop:disable Naming/ConstantName
55
+ ContentLength = 'Content-Length'
56
+ StatusesWithoutBody = Set.new [204, 304]
57
+ SuccessfulStatuses = (200..299).freeze
58
+ # rubocop:enable Naming/ConstantName
59
+
60
+ # A Set of HTTP verbs that typically send a body. If no body is set for
61
+ # these requests, the Content-Length header is set to 0.
62
+ MethodsWithBodies = Set.new(Faraday::METHODS_WITH_BODY.map(&:to_sym))
63
+
64
+ options request: RequestOptions,
65
+ request_headers: Utils::Headers, response_headers: Utils::Headers
66
+
67
+ extend Forwardable
68
+
69
+ def_delegators :request, :params_encoder
70
+
71
+ # Build a new Env from given value. Respects and updates `custom_members`.
72
+ #
73
+ # @param value [Object] a value fitting Option.from(v).
74
+ # @return [Env] from given value
75
+ def self.from(value)
76
+ env = super(value)
77
+ if value.respond_to?(:custom_members)
78
+ env.custom_members.update(value.custom_members)
79
+ end
80
+ env
81
+ end
82
+
83
+ # @param key [Object]
84
+ def [](key)
85
+ return self[current_body] if key == :body
86
+
87
+ if in_member_set?(key)
88
+ super(key)
89
+ else
90
+ custom_members[key]
91
+ end
92
+ end
93
+
94
+ # @param key [Object]
95
+ # @param value [Object]
96
+ def []=(key, value)
97
+ if key == :body
98
+ super(current_body, value)
99
+ return
100
+ end
101
+
102
+ if in_member_set?(key)
103
+ super(key, value)
104
+ else
105
+ custom_members[key] = value
106
+ end
107
+ end
108
+
109
+ def current_body
110
+ !!status ? :response_body : :request_body
111
+ end
112
+
113
+ def body
114
+ self[:body]
115
+ end
116
+
117
+ def body=(value)
118
+ self[:body] = value
119
+ end
120
+
121
+ # @return [Boolean] true if status is in the set of {SuccessfulStatuses}.
122
+ def success?
123
+ SuccessfulStatuses.include?(status)
124
+ end
125
+
126
+ # @return [Boolean] true if there's no body yet, and the method is in the
127
+ # set of {MethodsWithBodies}.
128
+ def needs_body?
129
+ !body && MethodsWithBodies.include?(method)
130
+ end
131
+
132
+ # Sets content length to zero and the body to the empty string.
133
+ def clear_body
134
+ request_headers[ContentLength] = '0'
135
+ self.body = +''
136
+ end
137
+
138
+ # @return [Boolean] true if the status isn't in the set of
139
+ # {StatusesWithoutBody}.
140
+ def parse_body?
141
+ !StatusesWithoutBody.include?(status)
142
+ end
143
+
144
+ # @return [Boolean] true if there is a parallel_manager
145
+ def parallel?
146
+ !!parallel_manager
147
+ end
148
+
149
+ def inspect
150
+ attrs = [nil]
151
+ members.each do |mem|
152
+ if (value = send(mem))
153
+ attrs << "@#{mem}=#{value.inspect}"
154
+ end
155
+ end
156
+ attrs << "@custom=#{custom_members.inspect}" unless custom_members.empty?
157
+ %(#<#{self.class}#{attrs.join(' ')}>)
158
+ end
159
+
160
+ # @private
161
+ def custom_members
162
+ @custom_members ||= {}
163
+ end
164
+
165
+ # @private
166
+ if members.first.is_a?(Symbol)
167
+ def in_member_set?(key)
168
+ self.class.member_set.include?(key.to_sym)
169
+ end
170
+ else
171
+ def in_member_set?(key)
172
+ self.class.member_set.include?(key.to_s)
173
+ end
174
+ end
175
+
176
+ # @private
177
+ def self.member_set
178
+ @member_set ||= Set.new(members)
179
+ end
180
+ end
181
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Faraday
4
+ # ProxyOptions contains the configurable properties for the proxy
5
+ # configuration used when making an HTTP request.
6
+ class ProxyOptions < Options.new(:uri, :user, :password)
7
+ extend Forwardable
8
+ def_delegators :uri, :scheme, :scheme=, :host, :host=, :port, :port=,
9
+ :path, :path=
10
+
11
+ def self.from(value)
12
+ case value
13
+ when String
14
+ value = { uri: Utils.URI(value) }
15
+ when URI
16
+ value = { uri: value }
17
+ when Hash, Options
18
+ if (uri = value.delete(:uri))
19
+ value[:uri] = Utils.URI(uri)
20
+ end
21
+ end
22
+ super(value)
23
+ end
24
+
25
+ memoized(:user) { uri&.user && Utils.unescape(uri.user) }
26
+ memoized(:password) { uri&.password && Utils.unescape(uri.password) }
27
+ end
28
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Faraday
4
+ # RequestOptions contains the configurable properties for a Faraday request.
5
+ class RequestOptions < Options.new(:params_encoder, :proxy, :bind,
6
+ :timeout, :open_timeout, :read_timeout,
7
+ :write_timeout, :boundary, :oauth,
8
+ :context, :on_data)
9
+
10
+ def []=(key, value)
11
+ if key && key.to_sym == :proxy
12
+ super(key, value ? ProxyOptions.from(value) : nil)
13
+ else
14
+ super(key, value)
15
+ end
16
+ end
17
+
18
+ def stream_response?
19
+ on_data.is_a?(Proc)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Faraday
4
+ # SSL-related options.
5
+ #
6
+ # @!attribute verify
7
+ # @return [Boolean] whether to verify SSL certificates or not
8
+ #
9
+ # @!attribute ca_file
10
+ # @return [String] CA file
11
+ #
12
+ # @!attribute ca_path
13
+ # @return [String] CA path
14
+ #
15
+ # @!attribute verify_mode
16
+ # @return [Integer] Any `OpenSSL::SSL::` constant (see https://ruby-doc.org/stdlib-2.5.1/libdoc/openssl/rdoc/OpenSSL/SSL.html)
17
+ #
18
+ # @!attribute cert_store
19
+ # @return [OpenSSL::X509::Store] certificate store
20
+ #
21
+ # @!attribute client_cert
22
+ # @return [String, OpenSSL::X509::Certificate] client certificate
23
+ #
24
+ # @!attribute client_key
25
+ # @return [String, OpenSSL::PKey::RSA, OpenSSL::PKey::DSA] client key
26
+ #
27
+ # @!attribute certificate
28
+ # @return [OpenSSL::X509::Certificate] certificate (Excon only)
29
+ #
30
+ # @!attribute private_key
31
+ # @return [OpenSSL::PKey::RSA, OpenSSL::PKey::DSA] private key (Excon only)
32
+ #
33
+ # @!attribute verify_depth
34
+ # @return [Integer] maximum depth for the certificate chain verification
35
+ #
36
+ # @!attribute version
37
+ # @return [String, Symbol] SSL version (see https://ruby-doc.org/stdlib-2.5.1/libdoc/openssl/rdoc/OpenSSL/SSL/SSLContext.html#method-i-ssl_version-3D)
38
+ #
39
+ # @!attribute min_version
40
+ # @return [String, Symbol] minimum SSL version (see https://ruby-doc.org/stdlib-2.5.1/libdoc/openssl/rdoc/OpenSSL/SSL/SSLContext.html#method-i-min_version-3D)
41
+ #
42
+ # @!attribute max_version
43
+ # @return [String, Symbol] maximum SSL version (see https://ruby-doc.org/stdlib-2.5.1/libdoc/openssl/rdoc/OpenSSL/SSL/SSLContext.html#method-i-max_version-3D)
44
+ class SSLOptions < Options.new(:verify, :ca_file, :ca_path, :verify_mode,
45
+ :cert_store, :client_cert, :client_key,
46
+ :certificate, :private_key, :verify_depth,
47
+ :version, :min_version, :max_version)
48
+
49
+ # @return [Boolean] true if should verify
50
+ def verify?
51
+ verify != false
52
+ end
53
+
54
+ # @return [Boolean] true if should not verify
55
+ def disable?
56
+ !verify?
57
+ end
58
+ end
59
+ end
@@ -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,197 +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
- elsif value.nil?
50
- return parent
51
- else
52
- encoded_value = escape(value)
53
- return "#{parent}=#{encoded_value}"
54
- end
55
- end
56
-
57
- # The params have form [['key1', 'value1'], ['key2', 'value2']].
58
- buffer = ''
59
- params.each do |parent, value|
60
- encoded_parent = escape(parent)
61
- buffer << "#{to_query.call(encoded_parent, value)}&"
62
- end
63
- return buffer.chop
64
- end
65
-
66
- def self.decode(query)
67
- return nil if query == nil
68
-
69
- params = {}
70
- query.split("&").each do |pair|
71
- next if pair.empty?
72
- key, value = pair.split("=", 2)
73
- key = unescape(key)
74
- value = unescape(value.gsub(/\+/, ' ')) if value
75
-
76
- subkeys = key.scan(/[^\[\]]+(?:\]?\[\])?/)
77
- context = params
78
- subkeys.each_with_index do |subkey, i|
79
- is_array = subkey =~ /[\[\]]+\Z/
80
- subkey = $` if is_array
81
- last_subkey = i == subkeys.length - 1
82
-
83
- if !last_subkey || is_array
84
- value_type = is_array ? Array : Hash
85
- if context[subkey] && !context[subkey].is_a?(value_type)
86
- raise TypeError, "expected %s (got %s) for param `%s'" % [
87
- value_type.name,
88
- context[subkey].class.name,
89
- subkey
90
- ]
91
- end
92
- context = (context[subkey] ||= value_type.new)
93
- end
94
-
95
- if context.is_a?(Array) && !is_array
96
- if !context.last.is_a?(Hash) || context.last.has_key?(subkey)
97
- context << {}
98
- end
99
- context = context.last
100
- end
101
-
102
- if last_subkey
103
- if is_array
104
- context << value
105
- else
106
- context[subkey] = value
107
- end
108
- end
109
- end
110
- end
111
-
112
- dehash(params, 0)
113
- end
114
-
115
- # Internal: convert a nested hash with purely numeric keys into an array.
116
- # FIXME: this is not compatible with Rack::Utils.parse_nested_query
117
- def self.dehash(hash, depth)
118
- hash.each do |key, value|
119
- hash[key] = dehash(value, depth + 1) if value.kind_of?(Hash)
120
- end
121
-
122
- if depth > 0 && !hash.empty? && hash.keys.all? { |k| k =~ /^\d+$/ }
123
- hash.keys.sort.inject([]) { |all, key| all << hash[key] }
124
- else
125
- hash
126
- end
127
- end
128
- end
129
-
130
- module FlatParamsEncoder
131
- class << self
132
- extend Forwardable
133
- def_delegators :'Faraday::Utils', :escape, :unescape
134
- end
135
-
136
- def self.encode(params)
137
- return nil if params == nil
138
-
139
- if !params.is_a?(Array)
140
- if !params.respond_to?(:to_hash)
141
- raise TypeError,
142
- "Can't convert #{params.class} into Hash."
143
- end
144
- params = params.to_hash
145
- params = params.map do |key, value|
146
- key = key.to_s if key.kind_of?(Symbol)
147
- [key, value]
148
- end
149
- # Useful default for OAuth and caching.
150
- # Only to be used for non-Array inputs. Arrays should preserve order.
151
- params.sort!
152
- end
153
-
154
- # The params have form [['key1', 'value1'], ['key2', 'value2']].
155
- buffer = ''
156
- params.each do |key, value|
157
- encoded_key = escape(key)
158
- value = value.to_s if value == true || value == false
159
- if value == nil
160
- buffer << "#{encoded_key}&"
161
- elsif value.kind_of?(Array)
162
- value.each do |sub_value|
163
- encoded_value = escape(sub_value)
164
- buffer << "#{encoded_key}=#{encoded_value}&"
165
- end
166
- else
167
- encoded_value = escape(value)
168
- buffer << "#{encoded_key}=#{encoded_value}&"
169
- end
170
- end
171
- return buffer.chop
172
- end
173
-
174
- def self.decode(query)
175
- empty_accumulator = {}
176
- return nil if query == nil
177
- split_query = (query.split('&').map do |pair|
178
- pair.split('=', 2) if pair && !pair.empty?
179
- end).compact
180
- return split_query.inject(empty_accumulator.dup) do |accu, pair|
181
- pair[0] = unescape(pair[0])
182
- pair[1] = true if pair[1].nil?
183
- if pair[1].respond_to?(:to_str)
184
- pair[1] = unescape(pair[1].to_str.gsub(/\+/, " "))
185
- end
186
- if accu[pair[0]].kind_of?(Array)
187
- accu[pair[0]] << pair[1]
188
- elsif accu[pair[0]]
189
- accu[pair[0]] = [accu[pair[0]], pair[1]]
190
- else
191
- accu[pair[0]] = pair[1]
192
- end
193
- accu
194
- end
195
- end
196
- end
197
- end
3
+ require 'forwardable'
4
+ require 'faraday/encoders/nested_params_encoder'
5
+ require 'faraday/encoders/flat_params_encoder'