faraday 0.15.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +570 -0
  3. data/LICENSE.md +1 -1
  4. data/README.md +25 -351
  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 +127 -72
  9. data/lib/faraday/adapter.rb +69 -22
  10. data/lib/faraday/adapter_registry.rb +30 -0
  11. data/lib/faraday/connection.rb +309 -232
  12. data/lib/faraday/encoders/flat_params_encoder.rb +105 -0
  13. data/lib/faraday/encoders/nested_params_encoder.rb +176 -0
  14. data/lib/faraday/error.rb +119 -38
  15. data/lib/faraday/logging/formatter.rb +106 -0
  16. data/lib/faraday/methods.rb +6 -0
  17. data/lib/faraday/middleware.rb +18 -25
  18. data/lib/faraday/middleware_registry.rb +83 -0
  19. data/lib/faraday/options/connection_options.rb +22 -0
  20. data/lib/faraday/options/env.rb +181 -0
  21. data/lib/faraday/options/proxy_options.rb +32 -0
  22. data/lib/faraday/options/request_options.rb +22 -0
  23. data/lib/faraday/options/ssl_options.rb +59 -0
  24. data/lib/faraday/options.rb +41 -195
  25. data/lib/faraday/parameters.rb +4 -196
  26. data/lib/faraday/rack_builder.rb +91 -76
  27. data/lib/faraday/request/authorization.rb +37 -29
  28. data/lib/faraday/request/instrumentation.rb +47 -27
  29. data/lib/faraday/request/json.rb +55 -0
  30. data/lib/faraday/request/url_encoded.rb +45 -23
  31. data/lib/faraday/request.rb +74 -32
  32. data/lib/faraday/response/json.rb +54 -0
  33. data/lib/faraday/response/logger.rb +22 -69
  34. data/lib/faraday/response/raise_error.rb +57 -14
  35. data/lib/faraday/response.rb +26 -33
  36. data/lib/faraday/utils/headers.rb +139 -0
  37. data/lib/faraday/utils/params_hash.rb +61 -0
  38. data/lib/faraday/utils.rb +47 -251
  39. data/lib/faraday/version.rb +5 -0
  40. data/lib/faraday.rb +108 -199
  41. data/spec/external_adapters/faraday_specs_setup.rb +14 -0
  42. data/spec/faraday/adapter/test_spec.rb +377 -0
  43. data/spec/faraday/adapter_registry_spec.rb +28 -0
  44. data/spec/faraday/adapter_spec.rb +55 -0
  45. data/spec/faraday/connection_spec.rb +787 -0
  46. data/spec/faraday/error_spec.rb +60 -0
  47. data/spec/faraday/middleware_registry_spec.rb +31 -0
  48. data/spec/faraday/middleware_spec.rb +52 -0
  49. data/spec/faraday/options/env_spec.rb +70 -0
  50. data/spec/faraday/options/options_spec.rb +297 -0
  51. data/spec/faraday/options/proxy_options_spec.rb +44 -0
  52. data/spec/faraday/options/request_options_spec.rb +19 -0
  53. data/spec/faraday/params_encoders/flat_spec.rb +42 -0
  54. data/spec/faraday/params_encoders/nested_spec.rb +142 -0
  55. data/spec/faraday/rack_builder_spec.rb +317 -0
  56. data/spec/faraday/request/authorization_spec.rb +83 -0
  57. data/spec/faraday/request/instrumentation_spec.rb +74 -0
  58. data/spec/faraday/request/json_spec.rb +111 -0
  59. data/spec/faraday/request/url_encoded_spec.rb +82 -0
  60. data/spec/faraday/request_spec.rb +109 -0
  61. data/spec/faraday/response/json_spec.rb +117 -0
  62. data/spec/faraday/response/logger_spec.rb +220 -0
  63. data/spec/faraday/response/raise_error_spec.rb +172 -0
  64. data/spec/faraday/response_spec.rb +75 -0
  65. data/spec/faraday/utils/headers_spec.rb +82 -0
  66. data/spec/faraday/utils_spec.rb +117 -0
  67. data/spec/faraday_spec.rb +37 -0
  68. data/spec/spec_helper.rb +132 -0
  69. data/spec/support/disabling_stub.rb +14 -0
  70. data/spec/support/fake_safe_buffer.rb +15 -0
  71. data/spec/support/helper_methods.rb +96 -0
  72. data/spec/support/shared_examples/adapter.rb +104 -0
  73. data/spec/support/shared_examples/params_encoder.rb +18 -0
  74. data/spec/support/shared_examples/request_method.rb +249 -0
  75. data/spec/support/streaming_response_checker.rb +35 -0
  76. metadata +86 -34
  77. data/lib/faraday/adapter/em_http.rb +0 -243
  78. data/lib/faraday/adapter/em_http_ssl_patch.rb +0 -56
  79. data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +0 -66
  80. data/lib/faraday/adapter/em_synchrony.rb +0 -106
  81. data/lib/faraday/adapter/excon.rb +0 -79
  82. data/lib/faraday/adapter/httpclient.rb +0 -128
  83. data/lib/faraday/adapter/net_http.rb +0 -137
  84. data/lib/faraday/adapter/net_http_persistent.rb +0 -63
  85. data/lib/faraday/adapter/patron.rb +0 -100
  86. data/lib/faraday/adapter/rack.rb +0 -58
  87. data/lib/faraday/adapter/typhoeus.rb +0 -12
  88. data/lib/faraday/autoload.rb +0 -84
  89. data/lib/faraday/request/basic_authentication.rb +0 -13
  90. data/lib/faraday/request/multipart.rb +0 -68
  91. data/lib/faraday/request/retry.rb +0 -211
  92. data/lib/faraday/request/token_authentication.rb +0 -15
  93. data/lib/faraday/upload_io.rb +0 -67
