actionpack 7.0.4.3 → 7.0.8.6
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.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +117 -1
- data/README.rdoc +2 -2
- data/lib/abstract_controller/helpers.rb +15 -11
- data/lib/abstract_controller/rendering.rb +9 -11
- data/lib/abstract_controller/translation.rb +25 -3
- data/lib/action_controller/api.rb +1 -1
- data/lib/action_controller/metal/basic_implicit_render.rb +3 -1
- data/lib/action_controller/metal/conditional_get.rb +121 -123
- data/lib/action_controller/metal/content_security_policy.rb +4 -4
- data/lib/action_controller/metal/data_streaming.rb +18 -18
- data/lib/action_controller/metal/etag_with_flash.rb +1 -1
- data/lib/action_controller/metal/head.rb +1 -1
- data/lib/action_controller/metal/http_authentication.rb +2 -1
- data/lib/action_controller/metal/live.rb +1 -1
- data/lib/action_controller/metal/permissions_policy.rb +1 -1
- data/lib/action_controller/metal/redirecting.rb +20 -3
- data/lib/action_controller/metal/renderers.rb +2 -2
- data/lib/action_controller/metal/rendering.rb +114 -2
- data/lib/action_controller/metal/request_forgery_protection.rb +5 -3
- data/lib/action_controller/metal/rescue.rb +4 -3
- data/lib/action_controller/metal/streaming.rb +1 -1
- data/lib/action_controller/metal/strong_parameters.rb +40 -63
- data/lib/action_controller/metal/url_for.rb +2 -4
- data/lib/action_controller/railtie.rb +2 -1
- data/lib/action_controller/renderer.rb +1 -20
- data/lib/action_dispatch/http/cache.rb +7 -7
- data/lib/action_dispatch/http/content_security_policy.rb +5 -1
- data/lib/action_dispatch/http/filter_parameters.rb +13 -28
- data/lib/action_dispatch/http/headers.rb +1 -1
- data/lib/action_dispatch/http/permissions_policy.rb +0 -7
- data/lib/action_dispatch/http/request.rb +15 -16
- data/lib/action_dispatch/http/response.rb +0 -4
- data/lib/action_dispatch/http/upload.rb +13 -2
- data/lib/action_dispatch/middleware/cookies.rb +6 -6
- data/lib/action_dispatch/middleware/host_authorization.rb +12 -5
- data/lib/action_dispatch/middleware/remote_ip.rb +4 -4
- data/lib/action_dispatch/middleware/request_id.rb +2 -2
- data/lib/action_dispatch/middleware/show_exceptions.rb +10 -7
- data/lib/action_dispatch/middleware/static.rb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +7 -3
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +5 -3
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +17 -8
- data/lib/action_dispatch/routing/mapper.rb +23 -0
- data/lib/action_dispatch/routing/url_for.rb +21 -21
- data/lib/action_dispatch/system_testing/browser.rb +1 -1
- data/lib/action_dispatch/system_testing/driver.rb +1 -1
- data/lib/action_dispatch/testing/assertions/response.rb +1 -1
- data/lib/action_pack/gem_version.rb +2 -2
- metadata +17 -17
|
@@ -24,12 +24,124 @@ module ActionController
|
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
+
# Renders a template and assigns the result to +self.response_body+.
|
|
28
|
+
#
|
|
29
|
+
# If no rendering mode option is specified, the template will be derived
|
|
30
|
+
# from the first argument.
|
|
31
|
+
#
|
|
32
|
+
# render "posts/show"
|
|
33
|
+
# # => renders app/views/posts/show.html.erb
|
|
34
|
+
#
|
|
35
|
+
# # In a PostsController action...
|
|
36
|
+
# render :show
|
|
37
|
+
# # => renders app/views/posts/show.html.erb
|
|
38
|
+
#
|
|
39
|
+
# If the first argument responds to +render_in+, the template will be
|
|
40
|
+
# rendered by calling +render_in+ with the current view context.
|
|
41
|
+
#
|
|
42
|
+
# ==== \Rendering Mode
|
|
43
|
+
#
|
|
44
|
+
# [+:partial+]
|
|
45
|
+
# See ActionView::PartialRenderer for details.
|
|
46
|
+
#
|
|
47
|
+
# render partial: "posts/form", locals: { post: Post.new }
|
|
48
|
+
# # => renders app/views/posts/_form.html.erb
|
|
49
|
+
#
|
|
50
|
+
# [+:file+]
|
|
51
|
+
# Renders the contents of a file. This option should <b>not</b> be used
|
|
52
|
+
# with unsanitized user input.
|
|
53
|
+
#
|
|
54
|
+
# render file: "/path/to/some/file"
|
|
55
|
+
# # => renders /path/to/some/file
|
|
56
|
+
#
|
|
57
|
+
# [+:inline+]
|
|
58
|
+
# Renders an ERB template string.
|
|
59
|
+
#
|
|
60
|
+
# @name = "World"
|
|
61
|
+
# render inline: "<h1>Hello, <%= @name %>!</h1>"
|
|
62
|
+
# # => renders "<h1>Hello, World!</h1>"
|
|
63
|
+
#
|
|
64
|
+
# [+:body+]
|
|
65
|
+
# Renders the provided text, and sets the content type as +text/plain+.
|
|
66
|
+
#
|
|
67
|
+
# render body: "Hello, World!"
|
|
68
|
+
# # => renders "Hello, World!"
|
|
69
|
+
#
|
|
70
|
+
# [+:plain+]
|
|
71
|
+
# Renders the provided text, and sets the content type as +text/plain+.
|
|
72
|
+
#
|
|
73
|
+
# render plain: "Hello, World!"
|
|
74
|
+
# # => renders "Hello, World!"
|
|
75
|
+
#
|
|
76
|
+
# [+:html+]
|
|
77
|
+
# Renders the provided HTML string, and sets the content type as +text/html+.
|
|
78
|
+
# If the string is not +html_safe?+, performs HTML escaping on the string
|
|
79
|
+
# before rendering.
|
|
80
|
+
#
|
|
81
|
+
# render html: "<h1>Hello, World!</h1>".html_safe
|
|
82
|
+
# # => renders "<h1>Hello, World!</h1>"
|
|
83
|
+
#
|
|
84
|
+
# render html: "<h1>Hello, World!</h1>"
|
|
85
|
+
# # => renders "<h1>Hello, World!</h1>"
|
|
86
|
+
#
|
|
87
|
+
# [+:json+]
|
|
88
|
+
# Renders the provided object as JSON, and sets the content type as
|
|
89
|
+
# +application/json+. If the object is not a string, it will be converted
|
|
90
|
+
# to JSON by calling +to_json+.
|
|
91
|
+
#
|
|
92
|
+
# render json: { hello: "world" }
|
|
93
|
+
# # => renders "{\"hello\":\"world\"}"
|
|
94
|
+
#
|
|
95
|
+
# By default, when a rendering mode is specified, no layout template is
|
|
96
|
+
# rendered.
|
|
97
|
+
#
|
|
98
|
+
# ==== Options
|
|
99
|
+
#
|
|
100
|
+
# [+:assigns+]
|
|
101
|
+
# Hash of instance variable assignments for the template.
|
|
102
|
+
#
|
|
103
|
+
# render inline: "<h1>Hello, <%= @name %>!</h1>", assigns: { name: "World" }
|
|
104
|
+
# # => renders "<h1>Hello, World!</h1>"
|
|
105
|
+
#
|
|
106
|
+
# [+:locals+]
|
|
107
|
+
# Hash of local variable assignments for the template.
|
|
108
|
+
#
|
|
109
|
+
# render inline: "<h1>Hello, <%= name %>!</h1>", locals: { name: "World" }
|
|
110
|
+
# # => renders "<h1>Hello, World!</h1>"
|
|
111
|
+
#
|
|
112
|
+
# [+:layout+]
|
|
113
|
+
# The layout template to render. Can also be +false+ or +true+ to disable
|
|
114
|
+
# or (re)enable the default layout template.
|
|
115
|
+
#
|
|
116
|
+
# render "posts/show", layout: "holiday"
|
|
117
|
+
# # => renders app/views/posts/show.html.erb with the app/views/layouts/holiday.html.erb layout
|
|
118
|
+
#
|
|
119
|
+
# render "posts/show", layout: false
|
|
120
|
+
# # => renders app/views/posts/show.html.erb with no layout
|
|
121
|
+
#
|
|
122
|
+
# render inline: "<h1>Hello, World!</h1>", layout: true
|
|
123
|
+
# # => renders "<h1>Hello, World!</h1>" with the default layout
|
|
124
|
+
#
|
|
125
|
+
# [+:status+]
|
|
126
|
+
# The HTTP status code to send with the response. Can be specified as a
|
|
127
|
+
# number or as the status name in Symbol form. Defaults to 200.
|
|
128
|
+
#
|
|
129
|
+
# render "posts/new", status: 422
|
|
130
|
+
# # => renders app/views/posts/new.html.erb with HTTP status code 422
|
|
131
|
+
#
|
|
132
|
+
# render "posts/new", status: :unprocessable_entity
|
|
133
|
+
# # => renders app/views/posts/new.html.erb with HTTP status code 422
|
|
134
|
+
#
|
|
135
|
+
#--
|
|
27
136
|
# Check for double render errors and set the content_type after rendering.
|
|
28
|
-
def render(*args)
|
|
137
|
+
def render(*args)
|
|
29
138
|
raise ::AbstractController::DoubleRenderError if response_body
|
|
30
139
|
super
|
|
31
140
|
end
|
|
32
141
|
|
|
142
|
+
# Similar to #render, but only returns the rendered template as a string,
|
|
143
|
+
# instead of setting +self.response_body+.
|
|
144
|
+
#--
|
|
33
145
|
# Override render_to_string because body can now be set to a Rack body.
|
|
34
146
|
def render_to_string(*)
|
|
35
147
|
result = super
|
|
@@ -42,7 +154,7 @@ module ActionController
|
|
|
42
154
|
end
|
|
43
155
|
end
|
|
44
156
|
|
|
45
|
-
def render_to_body(options = {})
|
|
157
|
+
def render_to_body(options = {}) # :nodoc:
|
|
46
158
|
super || _render_in_priorities(options) || " "
|
|
47
159
|
end
|
|
48
160
|
|
|
@@ -118,9 +118,11 @@ module ActionController # :nodoc:
|
|
|
118
118
|
# protect_from_forgery except: :index
|
|
119
119
|
# end
|
|
120
120
|
#
|
|
121
|
-
# You can disable forgery protection on controller
|
|
121
|
+
# You can disable forgery protection on a controller using skip_forgery_protection:
|
|
122
122
|
#
|
|
123
|
-
#
|
|
123
|
+
# class BarController < ApplicationController
|
|
124
|
+
# skip_forgery_protection
|
|
125
|
+
# end
|
|
124
126
|
#
|
|
125
127
|
# Valid Options:
|
|
126
128
|
#
|
|
@@ -334,7 +336,7 @@ module ActionController # :nodoc:
|
|
|
334
336
|
#
|
|
335
337
|
# * Is it a GET or HEAD request? GETs should be safe and idempotent
|
|
336
338
|
# * Does the form_authenticity_token match the given token value from the params?
|
|
337
|
-
# * Does the X-CSRF-Token header match the form_authenticity_token?
|
|
339
|
+
# * Does the +X-CSRF-Token+ header match the form_authenticity_token?
|
|
338
340
|
def verified_request? # :doc:
|
|
339
341
|
!protect_against_forgery? || request.get? || request.head? ||
|
|
340
342
|
(valid_request_origin? && any_authenticity_token_valid?)
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module ActionController # :nodoc:
|
|
4
|
-
# This module is responsible for providing
|
|
5
|
-
#
|
|
6
|
-
#
|
|
4
|
+
# This module is responsible for providing
|
|
5
|
+
# {rescue_from}[rdoc-ref:ActiveSupport::Rescuable::ClassMethods#rescue_from]
|
|
6
|
+
# to controllers, wrapping actions to handle configured errors, and
|
|
7
|
+
# configuring when detailed exceptions must be shown.
|
|
7
8
|
module Rescue
|
|
8
9
|
extend ActiveSupport::Concern
|
|
9
10
|
include ActiveSupport::Rescuable
|
|
@@ -147,7 +147,7 @@ module ActionController # :nodoc:
|
|
|
147
147
|
# needs to inject contents in the HTML body.
|
|
148
148
|
#
|
|
149
149
|
# Also <tt>Rack::Cache</tt> won't work with streaming as it does not support
|
|
150
|
-
# streaming bodies yet. Whenever streaming Cache-Control is automatically
|
|
150
|
+
# streaming bodies yet. Whenever streaming +Cache-Control+ is automatically
|
|
151
151
|
# set to "no-cache".
|
|
152
152
|
#
|
|
153
153
|
# == Errors
|
|
@@ -97,7 +97,7 @@ module ActionController
|
|
|
97
97
|
# * +false+ to take no action.
|
|
98
98
|
# * <tt>:log</tt> to emit an <tt>ActiveSupport::Notifications.instrument</tt> event on the
|
|
99
99
|
# <tt>unpermitted_parameters.action_controller</tt> topic and log at the DEBUG level.
|
|
100
|
-
# * <tt>:raise</tt> to raise
|
|
100
|
+
# * <tt>:raise</tt> to raise an ActionController::UnpermittedParameters exception.
|
|
101
101
|
#
|
|
102
102
|
# Examples:
|
|
103
103
|
#
|
|
@@ -146,7 +146,7 @@ module ActionController
|
|
|
146
146
|
# :method: each_key
|
|
147
147
|
#
|
|
148
148
|
# :call-seq:
|
|
149
|
-
# each_key()
|
|
149
|
+
# each_key(&block)
|
|
150
150
|
#
|
|
151
151
|
# Calls block once for each key in the parameters, passing the key.
|
|
152
152
|
# If no block is given, an enumerator is returned instead.
|
|
@@ -159,14 +159,6 @@ module ActionController
|
|
|
159
159
|
#
|
|
160
160
|
# Returns true if the parameters have no key/value pairs.
|
|
161
161
|
|
|
162
|
-
##
|
|
163
|
-
# :method: has_key?
|
|
164
|
-
#
|
|
165
|
-
# :call-seq:
|
|
166
|
-
# has_key?(key)
|
|
167
|
-
#
|
|
168
|
-
# Returns true if the given key is present in the parameters.
|
|
169
|
-
|
|
170
162
|
##
|
|
171
163
|
# :method: has_value?
|
|
172
164
|
#
|
|
@@ -183,22 +175,6 @@ module ActionController
|
|
|
183
175
|
#
|
|
184
176
|
# Returns true if the given key is present in the parameters.
|
|
185
177
|
|
|
186
|
-
##
|
|
187
|
-
# :method: key?
|
|
188
|
-
#
|
|
189
|
-
# :call-seq:
|
|
190
|
-
# key?(key)
|
|
191
|
-
#
|
|
192
|
-
# Returns true if the given key is present in the parameters.
|
|
193
|
-
|
|
194
|
-
##
|
|
195
|
-
# :method: member?
|
|
196
|
-
#
|
|
197
|
-
# :call-seq:
|
|
198
|
-
# member?(key)
|
|
199
|
-
#
|
|
200
|
-
# Returns true if the given key is present in the parameters.
|
|
201
|
-
|
|
202
178
|
##
|
|
203
179
|
# :method: keys
|
|
204
180
|
#
|
|
@@ -230,9 +206,13 @@ module ActionController
|
|
|
230
206
|
# values()
|
|
231
207
|
#
|
|
232
208
|
# Returns a new array of the values of the parameters.
|
|
233
|
-
delegate :keys, :
|
|
209
|
+
delegate :keys, :values, :has_value?, :value?, :empty?, :include?,
|
|
234
210
|
:as_json, :to_s, :each_key, to: :@parameters
|
|
235
211
|
|
|
212
|
+
alias_method :has_key?, :include?
|
|
213
|
+
alias_method :key?, :include?
|
|
214
|
+
alias_method :member?, :include?
|
|
215
|
+
|
|
236
216
|
# By default, never raise an UnpermittedParameters exception if these
|
|
237
217
|
# params are present. The default includes both 'controller' and 'action'
|
|
238
218
|
# because they are added by Rails and should be of no concern. One way
|
|
@@ -248,7 +228,7 @@ module ActionController
|
|
|
248
228
|
end
|
|
249
229
|
end
|
|
250
230
|
|
|
251
|
-
# Returns a new
|
|
231
|
+
# Returns a new <tt>ActionController::Parameters</tt> instance.
|
|
252
232
|
# Also, sets the +permitted+ attribute to the default value of
|
|
253
233
|
# <tt>ActionController::Parameters.permit_all_parameters</tt>.
|
|
254
234
|
#
|
|
@@ -290,7 +270,7 @@ module ActionController
|
|
|
290
270
|
[self.class, @parameters, @permitted].hash
|
|
291
271
|
end
|
|
292
272
|
|
|
293
|
-
# Returns a safe
|
|
273
|
+
# Returns a safe ActiveSupport::HashWithIndifferentAccess
|
|
294
274
|
# representation of the parameters with all unpermitted keys removed.
|
|
295
275
|
#
|
|
296
276
|
# params = ActionController::Parameters.new({
|
|
@@ -350,18 +330,15 @@ module ActionController
|
|
|
350
330
|
# safe_params.to_query("user")
|
|
351
331
|
# # => "user%5Bname%5D=David&user%5Bnationality%5D=Danish"
|
|
352
332
|
#
|
|
353
|
-
# The string pairs "key=value" that conform the query string
|
|
333
|
+
# The string pairs <tt>"key=value"</tt> that conform the query string
|
|
354
334
|
# are sorted lexicographically in ascending order.
|
|
355
|
-
#
|
|
356
|
-
# This method is also aliased as +to_param+.
|
|
357
335
|
def to_query(*args)
|
|
358
336
|
to_h.to_query(*args)
|
|
359
337
|
end
|
|
360
338
|
alias_method :to_param, :to_query
|
|
361
339
|
|
|
362
|
-
# Returns an unsafe, unfiltered
|
|
363
|
-
#
|
|
364
|
-
# parameters.
|
|
340
|
+
# Returns an unsafe, unfiltered ActiveSupport::HashWithIndifferentAccess
|
|
341
|
+
# representation of the parameters.
|
|
365
342
|
#
|
|
366
343
|
# params = ActionController::Parameters.new({
|
|
367
344
|
# name: "Senjougahara Hitagi",
|
|
@@ -401,7 +378,7 @@ module ActionController
|
|
|
401
378
|
# looping in the common use case permit + mass-assignment. Defined in a
|
|
402
379
|
# method to instantiate it only if needed.
|
|
403
380
|
#
|
|
404
|
-
# Testing membership still loops, but it's going to be faster than our own
|
|
381
|
+
# \Testing membership still loops, but it's going to be faster than our own
|
|
405
382
|
# loop that converts values. Also, we are not going to build a new array
|
|
406
383
|
# object per fetch.
|
|
407
384
|
def converted_arrays
|
|
@@ -449,7 +426,7 @@ module ActionController
|
|
|
449
426
|
# ActionController::Parameters.new(person: { name: "Francesco" }).require(:person)
|
|
450
427
|
# # => #<ActionController::Parameters {"name"=>"Francesco"} permitted: false>
|
|
451
428
|
#
|
|
452
|
-
# Otherwise raises
|
|
429
|
+
# Otherwise raises ActionController::ParameterMissing:
|
|
453
430
|
#
|
|
454
431
|
# ActionController::Parameters.new.require(:person)
|
|
455
432
|
# # ActionController::ParameterMissing: param is missing or the value is empty: person
|
|
@@ -501,7 +478,6 @@ module ActionController
|
|
|
501
478
|
end
|
|
502
479
|
end
|
|
503
480
|
|
|
504
|
-
# Alias of #require.
|
|
505
481
|
alias :required :require
|
|
506
482
|
|
|
507
483
|
# Returns a new <tt>ActionController::Parameters</tt> instance that
|
|
@@ -523,7 +499,7 @@ module ActionController
|
|
|
523
499
|
# +:name+ passes if it is a key of +params+ whose associated value is of type
|
|
524
500
|
# +String+, +Symbol+, +NilClass+, +Numeric+, +TrueClass+, +FalseClass+,
|
|
525
501
|
# +Date+, +Time+, +DateTime+, +StringIO+, +IO+,
|
|
526
|
-
#
|
|
502
|
+
# ActionDispatch::Http::UploadedFile or +Rack::Test::UploadedFile+.
|
|
527
503
|
# Otherwise, the key +:name+ is filtered out.
|
|
528
504
|
#
|
|
529
505
|
# You may declare that the parameter should be an array of permitted scalars
|
|
@@ -645,16 +621,16 @@ module ActionController
|
|
|
645
621
|
end
|
|
646
622
|
|
|
647
623
|
# Assigns a value to a given +key+. The given key may still get filtered out
|
|
648
|
-
# when
|
|
624
|
+
# when #permit is called.
|
|
649
625
|
def []=(key, value)
|
|
650
626
|
@parameters[key] = value
|
|
651
627
|
end
|
|
652
628
|
|
|
653
629
|
# Returns a parameter for the given +key+. If the +key+
|
|
654
630
|
# can't be found, there are several options: With no other arguments,
|
|
655
|
-
# it will raise an
|
|
631
|
+
# it will raise an ActionController::ParameterMissing error;
|
|
656
632
|
# if a second argument is given, then that is returned (converted to an
|
|
657
|
-
# instance of ActionController::Parameters if possible); if a block
|
|
633
|
+
# instance of +ActionController::Parameters+ if possible); if a block
|
|
658
634
|
# is given, then that will be run and its result returned.
|
|
659
635
|
#
|
|
660
636
|
# params = ActionController::Parameters.new(person: { name: "Francesco" })
|
|
@@ -700,7 +676,7 @@ module ActionController
|
|
|
700
676
|
new_instance_with_inherited_permitted_status(@parameters.slice(*keys))
|
|
701
677
|
end
|
|
702
678
|
|
|
703
|
-
# Returns current <tt>ActionController::Parameters</tt> instance which
|
|
679
|
+
# Returns the current <tt>ActionController::Parameters</tt> instance which
|
|
704
680
|
# contains only the given +keys+.
|
|
705
681
|
def slice!(*keys)
|
|
706
682
|
@parameters.slice!(*keys)
|
|
@@ -726,7 +702,7 @@ module ActionController
|
|
|
726
702
|
new_instance_with_inherited_permitted_status(@parameters.extract!(*keys))
|
|
727
703
|
end
|
|
728
704
|
|
|
729
|
-
# Returns a new <tt>ActionController::Parameters</tt> with the results of
|
|
705
|
+
# Returns a new <tt>ActionController::Parameters</tt> instance with the results of
|
|
730
706
|
# running +block+ once for every value. The keys are unchanged.
|
|
731
707
|
#
|
|
732
708
|
# params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
|
|
@@ -773,9 +749,9 @@ module ActionController
|
|
|
773
749
|
)
|
|
774
750
|
end
|
|
775
751
|
|
|
776
|
-
# Returns the <tt>ActionController::Parameters</tt> instance
|
|
777
|
-
# This includes the keys from the root hash and from all
|
|
778
|
-
# The values are unchanged.
|
|
752
|
+
# Returns the same <tt>ActionController::Parameters</tt> instance with
|
|
753
|
+
# changed keys. This includes the keys from the root hash and from all
|
|
754
|
+
# nested hashes and arrays. The values are unchanged.
|
|
779
755
|
def deep_transform_keys!(&block)
|
|
780
756
|
@parameters.deep_transform_keys!(&block)
|
|
781
757
|
self
|
|
@@ -783,13 +759,13 @@ module ActionController
|
|
|
783
759
|
|
|
784
760
|
# Deletes a key-value pair from +Parameters+ and returns the value. If
|
|
785
761
|
# +key+ is not found, returns +nil+ (or, with optional code block, yields
|
|
786
|
-
# +key+ and returns the result).
|
|
787
|
-
# corresponding +ActionController::Parameters+ object.
|
|
762
|
+
# +key+ and returns the result). This method is similar to #extract!, which
|
|
763
|
+
# returns the corresponding +ActionController::Parameters+ object.
|
|
788
764
|
def delete(key, &block)
|
|
789
765
|
convert_value_to_parameters(@parameters.delete(key, &block))
|
|
790
766
|
end
|
|
791
767
|
|
|
792
|
-
# Returns a new
|
|
768
|
+
# Returns a new <tt>ActionController::Parameters</tt> instance with only
|
|
793
769
|
# items that the block evaluates to true.
|
|
794
770
|
def select(&block)
|
|
795
771
|
new_instance_with_inherited_permitted_status(@parameters.select(&block))
|
|
@@ -802,7 +778,7 @@ module ActionController
|
|
|
802
778
|
end
|
|
803
779
|
alias_method :keep_if, :select!
|
|
804
780
|
|
|
805
|
-
# Returns a new
|
|
781
|
+
# Returns a new <tt>ActionController::Parameters</tt> instance with items
|
|
806
782
|
# that the block evaluates to true removed.
|
|
807
783
|
def reject(&block)
|
|
808
784
|
new_instance_with_inherited_permitted_status(@parameters.reject(&block))
|
|
@@ -815,7 +791,7 @@ module ActionController
|
|
|
815
791
|
end
|
|
816
792
|
alias_method :delete_if, :reject!
|
|
817
793
|
|
|
818
|
-
# Returns a new
|
|
794
|
+
# Returns a new <tt>ActionController::Parameters</tt> instance with +nil+ values removed.
|
|
819
795
|
def compact
|
|
820
796
|
new_instance_with_inherited_permitted_status(@parameters.compact)
|
|
821
797
|
end
|
|
@@ -825,7 +801,7 @@ module ActionController
|
|
|
825
801
|
self if @parameters.compact!
|
|
826
802
|
end
|
|
827
803
|
|
|
828
|
-
# Returns a new
|
|
804
|
+
# Returns a new <tt>ActionController::Parameters</tt> instance without the blank values.
|
|
829
805
|
# Uses Object#blank? for determining if a value is blank.
|
|
830
806
|
def compact_blank
|
|
831
807
|
reject { |_k, v| v.blank? }
|
|
@@ -843,7 +819,7 @@ module ActionController
|
|
|
843
819
|
convert_value_to_parameters(@parameters.values_at(*keys))
|
|
844
820
|
end
|
|
845
821
|
|
|
846
|
-
# Returns a new <tt>ActionController::Parameters</tt> with all keys from
|
|
822
|
+
# Returns a new <tt>ActionController::Parameters</tt> instance with all keys from
|
|
847
823
|
# +other_hash+ merged into current hash.
|
|
848
824
|
def merge(other_hash)
|
|
849
825
|
new_instance_with_inherited_permitted_status(
|
|
@@ -851,15 +827,15 @@ module ActionController
|
|
|
851
827
|
)
|
|
852
828
|
end
|
|
853
829
|
|
|
854
|
-
# Returns current <tt>ActionController::Parameters</tt> instance with
|
|
830
|
+
# Returns the current <tt>ActionController::Parameters</tt> instance with
|
|
855
831
|
# +other_hash+ merged into current hash.
|
|
856
832
|
def merge!(other_hash)
|
|
857
833
|
@parameters.merge!(other_hash.to_h)
|
|
858
834
|
self
|
|
859
835
|
end
|
|
860
836
|
|
|
861
|
-
# Returns a new <tt>ActionController::Parameters</tt> with all keys
|
|
862
|
-
# current hash merged into +other_hash+.
|
|
837
|
+
# Returns a new <tt>ActionController::Parameters</tt> instance with all keys
|
|
838
|
+
# from current hash merged into +other_hash+.
|
|
863
839
|
def reverse_merge(other_hash)
|
|
864
840
|
new_instance_with_inherited_permitted_status(
|
|
865
841
|
other_hash.to_h.merge(@parameters)
|
|
@@ -867,7 +843,7 @@ module ActionController
|
|
|
867
843
|
end
|
|
868
844
|
alias_method :with_defaults, :reverse_merge
|
|
869
845
|
|
|
870
|
-
# Returns current <tt>ActionController::Parameters</tt> instance with
|
|
846
|
+
# Returns the current <tt>ActionController::Parameters</tt> instance with
|
|
871
847
|
# current hash merged into +other_hash+.
|
|
872
848
|
def reverse_merge!(other_hash)
|
|
873
849
|
@parameters.merge!(other_hash.to_h) { |key, left, right| left }
|
|
@@ -917,7 +893,7 @@ module ActionController
|
|
|
917
893
|
coder.map = { "parameters" => @parameters, "permitted" => @permitted }
|
|
918
894
|
end
|
|
919
895
|
|
|
920
|
-
# Returns duplicate
|
|
896
|
+
# Returns a duplicate +ActionController::Parameters+ instance with the same permitted parameters.
|
|
921
897
|
def deep_dup
|
|
922
898
|
self.class.new(@parameters.deep_dup, @logging_context).tap do |duplicate|
|
|
923
899
|
duplicate.permitted = @permitted
|
|
@@ -1024,10 +1000,11 @@ module ActionController
|
|
|
1024
1000
|
# This is a list of permitted scalar types that includes the ones
|
|
1025
1001
|
# supported in XML and JSON requests.
|
|
1026
1002
|
#
|
|
1027
|
-
# This list is in particular used to filter ordinary requests, String goes
|
|
1003
|
+
# This list is in particular used to filter ordinary requests, \String goes
|
|
1028
1004
|
# as first element to quickly short-circuit the common case.
|
|
1029
1005
|
#
|
|
1030
|
-
# If you modify this collection please update the
|
|
1006
|
+
# If you modify this collection please update the one in the #permit doc
|
|
1007
|
+
# as well.
|
|
1031
1008
|
PERMITTED_SCALAR_TYPES = [
|
|
1032
1009
|
String,
|
|
1033
1010
|
Symbol,
|
|
@@ -1083,8 +1060,8 @@ module ActionController
|
|
|
1083
1060
|
value.is_a?(Array) || value.is_a?(Parameters)
|
|
1084
1061
|
end
|
|
1085
1062
|
|
|
1086
|
-
EMPTY_ARRAY = []
|
|
1087
|
-
EMPTY_HASH = {}
|
|
1063
|
+
EMPTY_ARRAY = [] # :nodoc:
|
|
1064
|
+
EMPTY_HASH = {} # :nodoc:
|
|
1088
1065
|
def hash_filter(params, filter)
|
|
1089
1066
|
filter = filter.with_indifferent_access
|
|
1090
1067
|
|
|
@@ -6,10 +6,8 @@ module ActionController
|
|
|
6
6
|
#
|
|
7
7
|
# In addition to AbstractController::UrlFor, this module accesses the HTTP layer to define
|
|
8
8
|
# URL options like the +host+. In order to do so, this module requires the host class
|
|
9
|
-
# to implement +env+ which needs to be Rack-compatible and +request+
|
|
10
|
-
#
|
|
11
|
-
# that responds to the +host+, +optional_port+, +protocol+, and
|
|
12
|
-
# +symbolized_path_parameter+ methods.
|
|
9
|
+
# to implement +env+ which needs to be Rack-compatible, and +request+ which
|
|
10
|
+
# returns an ActionDispatch::Request instance.
|
|
13
11
|
#
|
|
14
12
|
# class RootUrl
|
|
15
13
|
# include ActionController::UrlFor
|
|
@@ -111,7 +111,8 @@ module ActionController
|
|
|
111
111
|
app.config.action_controller.log_query_tags_around_actions
|
|
112
112
|
|
|
113
113
|
if query_logs_tags_enabled
|
|
114
|
-
app.config.active_record.query_log_tags
|
|
114
|
+
app.config.active_record.query_log_tags |= [:controller] unless app.config.active_record.query_log_tags.include?(:namespaced_controller)
|
|
115
|
+
app.config.active_record.query_log_tags |= [:action]
|
|
115
116
|
|
|
116
117
|
ActiveSupport.on_load(:active_record) do
|
|
117
118
|
ActiveRecord::QueryLogs.taggings.merge!(
|
|
@@ -68,26 +68,7 @@ module ActionController
|
|
|
68
68
|
@env = normalize_keys defaults, env
|
|
69
69
|
end
|
|
70
70
|
|
|
71
|
-
#
|
|
72
|
-
#
|
|
73
|
-
# The primary options are:
|
|
74
|
-
# * <tt>:partial</tt> - See ActionView::PartialRenderer for details.
|
|
75
|
-
# * <tt>:file</tt> - Renders an explicit template file. Add <tt>:locals</tt> to pass in, if so desired.
|
|
76
|
-
# It shouldn’t be used directly with unsanitized user input due to lack of validation.
|
|
77
|
-
# * <tt>:inline</tt> - Renders an ERB template string.
|
|
78
|
-
# * <tt>:plain</tt> - Renders provided text and sets the content type as <tt>text/plain</tt>.
|
|
79
|
-
# * <tt>:html</tt> - Renders the provided HTML safe string, otherwise
|
|
80
|
-
# performs HTML escape on the string first. Sets the content type as <tt>text/html</tt>.
|
|
81
|
-
# * <tt>:json</tt> - Renders the provided hash or object in JSON. You don't
|
|
82
|
-
# need to call <tt>.to_json</tt> on the object you want to render.
|
|
83
|
-
# * <tt>:body</tt> - Renders provided text and sets content type of <tt>text/plain</tt>.
|
|
84
|
-
#
|
|
85
|
-
# If no <tt>options</tt> hash is passed or if <tt>:update</tt> is specified, then:
|
|
86
|
-
#
|
|
87
|
-
# If an object responding to +render_in+ is passed, +render_in+ is called on the object,
|
|
88
|
-
# passing in the current view context.
|
|
89
|
-
#
|
|
90
|
-
# Otherwise, a partial is rendered using the second parameter as the locals hash.
|
|
71
|
+
# Renders a template to a string, just like ActionController::Rendering#render_to_string.
|
|
91
72
|
def render(*args)
|
|
92
73
|
raise "missing controller" unless controller
|
|
93
74
|
|
|
@@ -32,8 +32,8 @@ module ActionDispatch
|
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
# Check response freshness (Last-Modified and ETag) against request
|
|
36
|
-
# If-Modified-Since and If-None-Match conditions. If both headers are
|
|
35
|
+
# Check response freshness (+Last-Modified+ and ETag) against request
|
|
36
|
+
# +If-Modified-Since+ and +If-None-Match+ conditions. If both headers are
|
|
37
37
|
# supplied, both must match, or the request is not considered fresh.
|
|
38
38
|
def fresh?(response)
|
|
39
39
|
last_modified = if_modified_since
|
|
@@ -81,8 +81,8 @@ module ActionDispatch
|
|
|
81
81
|
|
|
82
82
|
# This method sets a weak ETag validator on the response so browsers
|
|
83
83
|
# and proxies may cache the response, keyed on the ETag. On subsequent
|
|
84
|
-
# requests, the If-None-Match header is set to the cached ETag. If it
|
|
85
|
-
# matches the current ETag, we can return a 304 Not Modified response
|
|
84
|
+
# requests, the +If-None-Match+ header is set to the cached ETag. If it
|
|
85
|
+
# matches the current ETag, we can return a <tt>304 Not Modified</tt> response
|
|
86
86
|
# with no body, letting the browser or proxy know that their cache is
|
|
87
87
|
# current. Big savings in request time and network bandwidth.
|
|
88
88
|
#
|
|
@@ -92,7 +92,7 @@ module ActionDispatch
|
|
|
92
92
|
# is viewing.
|
|
93
93
|
#
|
|
94
94
|
# Strong ETags are considered byte-for-byte identical. They allow a
|
|
95
|
-
# browser or proxy cache to support Range requests, useful for paging
|
|
95
|
+
# browser or proxy cache to support +Range+ requests, useful for paging
|
|
96
96
|
# through a PDF file or scrubbing through a video. Some CDNs only
|
|
97
97
|
# support strong ETags and will ignore weak ETags entirely.
|
|
98
98
|
#
|
|
@@ -112,12 +112,12 @@ module ActionDispatch
|
|
|
112
112
|
|
|
113
113
|
def etag?; etag; end
|
|
114
114
|
|
|
115
|
-
# True if an ETag is set and it's a weak validator (preceded with W
|
|
115
|
+
# True if an ETag is set, and it's a weak validator (preceded with <tt>W/</tt>).
|
|
116
116
|
def weak_etag?
|
|
117
117
|
etag? && etag.start_with?('W/"')
|
|
118
118
|
end
|
|
119
119
|
|
|
120
|
-
# True if an ETag is set and it isn't a weak validator (not preceded with W
|
|
120
|
+
# True if an ETag is set, and it isn't a weak validator (not preceded with <tt>W/</tt>).
|
|
121
121
|
def strong_etag?
|
|
122
122
|
etag? && !weak_etag?
|
|
123
123
|
end
|
|
@@ -33,7 +33,11 @@ module ActionDispatch # :nodoc:
|
|
|
33
33
|
|
|
34
34
|
def call(env)
|
|
35
35
|
request = ActionDispatch::Request.new env
|
|
36
|
-
|
|
36
|
+
status, headers, _ = response = @app.call(env)
|
|
37
|
+
|
|
38
|
+
# Returning CSP headers with a 304 Not Modified is harmful, since nonces in the new
|
|
39
|
+
# CSP headers might not match nonces in the cached HTML.
|
|
40
|
+
return response if status == 304
|
|
37
41
|
|
|
38
42
|
return response if policy_present?(headers)
|
|
39
43
|
|
|
@@ -4,33 +4,13 @@ require "active_support/parameter_filter"
|
|
|
4
4
|
|
|
5
5
|
module ActionDispatch
|
|
6
6
|
module Http
|
|
7
|
-
# Allows you to specify sensitive
|
|
8
|
-
# the request log
|
|
9
|
-
# sub-hashes of the params hash to filter. Filtering only certain sub-keys
|
|
10
|
-
# from a hash is possible by using the dot notation: 'credit_card.number'.
|
|
11
|
-
# If a block is given, each key and value of the params hash and all
|
|
12
|
-
# sub-hashes are passed to it, where the value or the key can be replaced using
|
|
13
|
-
# String#replace or similar methods.
|
|
14
|
-
#
|
|
15
|
-
# env["action_dispatch.parameter_filter"] = [:password]
|
|
16
|
-
# => replaces the value to all keys matching /password/i with "[FILTERED]"
|
|
7
|
+
# Allows you to specify sensitive query string and POST parameters to filter
|
|
8
|
+
# from the request log.
|
|
17
9
|
#
|
|
10
|
+
# # Replaces values with "[FILTERED]" for keys that match /foo|bar/i.
|
|
18
11
|
# env["action_dispatch.parameter_filter"] = [:foo, "bar"]
|
|
19
|
-
# => replaces the value to all keys matching /foo|bar/i with "[FILTERED]"
|
|
20
|
-
#
|
|
21
|
-
# env["action_dispatch.parameter_filter"] = [ /\Apin\z/i, /\Apin_/i ]
|
|
22
|
-
# => replaces the value for the exact (case-insensitive) key 'pin' and all
|
|
23
|
-
# (case-insensitive) keys beginning with 'pin_', with "[FILTERED]"
|
|
24
|
-
# Does not match keys with 'pin' as a substring, such as 'shipping_id'.
|
|
25
|
-
#
|
|
26
|
-
# env["action_dispatch.parameter_filter"] = [ "credit_card.code" ]
|
|
27
|
-
# => replaces { credit_card: {code: "xxxx"} } with "[FILTERED]", does not
|
|
28
|
-
# change { file: { code: "xxxx"} }
|
|
29
12
|
#
|
|
30
|
-
#
|
|
31
|
-
# v.reverse! if k.match?(/secret/i)
|
|
32
|
-
# end
|
|
33
|
-
# => reverses the value to all keys matching /secret/i
|
|
13
|
+
# For more information about filter behavior, see ActiveSupport::ParameterFilter.
|
|
34
14
|
module FilterParameters
|
|
35
15
|
ENV_MATCH = [/RAW_POST_DATA/, "rack.request.form_vars"] # :nodoc:
|
|
36
16
|
NULL_PARAM_FILTER = ActiveSupport::ParameterFilter.new # :nodoc:
|
|
@@ -78,12 +58,17 @@ module ActionDispatch
|
|
|
78
58
|
ActiveSupport::ParameterFilter.new(filters)
|
|
79
59
|
end
|
|
80
60
|
|
|
81
|
-
KV_RE = "[^&;=]+"
|
|
82
|
-
PAIR_RE = %r{(#{KV_RE})=(#{KV_RE})}
|
|
83
61
|
def filtered_query_string # :doc:
|
|
84
|
-
query_string.
|
|
85
|
-
|
|
62
|
+
parts = query_string.split(/([&;])/)
|
|
63
|
+
filtered_parts = parts.map do |part|
|
|
64
|
+
if part.include?("=")
|
|
65
|
+
key, value = part.split("=", 2)
|
|
66
|
+
parameter_filter.filter(key => value).first.join("=")
|
|
67
|
+
else
|
|
68
|
+
part
|
|
69
|
+
end
|
|
86
70
|
end
|
|
71
|
+
filtered_parts.join("")
|
|
87
72
|
end
|
|
88
73
|
end
|
|
89
74
|
end
|
|
@@ -65,7 +65,7 @@ module ActionDispatch
|
|
|
65
65
|
@req.set_header env_name(key), value
|
|
66
66
|
end
|
|
67
67
|
|
|
68
|
-
# Add a value to a multivalued header like Vary or Accept-Encoding
|
|
68
|
+
# Add a value to a multivalued header like +Vary+ or +Accept-Encoding+.
|
|
69
69
|
def add(key, value)
|
|
70
70
|
@req.add_header env_name(key), value
|
|
71
71
|
end
|