actionpack 5.0.7.2 → 5.1.0.beta1
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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +189 -1002
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/lib/abstract_controller.rb +3 -3
- data/lib/abstract_controller/base.rb +10 -12
- data/lib/abstract_controller/caching.rb +6 -3
- data/lib/abstract_controller/caching/fragments.rb +1 -1
- data/lib/abstract_controller/callbacks.rb +2 -43
- data/lib/abstract_controller/collector.rb +2 -2
- data/lib/abstract_controller/helpers.rb +19 -19
- data/lib/abstract_controller/rendering.rb +9 -11
- data/lib/abstract_controller/translation.rb +3 -3
- data/lib/action_controller.rb +15 -13
- data/lib/action_controller/api.rb +3 -3
- data/lib/action_controller/base.rb +7 -12
- data/lib/action_controller/caching.rb +1 -1
- data/lib/action_controller/log_subscriber.rb +2 -2
- data/lib/action_controller/metal.rb +34 -43
- data/lib/action_controller/metal/conditional_get.rb +10 -9
- data/lib/action_controller/metal/data_streaming.rb +8 -9
- data/lib/action_controller/metal/etag_with_flash.rb +16 -0
- data/lib/action_controller/metal/etag_with_template_digest.rb +15 -15
- data/lib/action_controller/metal/exceptions.rb +4 -14
- data/lib/action_controller/metal/flash.rb +1 -1
- data/lib/action_controller/metal/force_ssl.rb +6 -6
- data/lib/action_controller/metal/head.rb +13 -19
- data/lib/action_controller/metal/helpers.rb +6 -6
- data/lib/action_controller/metal/http_authentication.rb +22 -23
- data/lib/action_controller/metal/implicit_render.rb +2 -5
- data/lib/action_controller/metal/instrumentation.rb +14 -14
- data/lib/action_controller/metal/live.rb +15 -16
- data/lib/action_controller/metal/mime_responds.rb +3 -3
- data/lib/action_controller/metal/parameter_encoding.rb +49 -0
- data/lib/action_controller/metal/params_wrapper.rb +32 -32
- data/lib/action_controller/metal/redirecting.rb +8 -24
- data/lib/action_controller/metal/renderers.rb +2 -3
- data/lib/action_controller/metal/rendering.rb +50 -60
- data/lib/action_controller/metal/request_forgery_protection.rb +51 -49
- data/lib/action_controller/metal/rescue.rb +1 -1
- data/lib/action_controller/metal/streaming.rb +4 -4
- data/lib/action_controller/metal/strong_parameters.rb +117 -250
- data/lib/action_controller/metal/testing.rb +1 -1
- data/lib/action_controller/metal/url_for.rb +4 -4
- data/lib/action_controller/railtie.rb +9 -13
- data/lib/action_controller/renderer.rb +17 -16
- data/lib/action_controller/test_case.rb +75 -148
- data/lib/action_dispatch.rb +20 -19
- data/lib/action_dispatch/http/cache.rb +9 -10
- data/lib/action_dispatch/http/filter_parameters.rb +8 -8
- data/lib/action_dispatch/http/filter_redirect.rb +2 -4
- data/lib/action_dispatch/http/headers.rb +10 -10
- data/lib/action_dispatch/http/mime_negotiation.rb +17 -22
- data/lib/action_dispatch/http/mime_type.rb +27 -52
- data/lib/action_dispatch/http/parameter_filter.rb +8 -6
- data/lib/action_dispatch/http/parameters.rb +40 -17
- data/lib/action_dispatch/http/request.rb +38 -34
- data/lib/action_dispatch/http/response.rb +16 -16
- data/lib/action_dispatch/http/upload.rb +6 -10
- data/lib/action_dispatch/http/url.rb +48 -74
- data/lib/action_dispatch/journey.rb +5 -5
- data/lib/action_dispatch/journey/formatter.rb +8 -4
- data/lib/action_dispatch/journey/gtg/builder.rb +5 -5
- data/lib/action_dispatch/journey/gtg/simulator.rb +1 -1
- data/lib/action_dispatch/journey/gtg/transition_table.rb +15 -15
- data/lib/action_dispatch/journey/nfa/builder.rb +3 -3
- data/lib/action_dispatch/journey/nfa/dot.rb +2 -2
- data/lib/action_dispatch/journey/nfa/simulator.rb +1 -1
- data/lib/action_dispatch/journey/nfa/transition_table.rb +2 -2
- data/lib/action_dispatch/journey/nodes/node.rb +5 -5
- data/lib/action_dispatch/journey/parser.rb +23 -24
- data/lib/action_dispatch/journey/parser.y +3 -2
- data/lib/action_dispatch/journey/parser_extras.rb +2 -2
- data/lib/action_dispatch/journey/path/pattern.rb +10 -3
- data/lib/action_dispatch/journey/route.rb +19 -12
- data/lib/action_dispatch/journey/router.rb +19 -12
- data/lib/action_dispatch/journey/router/utils.rb +9 -9
- data/lib/action_dispatch/journey/scanner.rb +17 -15
- data/lib/action_dispatch/journey/visitors.rb +23 -23
- data/lib/action_dispatch/middleware/callbacks.rb +0 -12
- data/lib/action_dispatch/middleware/cookies.rb +39 -39
- data/lib/action_dispatch/middleware/debug_exceptions.rb +126 -112
- data/lib/action_dispatch/middleware/debug_locks.rb +8 -8
- data/lib/action_dispatch/middleware/exception_wrapper.rb +55 -55
- data/lib/action_dispatch/middleware/executor.rb +1 -1
- data/lib/action_dispatch/middleware/flash.rb +17 -16
- data/lib/action_dispatch/middleware/public_exceptions.rb +20 -20
- data/lib/action_dispatch/middleware/reloader.rb +3 -47
- data/lib/action_dispatch/middleware/remote_ip.rb +6 -8
- data/lib/action_dispatch/middleware/request_id.rb +6 -5
- data/lib/action_dispatch/middleware/session/abstract_store.rb +14 -26
- data/lib/action_dispatch/middleware/session/cache_store.rb +3 -3
- data/lib/action_dispatch/middleware/session/cookie_store.rb +35 -35
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +2 -2
- data/lib/action_dispatch/middleware/show_exceptions.rb +19 -19
- data/lib/action_dispatch/middleware/ssl.rb +9 -27
- data/lib/action_dispatch/middleware/stack.rb +7 -26
- data/lib/action_dispatch/middleware/static.rb +13 -24
- data/lib/action_dispatch/railtie.rb +9 -11
- data/lib/action_dispatch/request/session.rb +22 -22
- data/lib/action_dispatch/request/utils.rb +11 -2
- data/lib/action_dispatch/routing.rb +8 -6
- data/lib/action_dispatch/routing/inspector.rb +37 -37
- data/lib/action_dispatch/routing/mapper.rb +296 -203
- data/lib/action_dispatch/routing/polymorphic_routes.rb +160 -134
- data/lib/action_dispatch/routing/redirection.rb +27 -22
- data/lib/action_dispatch/routing/route_set.rb +206 -92
- data/lib/action_dispatch/routing/routes_proxy.rb +2 -2
- data/lib/action_dispatch/routing/url_for.rb +14 -12
- data/lib/action_dispatch/system_test_case.rb +119 -0
- data/lib/action_dispatch/system_testing/browser.rb +28 -0
- data/lib/action_dispatch/system_testing/driver.rb +18 -0
- data/lib/action_dispatch/system_testing/server.rb +32 -0
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +61 -0
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +20 -0
- data/lib/action_dispatch/testing/assertion_response.rb +6 -6
- data/lib/action_dispatch/testing/assertions.rb +4 -4
- data/lib/action_dispatch/testing/assertions/response.rb +8 -3
- data/lib/action_dispatch/testing/assertions/routing.rb +11 -11
- data/lib/action_dispatch/testing/integration.rb +47 -138
- data/lib/action_dispatch/testing/test_process.rb +2 -2
- data/lib/action_dispatch/testing/test_request.rb +16 -16
- data/lib/action_dispatch/testing/test_response.rb +1 -1
- data/lib/action_pack.rb +2 -2
- data/lib/action_pack/gem_version.rb +3 -3
- data/lib/action_pack/version.rb +1 -1
- metadata +20 -12
- data/lib/action_dispatch/middleware/params_parser.rb +0 -46
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "base64"
|
2
|
+
require "active_support/security_utils"
|
3
3
|
|
4
4
|
module ActionController
|
5
5
|
# Makes it dead easy to do HTTP Basic, Digest and Token authentication.
|
@@ -28,7 +28,7 @@ module ActionController
|
|
28
28
|
# class ApplicationController < ActionController::Base
|
29
29
|
# before_action :set_account, :authenticate
|
30
30
|
#
|
31
|
-
#
|
31
|
+
# private
|
32
32
|
# def set_account
|
33
33
|
# @account = Account.find_by(url_name: request.subdomains.first)
|
34
34
|
# end
|
@@ -99,23 +99,23 @@ module ActionController
|
|
99
99
|
end
|
100
100
|
|
101
101
|
def has_basic_credentials?(request)
|
102
|
-
request.authorization.present? && (auth_scheme(request).downcase ==
|
102
|
+
request.authorization.present? && (auth_scheme(request).downcase == "basic")
|
103
103
|
end
|
104
104
|
|
105
105
|
def user_name_and_password(request)
|
106
|
-
decode_credentials(request).split(
|
106
|
+
decode_credentials(request).split(":", 2)
|
107
107
|
end
|
108
108
|
|
109
109
|
def decode_credentials(request)
|
110
|
-
::Base64.decode64(auth_param(request) ||
|
110
|
+
::Base64.decode64(auth_param(request) || "")
|
111
111
|
end
|
112
112
|
|
113
113
|
def auth_scheme(request)
|
114
|
-
request.authorization.to_s.split(
|
114
|
+
request.authorization.to_s.split(" ", 2).first
|
115
115
|
end
|
116
116
|
|
117
117
|
def auth_param(request)
|
118
|
-
request.authorization.to_s.split(
|
118
|
+
request.authorization.to_s.split(" ", 2).second
|
119
119
|
end
|
120
120
|
|
121
121
|
def encode_credentials(user_name, password)
|
@@ -208,7 +208,7 @@ module ActionController
|
|
208
208
|
password = password_procedure.call(credentials[:username])
|
209
209
|
return false unless password
|
210
210
|
|
211
|
-
method = request.get_header(
|
211
|
+
method = request.get_header("rack.methodoverride.original_method") || request.get_header("REQUEST_METHOD")
|
212
212
|
uri = credentials[:uri]
|
213
213
|
|
214
214
|
[true, false].any? do |trailing_question_mark|
|
@@ -224,19 +224,19 @@ module ActionController
|
|
224
224
|
# Returns the expected response for a request of +http_method+ to +uri+ with the decoded +credentials+ and the expected +password+
|
225
225
|
# Optional parameter +password_is_ha1+ is set to +true+ by default, since best practice is to store ha1 digest instead
|
226
226
|
# of a plain-text password.
|
227
|
-
def expected_response(http_method, uri, credentials, password, password_is_ha1=true)
|
227
|
+
def expected_response(http_method, uri, credentials, password, password_is_ha1 = true)
|
228
228
|
ha1 = password_is_ha1 ? password : ha1(credentials, password)
|
229
|
-
ha2 = ::Digest::MD5.hexdigest([http_method.to_s.upcase, uri].join(
|
230
|
-
::Digest::MD5.hexdigest([ha1, credentials[:nonce], credentials[:nc], credentials[:cnonce], credentials[:qop], ha2].join(
|
229
|
+
ha2 = ::Digest::MD5.hexdigest([http_method.to_s.upcase, uri].join(":"))
|
230
|
+
::Digest::MD5.hexdigest([ha1, credentials[:nonce], credentials[:nc], credentials[:cnonce], credentials[:qop], ha2].join(":"))
|
231
231
|
end
|
232
232
|
|
233
233
|
def ha1(credentials, password)
|
234
|
-
::Digest::MD5.hexdigest([credentials[:username], credentials[:realm], password].join(
|
234
|
+
::Digest::MD5.hexdigest([credentials[:username], credentials[:realm], password].join(":"))
|
235
235
|
end
|
236
236
|
|
237
237
|
def encode_credentials(http_method, credentials, password, password_is_ha1)
|
238
238
|
credentials[:response] = expected_response(http_method, credentials[:uri], credentials, password, password_is_ha1)
|
239
|
-
"Digest " + credentials.sort_by {|x| x[0].to_s }.map {|v| "#{v[0]}='#{v[1]}'" }.join(
|
239
|
+
"Digest " + credentials.sort_by { |x| x[0].to_s }.map { |v| "#{v[0]}='#{v[1]}'" }.join(", ")
|
240
240
|
end
|
241
241
|
|
242
242
|
def decode_credentials_header(request)
|
@@ -244,9 +244,9 @@ module ActionController
|
|
244
244
|
end
|
245
245
|
|
246
246
|
def decode_credentials(header)
|
247
|
-
ActiveSupport::HashWithIndifferentAccess[header.to_s.gsub(/^Digest\s+/,
|
248
|
-
key, value = pair.split(
|
249
|
-
[key.strip, value.to_s.gsub(/^"|"$/,
|
247
|
+
ActiveSupport::HashWithIndifferentAccess[header.to_s.gsub(/^Digest\s+/, "").split(",").map do |pair|
|
248
|
+
key, value = pair.split("=", 2)
|
249
|
+
[key.strip, value.to_s.gsub(/^"|"$/, "").delete('\'')]
|
250
250
|
end]
|
251
251
|
end
|
252
252
|
|
@@ -314,7 +314,7 @@ module ActionController
|
|
314
314
|
# Can be much shorter if the Stale directive is implemented. This would
|
315
315
|
# allow a user to use new nonce without prompting the user again for their
|
316
316
|
# username and password.
|
317
|
-
def validate_nonce(secret_key, request, value, seconds_to_timeout=5*60)
|
317
|
+
def validate_nonce(secret_key, request, value, seconds_to_timeout = 5 * 60)
|
318
318
|
return false if value.nil?
|
319
319
|
t = ::Base64.decode64(value).split(":").first.to_i
|
320
320
|
nonce(secret_key, t) == value && (t - Time.now.to_i).abs <= seconds_to_timeout
|
@@ -324,7 +324,6 @@ module ActionController
|
|
324
324
|
def opaque(secret_key)
|
325
325
|
::Digest::MD5.hexdigest(secret_key)
|
326
326
|
end
|
327
|
-
|
328
327
|
end
|
329
328
|
|
330
329
|
# Makes it dead easy to do HTTP Token authentication.
|
@@ -364,7 +363,7 @@ module ActionController
|
|
364
363
|
# class ApplicationController < ActionController::Base
|
365
364
|
# before_action :set_account, :authenticate
|
366
365
|
#
|
367
|
-
#
|
366
|
+
# private
|
368
367
|
# def set_account
|
369
368
|
# @account = Account.find_by(url_name: request.subdomains.first)
|
370
369
|
# end
|
@@ -406,7 +405,7 @@ module ActionController
|
|
406
405
|
#
|
407
406
|
# RewriteRule ^(.*)$ dispatch.fcgi [E=X-HTTP_AUTHORIZATION:%{HTTP:Authorization},QSA,L]
|
408
407
|
module Token
|
409
|
-
TOKEN_KEY =
|
408
|
+
TOKEN_KEY = "token="
|
410
409
|
TOKEN_REGEX = /^(Token|Bearer)\s+/
|
411
410
|
AUTHN_PAIR_DELIMITERS = /(?:,|;|\t+)/
|
412
411
|
extend self
|
@@ -476,14 +475,14 @@ module ActionController
|
|
476
475
|
|
477
476
|
# This removes the <tt>"</tt> characters wrapping the value.
|
478
477
|
def rewrite_param_values(array_params)
|
479
|
-
array_params.each { |param| (param[1] || "").gsub! %r/^"|"$/,
|
478
|
+
array_params.each { |param| (param[1] || "").gsub! %r/^"|"$/, "" }
|
480
479
|
end
|
481
480
|
|
482
481
|
# This method takes an authorization body and splits up the key-value
|
483
482
|
# pairs by the standardized <tt>:</tt>, <tt>;</tt>, or <tt>\t</tt>
|
484
483
|
# delimiters defined in +AUTHN_PAIR_DELIMITERS+.
|
485
484
|
def raw_params(auth)
|
486
|
-
_raw_params = auth.sub(TOKEN_REGEX,
|
485
|
+
_raw_params = auth.sub(TOKEN_REGEX, "").split(/\s*#{AUTHN_PAIR_DELIMITERS}\s*/)
|
487
486
|
|
488
487
|
if !(_raw_params.first =~ %r{\A#{TOKEN_KEY}})
|
489
488
|
_raw_params[0] = "#{TOKEN_KEY}#{_raw_params.first}"
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'active_support/core_ext/string/strip'
|
2
|
-
|
3
1
|
module ActionController
|
4
2
|
# Handles implicit rendering for a controller action that does not
|
5
3
|
# explicitly respond with +render+, +respond_to+, +redirect+, or +head+.
|
@@ -27,7 +25,6 @@ module ActionController
|
|
27
25
|
# Finally, if we DON'T find a template AND the request isn't a browser page
|
28
26
|
# load, then we implicitly respond with 204 No Content.
|
29
27
|
module ImplicitRender
|
30
|
-
|
31
28
|
# :stopdoc:
|
32
29
|
include BasicImplicitRender
|
33
30
|
|
@@ -62,8 +59,8 @@ module ActionController
|
|
62
59
|
|
63
60
|
def method_for_action(action_name)
|
64
61
|
super || if template_exists?(action_name.to_s, _prefixes)
|
65
|
-
|
66
|
-
|
62
|
+
"default_render"
|
63
|
+
end
|
67
64
|
end
|
68
65
|
|
69
66
|
private
|
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "benchmark"
|
2
|
+
require "abstract_controller/logger"
|
3
3
|
|
4
4
|
module ActionController
|
5
5
|
# Adds instrumentation to several ends in ActionController::Base. It also provides
|
@@ -16,13 +16,13 @@ module ActionController
|
|
16
16
|
|
17
17
|
def process_action(*args)
|
18
18
|
raw_payload = {
|
19
|
-
:
|
20
|
-
:
|
21
|
-
:
|
22
|
-
:
|
23
|
-
:
|
24
|
-
:
|
25
|
-
:
|
19
|
+
controller: self.class.name,
|
20
|
+
action: action_name,
|
21
|
+
params: request.filtered_parameters,
|
22
|
+
headers: request.headers,
|
23
|
+
format: request.format.ref,
|
24
|
+
method: request.request_method,
|
25
|
+
path: request.fullpath
|
26
26
|
}
|
27
27
|
|
28
28
|
ActiveSupport::Notifications.instrument("start_processing.action_controller", raw_payload.dup)
|
@@ -46,9 +46,9 @@ module ActionController
|
|
46
46
|
render_output
|
47
47
|
end
|
48
48
|
|
49
|
-
def send_file(path, options={})
|
49
|
+
def send_file(path, options = {})
|
50
50
|
ActiveSupport::Notifications.instrument("send_file.action_controller",
|
51
|
-
options.merge(:
|
51
|
+
options.merge(path: path)) do
|
52
52
|
super
|
53
53
|
end
|
54
54
|
end
|
@@ -72,7 +72,7 @@ module ActionController
|
|
72
72
|
|
73
73
|
# A hook invoked every time a before callback is halted.
|
74
74
|
def halted_callback_hook(filter)
|
75
|
-
ActiveSupport::Notifications.instrument("halted_callback.action_controller", :
|
75
|
+
ActiveSupport::Notifications.instrument("halted_callback.action_controller", filter: filter)
|
76
76
|
end
|
77
77
|
|
78
78
|
# A hook which allows you to clean up any time, wrongly taken into account in
|
@@ -83,14 +83,14 @@ module ActionController
|
|
83
83
|
# end
|
84
84
|
#
|
85
85
|
# :api: plugin
|
86
|
-
def cleanup_view_runtime
|
86
|
+
def cleanup_view_runtime
|
87
87
|
yield
|
88
88
|
end
|
89
89
|
|
90
90
|
# Every time after an action is processed, this method is invoked
|
91
91
|
# with the payload, so you can add more information.
|
92
92
|
# :api: plugin
|
93
|
-
def append_info_to_payload(payload)
|
93
|
+
def append_info_to_payload(payload)
|
94
94
|
payload[:view_runtime] = view_runtime
|
95
95
|
end
|
96
96
|
|
@@ -1,6 +1,6 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "action_dispatch/http/response"
|
2
|
+
require "delegate"
|
3
|
+
require "active_support/json"
|
4
4
|
|
5
5
|
module ActionController
|
6
6
|
# Mix this module into your controller, and all actions in that controller
|
@@ -84,7 +84,6 @@ module ActionController
|
|
84
84
|
# Note: SSEs are not currently supported by IE. However, they are supported
|
85
85
|
# by Chrome, Firefox, Opera, and Safari.
|
86
86
|
class SSE
|
87
|
-
|
88
87
|
WHITELISTED_OPTIONS = %w( retry event id )
|
89
88
|
|
90
89
|
def initialize(stream, options = {})
|
@@ -220,18 +219,18 @@ module ActionController
|
|
220
219
|
class Response < ActionDispatch::Response #:nodoc: all
|
221
220
|
private
|
222
221
|
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
222
|
+
def before_committed
|
223
|
+
super
|
224
|
+
jar = request.cookie_jar
|
225
|
+
# The response can be committed multiple times
|
226
|
+
jar.write self unless committed?
|
227
|
+
end
|
229
228
|
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
229
|
+
def build_buffer(response, body)
|
230
|
+
buf = Live::Buffer.new response
|
231
|
+
body.each { |part| buf.write part }
|
232
|
+
buf
|
233
|
+
end
|
235
234
|
end
|
236
235
|
|
237
236
|
def process(name)
|
@@ -248,7 +247,7 @@ module ActionController
|
|
248
247
|
|
249
248
|
# Since we're processing the view in a different thread, copy the
|
250
249
|
# thread locals from the main thread to the child thread. :'(
|
251
|
-
locals.each { |k,v| t2[k] = v }
|
250
|
+
locals.each { |k, v| t2[k] = v }
|
252
251
|
|
253
252
|
begin
|
254
253
|
super(name)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "abstract_controller/collector"
|
2
2
|
|
3
3
|
module ActionController #:nodoc:
|
4
4
|
module MimeResponds
|
@@ -280,8 +280,8 @@ module ActionController #:nodoc:
|
|
280
280
|
|
281
281
|
def any(*args, &block)
|
282
282
|
if block_given?
|
283
|
-
if args.any? && args.none?{ |a| a == @variant }
|
284
|
-
args.each{ |v| @variants[v] = block }
|
283
|
+
if args.any? && args.none? { |a| a == @variant }
|
284
|
+
args.each { |v| @variants[v] = block }
|
285
285
|
else
|
286
286
|
@variants[:any] = block
|
287
287
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module ActionController
|
2
|
+
# Specify binary encoding for parameters for a given action.
|
3
|
+
module ParameterEncoding
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
def inherited(klass) # :nodoc:
|
8
|
+
super
|
9
|
+
klass.setup_param_encode
|
10
|
+
end
|
11
|
+
|
12
|
+
def setup_param_encode # :nodoc:
|
13
|
+
@_parameter_encodings = {}
|
14
|
+
end
|
15
|
+
|
16
|
+
def binary_params_for?(action) # :nodoc:
|
17
|
+
@_parameter_encodings[action.to_s]
|
18
|
+
end
|
19
|
+
|
20
|
+
# Specify that a given action's parameters should all be encoded as
|
21
|
+
# ASCII-8BIT (it "skips" the encoding default of UTF-8).
|
22
|
+
#
|
23
|
+
# For example, a controller would use it like this:
|
24
|
+
#
|
25
|
+
# class RepositoryController < ActionController::Base
|
26
|
+
# skip_parameter_encoding :show
|
27
|
+
#
|
28
|
+
# def show
|
29
|
+
# @repo = Repository.find_by_filesystem_path params[:file_path]
|
30
|
+
#
|
31
|
+
# # `repo_name` is guaranteed to be UTF-8, but was ASCII-8BIT, so
|
32
|
+
# # tag it as such
|
33
|
+
# @repo_name = params[:repo_name].force_encoding 'UTF-8'
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# def index
|
37
|
+
# @repositories = Repository.all
|
38
|
+
# end
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# The show action in the above controller would have all parameter values
|
42
|
+
# encoded as ASCII-8BIT. This is useful in the case where an application
|
43
|
+
# must handle data but encoding of the data is unknown, like file system data.
|
44
|
+
def skip_parameter_encoding(action)
|
45
|
+
@_parameter_encodings[action.to_s] = true
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
1
|
+
require "active_support/core_ext/hash/slice"
|
2
|
+
require "active_support/core_ext/hash/except"
|
3
|
+
require "active_support/core_ext/module/anonymous"
|
4
|
+
require "action_dispatch/http/mime_type"
|
5
5
|
|
6
6
|
module ActionController
|
7
7
|
# Wraps the parameters hash into a nested hash. This will allow clients to
|
@@ -71,7 +71,7 @@ module ActionController
|
|
71
71
|
|
72
72
|
EXCLUDE_PARAMETERS = %w(authenticity_token _method utf8)
|
73
73
|
|
74
|
-
require
|
74
|
+
require "mutex_m"
|
75
75
|
|
76
76
|
class Options < Struct.new(:name, :format, :include, :exclude, :klass, :model) # :nodoc:
|
77
77
|
include Mutex_m
|
@@ -128,30 +128,30 @@ module ActionController
|
|
128
128
|
end
|
129
129
|
|
130
130
|
private
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
131
|
+
# Determine the wrapper model from the controller's name. By convention,
|
132
|
+
# this could be done by trying to find the defined model that has the
|
133
|
+
# same singular name as the controller. For example, +UsersController+
|
134
|
+
# will try to find if the +User+ model exists.
|
135
|
+
#
|
136
|
+
# This method also does namespace lookup. Foo::Bar::UsersController will
|
137
|
+
# try to find Foo::Bar::User, Foo::User and finally User.
|
138
|
+
def _default_wrap_model
|
139
|
+
return nil if klass.anonymous?
|
140
|
+
model_name = klass.name.sub(/Controller$/, "").classify
|
141
|
+
|
142
|
+
begin
|
143
|
+
if model_klass = model_name.safe_constantize
|
144
|
+
model_klass
|
145
|
+
else
|
146
|
+
namespaces = model_name.split("::")
|
147
|
+
namespaces.delete_at(-2)
|
148
|
+
break if namespaces.last == model_name
|
149
|
+
model_name = namespaces.join("::")
|
150
|
+
end
|
151
|
+
end until model_klass
|
152
152
|
|
153
|
-
|
154
|
-
|
153
|
+
model_klass
|
154
|
+
end
|
155
155
|
end
|
156
156
|
|
157
157
|
included do
|
@@ -198,14 +198,14 @@ module ActionController
|
|
198
198
|
when Hash
|
199
199
|
options = name_or_model_or_options
|
200
200
|
when false
|
201
|
-
options = options.merge(:
|
201
|
+
options = options.merge(format: [])
|
202
202
|
when Symbol, String
|
203
|
-
options = options.merge(:
|
203
|
+
options = options.merge(name: name_or_model_or_options)
|
204
204
|
else
|
205
205
|
model = name_or_model_or_options
|
206
206
|
end
|
207
207
|
|
208
|
-
opts
|
208
|
+
opts = Options.from_hash _wrapper_options.to_h.slice(:format).merge(options)
|
209
209
|
opts.model = model
|
210
210
|
opts.klass = self
|
211
211
|
|
@@ -279,7 +279,7 @@ module ActionController
|
|
279
279
|
return false unless request.has_content_type?
|
280
280
|
|
281
281
|
ref = request.content_mime_type.ref
|
282
|
-
_wrapper_formats.include?(ref) && _wrapper_key && !request.request_parameters
|
282
|
+
_wrapper_formats.include?(ref) && _wrapper_key && !request.request_parameters[_wrapper_key]
|
283
283
|
end
|
284
284
|
end
|
285
285
|
end
|