actionpack 5.2.3

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionpack might be problematic. Click here for more details.

Files changed (170) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +429 -0
  3. data/MIT-LICENSE +21 -0
  4. data/README.rdoc +57 -0
  5. data/lib/abstract_controller.rb +27 -0
  6. data/lib/abstract_controller/asset_paths.rb +12 -0
  7. data/lib/abstract_controller/base.rb +265 -0
  8. data/lib/abstract_controller/caching.rb +66 -0
  9. data/lib/abstract_controller/caching/fragments.rb +166 -0
  10. data/lib/abstract_controller/callbacks.rb +212 -0
  11. data/lib/abstract_controller/collector.rb +43 -0
  12. data/lib/abstract_controller/error.rb +6 -0
  13. data/lib/abstract_controller/helpers.rb +194 -0
  14. data/lib/abstract_controller/logger.rb +14 -0
  15. data/lib/abstract_controller/railties/routes_helpers.rb +20 -0
  16. data/lib/abstract_controller/rendering.rb +127 -0
  17. data/lib/abstract_controller/translation.rb +31 -0
  18. data/lib/abstract_controller/url_for.rb +35 -0
  19. data/lib/action_controller.rb +66 -0
  20. data/lib/action_controller/api.rb +149 -0
  21. data/lib/action_controller/api/api_rendering.rb +16 -0
  22. data/lib/action_controller/base.rb +276 -0
  23. data/lib/action_controller/caching.rb +46 -0
  24. data/lib/action_controller/form_builder.rb +50 -0
  25. data/lib/action_controller/log_subscriber.rb +78 -0
  26. data/lib/action_controller/metal.rb +256 -0
  27. data/lib/action_controller/metal/basic_implicit_render.rb +13 -0
  28. data/lib/action_controller/metal/conditional_get.rb +274 -0
  29. data/lib/action_controller/metal/content_security_policy.rb +52 -0
  30. data/lib/action_controller/metal/cookies.rb +16 -0
  31. data/lib/action_controller/metal/data_streaming.rb +152 -0
  32. data/lib/action_controller/metal/etag_with_flash.rb +18 -0
  33. data/lib/action_controller/metal/etag_with_template_digest.rb +57 -0
  34. data/lib/action_controller/metal/exceptions.rb +53 -0
  35. data/lib/action_controller/metal/flash.rb +61 -0
  36. data/lib/action_controller/metal/force_ssl.rb +99 -0
  37. data/lib/action_controller/metal/head.rb +60 -0
  38. data/lib/action_controller/metal/helpers.rb +123 -0
  39. data/lib/action_controller/metal/http_authentication.rb +519 -0
  40. data/lib/action_controller/metal/implicit_render.rb +73 -0
  41. data/lib/action_controller/metal/instrumentation.rb +107 -0
  42. data/lib/action_controller/metal/live.rb +312 -0
  43. data/lib/action_controller/metal/mime_responds.rb +313 -0
  44. data/lib/action_controller/metal/parameter_encoding.rb +51 -0
  45. data/lib/action_controller/metal/params_wrapper.rb +293 -0
  46. data/lib/action_controller/metal/redirecting.rb +133 -0
  47. data/lib/action_controller/metal/renderers.rb +181 -0
  48. data/lib/action_controller/metal/rendering.rb +122 -0
  49. data/lib/action_controller/metal/request_forgery_protection.rb +445 -0
  50. data/lib/action_controller/metal/rescue.rb +28 -0
  51. data/lib/action_controller/metal/streaming.rb +223 -0
  52. data/lib/action_controller/metal/strong_parameters.rb +1086 -0
  53. data/lib/action_controller/metal/testing.rb +16 -0
  54. data/lib/action_controller/metal/url_for.rb +58 -0
  55. data/lib/action_controller/railtie.rb +89 -0
  56. data/lib/action_controller/railties/helpers.rb +24 -0
  57. data/lib/action_controller/renderer.rb +117 -0
  58. data/lib/action_controller/template_assertions.rb +11 -0
  59. data/lib/action_controller/test_case.rb +629 -0
  60. data/lib/action_dispatch.rb +112 -0
  61. data/lib/action_dispatch/http/cache.rb +222 -0
  62. data/lib/action_dispatch/http/content_security_policy.rb +272 -0
  63. data/lib/action_dispatch/http/filter_parameters.rb +84 -0
  64. data/lib/action_dispatch/http/filter_redirect.rb +37 -0
  65. data/lib/action_dispatch/http/headers.rb +132 -0
  66. data/lib/action_dispatch/http/mime_negotiation.rb +175 -0
  67. data/lib/action_dispatch/http/mime_type.rb +342 -0
  68. data/lib/action_dispatch/http/mime_types.rb +50 -0
  69. data/lib/action_dispatch/http/parameter_filter.rb +86 -0
  70. data/lib/action_dispatch/http/parameters.rb +126 -0
  71. data/lib/action_dispatch/http/rack_cache.rb +63 -0
  72. data/lib/action_dispatch/http/request.rb +430 -0
  73. data/lib/action_dispatch/http/response.rb +519 -0
  74. data/lib/action_dispatch/http/upload.rb +84 -0
  75. data/lib/action_dispatch/http/url.rb +350 -0
  76. data/lib/action_dispatch/journey.rb +7 -0
  77. data/lib/action_dispatch/journey/formatter.rb +189 -0
  78. data/lib/action_dispatch/journey/gtg/builder.rb +164 -0
  79. data/lib/action_dispatch/journey/gtg/simulator.rb +41 -0
  80. data/lib/action_dispatch/journey/gtg/transition_table.rb +158 -0
  81. data/lib/action_dispatch/journey/nfa/builder.rb +78 -0
  82. data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
  83. data/lib/action_dispatch/journey/nfa/simulator.rb +49 -0
  84. data/lib/action_dispatch/journey/nfa/transition_table.rb +120 -0
  85. data/lib/action_dispatch/journey/nodes/node.rb +140 -0
  86. data/lib/action_dispatch/journey/parser.rb +199 -0
  87. data/lib/action_dispatch/journey/parser.y +50 -0
  88. data/lib/action_dispatch/journey/parser_extras.rb +31 -0
  89. data/lib/action_dispatch/journey/path/pattern.rb +198 -0
  90. data/lib/action_dispatch/journey/route.rb +203 -0
  91. data/lib/action_dispatch/journey/router.rb +156 -0
  92. data/lib/action_dispatch/journey/router/utils.rb +102 -0
  93. data/lib/action_dispatch/journey/routes.rb +82 -0
  94. data/lib/action_dispatch/journey/scanner.rb +64 -0
  95. data/lib/action_dispatch/journey/visitors.rb +268 -0
  96. data/lib/action_dispatch/journey/visualizer/fsm.css +30 -0
  97. data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
  98. data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
  99. data/lib/action_dispatch/middleware/callbacks.rb +36 -0
  100. data/lib/action_dispatch/middleware/cookies.rb +685 -0
  101. data/lib/action_dispatch/middleware/debug_exceptions.rb +205 -0
  102. data/lib/action_dispatch/middleware/debug_locks.rb +124 -0
  103. data/lib/action_dispatch/middleware/exception_wrapper.rb +147 -0
  104. data/lib/action_dispatch/middleware/executor.rb +21 -0
  105. data/lib/action_dispatch/middleware/flash.rb +300 -0
  106. data/lib/action_dispatch/middleware/public_exceptions.rb +57 -0
  107. data/lib/action_dispatch/middleware/reloader.rb +12 -0
  108. data/lib/action_dispatch/middleware/remote_ip.rb +183 -0
  109. data/lib/action_dispatch/middleware/request_id.rb +43 -0
  110. data/lib/action_dispatch/middleware/session/abstract_store.rb +92 -0
  111. data/lib/action_dispatch/middleware/session/cache_store.rb +54 -0
  112. data/lib/action_dispatch/middleware/session/cookie_store.rb +118 -0
  113. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +28 -0
  114. data/lib/action_dispatch/middleware/show_exceptions.rb +62 -0
  115. data/lib/action_dispatch/middleware/ssl.rb +150 -0
  116. data/lib/action_dispatch/middleware/stack.rb +116 -0
  117. data/lib/action_dispatch/middleware/static.rb +130 -0
  118. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +22 -0
  119. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +23 -0
  120. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +27 -0
  121. data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
  122. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +52 -0
  123. data/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb +9 -0
  124. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +16 -0
  125. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +9 -0
  126. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +21 -0
  127. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +13 -0
  128. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +161 -0
  129. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +11 -0
  130. data/lib/action_dispatch/middleware/templates/rescues/missing_template.text.erb +3 -0
  131. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +32 -0
  132. data/lib/action_dispatch/middleware/templates/rescues/routing_error.text.erb +11 -0
  133. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +20 -0
  134. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +7 -0
  135. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +6 -0
  136. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +3 -0
  137. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +16 -0
  138. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +200 -0
  139. data/lib/action_dispatch/railtie.rb +55 -0
  140. data/lib/action_dispatch/request/session.rb +234 -0
  141. data/lib/action_dispatch/request/utils.rb +78 -0
  142. data/lib/action_dispatch/routing.rb +260 -0
  143. data/lib/action_dispatch/routing/endpoint.rb +17 -0
  144. data/lib/action_dispatch/routing/inspector.rb +225 -0
  145. data/lib/action_dispatch/routing/mapper.rb +2267 -0
  146. data/lib/action_dispatch/routing/polymorphic_routes.rb +352 -0
  147. data/lib/action_dispatch/routing/redirection.rb +201 -0
  148. data/lib/action_dispatch/routing/route_set.rb +890 -0
  149. data/lib/action_dispatch/routing/routes_proxy.rb +69 -0
  150. data/lib/action_dispatch/routing/url_for.rb +236 -0
  151. data/lib/action_dispatch/system_test_case.rb +147 -0
  152. data/lib/action_dispatch/system_testing/browser.rb +49 -0
  153. data/lib/action_dispatch/system_testing/driver.rb +59 -0
  154. data/lib/action_dispatch/system_testing/server.rb +31 -0
  155. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +96 -0
  156. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +31 -0
  157. data/lib/action_dispatch/system_testing/test_helpers/undef_methods.rb +26 -0
  158. data/lib/action_dispatch/testing/assertion_response.rb +47 -0
  159. data/lib/action_dispatch/testing/assertions.rb +24 -0
  160. data/lib/action_dispatch/testing/assertions/response.rb +107 -0
  161. data/lib/action_dispatch/testing/assertions/routing.rb +222 -0
  162. data/lib/action_dispatch/testing/integration.rb +652 -0
  163. data/lib/action_dispatch/testing/request_encoder.rb +55 -0
  164. data/lib/action_dispatch/testing/test_process.rb +50 -0
  165. data/lib/action_dispatch/testing/test_request.rb +71 -0
  166. data/lib/action_dispatch/testing/test_response.rb +53 -0
  167. data/lib/action_pack.rb +26 -0
  168. data/lib/action_pack/gem_version.rb +17 -0
  169. data/lib/action_pack/version.rb +10 -0
  170. metadata +318 -0
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "action_dispatch"
4
+ require "active_support/messages/rotation_configuration"
5
+
6
+ module ActionDispatch
7
+ class Railtie < Rails::Railtie # :nodoc:
8
+ config.action_dispatch = ActiveSupport::OrderedOptions.new
9
+ config.action_dispatch.x_sendfile_header = nil
10
+ config.action_dispatch.ip_spoofing_check = true
11
+ config.action_dispatch.show_exceptions = true
12
+ config.action_dispatch.tld_length = 1
13
+ config.action_dispatch.ignore_accept_header = false
14
+ config.action_dispatch.rescue_templates = {}
15
+ config.action_dispatch.rescue_responses = {}
16
+ config.action_dispatch.default_charset = nil
17
+ config.action_dispatch.rack_cache = false
18
+ config.action_dispatch.http_auth_salt = "http authentication"
19
+ config.action_dispatch.signed_cookie_salt = "signed cookie"
20
+ config.action_dispatch.encrypted_cookie_salt = "encrypted cookie"
21
+ config.action_dispatch.encrypted_signed_cookie_salt = "signed encrypted cookie"
22
+ config.action_dispatch.authenticated_encrypted_cookie_salt = "authenticated encrypted cookie"
23
+ config.action_dispatch.use_authenticated_cookie_encryption = false
24
+ config.action_dispatch.perform_deep_munge = true
25
+
26
+ config.action_dispatch.default_headers = {
27
+ "X-Frame-Options" => "SAMEORIGIN",
28
+ "X-XSS-Protection" => "1; mode=block",
29
+ "X-Content-Type-Options" => "nosniff",
30
+ "X-Download-Options" => "noopen",
31
+ "X-Permitted-Cross-Domain-Policies" => "none",
32
+ "Referrer-Policy" => "strict-origin-when-cross-origin"
33
+ }
34
+
35
+ config.action_dispatch.cookies_rotations = ActiveSupport::Messages::RotationConfiguration.new
36
+
37
+ config.eager_load_namespaces << ActionDispatch
38
+
39
+ initializer "action_dispatch.configure" do |app|
40
+ ActionDispatch::Http::URL.tld_length = app.config.action_dispatch.tld_length
41
+ ActionDispatch::Request.ignore_accept_header = app.config.action_dispatch.ignore_accept_header
42
+ ActionDispatch::Request::Utils.perform_deep_munge = app.config.action_dispatch.perform_deep_munge
43
+ ActionDispatch::Response.default_charset = app.config.action_dispatch.default_charset || app.config.encoding
44
+ ActionDispatch::Response.default_headers = app.config.action_dispatch.default_headers
45
+
46
+ ActionDispatch::ExceptionWrapper.rescue_responses.merge!(config.action_dispatch.rescue_responses)
47
+ ActionDispatch::ExceptionWrapper.rescue_templates.merge!(config.action_dispatch.rescue_templates)
48
+
49
+ config.action_dispatch.always_write_cookie = Rails.env.development? if config.action_dispatch.always_write_cookie.nil?
50
+ ActionDispatch::Cookies::CookieJar.always_write_cookie = config.action_dispatch.always_write_cookie
51
+
52
+ ActionDispatch.test_app = app
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,234 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rack/session/abstract/id"
4
+
5
+ module ActionDispatch
6
+ class Request
7
+ # Session is responsible for lazily loading the session from store.
8
+ class Session # :nodoc:
9
+ ENV_SESSION_KEY = Rack::RACK_SESSION # :nodoc:
10
+ ENV_SESSION_OPTIONS_KEY = Rack::RACK_SESSION_OPTIONS # :nodoc:
11
+
12
+ # Singleton object used to determine if an optional param wasn't specified.
13
+ Unspecified = Object.new
14
+
15
+ # Creates a session hash, merging the properties of the previous session if any.
16
+ def self.create(store, req, default_options)
17
+ session_was = find req
18
+ session = Request::Session.new(store, req)
19
+ session.merge! session_was if session_was
20
+
21
+ set(req, session)
22
+ Options.set(req, Request::Session::Options.new(store, default_options))
23
+ session
24
+ end
25
+
26
+ def self.find(req)
27
+ req.get_header ENV_SESSION_KEY
28
+ end
29
+
30
+ def self.set(req, session)
31
+ req.set_header ENV_SESSION_KEY, session
32
+ end
33
+
34
+ class Options #:nodoc:
35
+ def self.set(req, options)
36
+ req.set_header ENV_SESSION_OPTIONS_KEY, options
37
+ end
38
+
39
+ def self.find(req)
40
+ req.get_header ENV_SESSION_OPTIONS_KEY
41
+ end
42
+
43
+ def initialize(by, default_options)
44
+ @by = by
45
+ @delegate = default_options.dup
46
+ end
47
+
48
+ def [](key)
49
+ @delegate[key]
50
+ end
51
+
52
+ def id(req)
53
+ @delegate.fetch(:id) {
54
+ @by.send(:extract_session_id, req)
55
+ }
56
+ end
57
+
58
+ def []=(k, v); @delegate[k] = v; end
59
+ def to_hash; @delegate.dup; end
60
+ def values_at(*args); @delegate.values_at(*args); end
61
+ end
62
+
63
+ def initialize(by, req)
64
+ @by = by
65
+ @req = req
66
+ @delegate = {}
67
+ @loaded = false
68
+ @exists = nil # We haven't checked yet.
69
+ end
70
+
71
+ def id
72
+ options.id(@req)
73
+ end
74
+
75
+ def options
76
+ Options.find @req
77
+ end
78
+
79
+ def destroy
80
+ clear
81
+ options = self.options || {}
82
+ @by.send(:delete_session, @req, options.id(@req), options)
83
+
84
+ # Load the new sid to be written with the response.
85
+ @loaded = false
86
+ load_for_write!
87
+ end
88
+
89
+ # Returns value of the key stored in the session or
90
+ # +nil+ if the given key is not found in the session.
91
+ def [](key)
92
+ load_for_read!
93
+ @delegate[key.to_s]
94
+ end
95
+
96
+ # Returns true if the session has the given key or false.
97
+ def has_key?(key)
98
+ load_for_read!
99
+ @delegate.key?(key.to_s)
100
+ end
101
+ alias :key? :has_key?
102
+ alias :include? :has_key?
103
+
104
+ # Returns keys of the session as Array.
105
+ def keys
106
+ load_for_read!
107
+ @delegate.keys
108
+ end
109
+
110
+ # Returns values of the session as Array.
111
+ def values
112
+ load_for_read!
113
+ @delegate.values
114
+ end
115
+
116
+ # Writes given value to given key of the session.
117
+ def []=(key, value)
118
+ load_for_write!
119
+ @delegate[key.to_s] = value
120
+ end
121
+
122
+ # Clears the session.
123
+ def clear
124
+ load_for_write!
125
+ @delegate.clear
126
+ end
127
+
128
+ # Returns the session as Hash.
129
+ def to_hash
130
+ load_for_read!
131
+ @delegate.dup.delete_if { |_, v| v.nil? }
132
+ end
133
+ alias :to_h :to_hash
134
+
135
+ # Updates the session with given Hash.
136
+ #
137
+ # session.to_hash
138
+ # # => {"session_id"=>"e29b9ea315edf98aad94cc78c34cc9b2"}
139
+ #
140
+ # session.update({ "foo" => "bar" })
141
+ # # => {"session_id"=>"e29b9ea315edf98aad94cc78c34cc9b2", "foo" => "bar"}
142
+ #
143
+ # session.to_hash
144
+ # # => {"session_id"=>"e29b9ea315edf98aad94cc78c34cc9b2", "foo" => "bar"}
145
+ def update(hash)
146
+ load_for_write!
147
+ @delegate.update stringify_keys(hash)
148
+ end
149
+
150
+ # Deletes given key from the session.
151
+ def delete(key)
152
+ load_for_write!
153
+ @delegate.delete key.to_s
154
+ end
155
+
156
+ # Returns value of the given key from the session, or raises +KeyError+
157
+ # if can't find the given key and no default value is set.
158
+ # Returns default value if specified.
159
+ #
160
+ # session.fetch(:foo)
161
+ # # => KeyError: key not found: "foo"
162
+ #
163
+ # session.fetch(:foo, :bar)
164
+ # # => :bar
165
+ #
166
+ # session.fetch(:foo) do
167
+ # :bar
168
+ # end
169
+ # # => :bar
170
+ def fetch(key, default = Unspecified, &block)
171
+ load_for_read!
172
+ if default == Unspecified
173
+ @delegate.fetch(key.to_s, &block)
174
+ else
175
+ @delegate.fetch(key.to_s, default, &block)
176
+ end
177
+ end
178
+
179
+ def inspect
180
+ if loaded?
181
+ super
182
+ else
183
+ "#<#{self.class}:0x#{(object_id << 1).to_s(16)} not yet loaded>"
184
+ end
185
+ end
186
+
187
+ def exists?
188
+ return @exists unless @exists.nil?
189
+ @exists = @by.send(:session_exists?, @req)
190
+ end
191
+
192
+ def loaded?
193
+ @loaded
194
+ end
195
+
196
+ def empty?
197
+ load_for_read!
198
+ @delegate.empty?
199
+ end
200
+
201
+ def merge!(other)
202
+ load_for_write!
203
+ @delegate.merge!(other)
204
+ end
205
+
206
+ def each(&block)
207
+ to_hash.each(&block)
208
+ end
209
+
210
+ private
211
+
212
+ def load_for_read!
213
+ load! if !loaded? && exists?
214
+ end
215
+
216
+ def load_for_write!
217
+ load! unless loaded?
218
+ end
219
+
220
+ def load!
221
+ id, session = @by.load_session @req
222
+ options[:id] = id
223
+ @delegate.replace(stringify_keys(session))
224
+ @loaded = true
225
+ end
226
+
227
+ def stringify_keys(other)
228
+ other.each_with_object({}) { |(key, value), hash|
229
+ hash[key.to_s] = value
230
+ }
231
+ end
232
+ end
233
+ end
234
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/hash/indifferent_access"
4
+
5
+ module ActionDispatch
6
+ class Request
7
+ class Utils # :nodoc:
8
+ mattr_accessor :perform_deep_munge, default: true
9
+
10
+ def self.each_param_value(params, &block)
11
+ case params
12
+ when Array
13
+ params.each { |element| each_param_value(element, &block) }
14
+ when Hash
15
+ params.each_value { |value| each_param_value(value, &block) }
16
+ when String
17
+ block.call params
18
+ end
19
+ end
20
+
21
+ def self.normalize_encode_params(params)
22
+ if perform_deep_munge
23
+ NoNilParamEncoder.normalize_encode_params params
24
+ else
25
+ ParamEncoder.normalize_encode_params params
26
+ end
27
+ end
28
+
29
+ def self.check_param_encoding(params)
30
+ case params
31
+ when Array
32
+ params.each { |element| check_param_encoding(element) }
33
+ when Hash
34
+ params.each_value { |value| check_param_encoding(value) }
35
+ when String
36
+ unless params.valid_encoding?
37
+ # Raise Rack::Utils::InvalidParameterError for consistency with Rack.
38
+ # ActionDispatch::Request#GET will re-raise as a BadRequest error.
39
+ raise Rack::Utils::InvalidParameterError, "Invalid encoding for parameter: #{params.scrub}"
40
+ end
41
+ end
42
+ end
43
+
44
+ class ParamEncoder # :nodoc:
45
+ # Convert nested Hash to HashWithIndifferentAccess.
46
+ def self.normalize_encode_params(params)
47
+ case params
48
+ when Array
49
+ handle_array params
50
+ when Hash
51
+ if params.has_key?(:tempfile)
52
+ ActionDispatch::Http::UploadedFile.new(params)
53
+ else
54
+ params.each_with_object({}) do |(key, val), new_hash|
55
+ new_hash[key] = normalize_encode_params(val)
56
+ end.with_indifferent_access
57
+ end
58
+ else
59
+ params
60
+ end
61
+ end
62
+
63
+ def self.handle_array(params)
64
+ params.map! { |el| normalize_encode_params(el) }
65
+ end
66
+ end
67
+
68
+ # Remove nils from the params hash.
69
+ class NoNilParamEncoder < ParamEncoder # :nodoc:
70
+ def self.handle_array(params)
71
+ list = super
72
+ list.compact!
73
+ list
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,260 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/string/filters"
4
+
5
+ module ActionDispatch
6
+ # The routing module provides URL rewriting in native Ruby. It's a way to
7
+ # redirect incoming requests to controllers and actions. This replaces
8
+ # mod_rewrite rules. Best of all, Rails' \Routing works with any web server.
9
+ # Routes are defined in <tt>config/routes.rb</tt>.
10
+ #
11
+ # Think of creating routes as drawing a map for your requests. The map tells
12
+ # them where to go based on some predefined pattern:
13
+ #
14
+ # Rails.application.routes.draw do
15
+ # Pattern 1 tells some request to go to one place
16
+ # Pattern 2 tell them to go to another
17
+ # ...
18
+ # end
19
+ #
20
+ # The following symbols are special:
21
+ #
22
+ # :controller maps to your controller name
23
+ # :action maps to an action with your controllers
24
+ #
25
+ # Other names simply map to a parameter as in the case of <tt>:id</tt>.
26
+ #
27
+ # == Resources
28
+ #
29
+ # Resource routing allows you to quickly declare all of the common routes
30
+ # for a given resourceful controller. Instead of declaring separate routes
31
+ # for your +index+, +show+, +new+, +edit+, +create+, +update+ and +destroy+
32
+ # actions, a resourceful route declares them in a single line of code:
33
+ #
34
+ # resources :photos
35
+ #
36
+ # Sometimes, you have a resource that clients always look up without
37
+ # referencing an ID. A common example, /profile always shows the profile of
38
+ # the currently logged in user. In this case, you can use a singular resource
39
+ # to map /profile (rather than /profile/:id) to the show action.
40
+ #
41
+ # resource :profile
42
+ #
43
+ # It's common to have resources that are logically children of other
44
+ # resources:
45
+ #
46
+ # resources :magazines do
47
+ # resources :ads
48
+ # end
49
+ #
50
+ # You may wish to organize groups of controllers under a namespace. Most
51
+ # commonly, you might group a number of administrative controllers under
52
+ # an +admin+ namespace. You would place these controllers under the
53
+ # <tt>app/controllers/admin</tt> directory, and you can group them together
54
+ # in your router:
55
+ #
56
+ # namespace "admin" do
57
+ # resources :posts, :comments
58
+ # end
59
+ #
60
+ # Alternatively, you can add prefixes to your path without using a separate
61
+ # directory by using +scope+. +scope+ takes additional options which
62
+ # apply to all enclosed routes.
63
+ #
64
+ # scope path: "/cpanel", as: 'admin' do
65
+ # resources :posts, :comments
66
+ # end
67
+ #
68
+ # For more, see <tt>Routing::Mapper::Resources#resources</tt>,
69
+ # <tt>Routing::Mapper::Scoping#namespace</tt>, and
70
+ # <tt>Routing::Mapper::Scoping#scope</tt>.
71
+ #
72
+ # == Non-resourceful routes
73
+ #
74
+ # For routes that don't fit the <tt>resources</tt> mold, you can use the HTTP helper
75
+ # methods <tt>get</tt>, <tt>post</tt>, <tt>patch</tt>, <tt>put</tt> and <tt>delete</tt>.
76
+ #
77
+ # get 'post/:id' => 'posts#show'
78
+ # post 'post/:id' => 'posts#create_comment'
79
+ #
80
+ # Now, if you POST to <tt>/posts/:id</tt>, it will route to the <tt>create_comment</tt> action. A GET on the same
81
+ # URL will route to the <tt>show</tt> action.
82
+ #
83
+ # If your route needs to respond to more than one HTTP method (or all methods) then using the
84
+ # <tt>:via</tt> option on <tt>match</tt> is preferable.
85
+ #
86
+ # match 'post/:id' => 'posts#show', via: [:get, :post]
87
+ #
88
+ # == Named routes
89
+ #
90
+ # Routes can be named by passing an <tt>:as</tt> option,
91
+ # allowing for easy reference within your source as +name_of_route_url+
92
+ # for the full URL and +name_of_route_path+ for the URI path.
93
+ #
94
+ # Example:
95
+ #
96
+ # # In config/routes.rb
97
+ # get '/login' => 'accounts#login', as: 'login'
98
+ #
99
+ # # With render, redirect_to, tests, etc.
100
+ # redirect_to login_url
101
+ #
102
+ # Arguments can be passed as well.
103
+ #
104
+ # redirect_to show_item_path(id: 25)
105
+ #
106
+ # Use <tt>root</tt> as a shorthand to name a route for the root path "/".
107
+ #
108
+ # # In config/routes.rb
109
+ # root to: 'blogs#index'
110
+ #
111
+ # # would recognize http://www.example.com/ as
112
+ # params = { controller: 'blogs', action: 'index' }
113
+ #
114
+ # # and provide these named routes
115
+ # root_url # => 'http://www.example.com/'
116
+ # root_path # => '/'
117
+ #
118
+ # Note: when using +controller+, the route is simply named after the
119
+ # method you call on the block parameter rather than map.
120
+ #
121
+ # # In config/routes.rb
122
+ # controller :blog do
123
+ # get 'blog/show' => :list
124
+ # get 'blog/delete' => :delete
125
+ # get 'blog/edit' => :edit
126
+ # end
127
+ #
128
+ # # provides named routes for show, delete, and edit
129
+ # link_to @article.title, blog_show_path(id: @article.id)
130
+ #
131
+ # == Pretty URLs
132
+ #
133
+ # Routes can generate pretty URLs. For example:
134
+ #
135
+ # get '/articles/:year/:month/:day' => 'articles#find_by_id', constraints: {
136
+ # year: /\d{4}/,
137
+ # month: /\d{1,2}/,
138
+ # day: /\d{1,2}/
139
+ # }
140
+ #
141
+ # Using the route above, the URL "http://localhost:3000/articles/2005/11/06"
142
+ # maps to
143
+ #
144
+ # params = {year: '2005', month: '11', day: '06'}
145
+ #
146
+ # == Regular Expressions and parameters
147
+ # You can specify a regular expression to define a format for a parameter.
148
+ #
149
+ # controller 'geocode' do
150
+ # get 'geocode/:postalcode' => :show, constraints: {
151
+ # postalcode: /\d{5}(-\d{4})?/
152
+ # }
153
+ # end
154
+ #
155
+ # Constraints can include the 'ignorecase' and 'extended syntax' regular
156
+ # expression modifiers:
157
+ #
158
+ # controller 'geocode' do
159
+ # get 'geocode/:postalcode' => :show, constraints: {
160
+ # postalcode: /hx\d\d\s\d[a-z]{2}/i
161
+ # }
162
+ # end
163
+ #
164
+ # controller 'geocode' do
165
+ # get 'geocode/:postalcode' => :show, constraints: {
166
+ # postalcode: /# Postalcode format
167
+ # \d{5} #Prefix
168
+ # (-\d{4})? #Suffix
169
+ # /x
170
+ # }
171
+ # end
172
+ #
173
+ # Using the multiline modifier will raise an +ArgumentError+.
174
+ # Encoding regular expression modifiers are silently ignored. The
175
+ # match will always use the default encoding or ASCII.
176
+ #
177
+ # == External redirects
178
+ #
179
+ # You can redirect any path to another path using the redirect helper in your router:
180
+ #
181
+ # get "/stories" => redirect("/posts")
182
+ #
183
+ # == Unicode character routes
184
+ #
185
+ # You can specify unicode character routes in your router:
186
+ #
187
+ # get "こんにちは" => "welcome#index"
188
+ #
189
+ # == Routing to Rack Applications
190
+ #
191
+ # Instead of a String, like <tt>posts#index</tt>, which corresponds to the
192
+ # index action in the PostsController, you can specify any Rack application
193
+ # as the endpoint for a matcher:
194
+ #
195
+ # get "/application.js" => Sprockets
196
+ #
197
+ # == Reloading routes
198
+ #
199
+ # You can reload routes if you feel you must:
200
+ #
201
+ # Rails.application.reload_routes!
202
+ #
203
+ # This will clear all named routes and reload config/routes.rb if the file has been modified from
204
+ # last load. To absolutely force reloading, use <tt>reload!</tt>.
205
+ #
206
+ # == Testing Routes
207
+ #
208
+ # The two main methods for testing your routes:
209
+ #
210
+ # === +assert_routing+
211
+ #
212
+ # def test_movie_route_properly_splits
213
+ # opts = {controller: "plugin", action: "checkout", id: "2"}
214
+ # assert_routing "plugin/checkout/2", opts
215
+ # end
216
+ #
217
+ # +assert_routing+ lets you test whether or not the route properly resolves into options.
218
+ #
219
+ # === +assert_recognizes+
220
+ #
221
+ # def test_route_has_options
222
+ # opts = {controller: "plugin", action: "show", id: "12"}
223
+ # assert_recognizes opts, "/plugins/show/12"
224
+ # end
225
+ #
226
+ # Note the subtle difference between the two: +assert_routing+ tests that
227
+ # a URL fits options while +assert_recognizes+ tests that a URL
228
+ # breaks into parameters properly.
229
+ #
230
+ # In tests you can simply pass the URL or named route to +get+ or +post+.
231
+ #
232
+ # def send_to_jail
233
+ # get '/jail'
234
+ # assert_response :success
235
+ # end
236
+ #
237
+ # def goes_to_login
238
+ # get login_url
239
+ # #...
240
+ # end
241
+ #
242
+ # == View a list of all your routes
243
+ #
244
+ # rails routes
245
+ #
246
+ # Target specific controllers by prefixing the command with <tt>-c</tt> option.
247
+ #
248
+ module Routing
249
+ extend ActiveSupport::Autoload
250
+
251
+ autoload :Mapper
252
+ autoload :RouteSet
253
+ autoload :RoutesProxy
254
+ autoload :UrlFor
255
+ autoload :PolymorphicRoutes
256
+
257
+ SEPARATORS = %w( / . ? ) #:nodoc:
258
+ HTTP_METHODS = [:get, :head, :post, :patch, :put, :delete, :options] #:nodoc:
259
+ end
260
+ end