actionpack 5.2.4.5 → 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 +111 -384
- 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.rb +2 -2
- 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 +18 -14
- 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 +26 -40
- data/lib/action_controller/metal/strong_parameters.rb +57 -34
- 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 +3 -7
- data/lib/action_dispatch.rb +7 -6
- 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 +14 -14
- 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 -4
- 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/abstract_store.rb +0 -14
- data/lib/action_dispatch/middleware/session/cache_store.rb +6 -11
- data/lib/action_dispatch/middleware/session/cookie_store.rb +11 -27
- data/lib/action_dispatch/middleware/ssl.rb +8 -8
- data/lib/action_dispatch/middleware/stack.rb +2 -2
- 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 -6
- 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 +22 -20
@@ -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'
|
@@ -337,11 +345,17 @@ module ActionController
|
|
337
345
|
@parameters.each_pair do |key, value|
|
338
346
|
yield [key, convert_hashes_to_parameters(key, value)]
|
339
347
|
end
|
340
|
-
|
341
|
-
self
|
342
348
|
end
|
343
349
|
alias_method :each, :each_pair
|
344
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
|
+
|
345
359
|
# Attribute that keeps track of converted arrays, if any, to avoid double
|
346
360
|
# looping in the common use case permit + mass-assignment. Defined in a
|
347
361
|
# method to instantiate it only if needed.
|
@@ -508,7 +522,7 @@ module ActionController
|
|
508
522
|
#
|
509
523
|
# Note that if you use +permit+ in a key that points to a hash,
|
510
524
|
# it won't allow all the hash. You also need to specify which
|
511
|
-
# attributes inside the hash should be
|
525
|
+
# attributes inside the hash should be permitted.
|
512
526
|
#
|
513
527
|
# params = ActionController::Parameters.new({
|
514
528
|
# person: {
|
@@ -585,20 +599,18 @@ module ActionController
|
|
585
599
|
)
|
586
600
|
end
|
587
601
|
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
@parameters.dig(*keys)
|
601
|
-
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)
|
602
614
|
end
|
603
615
|
|
604
616
|
# Returns a new <tt>ActionController::Parameters</tt> instance that
|
@@ -798,9 +810,7 @@ module ActionController
|
|
798
810
|
protected
|
799
811
|
attr_reader :parameters
|
800
812
|
|
801
|
-
|
802
|
-
@permitted = new_permitted
|
803
|
-
end
|
813
|
+
attr_writer :permitted
|
804
814
|
|
805
815
|
def fields_for_style?
|
806
816
|
@parameters.all? { |k, v| k =~ /\A-?\d+\z/ && (v.is_a?(Hash) || v.is_a?(Parameters)) }
|
@@ -911,15 +921,28 @@ module ActionController
|
|
911
921
|
PERMITTED_SCALAR_TYPES.any? { |type| value.is_a?(type) }
|
912
922
|
end
|
913
923
|
|
914
|
-
|
915
|
-
|
916
|
-
|
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]
|
917
939
|
end
|
918
940
|
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
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])
|
923
946
|
end
|
924
947
|
end
|
925
948
|
|
@@ -1004,8 +1027,8 @@ module ActionController
|
|
1004
1027
|
#
|
1005
1028
|
# It provides an interface for protecting attributes from end-user
|
1006
1029
|
# assignment. This makes Action Controller parameters forbidden
|
1007
|
-
# to be used in Active Model mass assignment until they have been
|
1008
|
-
#
|
1030
|
+
# to be used in Active Model mass assignment until they have been explicitly
|
1031
|
+
# enumerated.
|
1009
1032
|
#
|
1010
1033
|
# In addition, parameters can be marked as required and flow through a
|
1011
1034
|
# predefined raise/rescue flow to end up as a <tt>400 Bad Request</tt> with no
|
@@ -1041,7 +1064,7 @@ module ActionController
|
|
1041
1064
|
# end
|
1042
1065
|
#
|
1043
1066
|
# In order to use <tt>accepts_nested_attributes_for</tt> with Strong \Parameters, you
|
1044
|
-
# will need to specify which nested attributes should be
|
1067
|
+
# will need to specify which nested attributes should be permitted. You might want
|
1045
1068
|
# to allow +:id+ and +:_destroy+, see ActiveRecord::NestedAttributes for more information.
|
1046
1069
|
#
|
1047
1070
|
# class Person
|
@@ -1059,7 +1082,7 @@ module ActionController
|
|
1059
1082
|
# private
|
1060
1083
|
#
|
1061
1084
|
# def person_params
|
1062
|
-
# # It's mandatory to specify the nested attributes that should be
|
1085
|
+
# # It's mandatory to specify the nested attributes that should be permitted.
|
1063
1086
|
# # If you use `permit` with just the key that points to the nested attributes hash,
|
1064
1087
|
# # it will return an empty hash.
|
1065
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
|
@@ -460,7 +457,6 @@ module ActionController
|
|
460
457
|
def process(action, method: "GET", params: nil, session: nil, body: nil, flash: {}, format: nil, xhr: false, as: nil)
|
461
458
|
check_required_ivars
|
462
459
|
|
463
|
-
action = action.to_s.dup
|
464
460
|
http_method = method.to_s.upcase
|
465
461
|
|
466
462
|
@html_document = nil
|
@@ -492,11 +488,11 @@ module ActionController
|
|
492
488
|
parameters[:format] = format
|
493
489
|
end
|
494
490
|
|
495
|
-
generated_extras = @routes.generate_extras(parameters.merge(controller: controller_class_name, action: action))
|
491
|
+
generated_extras = @routes.generate_extras(parameters.merge(controller: controller_class_name, action: action.to_s))
|
496
492
|
generated_path = generated_path(generated_extras)
|
497
493
|
query_string_keys = query_parameter_names(generated_extras)
|
498
494
|
|
499
|
-
@request.assign_parameters(@routes, controller_class_name, action, parameters, generated_path, query_string_keys)
|
495
|
+
@request.assign_parameters(@routes, controller_class_name, action.to_s, parameters, generated_path, query_string_keys)
|
500
496
|
|
501
497
|
@request.session.update(session) if session
|
502
498
|
@request.flash.update(flash || {})
|
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
|
@@ -83,11 +85,10 @@ module ActionDispatch
|
|
83
85
|
end
|
84
86
|
|
85
87
|
module Session
|
86
|
-
autoload :AbstractStore,
|
87
|
-
autoload :
|
88
|
-
autoload :
|
89
|
-
autoload :
|
90
|
-
autoload :CacheStore, "action_dispatch/middleware/session/cache_store"
|
88
|
+
autoload :AbstractStore, "action_dispatch/middleware/session/abstract_store"
|
89
|
+
autoload :CookieStore, "action_dispatch/middleware/session/cookie_store"
|
90
|
+
autoload :MemCacheStore, "action_dispatch/middleware/session/mem_cache_store"
|
91
|
+
autoload :CacheStore, "action_dispatch/middleware/session/cache_store"
|
91
92
|
end
|
92
93
|
|
93
94
|
mattr_accessor :test_app
|
@@ -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
|
|