actionpack 5.2.3.rc1 → 6.0.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 +4 -4
- data/CHANGELOG.md +124 -337
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/lib/abstract_controller/base.rb +4 -2
- data/lib/abstract_controller/caching/fragments.rb +6 -21
- data/lib/abstract_controller/callbacks.rb +12 -0
- data/lib/abstract_controller/collector.rb +1 -1
- data/lib/abstract_controller/helpers.rb +2 -2
- data/lib/abstract_controller/railties/routes_helpers.rb +1 -1
- data/lib/action_controller.rb +1 -0
- data/lib/action_controller/api.rb +2 -1
- data/lib/action_controller/base.rb +2 -7
- data/lib/action_controller/caching.rb +1 -1
- data/lib/action_controller/log_subscriber.rb +8 -5
- data/lib/action_controller/metal/conditional_get.rb +9 -3
- data/lib/action_controller/metal/data_streaming.rb +5 -6
- data/lib/action_controller/metal/default_headers.rb +17 -0
- data/lib/action_controller/metal/exceptions.rb +22 -1
- data/lib/action_controller/metal/flash.rb +5 -5
- data/lib/action_controller/metal/force_ssl.rb +17 -57
- data/lib/action_controller/metal/head.rb +1 -1
- data/lib/action_controller/metal/helpers.rb +1 -2
- data/lib/action_controller/metal/http_authentication.rb +20 -21
- data/lib/action_controller/metal/implicit_render.rb +2 -12
- data/lib/action_controller/metal/instrumentation.rb +3 -5
- data/lib/action_controller/metal/live.rb +28 -26
- data/lib/action_controller/metal/mime_responds.rb +13 -2
- data/lib/action_controller/metal/params_wrapper.rb +16 -12
- data/lib/action_controller/metal/redirecting.rb +32 -11
- data/lib/action_controller/metal/rendering.rb +1 -1
- data/lib/action_controller/metal/request_forgery_protection.rb +22 -11
- data/lib/action_controller/metal/strong_parameters.rb +57 -32
- data/lib/action_controller/metal/url_for.rb +1 -1
- data/lib/action_controller/railties/helpers.rb +1 -1
- data/lib/action_controller/renderer.rb +15 -2
- data/lib/action_controller/test_case.rb +1 -4
- data/lib/action_dispatch.rb +3 -1
- data/lib/action_dispatch/http/cache.rb +14 -10
- data/lib/action_dispatch/http/content_disposition.rb +45 -0
- data/lib/action_dispatch/http/content_security_policy.rb +9 -8
- data/lib/action_dispatch/http/filter_parameters.rb +8 -6
- data/lib/action_dispatch/http/filter_redirect.rb +1 -1
- data/lib/action_dispatch/http/headers.rb +1 -1
- data/lib/action_dispatch/http/mime_negotiation.rb +7 -10
- data/lib/action_dispatch/http/mime_type.rb +1 -5
- data/lib/action_dispatch/http/parameter_filter.rb +5 -79
- data/lib/action_dispatch/http/parameters.rb +13 -3
- data/lib/action_dispatch/http/request.rb +10 -13
- data/lib/action_dispatch/http/response.rb +18 -17
- data/lib/action_dispatch/http/upload.rb +5 -0
- data/lib/action_dispatch/http/url.rb +81 -81
- data/lib/action_dispatch/journey/formatter.rb +1 -1
- data/lib/action_dispatch/journey/nfa/simulator.rb +0 -2
- data/lib/action_dispatch/journey/nodes/node.rb +9 -8
- data/lib/action_dispatch/journey/path/pattern.rb +3 -3
- data/lib/action_dispatch/journey/router.rb +0 -3
- data/lib/action_dispatch/journey/router/utils.rb +10 -10
- data/lib/action_dispatch/journey/scanner.rb +11 -4
- data/lib/action_dispatch/journey/visitors.rb +1 -1
- data/lib/action_dispatch/middleware/callbacks.rb +2 -4
- data/lib/action_dispatch/middleware/cookies.rb +49 -70
- data/lib/action_dispatch/middleware/debug_exceptions.rb +32 -58
- data/lib/action_dispatch/middleware/debug_locks.rb +5 -5
- data/lib/action_dispatch/middleware/debug_view.rb +50 -0
- data/lib/action_dispatch/middleware/exception_wrapper.rb +36 -7
- data/lib/action_dispatch/middleware/flash.rb +1 -1
- data/lib/action_dispatch/middleware/host_authorization.rb +103 -0
- data/lib/action_dispatch/middleware/remote_ip.rb +6 -8
- data/lib/action_dispatch/middleware/request_id.rb +2 -2
- data/lib/action_dispatch/middleware/session/cookie_store.rb +4 -10
- data/lib/action_dispatch/middleware/ssl.rb +8 -8
- data/lib/action_dispatch/middleware/static.rb +5 -6
- data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +4 -2
- data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +45 -35
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +7 -0
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +5 -0
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +20 -2
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +19 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.text.erb +3 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +3 -0
- data/lib/action_dispatch/railtie.rb +1 -0
- data/lib/action_dispatch/request/session.rb +8 -0
- data/lib/action_dispatch/routing.rb +3 -2
- data/lib/action_dispatch/routing/inspector.rb +99 -50
- data/lib/action_dispatch/routing/mapper.rb +36 -29
- data/lib/action_dispatch/routing/polymorphic_routes.rb +3 -4
- data/lib/action_dispatch/routing/route_set.rb +11 -12
- data/lib/action_dispatch/routing/url_for.rb +1 -0
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +3 -3
- data/lib/action_dispatch/testing/assertions/response.rb +2 -3
- data/lib/action_dispatch/testing/assertions/routing.rb +7 -2
- data/lib/action_dispatch/testing/integration.rb +11 -4
- data/lib/action_dispatch/testing/test_process.rb +2 -2
- data/lib/action_dispatch/testing/test_response.rb +4 -32
- data/lib/action_pack.rb +1 -1
- data/lib/action_pack/gem_version.rb +4 -4
- metadata +19 -11
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_support/core_ext/hash/indifferent_access"
|
4
|
-
require "active_support/core_ext/hash/transform_values"
|
5
4
|
require "active_support/core_ext/array/wrap"
|
6
5
|
require "active_support/core_ext/string/filters"
|
7
6
|
require "active_support/core_ext/object/to_query"
|
@@ -59,7 +58,7 @@ module ActionController
|
|
59
58
|
|
60
59
|
# == Action Controller \Parameters
|
61
60
|
#
|
62
|
-
# Allows you to choose which attributes should be
|
61
|
+
# Allows you to choose which attributes should be permitted for mass updating
|
63
62
|
# and thus prevent accidentally exposing that which shouldn't be exposed.
|
64
63
|
# Provides two methods for this purpose: #require and #permit. The former is
|
65
64
|
# used to mark parameters as required. The latter is used to set the parameter
|
@@ -133,6 +132,15 @@ module ActionController
|
|
133
132
|
#
|
134
133
|
# Returns a hash that can be used as the JSON representation for the parameters.
|
135
134
|
|
135
|
+
##
|
136
|
+
# :method: each_key
|
137
|
+
#
|
138
|
+
# :call-seq:
|
139
|
+
# each_key()
|
140
|
+
#
|
141
|
+
# Calls block once for each key in the parameters, passing the key.
|
142
|
+
# If no block is given, an enumerator is returned instead.
|
143
|
+
|
136
144
|
##
|
137
145
|
# :method: empty?
|
138
146
|
#
|
@@ -205,7 +213,7 @@ module ActionController
|
|
205
213
|
#
|
206
214
|
# Returns a new array of the values of the parameters.
|
207
215
|
delegate :keys, :key?, :has_key?, :values, :has_value?, :value?, :empty?, :include?,
|
208
|
-
:as_json, :to_s, to: :@parameters
|
216
|
+
:as_json, :to_s, :each_key, to: :@parameters
|
209
217
|
|
210
218
|
# By default, never raise an UnpermittedParameters exception if these
|
211
219
|
# params are present. The default includes both 'controller' and 'action'
|
@@ -340,6 +348,14 @@ module ActionController
|
|
340
348
|
end
|
341
349
|
alias_method :each, :each_pair
|
342
350
|
|
351
|
+
# Convert all hashes in values into parameters, then yield each value in
|
352
|
+
# the same way as <tt>Hash#each_value</tt>.
|
353
|
+
def each_value(&block)
|
354
|
+
@parameters.each_pair do |key, value|
|
355
|
+
yield convert_hashes_to_parameters(key, value)
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
343
359
|
# Attribute that keeps track of converted arrays, if any, to avoid double
|
344
360
|
# looping in the common use case permit + mass-assignment. Defined in a
|
345
361
|
# method to instantiate it only if needed.
|
@@ -506,7 +522,7 @@ module ActionController
|
|
506
522
|
#
|
507
523
|
# Note that if you use +permit+ in a key that points to a hash,
|
508
524
|
# it won't allow all the hash. You also need to specify which
|
509
|
-
# attributes inside the hash should be
|
525
|
+
# attributes inside the hash should be permitted.
|
510
526
|
#
|
511
527
|
# params = ActionController::Parameters.new({
|
512
528
|
# person: {
|
@@ -583,20 +599,18 @@ module ActionController
|
|
583
599
|
)
|
584
600
|
end
|
585
601
|
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
@parameters.dig(*keys)
|
599
|
-
end
|
602
|
+
# Extracts the nested parameter from the given +keys+ by calling +dig+
|
603
|
+
# at each step. Returns +nil+ if any intermediate step is +nil+.
|
604
|
+
#
|
605
|
+
# params = ActionController::Parameters.new(foo: { bar: { baz: 1 } })
|
606
|
+
# params.dig(:foo, :bar, :baz) # => 1
|
607
|
+
# params.dig(:foo, :zot, :xyz) # => nil
|
608
|
+
#
|
609
|
+
# params2 = ActionController::Parameters.new(foo: [10, 11, 12])
|
610
|
+
# params2.dig(:foo, 1) # => 11
|
611
|
+
def dig(*keys)
|
612
|
+
convert_hashes_to_parameters(keys.first, @parameters[keys.first])
|
613
|
+
@parameters.dig(*keys)
|
600
614
|
end
|
601
615
|
|
602
616
|
# Returns a new <tt>ActionController::Parameters</tt> instance that
|
@@ -796,9 +810,7 @@ module ActionController
|
|
796
810
|
protected
|
797
811
|
attr_reader :parameters
|
798
812
|
|
799
|
-
|
800
|
-
@permitted = new_permitted
|
801
|
-
end
|
813
|
+
attr_writer :permitted
|
802
814
|
|
803
815
|
def fields_for_style?
|
804
816
|
@parameters.all? { |k, v| k =~ /\A-?\d+\z/ && (v.is_a?(Hash) || v.is_a?(Parameters)) }
|
@@ -909,15 +921,28 @@ module ActionController
|
|
909
921
|
PERMITTED_SCALAR_TYPES.any? { |type| value.is_a?(type) }
|
910
922
|
end
|
911
923
|
|
912
|
-
|
913
|
-
|
914
|
-
|
924
|
+
# Adds existing keys to the params if their values are scalar.
|
925
|
+
#
|
926
|
+
# For example:
|
927
|
+
#
|
928
|
+
# puts self.keys #=> ["zipcode(90210i)"]
|
929
|
+
# params = {}
|
930
|
+
#
|
931
|
+
# permitted_scalar_filter(params, "zipcode")
|
932
|
+
#
|
933
|
+
# puts params.keys # => ["zipcode"]
|
934
|
+
def permitted_scalar_filter(params, permitted_key)
|
935
|
+
permitted_key = permitted_key.to_s
|
936
|
+
|
937
|
+
if has_key?(permitted_key) && permitted_scalar?(self[permitted_key])
|
938
|
+
params[permitted_key] = self[permitted_key]
|
915
939
|
end
|
916
940
|
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
941
|
+
each_key do |key|
|
942
|
+
next unless key =~ /\(\d+[if]?\)\z/
|
943
|
+
next unless $~.pre_match == permitted_key
|
944
|
+
|
945
|
+
params[key] = self[key] if permitted_scalar?(self[key])
|
921
946
|
end
|
922
947
|
end
|
923
948
|
|
@@ -1002,8 +1027,8 @@ module ActionController
|
|
1002
1027
|
#
|
1003
1028
|
# It provides an interface for protecting attributes from end-user
|
1004
1029
|
# assignment. This makes Action Controller parameters forbidden
|
1005
|
-
# to be used in Active Model mass assignment until they have been
|
1006
|
-
#
|
1030
|
+
# to be used in Active Model mass assignment until they have been explicitly
|
1031
|
+
# enumerated.
|
1007
1032
|
#
|
1008
1033
|
# In addition, parameters can be marked as required and flow through a
|
1009
1034
|
# predefined raise/rescue flow to end up as a <tt>400 Bad Request</tt> with no
|
@@ -1039,7 +1064,7 @@ module ActionController
|
|
1039
1064
|
# end
|
1040
1065
|
#
|
1041
1066
|
# In order to use <tt>accepts_nested_attributes_for</tt> with Strong \Parameters, you
|
1042
|
-
# will need to specify which nested attributes should be
|
1067
|
+
# will need to specify which nested attributes should be permitted. You might want
|
1043
1068
|
# to allow +:id+ and +:_destroy+, see ActiveRecord::NestedAttributes for more information.
|
1044
1069
|
#
|
1045
1070
|
# class Person
|
@@ -1057,7 +1082,7 @@ module ActionController
|
|
1057
1082
|
# private
|
1058
1083
|
#
|
1059
1084
|
# def person_params
|
1060
|
-
# # It's mandatory to specify the nested attributes that should be
|
1085
|
+
# # It's mandatory to specify the nested attributes that should be permitted.
|
1061
1086
|
# # If you use `permit` with just the key that points to the nested attributes hash,
|
1062
1087
|
# # it will return an empty hash.
|
1063
1088
|
# params.require(:person).permit(:name, :age, pets_attributes: [ :id, :name, :category ])
|
@@ -44,7 +44,7 @@ module ActionController
|
|
44
44
|
options[:original_script_name] = original_script_name
|
45
45
|
else
|
46
46
|
if same_origin
|
47
|
-
options[:script_name] = request.script_name.empty? ? ""
|
47
|
+
options[:script_name] = request.script_name.empty? ? "" : request.script_name.dup
|
48
48
|
else
|
49
49
|
options[:script_name] = script_name
|
50
50
|
end
|
@@ -7,7 +7,7 @@ module ActionController
|
|
7
7
|
super
|
8
8
|
return unless klass.respond_to?(:helpers_path=)
|
9
9
|
|
10
|
-
if namespace = klass.
|
10
|
+
if namespace = klass.module_parents.detect { |m| m.respond_to?(:railtie_helpers_paths) }
|
11
11
|
paths = namespace.railtie_helpers_paths
|
12
12
|
else
|
13
13
|
paths = ActionController::Helpers.helpers_path
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "active_support/core_ext/hash/keys"
|
4
|
-
|
5
3
|
module ActionController
|
6
4
|
# ActionController::Renderer allows you to render arbitrary templates
|
7
5
|
# without requirement of being in controller actions.
|
@@ -71,6 +69,21 @@ module ActionController
|
|
71
69
|
end
|
72
70
|
|
73
71
|
# Render templates with any options from ActionController::Base#render_to_string.
|
72
|
+
#
|
73
|
+
# The primary options are:
|
74
|
+
# * <tt>:partial</tt> - See <tt>ActionView::PartialRenderer</tt> 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 a 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, the default is
|
86
|
+
# to render a partial and use the second parameter as the locals hash.
|
74
87
|
def render(*args)
|
75
88
|
raise "missing controller" unless controller
|
76
89
|
|
@@ -26,7 +26,7 @@ module ActionController
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
-
# ActionController::TestCase will be deprecated and moved to a gem in
|
29
|
+
# ActionController::TestCase will be deprecated and moved to a gem in the future.
|
30
30
|
# Please use ActionDispatch::IntegrationTest going forward.
|
31
31
|
class TestRequest < ActionDispatch::TestRequest #:nodoc:
|
32
32
|
DEFAULT_ENV = ActionDispatch::TestRequest::DEFAULT_ENV.dup
|
@@ -276,9 +276,6 @@ module ActionController
|
|
276
276
|
# after calling +post+. If the various assert methods are not sufficient, then you
|
277
277
|
# may use this object to inspect the HTTP response in detail.
|
278
278
|
#
|
279
|
-
# (Earlier versions of \Rails required each functional test to subclass
|
280
|
-
# Test::Unit::TestCase and define @controller, @request, @response in +setup+.)
|
281
|
-
#
|
282
279
|
# == Controller is automatically inferred
|
283
280
|
#
|
284
281
|
# ActionController::TestCase will automatically infer the controller under test
|
data/lib/action_dispatch.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#--
|
4
|
-
# Copyright (c) 2004-
|
4
|
+
# Copyright (c) 2004-2019 David Heinemeier Hansson
|
5
5
|
#
|
6
6
|
# Permission is hereby granted, free of charge, to any person obtaining
|
7
7
|
# a copy of this software and associated documentation files (the
|
@@ -49,11 +49,13 @@ module ActionDispatch
|
|
49
49
|
end
|
50
50
|
|
51
51
|
autoload_under "middleware" do
|
52
|
+
autoload :HostAuthorization
|
52
53
|
autoload :RequestId
|
53
54
|
autoload :Callbacks
|
54
55
|
autoload :Cookies
|
55
56
|
autoload :DebugExceptions
|
56
57
|
autoload :DebugLocks
|
58
|
+
autoload :DebugView
|
57
59
|
autoload :ExceptionWrapper
|
58
60
|
autoload :Executor
|
59
61
|
autoload :Flash
|
@@ -4,8 +4,8 @@ module ActionDispatch
|
|
4
4
|
module Http
|
5
5
|
module Cache
|
6
6
|
module Request
|
7
|
-
HTTP_IF_MODIFIED_SINCE = "HTTP_IF_MODIFIED_SINCE"
|
8
|
-
HTTP_IF_NONE_MATCH = "HTTP_IF_NONE_MATCH"
|
7
|
+
HTTP_IF_MODIFIED_SINCE = "HTTP_IF_MODIFIED_SINCE"
|
8
|
+
HTTP_IF_NONE_MATCH = "HTTP_IF_NONE_MATCH"
|
9
9
|
|
10
10
|
def if_modified_since
|
11
11
|
if since = get_header(HTTP_IF_MODIFIED_SINCE)
|
@@ -124,8 +124,8 @@ module ActionDispatch
|
|
124
124
|
|
125
125
|
private
|
126
126
|
|
127
|
-
DATE = "Date"
|
128
|
-
LAST_MODIFIED = "Last-Modified"
|
127
|
+
DATE = "Date"
|
128
|
+
LAST_MODIFIED = "Last-Modified"
|
129
129
|
SPECIAL_KEYS = Set.new(%w[extras no-cache max-age public private must-revalidate])
|
130
130
|
|
131
131
|
def generate_weak_etag(validators)
|
@@ -166,11 +166,11 @@ module ActionDispatch
|
|
166
166
|
@cache_control = cache_control_headers
|
167
167
|
end
|
168
168
|
|
169
|
-
DEFAULT_CACHE_CONTROL = "max-age=0, private, must-revalidate"
|
170
|
-
NO_CACHE = "no-cache"
|
171
|
-
PUBLIC = "public"
|
172
|
-
PRIVATE = "private"
|
173
|
-
MUST_REVALIDATE = "must-revalidate"
|
169
|
+
DEFAULT_CACHE_CONTROL = "max-age=0, private, must-revalidate"
|
170
|
+
NO_CACHE = "no-cache"
|
171
|
+
PUBLIC = "public"
|
172
|
+
PRIVATE = "private"
|
173
|
+
MUST_REVALIDATE = "must-revalidate"
|
174
174
|
|
175
175
|
def handle_conditional_get!
|
176
176
|
# Normally default cache control setting is handled by ETag
|
@@ -204,13 +204,17 @@ module ActionDispatch
|
|
204
204
|
|
205
205
|
self._cache_control = options.join(", ")
|
206
206
|
else
|
207
|
-
extras
|
207
|
+
extras = control[:extras]
|
208
208
|
max_age = control[:max_age]
|
209
|
+
stale_while_revalidate = control[:stale_while_revalidate]
|
210
|
+
stale_if_error = control[:stale_if_error]
|
209
211
|
|
210
212
|
options = []
|
211
213
|
options << "max-age=#{max_age.to_i}" if max_age
|
212
214
|
options << (control[:public] ? PUBLIC : PRIVATE)
|
213
215
|
options << MUST_REVALIDATE if control[:must_revalidate]
|
216
|
+
options << "stale-while-revalidate=#{stale_while_revalidate.to_i}" if stale_while_revalidate
|
217
|
+
options << "stale-if-error=#{stale_if_error.to_i}" if stale_if_error
|
214
218
|
options.concat(extras) if extras
|
215
219
|
|
216
220
|
self._cache_control = options.join(", ")
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionDispatch
|
4
|
+
module Http
|
5
|
+
class ContentDisposition # :nodoc:
|
6
|
+
def self.format(disposition:, filename:)
|
7
|
+
new(disposition: disposition, filename: filename).to_s
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :disposition, :filename
|
11
|
+
|
12
|
+
def initialize(disposition:, filename:)
|
13
|
+
@disposition = disposition
|
14
|
+
@filename = filename
|
15
|
+
end
|
16
|
+
|
17
|
+
TRADITIONAL_ESCAPED_CHAR = /[^ A-Za-z0-9!#$+.^_`|~-]/
|
18
|
+
|
19
|
+
def ascii_filename
|
20
|
+
'filename="' + percent_escape(I18n.transliterate(filename), TRADITIONAL_ESCAPED_CHAR) + '"'
|
21
|
+
end
|
22
|
+
|
23
|
+
RFC_5987_ESCAPED_CHAR = /[^A-Za-z0-9!#$&+.^_`|~-]/
|
24
|
+
|
25
|
+
def utf8_filename
|
26
|
+
"filename*=UTF-8''" + percent_escape(filename, RFC_5987_ESCAPED_CHAR)
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_s
|
30
|
+
if filename
|
31
|
+
"#{disposition}; #{ascii_filename}; #{utf8_filename}"
|
32
|
+
else
|
33
|
+
"#{disposition}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
def percent_escape(string, pattern)
|
39
|
+
string.gsub(pattern) do |char|
|
40
|
+
char.bytes.map { |byte| "%%%02X" % byte }.join
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -5,9 +5,9 @@ require "active_support/core_ext/object/deep_dup"
|
|
5
5
|
module ActionDispatch #:nodoc:
|
6
6
|
class ContentSecurityPolicy
|
7
7
|
class Middleware
|
8
|
-
CONTENT_TYPE = "Content-Type"
|
9
|
-
POLICY = "Content-Security-Policy"
|
10
|
-
POLICY_REPORT_ONLY = "Content-Security-Policy-Report-Only"
|
8
|
+
CONTENT_TYPE = "Content-Type"
|
9
|
+
POLICY = "Content-Security-Policy"
|
10
|
+
POLICY_REPORT_ONLY = "Content-Security-Policy-Report-Only"
|
11
11
|
|
12
12
|
def initialize(app)
|
13
13
|
@app = app
|
@@ -51,10 +51,10 @@ module ActionDispatch #:nodoc:
|
|
51
51
|
end
|
52
52
|
|
53
53
|
module Request
|
54
|
-
POLICY = "action_dispatch.content_security_policy"
|
55
|
-
POLICY_REPORT_ONLY = "action_dispatch.content_security_policy_report_only"
|
56
|
-
NONCE_GENERATOR = "action_dispatch.content_security_policy_nonce_generator"
|
57
|
-
NONCE = "action_dispatch.content_security_policy_nonce"
|
54
|
+
POLICY = "action_dispatch.content_security_policy"
|
55
|
+
POLICY_REPORT_ONLY = "action_dispatch.content_security_policy_report_only"
|
56
|
+
NONCE_GENERATOR = "action_dispatch.content_security_policy_nonce_generator"
|
57
|
+
NONCE = "action_dispatch.content_security_policy_nonce"
|
58
58
|
|
59
59
|
def content_security_policy
|
60
60
|
get_header(POLICY)
|
@@ -127,12 +127,13 @@ module ActionDispatch #:nodoc:
|
|
127
127
|
manifest_src: "manifest-src",
|
128
128
|
media_src: "media-src",
|
129
129
|
object_src: "object-src",
|
130
|
+
prefetch_src: "prefetch-src",
|
130
131
|
script_src: "script-src",
|
131
132
|
style_src: "style-src",
|
132
133
|
worker_src: "worker-src"
|
133
134
|
}.freeze
|
134
135
|
|
135
|
-
NONCE_DIRECTIVES = %w[script-src].freeze
|
136
|
+
NONCE_DIRECTIVES = %w[script-src style-src].freeze
|
136
137
|
|
137
138
|
private_constant :MAPPINGS, :DIRECTIVES, :NONCE_DIRECTIVES
|
138
139
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "
|
3
|
+
require "active_support/parameter_filter"
|
4
4
|
|
5
5
|
module ActionDispatch
|
6
6
|
module Http
|
@@ -9,8 +9,8 @@ module ActionDispatch
|
|
9
9
|
# sub-hashes of the params hash to filter. Filtering only certain sub-keys
|
10
10
|
# from a hash is possible by using the dot notation: 'credit_card.number'.
|
11
11
|
# If a block is given, each key and value of the params hash and all
|
12
|
-
# sub-hashes
|
13
|
-
# String#replace or similar
|
12
|
+
# sub-hashes are passed to it, where the value or the key can be replaced using
|
13
|
+
# String#replace or similar methods.
|
14
14
|
#
|
15
15
|
# env["action_dispatch.parameter_filter"] = [:password]
|
16
16
|
# => replaces the value to all keys matching /password/i with "[FILTERED]"
|
@@ -28,8 +28,8 @@ module ActionDispatch
|
|
28
28
|
# => reverses the value to all keys matching /secret/i
|
29
29
|
module FilterParameters
|
30
30
|
ENV_MATCH = [/RAW_POST_DATA/, "rack.request.form_vars"] # :nodoc:
|
31
|
-
NULL_PARAM_FILTER = ParameterFilter.new # :nodoc:
|
32
|
-
NULL_ENV_FILTER = ParameterFilter.new ENV_MATCH # :nodoc:
|
31
|
+
NULL_PARAM_FILTER = ActiveSupport::ParameterFilter.new # :nodoc:
|
32
|
+
NULL_ENV_FILTER = ActiveSupport::ParameterFilter.new ENV_MATCH # :nodoc:
|
33
33
|
|
34
34
|
def initialize
|
35
35
|
super
|
@@ -41,6 +41,8 @@ module ActionDispatch
|
|
41
41
|
# Returns a hash of parameters with all sensitive data replaced.
|
42
42
|
def filtered_parameters
|
43
43
|
@filtered_parameters ||= parameter_filter.filter(parameters)
|
44
|
+
rescue ActionDispatch::Http::Parameters::ParseError
|
45
|
+
@filtered_parameters = {}
|
44
46
|
end
|
45
47
|
|
46
48
|
# Returns a hash of request.env with all sensitive data replaced.
|
@@ -69,7 +71,7 @@ module ActionDispatch
|
|
69
71
|
end
|
70
72
|
|
71
73
|
def parameter_filter_for(filters) # :doc:
|
72
|
-
ParameterFilter.new(filters)
|
74
|
+
ActiveSupport::ParameterFilter.new(filters)
|
73
75
|
end
|
74
76
|
|
75
77
|
KV_RE = "[^&;=]+"
|