actionpack 4.2.11.1 → 6.0.3
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +212 -526
- data/MIT-LICENSE +1 -1
- data/README.rdoc +9 -9
- data/lib/abstract_controller/asset_paths.rb +2 -0
- data/lib/abstract_controller/base.rb +47 -50
- data/lib/{action_controller → abstract_controller}/caching/fragments.rb +64 -17
- data/lib/abstract_controller/caching.rb +66 -0
- data/lib/abstract_controller/callbacks.rb +59 -31
- data/lib/abstract_controller/collector.rb +9 -13
- data/lib/abstract_controller/error.rb +6 -0
- data/lib/abstract_controller/helpers.rb +31 -30
- data/lib/abstract_controller/logger.rb +2 -0
- data/lib/abstract_controller/railties/routes_helpers.rb +5 -3
- data/lib/abstract_controller/rendering.rb +42 -41
- data/lib/abstract_controller/translation.rb +12 -9
- data/lib/abstract_controller/url_for.rb +2 -0
- data/lib/abstract_controller.rb +12 -5
- data/lib/action_controller/api/api_rendering.rb +16 -0
- data/lib/action_controller/api.rb +150 -0
- data/lib/action_controller/base.rb +25 -22
- data/lib/action_controller/caching.rb +13 -57
- data/lib/action_controller/form_builder.rb +50 -0
- data/lib/action_controller/log_subscriber.rb +15 -17
- data/lib/action_controller/metal/basic_implicit_render.rb +13 -0
- data/lib/action_controller/metal/conditional_get.rb +124 -44
- data/lib/action_controller/metal/content_security_policy.rb +51 -0
- data/lib/action_controller/metal/cookies.rb +3 -3
- data/lib/action_controller/metal/data_streaming.rb +29 -49
- data/lib/action_controller/metal/default_headers.rb +17 -0
- data/lib/action_controller/metal/etag_with_flash.rb +18 -0
- data/lib/action_controller/metal/etag_with_template_digest.rb +20 -13
- data/lib/action_controller/metal/exceptions.rb +30 -15
- data/lib/action_controller/metal/flash.rb +9 -8
- data/lib/action_controller/metal/force_ssl.rb +23 -62
- data/lib/action_controller/metal/head.rb +22 -20
- data/lib/action_controller/metal/helpers.rb +26 -17
- data/lib/action_controller/metal/http_authentication.rb +76 -70
- data/lib/action_controller/metal/implicit_render.rb +53 -9
- data/lib/action_controller/metal/instrumentation.rb +22 -27
- data/lib/action_controller/metal/live.rb +101 -119
- data/lib/action_controller/metal/mime_responds.rb +44 -46
- data/lib/action_controller/metal/parameter_encoding.rb +51 -0
- data/lib/action_controller/metal/params_wrapper.rb +74 -63
- data/lib/action_controller/metal/redirecting.rb +53 -32
- data/lib/action_controller/metal/renderers.rb +87 -44
- data/lib/action_controller/metal/rendering.rb +72 -51
- data/lib/action_controller/metal/request_forgery_protection.rb +217 -97
- data/lib/action_controller/metal/rescue.rb +9 -16
- data/lib/action_controller/metal/streaming.rb +12 -11
- data/lib/action_controller/metal/strong_parameters.rb +619 -183
- data/lib/action_controller/metal/testing.rb +2 -17
- data/lib/action_controller/metal/url_for.rb +19 -10
- data/lib/action_controller/metal.rb +104 -87
- data/lib/action_controller/railtie.rb +28 -10
- data/lib/action_controller/railties/helpers.rb +3 -1
- data/lib/action_controller/renderer.rb +130 -0
- data/lib/action_controller/template_assertions.rb +11 -0
- data/lib/action_controller/test_case.rb +286 -418
- data/lib/action_controller.rb +33 -21
- data/lib/action_dispatch/http/cache.rb +100 -51
- data/lib/action_dispatch/http/content_disposition.rb +45 -0
- data/lib/action_dispatch/http/content_security_policy.rb +282 -0
- data/lib/action_dispatch/http/filter_parameters.rb +31 -24
- data/lib/action_dispatch/http/filter_redirect.rb +10 -12
- data/lib/action_dispatch/http/headers.rb +54 -22
- data/lib/action_dispatch/http/mime_negotiation.rb +61 -45
- data/lib/action_dispatch/http/mime_type.rb +141 -122
- data/lib/action_dispatch/http/mime_types.rb +20 -6
- data/lib/action_dispatch/http/parameter_filter.rb +8 -68
- data/lib/action_dispatch/http/parameters.rb +107 -39
- data/lib/action_dispatch/http/rack_cache.rb +2 -0
- data/lib/action_dispatch/http/request.rb +204 -117
- data/lib/action_dispatch/http/response.rb +248 -114
- data/lib/action_dispatch/http/upload.rb +21 -7
- data/lib/action_dispatch/http/url.rb +181 -100
- data/lib/action_dispatch/journey/formatter.rb +56 -34
- data/lib/action_dispatch/journey/gtg/builder.rb +7 -6
- data/lib/action_dispatch/journey/gtg/simulator.rb +3 -9
- data/lib/action_dispatch/journey/gtg/transition_table.rb +17 -17
- data/lib/action_dispatch/journey/nfa/builder.rb +5 -3
- data/lib/action_dispatch/journey/nfa/dot.rb +13 -13
- data/lib/action_dispatch/journey/nfa/simulator.rb +3 -3
- data/lib/action_dispatch/journey/nfa/transition_table.rb +5 -49
- data/lib/action_dispatch/journey/nodes/node.rb +25 -12
- data/lib/action_dispatch/journey/parser.rb +23 -22
- data/lib/action_dispatch/journey/parser.y +3 -2
- data/lib/action_dispatch/journey/parser_extras.rb +12 -4
- data/lib/action_dispatch/journey/path/pattern.rb +55 -46
- data/lib/action_dispatch/journey/route.rb +107 -28
- data/lib/action_dispatch/journey/router/utils.rb +25 -16
- data/lib/action_dispatch/journey/router.rb +35 -27
- data/lib/action_dispatch/journey/routes.rb +17 -17
- data/lib/action_dispatch/journey/scanner.rb +26 -17
- data/lib/action_dispatch/journey/visitors.rb +98 -54
- data/lib/action_dispatch/journey.rb +7 -5
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +39 -0
- data/lib/action_dispatch/middleware/callbacks.rb +3 -6
- data/lib/action_dispatch/middleware/cookies.rb +292 -203
- data/lib/action_dispatch/middleware/debug_exceptions.rb +142 -63
- data/lib/action_dispatch/middleware/debug_locks.rb +124 -0
- data/lib/action_dispatch/middleware/debug_view.rb +66 -0
- data/lib/action_dispatch/middleware/exception_wrapper.rb +102 -70
- data/lib/action_dispatch/middleware/executor.rb +21 -0
- data/lib/action_dispatch/middleware/flash.rb +78 -54
- data/lib/action_dispatch/middleware/host_authorization.rb +101 -0
- data/lib/action_dispatch/middleware/public_exceptions.rb +32 -27
- data/lib/action_dispatch/middleware/reloader.rb +5 -91
- data/lib/action_dispatch/middleware/remote_ip.rb +48 -41
- data/lib/action_dispatch/middleware/request_id.rb +17 -9
- data/lib/action_dispatch/middleware/session/abstract_store.rb +41 -26
- data/lib/action_dispatch/middleware/session/cache_store.rb +24 -14
- data/lib/action_dispatch/middleware/session/cookie_store.rb +72 -73
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -2
- data/lib/action_dispatch/middleware/show_exceptions.rb +26 -23
- data/lib/action_dispatch/middleware/ssl.rb +113 -35
- data/lib/action_dispatch/middleware/stack.rb +64 -41
- data/lib/action_dispatch/middleware/static.rb +57 -51
- data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +13 -0
- data/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb +0 -0
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +4 -14
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/{_source.erb → _source.html.erb} +4 -2
- data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
- 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 +26 -4
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +24 -0
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +15 -0
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +5 -0
- 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 +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +67 -64
- data/lib/action_dispatch/railtie.rb +26 -13
- data/lib/action_dispatch/request/session.rb +114 -60
- data/lib/action_dispatch/request/utils.rb +67 -24
- data/lib/action_dispatch/routing/endpoint.rb +9 -2
- data/lib/action_dispatch/routing/inspector.rb +140 -102
- data/lib/action_dispatch/routing/mapper.rb +762 -455
- data/lib/action_dispatch/routing/polymorphic_routes.rb +161 -142
- data/lib/action_dispatch/routing/redirection.rb +36 -26
- data/lib/action_dispatch/routing/route_set.rb +322 -298
- data/lib/action_dispatch/routing/routes_proxy.rb +32 -5
- data/lib/action_dispatch/routing/url_for.rb +65 -26
- data/lib/action_dispatch/routing.rb +36 -36
- data/lib/action_dispatch/system_test_case.rb +185 -0
- data/lib/action_dispatch/system_testing/browser.rb +80 -0
- data/lib/action_dispatch/system_testing/driver.rb +68 -0
- data/lib/action_dispatch/system_testing/server.rb +31 -0
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +97 -0
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +32 -0
- data/lib/action_dispatch/testing/assertion_response.rb +46 -0
- data/lib/action_dispatch/testing/assertions/response.rb +44 -20
- data/lib/action_dispatch/testing/assertions/routing.rb +44 -28
- data/lib/action_dispatch/testing/assertions.rb +6 -4
- data/lib/action_dispatch/testing/integration.rb +375 -215
- data/lib/action_dispatch/testing/request_encoder.rb +55 -0
- data/lib/action_dispatch/testing/test_process.rb +28 -22
- data/lib/action_dispatch/testing/test_request.rb +27 -34
- data/lib/action_dispatch/testing/test_response.rb +11 -11
- data/lib/action_dispatch.rb +33 -20
- data/lib/action_pack/gem_version.rb +6 -4
- data/lib/action_pack/version.rb +3 -1
- data/lib/action_pack.rb +4 -2
- metadata +71 -40
- data/lib/action_controller/metal/hide_actions.rb +0 -40
- data/lib/action_controller/metal/rack_delegation.rb +0 -32
- data/lib/action_controller/middleware.rb +0 -39
- data/lib/action_controller/model_naming.rb +0 -12
- data/lib/action_dispatch/journey/backwards.rb +0 -5
- data/lib/action_dispatch/journey/router/strexp.rb +0 -27
- data/lib/action_dispatch/middleware/params_parser.rb +0 -60
- data/lib/action_dispatch/testing/assertions/dom.rb +0 -3
- data/lib/action_dispatch/testing/assertions/selector.rb +0 -3
- data/lib/action_dispatch/testing/assertions/tag.rb +0 -3
@@ -1,4 +1,7 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "action_controller/metal/exceptions"
|
4
|
+
require "action_dispatch/http/content_disposition"
|
2
5
|
|
3
6
|
module ActionController #:nodoc:
|
4
7
|
# Methods for sending arbitrary data and for streaming files to the browser,
|
@@ -8,10 +11,10 @@ module ActionController #:nodoc:
|
|
8
11
|
|
9
12
|
include ActionController::Rendering
|
10
13
|
|
11
|
-
DEFAULT_SEND_FILE_TYPE =
|
12
|
-
DEFAULT_SEND_FILE_DISPOSITION =
|
14
|
+
DEFAULT_SEND_FILE_TYPE = "application/octet-stream" #:nodoc:
|
15
|
+
DEFAULT_SEND_FILE_DISPOSITION = "attachment" #:nodoc:
|
13
16
|
|
14
|
-
|
17
|
+
private
|
15
18
|
# Sends the file. This uses a server-appropriate method (such as X-Sendfile)
|
16
19
|
# via the Rack::Sendfile middleware. The header to use is set via
|
17
20
|
# +config.action_dispatch.x_sendfile_header+.
|
@@ -25,14 +28,13 @@ module ActionController #:nodoc:
|
|
25
28
|
# * <tt>:filename</tt> - suggests a filename for the browser to use.
|
26
29
|
# Defaults to <tt>File.basename(path)</tt>.
|
27
30
|
# * <tt>:type</tt> - specifies an HTTP content type.
|
28
|
-
# You can specify either a string or a symbol for a registered type register
|
29
|
-
# <tt
|
30
|
-
# If
|
31
|
-
# If no content type is registered for the extension, default type 'application/octet-stream' will be used.
|
31
|
+
# You can specify either a string or a symbol for a registered type with <tt>Mime::Type.register</tt>, for example :json.
|
32
|
+
# If omitted, the type will be inferred from the file extension specified in <tt>:filename</tt>.
|
33
|
+
# If no content type is registered for the extension, the default type 'application/octet-stream' will be used.
|
32
34
|
# * <tt>:disposition</tt> - specifies whether the file will be shown inline or downloaded.
|
33
35
|
# Valid values are 'inline' and 'attachment' (default).
|
34
36
|
# * <tt>:status</tt> - specifies the status code to send with the response. Defaults to 200.
|
35
|
-
# * <tt>:url_based_filename</tt> - set to +true+ if you want the browser guess the filename from
|
37
|
+
# * <tt>:url_based_filename</tt> - set to +true+ if you want the browser to guess the filename from
|
36
38
|
# the URL, which is necessary for i18n filenames on certain browsers
|
37
39
|
# (setting <tt>:filename</tt> overrides this option).
|
38
40
|
#
|
@@ -55,58 +57,38 @@ module ActionController #:nodoc:
|
|
55
57
|
#
|
56
58
|
# Read about the other Content-* HTTP headers if you'd like to
|
57
59
|
# provide the user with more information (such as Content-Description) in
|
58
|
-
#
|
60
|
+
# https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11.
|
59
61
|
#
|
60
62
|
# Also be aware that the document may be cached by proxies and browsers.
|
61
63
|
# The Pragma and Cache-Control headers declare how the file may be cached
|
62
64
|
# by intermediaries. They default to require clients to validate with
|
63
65
|
# the server before releasing cached responses. See
|
64
|
-
#
|
65
|
-
#
|
66
|
+
# https://www.mnot.net/cache_docs/ for an overview of web caching and
|
67
|
+
# https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9
|
66
68
|
# for the Cache-Control header spec.
|
67
69
|
def send_file(path, options = {}) #:doc:
|
68
|
-
raise MissingFile, "Cannot read file #{path}" unless File.file?(path)
|
70
|
+
raise MissingFile, "Cannot read file #{path}" unless File.file?(path) && File.readable?(path)
|
69
71
|
|
70
72
|
options[:filename] ||= File.basename(path) unless options[:url_based_filename]
|
71
73
|
send_file_headers! options
|
72
74
|
|
73
75
|
self.status = options[:status] || 200
|
74
76
|
self.content_type = options[:content_type] if options.key?(:content_type)
|
75
|
-
|
76
|
-
end
|
77
|
-
|
78
|
-
# Avoid having to pass an open file handle as the response body.
|
79
|
-
# Rack::Sendfile will usually intercept the response and uses
|
80
|
-
# the path directly, so there is no reason to open the file.
|
81
|
-
class FileBody #:nodoc:
|
82
|
-
attr_reader :to_path
|
83
|
-
|
84
|
-
def initialize(path)
|
85
|
-
@to_path = path
|
86
|
-
end
|
87
|
-
|
88
|
-
# Stream the file's contents if Rack::Sendfile isn't present.
|
89
|
-
def each
|
90
|
-
File.open(to_path, 'rb') do |file|
|
91
|
-
while chunk = file.read(16384)
|
92
|
-
yield chunk
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
77
|
+
response.send_file path
|
96
78
|
end
|
97
79
|
|
98
80
|
# Sends the given binary data to the browser. This method is similar to
|
99
81
|
# <tt>render plain: data</tt>, but also allows you to specify whether
|
100
82
|
# the browser should display the response as a file attachment (i.e. in a
|
101
83
|
# download dialog) or as inline data. You may also set the content type,
|
102
|
-
# the
|
84
|
+
# the file name, and other things.
|
103
85
|
#
|
104
86
|
# Options:
|
105
87
|
# * <tt>:filename</tt> - suggests a filename for the browser to use.
|
106
|
-
# * <tt>:type</tt> - specifies an HTTP content type. Defaults to 'application/octet-stream'.
|
107
|
-
# either a string or a symbol for a registered type
|
108
|
-
# If omitted, type will be
|
109
|
-
# If no content type is registered for the extension, default type 'application/octet-stream' will be used.
|
88
|
+
# * <tt>:type</tt> - specifies an HTTP content type. Defaults to 'application/octet-stream'.
|
89
|
+
# You can specify either a string or a symbol for a registered type with <tt>Mime::Type.register</tt>, for example :json.
|
90
|
+
# If omitted, type will be inferred from the file extension specified in <tt>:filename</tt>.
|
91
|
+
# If no content type is registered for the extension, the default type 'application/octet-stream' will be used.
|
110
92
|
# * <tt>:disposition</tt> - specifies whether the file will be shown inline or downloaded.
|
111
93
|
# Valid values are 'inline' and 'attachment' (default).
|
112
94
|
# * <tt>:status</tt> - specifies the status code to send with the response. Defaults to 200.
|
@@ -126,14 +108,16 @@ module ActionController #:nodoc:
|
|
126
108
|
# See +send_file+ for more information on HTTP Content-* headers and caching.
|
127
109
|
def send_data(data, options = {}) #:doc:
|
128
110
|
send_file_headers! options
|
129
|
-
render options.slice(:status, :content_type).merge(:
|
111
|
+
render options.slice(:status, :content_type).merge(body: data)
|
130
112
|
end
|
131
113
|
|
132
|
-
private
|
133
114
|
def send_file_headers!(options)
|
134
115
|
type_provided = options.has_key?(:type)
|
135
116
|
|
136
117
|
content_type = options.fetch(:type, DEFAULT_SEND_FILE_TYPE)
|
118
|
+
self.content_type = content_type
|
119
|
+
response.sending_file = true
|
120
|
+
|
137
121
|
raise ArgumentError, ":type option required" if content_type.nil?
|
138
122
|
|
139
123
|
if content_type.is_a?(Symbol)
|
@@ -143,21 +127,17 @@ module ActionController #:nodoc:
|
|
143
127
|
else
|
144
128
|
if !type_provided && options[:filename]
|
145
129
|
# If type wasn't provided, try guessing from file extension.
|
146
|
-
content_type = Mime::Type.lookup_by_extension(File.extname(options[:filename]).downcase.delete(
|
130
|
+
content_type = Mime::Type.lookup_by_extension(File.extname(options[:filename]).downcase.delete(".")) || content_type
|
147
131
|
end
|
148
132
|
self.content_type = content_type
|
149
133
|
end
|
150
134
|
|
151
135
|
disposition = options.fetch(:disposition, DEFAULT_SEND_FILE_DISPOSITION)
|
152
|
-
|
153
|
-
|
154
|
-
disposition += %(; filename="#{options[:filename]}") if options[:filename]
|
155
|
-
headers['Content-Disposition'] = disposition
|
136
|
+
if disposition
|
137
|
+
headers["Content-Disposition"] = ActionDispatch::Http::ContentDisposition.format(disposition: disposition, filename: options[:filename])
|
156
138
|
end
|
157
139
|
|
158
|
-
headers[
|
159
|
-
|
160
|
-
response.sending_file = true
|
140
|
+
headers["Content-Transfer-Encoding"] = "binary"
|
161
141
|
|
162
142
|
# Fix a problem with IE 6.0 on opening downloaded files:
|
163
143
|
# If Cache-Control: no-cache is set (which Rails does by default),
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionController
|
4
|
+
# Allows configuring default headers that will be automatically merged into
|
5
|
+
# each response.
|
6
|
+
module DefaultHeaders
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def make_response!(request)
|
11
|
+
ActionDispatch::Response.create.tap do |res|
|
12
|
+
res.request = request
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionController
|
4
|
+
# When you're using the flash, it's generally used as a conditional on the view.
|
5
|
+
# This means the content of the view depends on the flash. Which in turn means
|
6
|
+
# that the ETag for a response should be computed with the content of the flash
|
7
|
+
# in mind. This does that by including the content of the flash as a component
|
8
|
+
# in the ETag that's generated for a response.
|
9
|
+
module EtagWithFlash
|
10
|
+
extend ActiveSupport::Concern
|
11
|
+
|
12
|
+
include ActionController::ConditionalGet
|
13
|
+
|
14
|
+
included do
|
15
|
+
etag { flash unless flash.empty? }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActionController
|
2
4
|
# When our views change, they should bubble up into HTTP cache freshness
|
3
5
|
# and bust browser caches. So the template digest for the current action
|
@@ -22,10 +24,9 @@ module ActionController
|
|
22
24
|
include ActionController::ConditionalGet
|
23
25
|
|
24
26
|
included do
|
25
|
-
class_attribute :etag_with_template_digest
|
26
|
-
self.etag_with_template_digest = true
|
27
|
+
class_attribute :etag_with_template_digest, default: true
|
27
28
|
|
28
|
-
ActiveSupport.on_load :action_view, yield: true do
|
29
|
+
ActiveSupport.on_load :action_view, yield: true do
|
29
30
|
etag do |options|
|
30
31
|
determine_template_etag(options) if etag_with_template_digest
|
31
32
|
end
|
@@ -33,18 +34,24 @@ module ActionController
|
|
33
34
|
end
|
34
35
|
|
35
36
|
private
|
36
|
-
|
37
|
-
|
38
|
-
|
37
|
+
def determine_template_etag(options)
|
38
|
+
if template = pick_template_for_etag(options)
|
39
|
+
lookup_and_digest_template(template)
|
40
|
+
end
|
39
41
|
end
|
40
|
-
end
|
41
42
|
|
42
|
-
|
43
|
-
|
44
|
-
|
43
|
+
# Pick the template digest to include in the ETag. If the +:template+ option
|
44
|
+
# is present, use the named template. If +:template+ is +nil+ or absent, use
|
45
|
+
# the default controller/action template. If +:template+ is false, omit the
|
46
|
+
# template digest from the ETag.
|
47
|
+
def pick_template_for_etag(options)
|
48
|
+
unless options[:template] == false
|
49
|
+
options[:template] || "#{controller_path}/#{action_name}"
|
50
|
+
end
|
51
|
+
end
|
45
52
|
|
46
|
-
|
47
|
-
|
48
|
-
|
53
|
+
def lookup_and_digest_template(template)
|
54
|
+
ActionView::Digestor.digest name: template, format: nil, finder: lookup_context
|
55
|
+
end
|
49
56
|
end
|
50
57
|
end
|
@@ -1,16 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActionController
|
2
4
|
class ActionControllerError < StandardError #:nodoc:
|
3
5
|
end
|
4
6
|
|
5
7
|
class BadRequest < ActionControllerError #:nodoc:
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
return super() unless type && e
|
10
|
-
|
11
|
-
super("Invalid #{type} parameters: #{e.message}")
|
12
|
-
@original_exception = e
|
13
|
-
set_backtrace e.backtrace
|
8
|
+
def initialize(msg = nil)
|
9
|
+
super(msg)
|
10
|
+
set_backtrace $!.backtrace if $!
|
14
11
|
end
|
15
12
|
end
|
16
13
|
|
@@ -19,32 +16,29 @@ module ActionController
|
|
19
16
|
|
20
17
|
class RoutingError < ActionControllerError #:nodoc:
|
21
18
|
attr_reader :failures
|
22
|
-
def initialize(message, failures=[])
|
19
|
+
def initialize(message, failures = [])
|
23
20
|
super(message)
|
24
21
|
@failures = failures
|
25
22
|
end
|
26
23
|
end
|
27
24
|
|
28
|
-
class
|
25
|
+
class UrlGenerationError < ActionControllerError #:nodoc:
|
29
26
|
end
|
30
27
|
|
31
28
|
class MethodNotAllowed < ActionControllerError #:nodoc:
|
32
29
|
def initialize(*allowed_methods)
|
33
|
-
super("Only #{allowed_methods.to_sentence
|
30
|
+
super("Only #{allowed_methods.to_sentence} requests are allowed.")
|
34
31
|
end
|
35
32
|
end
|
36
33
|
|
37
34
|
class NotImplemented < MethodNotAllowed #:nodoc:
|
38
35
|
end
|
39
36
|
|
40
|
-
class UnknownController < ActionControllerError #:nodoc:
|
41
|
-
end
|
42
|
-
|
43
37
|
class MissingFile < ActionControllerError #:nodoc:
|
44
38
|
end
|
45
39
|
|
46
40
|
class SessionOverflowError < ActionControllerError #:nodoc:
|
47
|
-
DEFAULT_MESSAGE =
|
41
|
+
DEFAULT_MESSAGE = "Your session data is larger than the data column in which it is to be stored. You must increase the size of your data column if you intend to store large data."
|
48
42
|
|
49
43
|
def initialize(message = nil)
|
50
44
|
super(message || DEFAULT_MESSAGE)
|
@@ -56,4 +50,25 @@ module ActionController
|
|
56
50
|
|
57
51
|
class UnknownFormat < ActionControllerError #:nodoc:
|
58
52
|
end
|
53
|
+
|
54
|
+
# Raised when a nested respond_to is triggered and the content types of each
|
55
|
+
# are incompatible. For example:
|
56
|
+
#
|
57
|
+
# respond_to do |outer_type|
|
58
|
+
# outer_type.js do
|
59
|
+
# respond_to do |inner_type|
|
60
|
+
# inner_type.html { render body: "HTML" }
|
61
|
+
# end
|
62
|
+
# end
|
63
|
+
# end
|
64
|
+
class RespondToMismatchError < ActionControllerError
|
65
|
+
DEFAULT_MESSAGE = "respond_to was called multiple times and matched with conflicting formats in this action. Please note that you may only call respond_to and match on a single format per action."
|
66
|
+
|
67
|
+
def initialize(message = nil)
|
68
|
+
super(message || DEFAULT_MESSAGE)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
class MissingExactTemplate < UnknownFormat #:nodoc:
|
73
|
+
end
|
59
74
|
end
|
@@ -1,10 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActionController #:nodoc:
|
2
4
|
module Flash
|
3
5
|
extend ActiveSupport::Concern
|
4
6
|
|
5
7
|
included do
|
6
|
-
class_attribute :_flash_types, instance_accessor: false
|
7
|
-
self._flash_types = []
|
8
|
+
class_attribute :_flash_types, instance_accessor: false, default: []
|
8
9
|
|
9
10
|
delegate :flash, to: :request
|
10
11
|
add_flash_types(:alert, :notice)
|
@@ -35,26 +36,26 @@ module ActionController #:nodoc:
|
|
35
36
|
define_method(type) do
|
36
37
|
request.flash[type]
|
37
38
|
end
|
38
|
-
helper_method
|
39
|
+
helper_method(type) if respond_to?(:helper_method)
|
39
40
|
|
40
41
|
self._flash_types += [type]
|
41
42
|
end
|
42
43
|
end
|
43
44
|
end
|
44
45
|
|
45
|
-
|
46
|
-
def redirect_to(options = {},
|
46
|
+
private
|
47
|
+
def redirect_to(options = {}, response_options_and_flash = {}) #:doc:
|
47
48
|
self.class._flash_types.each do |flash_type|
|
48
|
-
if type =
|
49
|
+
if type = response_options_and_flash.delete(flash_type)
|
49
50
|
flash[flash_type] = type
|
50
51
|
end
|
51
52
|
end
|
52
53
|
|
53
|
-
if other_flashes =
|
54
|
+
if other_flashes = response_options_and_flash.delete(:flash)
|
54
55
|
flash.update(other_flashes)
|
55
56
|
end
|
56
57
|
|
57
|
-
super(options,
|
58
|
+
super(options, response_options_and_flash)
|
58
59
|
end
|
59
60
|
end
|
60
61
|
end
|
@@ -1,19 +1,13 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/hash/except"
|
4
|
+
require "active_support/core_ext/hash/slice"
|
3
5
|
|
4
6
|
module ActionController
|
5
|
-
# This module
|
6
|
-
#
|
7
|
-
#
|
8
|
-
|
9
|
-
# user authentication, account information, or credit card information.
|
10
|
-
#
|
11
|
-
# Note that if you are really concerned about your application security,
|
12
|
-
# you might consider using +config.force_ssl+ in your config file instead.
|
13
|
-
# That will ensure all the data transferred via HTTPS protocol and prevent
|
14
|
-
# user from getting session hijacked when accessing the site under unsecured
|
15
|
-
# HTTP protocol.
|
16
|
-
module ForceSSL
|
7
|
+
# This module is deprecated in favor of +config.force_ssl+ in your environment
|
8
|
+
# config file. This will ensure all endpoints not explicitly marked otherwise
|
9
|
+
# will have all communication served over HTTPS.
|
10
|
+
module ForceSSL # :nodoc:
|
17
11
|
extend ActiveSupport::Concern
|
18
12
|
include AbstractController::Callbacks
|
19
13
|
|
@@ -21,45 +15,17 @@ module ActionController
|
|
21
15
|
URL_OPTIONS = [:protocol, :host, :domain, :subdomain, :port, :path]
|
22
16
|
REDIRECT_OPTIONS = [:status, :flash, :alert, :notice]
|
23
17
|
|
24
|
-
module ClassMethods
|
25
|
-
# Force the request to this particular controller or specified actions to be
|
26
|
-
# under HTTPS protocol.
|
27
|
-
#
|
28
|
-
# If you need to disable this for any reason (e.g. development) then you can use
|
29
|
-
# an +:if+ or +:unless+ condition.
|
30
|
-
#
|
31
|
-
# class AccountsController < ApplicationController
|
32
|
-
# force_ssl if: :ssl_configured?
|
33
|
-
#
|
34
|
-
# def ssl_configured?
|
35
|
-
# !Rails.env.development?
|
36
|
-
# end
|
37
|
-
# end
|
38
|
-
#
|
39
|
-
# ==== URL Options
|
40
|
-
# You can pass any of the following options to affect the redirect url
|
41
|
-
# * <tt>host</tt> - Redirect to a different host name
|
42
|
-
# * <tt>subdomain</tt> - Redirect to a different subdomain
|
43
|
-
# * <tt>domain</tt> - Redirect to a different domain
|
44
|
-
# * <tt>port</tt> - Redirect to a non-standard port
|
45
|
-
# * <tt>path</tt> - Redirect to a different path
|
46
|
-
#
|
47
|
-
# ==== Redirect Options
|
48
|
-
# You can pass any of the following options to affect the redirect status and response
|
49
|
-
# * <tt>status</tt> - Redirect with a custom status (default is 301 Moved Permanently)
|
50
|
-
# * <tt>flash</tt> - Set a flash message when redirecting
|
51
|
-
# * <tt>alert</tt> - Set an alert message when redirecting
|
52
|
-
# * <tt>notice</tt> - Set a notice message when redirecting
|
53
|
-
#
|
54
|
-
# ==== Action Options
|
55
|
-
# You can pass any of the following options to affect the before_action callback
|
56
|
-
# * <tt>only</tt> - The callback should be run only for this action
|
57
|
-
# * <tt>except</tt> - The callback should be run for all actions except this action
|
58
|
-
# * <tt>if</tt> - A symbol naming an instance method or a proc; the callback
|
59
|
-
# will be called only when it returns a true value.
|
60
|
-
# * <tt>unless</tt> - A symbol naming an instance method or a proc; the callback
|
61
|
-
# will be called only when it returns a false value.
|
18
|
+
module ClassMethods # :nodoc:
|
62
19
|
def force_ssl(options = {})
|
20
|
+
ActiveSupport::Deprecation.warn(<<-MESSAGE.squish)
|
21
|
+
Controller-level `force_ssl` is deprecated and will be removed from
|
22
|
+
Rails 6.1. Please enable `config.force_ssl` in your environment
|
23
|
+
configuration to enable the ActionDispatch::SSL middleware to more
|
24
|
+
fully enforce that your application communicate over HTTPS. If needed,
|
25
|
+
you can use `config.ssl_options` to exempt matching endpoints from
|
26
|
+
being redirected to HTTPS.
|
27
|
+
MESSAGE
|
28
|
+
|
63
29
|
action_options = options.slice(*ACTION_OPTIONS)
|
64
30
|
redirect_options = options.except(*ACTION_OPTIONS)
|
65
31
|
before_action(action_options) do
|
@@ -68,18 +34,13 @@ module ActionController
|
|
68
34
|
end
|
69
35
|
end
|
70
36
|
|
71
|
-
# Redirect the existing request to use the HTTPS protocol.
|
72
|
-
#
|
73
|
-
# ==== Parameters
|
74
|
-
# * <tt>host_or_options</tt> - Either a host name or any of the url & redirect options
|
75
|
-
# available to the <tt>force_ssl</tt> method.
|
76
37
|
def force_ssl_redirect(host_or_options = nil)
|
77
38
|
unless request.ssl?
|
78
39
|
options = {
|
79
|
-
:
|
80
|
-
:
|
81
|
-
:
|
82
|
-
:
|
40
|
+
protocol: "https://",
|
41
|
+
host: request.host,
|
42
|
+
path: request.fullpath,
|
43
|
+
status: :moved_permanently,
|
83
44
|
}
|
84
45
|
|
85
46
|
if host_or_options.is_a?(Hash)
|
@@ -89,7 +50,7 @@ module ActionController
|
|
89
50
|
end
|
90
51
|
|
91
52
|
secure_url = ActionDispatch::Http::URL.url_for(options.slice(*URL_OPTIONS))
|
92
|
-
flash.keep if respond_to?(:flash)
|
53
|
+
flash.keep if respond_to?(:flash) && request.respond_to?(:flash)
|
93
54
|
redirect_to secure_url, options.slice(*REDIRECT_OPTIONS)
|
94
55
|
end
|
95
56
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActionController
|
2
4
|
module Head
|
3
5
|
# Returns a response that has no content (merely headers). The options
|
@@ -17,13 +19,17 @@ module ActionController
|
|
17
19
|
#
|
18
20
|
# See Rack::Utils::SYMBOL_TO_STATUS_CODE for a full list of valid +status+ symbols.
|
19
21
|
def head(status, options = {})
|
20
|
-
|
21
|
-
|
22
|
+
if status.is_a?(Hash)
|
23
|
+
raise ArgumentError, "#{status.inspect} is not a valid value for `status`."
|
24
|
+
end
|
25
|
+
|
26
|
+
status ||= :ok
|
27
|
+
|
22
28
|
location = options.delete(:location)
|
23
29
|
content_type = options.delete(:content_type)
|
24
30
|
|
25
31
|
options.each do |key, value|
|
26
|
-
headers[key.to_s.dasherize.split(
|
32
|
+
headers[key.to_s.dasherize.split("-").each { |v| v[0] = v[0].chr.upcase }.join("-")] = value.to_s
|
27
33
|
end
|
28
34
|
|
29
35
|
self.status = status
|
@@ -31,28 +37,24 @@ module ActionController
|
|
31
37
|
|
32
38
|
self.response_body = ""
|
33
39
|
|
34
|
-
if include_content?(
|
35
|
-
self.content_type = content_type || (Mime[formats.first] if formats)
|
36
|
-
|
37
|
-
else
|
38
|
-
headers.delete('Content-Type')
|
39
|
-
headers.delete('Content-Length')
|
40
|
+
if include_content?(response_code)
|
41
|
+
self.content_type = content_type || (Mime[formats.first] if formats) || Mime[:html]
|
42
|
+
response.charset = false
|
40
43
|
end
|
41
|
-
|
44
|
+
|
42
45
|
true
|
43
46
|
end
|
44
47
|
|
45
48
|
private
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
49
|
+
def include_content?(status)
|
50
|
+
case status
|
51
|
+
when 100..199
|
52
|
+
false
|
53
|
+
when 204, 205, 304
|
54
|
+
false
|
55
|
+
else
|
56
|
+
true
|
57
|
+
end
|
55
58
|
end
|
56
|
-
end
|
57
59
|
end
|
58
60
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActionController
|
2
4
|
# The \Rails framework provides a large number of helpers for working with assets, dates, forms,
|
3
5
|
# numbers and model objects, to name a few. These helpers are available to all templates
|
@@ -5,10 +7,10 @@ module ActionController
|
|
5
7
|
#
|
6
8
|
# In addition to using the standard template helpers provided, creating custom helpers to
|
7
9
|
# extract complicated logic or reusable functionality is strongly encouraged. By default, each controller
|
8
|
-
# will include all helpers. These helpers are only accessible on the controller through <tt
|
10
|
+
# will include all helpers. These helpers are only accessible on the controller through <tt>#helpers</tt>
|
9
11
|
#
|
10
|
-
# In previous versions of \Rails the controller will include a helper
|
11
|
-
#
|
12
|
+
# In previous versions of \Rails the controller will include a helper which
|
13
|
+
# matches the name of the controller, e.g., <tt>MyController</tt> will automatically
|
12
14
|
# include <tt>MyHelper</tt>. To return old behavior set +config.action_controller.include_all_helpers+ to +false+.
|
13
15
|
#
|
14
16
|
# Additional helpers can be specified using the +helper+ class method in ActionController::Base or any
|
@@ -32,7 +34,7 @@ module ActionController
|
|
32
34
|
# end
|
33
35
|
# end
|
34
36
|
#
|
35
|
-
# Then, in any view rendered by <tt>
|
37
|
+
# Then, in any view rendered by <tt>EventsController</tt>, the <tt>format_time</tt> method can be called:
|
36
38
|
#
|
37
39
|
# <% @events.each do |event| -%>
|
38
40
|
# <p>
|
@@ -44,7 +46,7 @@ module ActionController
|
|
44
46
|
# the output might look like this:
|
45
47
|
#
|
46
48
|
# 23 Aug 11:30 | Carolina Railhawks Soccer Match
|
47
|
-
# N/A | Carolina
|
49
|
+
# N/A | Carolina Railhawks Training Workshop
|
48
50
|
#
|
49
51
|
module Helpers
|
50
52
|
extend ActiveSupport::Concern
|
@@ -53,9 +55,8 @@ module ActionController
|
|
53
55
|
include AbstractController::Helpers
|
54
56
|
|
55
57
|
included do
|
56
|
-
class_attribute :helpers_path, :
|
57
|
-
|
58
|
-
self.include_all_helpers = true
|
58
|
+
class_attribute :helpers_path, default: []
|
59
|
+
class_attribute :include_all_helpers, default: true
|
59
60
|
end
|
60
61
|
|
61
62
|
module ClassMethods
|
@@ -71,10 +72,10 @@ module ActionController
|
|
71
72
|
attrs.flatten.each { |attr| helper_method(attr, "#{attr}=") }
|
72
73
|
end
|
73
74
|
|
74
|
-
# Provides a proxy to access
|
75
|
+
# Provides a proxy to access helper methods from outside the view.
|
75
76
|
def helpers
|
76
|
-
@helper_proxy ||= begin
|
77
|
-
proxy = ActionView::Base.
|
77
|
+
@helper_proxy ||= begin
|
78
|
+
proxy = ActionView::Base.empty
|
78
79
|
proxy.config = config.inheritable_copy
|
79
80
|
proxy.extend(_helpers)
|
80
81
|
end
|
@@ -93,10 +94,13 @@ module ActionController
|
|
93
94
|
super(args)
|
94
95
|
end
|
95
96
|
|
97
|
+
# Returns a list of helper names in a given path.
|
98
|
+
#
|
99
|
+
# ActionController::Base.all_helpers_from_path 'app/helpers'
|
100
|
+
# # => ["application", "chart", "rubygems"]
|
96
101
|
def all_helpers_from_path(path)
|
97
102
|
helpers = Array(path).flat_map do |_path|
|
98
|
-
|
99
|
-
names = Dir["#{_path}/**/*_helper.rb"].map { |file| file.sub(extract, '\1') }
|
103
|
+
names = Dir["#{_path}/**/*_helper.rb"].map { |file| file[_path.to_s.size + 1..-"_helper.rb".size - 1] }
|
100
104
|
names.sort!
|
101
105
|
end
|
102
106
|
helpers.uniq!
|
@@ -104,10 +108,15 @@ module ActionController
|
|
104
108
|
end
|
105
109
|
|
106
110
|
private
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
+
# Extract helper names from files in <tt>app/helpers/**/*_helper.rb</tt>
|
112
|
+
def all_application_helpers
|
113
|
+
all_helpers_from_path(helpers_path)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# Provides a proxy to access helper methods from outside the view.
|
118
|
+
def helpers
|
119
|
+
@_helper_proxy ||= view_context
|
111
120
|
end
|
112
121
|
end
|
113
122
|
end
|