@@ -1,137 +0,0 @@
1
- begin
2
- require 'net/https'
3
- rescue LoadError
4
- warn "Warning: no such file to load -- net/https. Make sure openssl is installed if you want ssl support"
5
- require 'net/http'
6
- end
7
- require 'zlib'
8
-
9
- module Faraday
10
- class Adapter
11
- class NetHttp < Faraday::Adapter
12
- NET_HTTP_EXCEPTIONS = [
13
- IOError,
14
- Errno::ECONNABORTED,
15
- Errno::ECONNREFUSED,
16
- Errno::ECONNRESET,
17
- Errno::EHOSTUNREACH,
18
- Errno::EINVAL,
19
- Errno::ENETUNREACH,
20
- Errno::EPIPE,
21
- Net::HTTPBadResponse,
22
- Net::HTTPHeaderSyntaxError,
23
- Net::ProtocolError,
24
- SocketError,
25
- Zlib::GzipFile::Error,
26
- ]
27
-
28
- NET_HTTP_EXCEPTIONS << OpenSSL::SSL::SSLError if defined?(OpenSSL)
29
- NET_HTTP_EXCEPTIONS << Net::OpenTimeout if defined?(Net::OpenTimeout)
30
-
31
- def call(env)
32
- super
33
- with_net_http_connection(env) do |http|
34
- configure_ssl(http, env[:ssl]) if env[:url].scheme == 'https' and env[:ssl]
35
- configure_request(http, env[:request])
36
-
37
- begin
38
- http_response = perform_request(http, env)
39
- rescue *NET_HTTP_EXCEPTIONS => err
40
- if defined?(OpenSSL) && OpenSSL::SSL::SSLError === err
41
- raise Faraday::SSLError, err
42
- else
43
- raise Error::ConnectionFailed, err
44
- end
45
- end
46
-
47
- save_response(env, http_response.code.to_i, http_response.body || '', nil, http_response.message) do |response_headers|
48
- http_response.each_header do |key, value|
49
- response_headers[key] = value
50
- end
51
- end
52
- end
53
-
54
- @app.call env
55
- rescue Timeout::Error, Errno::ETIMEDOUT => err
56
- raise Faraday::Error::TimeoutError, err
57
- end
58
-
59
- private
60
-
61
- def create_request(env)
62
- request = Net::HTTPGenericRequest.new \
63
- env[:method].to_s.upcase, # request method
64
- !!env[:body], # is there request body
65
- :head != env[:method], # is there response body
66
- env[:url].request_uri, # request uri path
67
- env[:request_headers] # request headers
68
-
69
- if env[:body].respond_to?(:read)
70
- request.body_stream = env[:body]
71
- else
72
- request.body = env[:body]
73
- end
74
- request
75
- end
76
-
77
- def perform_request(http, env)
78
- if :get == env[:method] and !env[:body]
79
- # prefer `get` to `request` because the former handles gzip (ruby 1.9)
80
- http.get env[:url].request_uri, env[:request_headers]
81
- else
82
- http.request create_request(env)
83
- end
84
- end
85
-
86
- def with_net_http_connection(env)
87
- yield net_http_connection(env)
88
- end
89
-
90
- def net_http_connection(env)
91
- if proxy = env[:request][:proxy]
92
- Net::HTTP::Proxy(proxy[:uri].hostname, proxy[:uri].port, proxy[:user], proxy[:password])
93
- else
94
- Net::HTTP
95
- end.new(env[:url].hostname, env[:url].port || (env[:url].scheme == 'https' ? 443 : 80))
96
- end
97
-
98
- def configure_ssl(http, ssl)
99
- http.use_ssl = true
100
- http.verify_mode = ssl_verify_mode(ssl)
101
- http.cert_store = ssl_cert_store(ssl)
102
-
103
- http.cert = ssl[:client_cert] if ssl[:client_cert]
104
- http.key = ssl[:client_key] if ssl[:client_key]
105
- http.ca_file = ssl[:ca_file] if ssl[:ca_file]
106
- http.ca_path = ssl[:ca_path] if ssl[:ca_path]
107
- http.verify_depth = ssl[:verify_depth] if ssl[:verify_depth]
108
- http.ssl_version = ssl[:version] if ssl[:version]
109
- end
110
-
111
- def configure_request(http, req)
112
- http.read_timeout = http.open_timeout = req[:timeout] if req[:timeout]
113
- http.open_timeout = req[:open_timeout] if req[:open_timeout]
114
-
115
- @config_block.call(http) if @config_block
116
- end
117
-
118
- def ssl_cert_store(ssl)
119
- return ssl[:cert_store] if ssl[:cert_store]
120
- # Use the default cert store by default, i.e. system ca certs
121
- cert_store = OpenSSL::X509::Store.new
122
- cert_store.set_default_paths
123
- cert_store
124
- end
125
-
126
- def ssl_verify_mode(ssl)
127
- ssl[:verify_mode] || begin
128
- if ssl.fetch(:verify, true)
129
- OpenSSL::SSL::VERIFY_PEER
130
- else
131
- OpenSSL::SSL::VERIFY_NONE
132
- end
133
- end
134
- end
135
- end
136
- end
137
- end
@@ -1,63 +0,0 @@
1
- module Faraday
2
- class Adapter
3
- class NetHttpPersistent < NetHttp
4
- dependency 'net/http/persistent'
5
-
6
- private
7
-
8
- def net_http_connection(env)
9
- proxy_uri = proxy_uri(env)
10
-
11
- cached_connection env[:url], proxy_uri do
12
- if Net::HTTP::Persistent.instance_method(:initialize).parameters.first == [:key, :name]
13
- Net::HTTP::Persistent.new(name: 'Faraday', proxy: proxy_uri)
14
- else
15
- Net::HTTP::Persistent.new('Faraday', proxy_uri)
16
- end
17
- end
18
- end
19
-
20
- def proxy_uri(env)
21
- proxy_uri = nil
22
- if (proxy = env[:request][:proxy])
23
- proxy_uri = ::URI::HTTP === proxy[:uri] ? proxy[:uri].dup : ::URI.parse(proxy[:uri].to_s)
24
- proxy_uri.user = proxy_uri.password = nil
25
- # awful patch for net-http-persistent 2.8 not unescaping user/password
26
- (class << proxy_uri; self; end).class_eval do
27
- define_method(:user) { proxy[:user] }
28
- define_method(:password) { proxy[:password] }
29
- end if proxy[:user]
30
- end
31
- proxy_uri
32
- end
33
-
34
- def perform_request(http, env)
35
- http.request env[:url], create_request(env)
36
- rescue Errno::ETIMEDOUT => error
37
- raise Faraday::Error::TimeoutError, error
38
- rescue Net::HTTP::Persistent::Error => error
39
- if error.message.include? 'Timeout'
40
- raise Faraday::Error::TimeoutError, error
41
- elsif error.message.include? 'connection refused'
42
- raise Faraday::Error::ConnectionFailed, error
43
- else
44
- raise
45
- end
46
- end
47
-
48
- def configure_ssl(http, ssl)
49
- http.verify_mode = ssl_verify_mode(ssl)
50
- http.cert_store = ssl_cert_store(ssl)
51
-
52
- http.certificate = ssl[:client_cert] if ssl[:client_cert]
53
- http.private_key = ssl[:client_key] if ssl[:client_key]
54
- http.ca_file = ssl[:ca_file] if ssl[:ca_file]
55
- http.ssl_version = ssl[:version] if ssl[:version]
56
- end
57
-
58
- def cached_connection(url, proxy_uri)
59
- (@cached_connection ||= {})[[url.scheme, url.host, url.port, proxy_uri]] ||= yield
60
- end
61
- end
62
- end
63
- end
@@ -1,100 +0,0 @@
1
- module Faraday
2
- class Adapter
3
- class Patron < Faraday::Adapter
4
- dependency 'patron'
5
-
6
- def call(env)
7
- super
8
- # TODO: support streaming requests
9
- env[:body] = env[:body].read if env[:body].respond_to? :read
10
-
11
- session = @session ||= create_session
12
- configure_ssl(session, env[:ssl]) if env[:url].scheme == 'https' and env[:ssl]
13
-
14
- if req = env[:request]
15
- session.timeout = session.connect_timeout = req[:timeout] if req[:timeout]
16
- session.connect_timeout = req[:open_timeout] if req[:open_timeout]
17
-
18
- if proxy = req[:proxy]
19
- proxy_uri = proxy[:uri].dup
20
- proxy_uri.user = proxy[:user] && Utils.escape(proxy[:user]).gsub('+', '%20')
21
- proxy_uri.password = proxy[:password] && Utils.escape(proxy[:password]).gsub('+', '%20')
22
- session.proxy = proxy_uri.to_s
23
- end
24
- end
25
-
26
- response = begin
27
- data = env[:body] ? env[:body].to_s : nil
28
- session.request(env[:method], env[:url].to_s, env[:request_headers], :data => data)
29
- rescue Errno::ECONNREFUSED, ::Patron::ConnectionFailed
30
- raise Error::ConnectionFailed, $!
31
- end
32
-
33
- # Remove the "HTTP/1.1 200", leaving just the reason phrase
34
- reason_phrase = response.status_line.gsub(/^.* \d{3} /, '')
35
-
36
- save_response(env, response.status, response.body, response.headers, reason_phrase)
37
-
38
- @app.call env
39
- rescue ::Patron::TimeoutError => err
40
- if connection_timed_out_message?(err.message)
41
- raise Faraday::Error::ConnectionFailed, err
42
- else
43
- raise Faraday::Error::TimeoutError, err
44
- end
45
- rescue ::Patron::Error => err
46
- if err.message.include?("code 407")
47
- raise Error::ConnectionFailed, %{407 "Proxy Authentication Required "}
48
- else
49
- raise Error::ConnectionFailed, err
50
- end
51
- end
52
-
53
- if loaded? && defined?(::Patron::Request::VALID_ACTIONS)
54
- # HAX: helps but doesn't work completely
55
- # https://github.com/toland/patron/issues/34
56
- ::Patron::Request::VALID_ACTIONS.tap do |actions|
57
- if actions[0].is_a?(Symbol)
58
- actions << :patch unless actions.include? :patch
59
- actions << :options unless actions.include? :options
60
- else
61
- # Patron 0.4.20 and up
62
- actions << "PATCH" unless actions.include? "PATCH"
63
- actions << "OPTIONS" unless actions.include? "OPTIONS"
64
- end
65
- end
66
- end
67
-
68
- def create_session
69
- session = ::Patron::Session.new
70
- @config_block.call(session) if @config_block
71
- session
72
- end
73
-
74
- def configure_ssl(session, ssl)
75
- if ssl.fetch(:verify, true)
76
- session.cacert = ssl[:ca_file]
77
- else
78
- session.insecure = true
79
- end
80
- end
81
-
82
- private
83
-
84
- CURL_TIMEOUT_MESSAGES = [ "Connection time-out",
85
- "Connection timed out",
86
- "Timed out before name resolve",
87
- "server connect has timed out",
88
- "Resolving timed out",
89
- "name lookup timed out",
90
- "timed out before SSL",
91
- "connect() timed out"
92
- ].freeze
93
-
94
- def connection_timed_out_message?(message)
95
- CURL_TIMEOUT_MESSAGES.any? { |curl_message| message.include?(curl_message) }
96
- end
97
-
98
- end
99
- end
100
- end
@@ -1,58 +0,0 @@
1
- module Faraday
2
- class Adapter
3
- # Sends requests to a Rack app.
4
- #
5
- # Examples
6
- #
7
- # class MyRackApp
8
- # def call(env)
9
- # [200, {'Content-Type' => 'text/html'}, ["hello world"]]
10
- # end
11
- # end
12
- #
13
- # Faraday.new do |conn|
14
- # conn.adapter :rack, MyRackApp.new
15
- # end
16
- class Rack < Faraday::Adapter
17
- dependency 'rack/test'
18
-
19
- # not prefixed with "HTTP_"
20
- SPECIAL_HEADERS = %w[ CONTENT_LENGTH CONTENT_TYPE ]
21
-
22
- def initialize(faraday_app, rack_app)
23
- super(faraday_app)
24
- mock_session = ::Rack::MockSession.new(rack_app)
25
- @session = ::Rack::Test::Session.new(mock_session)
26
- end
27
-
28
- def call(env)
29
- 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
- }
35
-
36
- env[:request_headers].each do |name, value|
37
- name = name.upcase.tr('-', '_')
38
- name = "HTTP_#{name}" unless SPECIAL_HEADERS.include? name
39
- rack_env[name] = value
40
- end if env[:request_headers]
41
-
42
- timeout = env[:request][:timeout] || env[:request][:open_timeout]
43
- response = if timeout
44
- Timer.timeout(timeout, Faraday::Error::TimeoutError) { execute_request(env, rack_env) }
45
- else
46
- execute_request(env, rack_env)
47
- end
48
-
49
- save_response(env, response.status, response.body, response.headers)
50
- @app.call env
51
- end
52
-
53
- def execute_request(env, rack_env)
54
- @session.request(env[:url].to_s, rack_env)
55
- end
56
- end
57
- end
58
- end
@@ -1,12 +0,0 @@
1
- module Faraday
2
- class Adapter
3
- # This class is just a stub, the real adapter is in https://github.com/philsturgeon/typhoeus/blob/master/lib/typhoeus/adapters/faraday.rb
4
- class Typhoeus < Faraday::Adapter
5
- # Needs to define this method in order to support Typhoeus <= 1.3.0
6
- def call; end
7
-
8
- dependency 'typhoeus'
9
- dependency 'typhoeus/adapters/faraday'
10
- end
11
- end
12
- end
@@ -1,84 +0,0 @@
1
- module Faraday
2
- # Internal: Adds the ability for other modules to manage autoloadable
3
- # constants.
4
- module AutoloadHelper
5
- # Internal: Registers the constants to be auto loaded.
6
- #
7
- # prefix - The String require prefix. If the path is inside Faraday, then
8
- # it will be prefixed with the root path of this loaded Faraday
9
- # version.
10
- # options - Hash of Symbol => String library names.
11
- #
12
- # Examples.
13
- #
14
- # Faraday.autoload_all 'faraday/foo',
15
- # :Bar => 'bar'
16
- #
17
- # # requires faraday/foo/bar to load Faraday::Bar.
18
- # Faraday::Bar
19
- #
20
- #
21
- # Returns nothing.
22
- def autoload_all(prefix, options)
23
- if prefix =~ /^faraday(\/|$)/i
24
- prefix = File.join(Faraday.root_path, prefix)
25
- end
26
- options.each do |const_name, path|
27
- autoload const_name, File.join(prefix, path)
28
- end
29
- end
30
-
31
- # Internal: Loads each autoloaded constant. If thread safety is a concern,
32
- # wrap this in a Mutex.
33
- #
34
- # Returns nothing.
35
- def load_autoloaded_constants
36
- constants.each do |const|
37
- const_get(const) if autoload?(const)
38
- end
39
- end
40
-
41
- # Internal: Filters the module's contents with those that have been already
42
- # autoloaded.
43
- #
44
- # Returns an Array of Class/Module objects.
45
- def all_loaded_constants
46
- constants.map { |c| const_get(c) }.
47
- select { |a| a.respond_to?(:loaded?) && a.loaded? }
48
- end
49
- end
50
-
51
- class Adapter
52
- extend AutoloadHelper
53
- autoload_all 'faraday/adapter',
54
- :NetHttp => 'net_http',
55
- :NetHttpPersistent => 'net_http_persistent',
56
- :EMSynchrony => 'em_synchrony',
57
- :EMHttp => 'em_http',
58
- :Typhoeus => 'typhoeus',
59
- :Patron => 'patron',
60
- :Excon => 'excon',
61
- :Test => 'test',
62
- :Rack => 'rack',
63
- :HTTPClient => 'httpclient'
64
- end
65
-
66
- class Request
67
- extend AutoloadHelper
68
- autoload_all 'faraday/request',
69
- :UrlEncoded => 'url_encoded',
70
- :Multipart => 'multipart',
71
- :Retry => 'retry',
72
- :Authorization => 'authorization',
73
- :BasicAuthentication => 'basic_authentication',
74
- :TokenAuthentication => 'token_authentication',
75
- :Instrumentation => 'instrumentation'
76
- end
77
-
78
- class Response
79
- extend AutoloadHelper
80
- autoload_all 'faraday/response',
81
- :RaiseError => 'raise_error',
82
- :Logger => 'logger'
83
- end
84
- end
@@ -1,13 +0,0 @@
1
- require 'base64'
2
-
3
- module Faraday
4
- class Request::BasicAuthentication < Request.load_middleware(:authorization)
5
- # Public
6
- def self.header(login, pass)
7
- value = Base64.encode64([login, pass].join(':'))
8
- value.gsub!("\n", '')
9
- super(:Basic, value)
10
- end
11
- end
12
- end
13
-
@@ -1,68 +0,0 @@
1
- require File.expand_path("../url_encoded", __FILE__)
2
- require 'securerandom'
3
-
4
- module Faraday
5
- class Request::Multipart < Request::UrlEncoded
6
- self.mime_type = 'multipart/form-data'.freeze
7
- DEFAULT_BOUNDARY_PREFIX = "-----------RubyMultipartPost".freeze unless defined? DEFAULT_BOUNDARY_PREFIX
8
-
9
- def call(env)
10
- match_content_type(env) do |params|
11
- env.request.boundary ||= unique_boundary
12
- env.request_headers[CONTENT_TYPE] += "; boundary=#{env.request.boundary}"
13
- env.body = create_multipart(env, params)
14
- end
15
- @app.call env
16
- end
17
-
18
- def process_request?(env)
19
- type = request_type(env)
20
- env.body.respond_to?(:each_key) and !env.body.empty? and (
21
- (type.empty? and has_multipart?(env.body)) or
22
- type == self.class.mime_type
23
- )
24
- end
25
-
26
- def has_multipart?(obj)
27
- # string is an enum in 1.8, returning list of itself
28
- if obj.respond_to?(:each) && !obj.is_a?(String)
29
- (obj.respond_to?(:values) ? obj.values : obj).each do |val|
30
- return true if (val.respond_to?(:content_type) || has_multipart?(val))
31
- end
32
- end
33
- false
34
- end
35
-
36
- def create_multipart(env, params)
37
- boundary = env.request.boundary
38
- parts = process_params(params) do |key, value|
39
- Faraday::Parts::Part.new(boundary, key, value)
40
- end
41
- parts << Faraday::Parts::EpiloguePart.new(boundary)
42
-
43
- body = Faraday::CompositeReadIO.new(parts)
44
- env.request_headers[Faraday::Env::ContentLength] = body.length.to_s
45
- return body
46
- end
47
-
48
- def unique_boundary
49
- "#{DEFAULT_BOUNDARY_PREFIX}-#{SecureRandom.hex}"
50
- end
51
-
52
- def process_params(params, prefix = nil, pieces = nil, &block)
53
- params.inject(pieces || []) do |all, (key, value)|
54
- key = "#{prefix}[#{key}]" if prefix
55
-
56
- case value
57
- when Array
58
- values = value.inject([]) { |a,v| a << [nil, v] }
59
- process_params(values, key, all, &block)
60
- when Hash
61
- process_params(value, key, all, &block)
62
- else
63
- all << block.call(key, value)
64
- end
65
- end
66
- end
67
- end
68
- end