actionpack 6.1.5 → 7.0.0.alpha1
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 +99 -521
- data/MIT-LICENSE +2 -1
- data/README.rdoc +2 -3
- data/lib/abstract_controller/asset_paths.rb +1 -1
- data/lib/abstract_controller/base.rb +7 -21
- data/lib/abstract_controller/caching/fragments.rb +2 -2
- data/lib/abstract_controller/caching.rb +1 -1
- data/lib/abstract_controller/callbacks.rb +9 -8
- data/lib/abstract_controller/collector.rb +2 -2
- data/lib/abstract_controller/error.rb +1 -1
- data/lib/abstract_controller/helpers.rb +3 -2
- data/lib/abstract_controller/logger.rb +1 -1
- data/lib/abstract_controller/railties/routes_helpers.rb +2 -0
- data/lib/abstract_controller/translation.rb +0 -2
- data/lib/abstract_controller/url_for.rb +4 -6
- data/lib/action_controller/api.rb +1 -1
- data/lib/action_controller/log_subscriber.rb +3 -1
- data/lib/action_controller/metal/conditional_get.rb +38 -1
- data/lib/action_controller/metal/content_security_policy.rb +1 -1
- data/lib/action_controller/metal/cookies.rb +1 -1
- data/lib/action_controller/metal/data_streaming.rb +5 -13
- data/lib/action_controller/metal/exceptions.rb +19 -30
- data/lib/action_controller/metal/flash.rb +6 -2
- data/lib/action_controller/metal/http_authentication.rb +15 -16
- data/lib/action_controller/metal/instrumentation.rb +55 -52
- data/lib/action_controller/metal/live.rb +42 -2
- data/lib/action_controller/metal/mime_responds.rb +3 -3
- data/lib/action_controller/metal/params_wrapper.rb +7 -7
- data/lib/action_controller/metal/permissions_policy.rb +1 -1
- data/lib/action_controller/metal/query_tags.rb +16 -0
- data/lib/action_controller/metal/redirecting.rb +50 -16
- data/lib/action_controller/metal/rendering.rb +7 -7
- data/lib/action_controller/metal/request_forgery_protection.rb +64 -20
- data/lib/action_controller/metal/rescue.rb +1 -1
- data/lib/action_controller/metal/streaming.rb +1 -3
- data/lib/action_controller/metal/strong_parameters.rb +25 -29
- data/lib/action_controller/metal/testing.rb +0 -2
- data/lib/action_controller/metal.rb +7 -10
- data/lib/action_controller/railtie.rb +42 -5
- data/lib/action_controller/test_case.rb +6 -2
- data/lib/action_controller.rb +2 -5
- data/lib/action_dispatch/http/cache.rb +13 -6
- data/lib/action_dispatch/http/content_security_policy.rb +40 -37
- data/lib/action_dispatch/http/filter_parameters.rb +5 -0
- data/lib/action_dispatch/http/mime_negotiation.rb +13 -3
- data/lib/action_dispatch/http/mime_type.rb +9 -11
- data/lib/action_dispatch/http/parameters.rb +4 -4
- data/lib/action_dispatch/http/permissions_policy.rb +1 -1
- data/lib/action_dispatch/http/request.rb +10 -19
- data/lib/action_dispatch/http/response.rb +3 -3
- data/lib/action_dispatch/http/url.rb +9 -10
- data/lib/action_dispatch/journey/gtg/builder.rb +11 -12
- data/lib/action_dispatch/journey/gtg/simulator.rb +10 -4
- data/lib/action_dispatch/journey/gtg/transition_table.rb +77 -21
- data/lib/action_dispatch/journey/nodes/node.rb +70 -5
- data/lib/action_dispatch/journey/path/pattern.rb +22 -13
- data/lib/action_dispatch/journey/route.rb +5 -12
- data/lib/action_dispatch/journey/router/utils.rb +2 -2
- data/lib/action_dispatch/journey/router.rb +1 -1
- data/lib/action_dispatch/journey/routes.rb +3 -3
- data/lib/action_dispatch/journey/visualizer/fsm.js +49 -24
- data/lib/action_dispatch/journey/visualizer/index.html.erb +1 -1
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +0 -1
- data/lib/action_dispatch/middleware/cookies.rb +7 -3
- data/lib/action_dispatch/middleware/debug_exceptions.rb +6 -4
- data/lib/action_dispatch/middleware/debug_locks.rb +3 -3
- data/lib/action_dispatch/middleware/exception_wrapper.rb +4 -0
- data/lib/action_dispatch/middleware/executor.rb +1 -1
- data/lib/action_dispatch/middleware/flash.rb +9 -11
- data/lib/action_dispatch/middleware/host_authorization.rb +25 -73
- data/lib/action_dispatch/middleware/remote_ip.rb +16 -4
- data/lib/action_dispatch/middleware/session/abstract_store.rb +1 -1
- data/lib/action_dispatch/middleware/show_exceptions.rb +6 -18
- data/lib/action_dispatch/middleware/stack.rb +50 -9
- data/lib/action_dispatch/middleware/static.rb +2 -5
- data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +4 -11
- data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +28 -18
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +5 -14
- data/lib/action_dispatch/railtie.rb +8 -2
- data/lib/action_dispatch/request/session.rb +43 -13
- data/lib/action_dispatch/routing/mapper.rb +44 -72
- data/lib/action_dispatch/routing/redirection.rb +0 -2
- data/lib/action_dispatch/routing/route_set.rb +7 -4
- data/lib/action_dispatch/routing/routes_proxy.rb +1 -1
- data/lib/action_dispatch/routing/url_for.rb +1 -2
- data/lib/action_dispatch/routing.rb +2 -2
- data/lib/action_dispatch/system_test_case.rb +6 -12
- data/lib/action_dispatch/system_testing/driver.rb +24 -4
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +10 -6
- data/lib/action_dispatch/testing/assertions.rb +2 -5
- data/lib/action_dispatch/testing/integration.rb +6 -8
- data/lib/action_dispatch/testing/test_process.rb +2 -2
- data/lib/action_dispatch.rb +1 -1
- data/lib/action_pack/gem_version.rb +4 -4
- data/lib/action_pack.rb +1 -1
- metadata +18 -18
data/MIT-LICENSE
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright (c) 2004-
|
1
|
+
Copyright (c) 2004-2021 David Heinemeier Hansson
|
2
2
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining
|
4
4
|
a copy of this software and associated documentation files (the
|
@@ -18,3 +18,4 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
18
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
19
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
20
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
data/README.rdoc
CHANGED
@@ -2,9 +2,8 @@
|
|
2
2
|
|
3
3
|
Action Pack is a framework for handling and responding to web requests. It
|
4
4
|
provides mechanisms for *routing* (mapping request URLs to actions), defining
|
5
|
-
*controllers* that implement actions, and generating responses
|
6
|
-
|
7
|
-
provides the view and controller layers in the MVC paradigm.
|
5
|
+
*controllers* that implement actions, and generating responses. In short, Action Pack
|
6
|
+
provides the controller layer in the MVC paradigm.
|
8
7
|
|
9
8
|
It consists of several modules:
|
10
9
|
|
@@ -9,35 +9,21 @@ require "active_support/core_ext/module/attr_internal"
|
|
9
9
|
module AbstractController
|
10
10
|
# Raised when a non-existing controller action is triggered.
|
11
11
|
class ActionNotFound < StandardError
|
12
|
-
attr_reader :controller, :action
|
13
|
-
|
12
|
+
attr_reader :controller, :action # :nodoc:
|
13
|
+
|
14
|
+
def initialize(message = nil, controller = nil, action = nil) # :nodoc:
|
14
15
|
@controller = controller
|
15
16
|
@action = action
|
16
17
|
super(message)
|
17
18
|
end
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
@error = error
|
22
|
-
end
|
23
|
-
|
24
|
-
def corrections
|
25
|
-
if @error.action
|
26
|
-
maybe_these = @error.controller.class.action_methods
|
20
|
+
if defined?(DidYouMean::Correctable) && defined?(DidYouMean::SpellChecker)
|
21
|
+
include DidYouMean::Correctable # :nodoc:
|
27
22
|
|
28
|
-
|
29
|
-
|
30
|
-
}.reverse.first(4)
|
31
|
-
else
|
32
|
-
[]
|
33
|
-
end
|
23
|
+
def corrections # :nodoc:
|
24
|
+
@corrections ||= DidYouMean::SpellChecker.new(dictionary: controller.class.action_methods).correct(action)
|
34
25
|
end
|
35
26
|
end
|
36
|
-
|
37
|
-
# We may not have DYM, and DYM might not let us register error handlers
|
38
|
-
if defined?(DidYouMean) && DidYouMean.respond_to?(:correct_error)
|
39
|
-
DidYouMean.correct_error(self, Correction)
|
40
|
-
end
|
41
27
|
end
|
42
28
|
|
43
29
|
# AbstractController::Base is a low-level API. Nobody should be
|
@@ -142,8 +142,8 @@ module AbstractController
|
|
142
142
|
end
|
143
143
|
end
|
144
144
|
|
145
|
-
def instrument_fragment_cache(name, key) # :nodoc:
|
146
|
-
ActiveSupport::Notifications.instrument("#{name}.#{instrument_name}", instrument_payload(key))
|
145
|
+
def instrument_fragment_cache(name, key, &block) # :nodoc:
|
146
|
+
ActiveSupport::Notifications.instrument("#{name}.#{instrument_name}", instrument_payload(key), &block)
|
147
147
|
end
|
148
148
|
end
|
149
149
|
end
|
@@ -35,14 +35,6 @@ module AbstractController
|
|
35
35
|
skip_after_callbacks_if_terminated: true
|
36
36
|
end
|
37
37
|
|
38
|
-
# Override <tt>AbstractController::Base#process_action</tt> to run the
|
39
|
-
# <tt>process_action</tt> callbacks around the normal behavior.
|
40
|
-
def process_action(*)
|
41
|
-
run_callbacks(:process_action) do
|
42
|
-
super
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
38
|
module ClassMethods
|
47
39
|
# If +:only+ or +:except+ are used, convert the options into the
|
48
40
|
# +:if+ and +:unless+ options of ActiveSupport::Callbacks.
|
@@ -220,5 +212,14 @@ module AbstractController
|
|
220
212
|
alias_method :"append_#{callback}_action", :"#{callback}_action"
|
221
213
|
end
|
222
214
|
end
|
215
|
+
|
216
|
+
private
|
217
|
+
# Override <tt>AbstractController::Base#process_action</tt> to run the
|
218
|
+
# <tt>process_action</tt> callbacks around the normal behavior.
|
219
|
+
def process_action(*)
|
220
|
+
run_callbacks(:process_action) do
|
221
|
+
super
|
222
|
+
end
|
223
|
+
end
|
223
224
|
end
|
224
225
|
end
|
@@ -10,7 +10,7 @@ module AbstractController
|
|
10
10
|
def #{sym}(*args, &block)
|
11
11
|
custom(Mime[:#{sym}], *args, &block)
|
12
12
|
end
|
13
|
-
ruby2_keywords(:#{sym})
|
13
|
+
ruby2_keywords(:#{sym})
|
14
14
|
RUBY
|
15
15
|
end
|
16
16
|
|
@@ -39,6 +39,6 @@ module AbstractController
|
|
39
39
|
super
|
40
40
|
end
|
41
41
|
end
|
42
|
-
ruby2_keywords(:method_missing)
|
42
|
+
ruby2_keywords(:method_missing)
|
43
43
|
end
|
44
44
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_support/dependencies"
|
4
|
+
require "active_support/core_ext/name_error"
|
4
5
|
|
5
6
|
module AbstractController
|
6
7
|
module Helpers
|
@@ -83,11 +84,11 @@ module AbstractController
|
|
83
84
|
file, line = location.path, location.lineno
|
84
85
|
|
85
86
|
methods.each do |method|
|
86
|
-
_helpers_for_modification.class_eval
|
87
|
+
_helpers_for_modification.class_eval <<~ruby_eval, file, line
|
87
88
|
def #{method}(*args, &block) # def current_user(*args, &block)
|
88
89
|
controller.send(:'#{method}', *args, &block) # controller.send(:'current_user', *args, &block)
|
89
90
|
end # end
|
90
|
-
ruby2_keywords(:'#{method}')
|
91
|
+
ruby2_keywords(:'#{method}')
|
91
92
|
ruby_eval
|
92
93
|
end
|
93
94
|
end
|
@@ -22,12 +22,10 @@ module AbstractController
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def action_methods
|
25
|
-
@action_methods ||=
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
super
|
30
|
-
end
|
25
|
+
@action_methods ||= if _routes
|
26
|
+
super - _routes.named_routes.helper_names
|
27
|
+
else
|
28
|
+
super
|
31
29
|
end
|
32
30
|
end
|
33
31
|
end
|
@@ -37,7 +37,7 @@ module ActionController
|
|
37
37
|
# == Renders
|
38
38
|
#
|
39
39
|
# The default API Controller stack includes all renderers, which means you
|
40
|
-
# can use <tt>render :json</tt> and
|
40
|
+
# can use <tt>render :json</tt> and siblings freely in your controllers. Keep
|
41
41
|
# in mind that templates are not going to be rendered, so you need to ensure
|
42
42
|
# your controller is calling either <tt>render</tt> or <tt>redirect_to</tt> in
|
43
43
|
# all actions, otherwise it will return 204 No Content.
|
@@ -56,7 +56,9 @@ module ActionController
|
|
56
56
|
def unpermitted_parameters(event)
|
57
57
|
debug do
|
58
58
|
unpermitted_keys = event.payload[:keys]
|
59
|
-
|
59
|
+
display_unpermitted_keys = unpermitted_keys.map { |e| ":#{e}" }.join(", ")
|
60
|
+
context = event.payload[:context].map { |k, v| "#{k}: #{v}" }.join(", ")
|
61
|
+
color("Unpermitted parameter#{'s' if unpermitted_keys.size > 1}: #{display_unpermitted_keys}. Context: { #{context} }", RED)
|
60
62
|
end
|
61
63
|
end
|
62
64
|
|
@@ -57,6 +57,8 @@ module ActionController
|
|
57
57
|
# 304 Not Modified response if last_modified <= If-Modified-Since.
|
58
58
|
# * <tt>:public</tt> By default the Cache-Control header is private, set this to
|
59
59
|
# +true+ if you want your application to be cacheable by other devices (proxy caches).
|
60
|
+
# * <tt>:cache_control</tt> When given will overwrite an existing Cache-Control header.
|
61
|
+
# See https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html for more possibilities.
|
60
62
|
# * <tt>:template</tt> By default, the template digest for the current
|
61
63
|
# controller/action is included in ETags. If the action renders a
|
62
64
|
# different template, you can include its digest instead. If the action
|
@@ -98,12 +100,22 @@ module ActionController
|
|
98
100
|
# fresh_when(@article, public: true)
|
99
101
|
# end
|
100
102
|
#
|
103
|
+
# When overwriting Cache-Control header:
|
104
|
+
#
|
105
|
+
# def show
|
106
|
+
# @article = Article.find(params[:id])
|
107
|
+
# fresh_when(@article, public: true, cache_control: { no_cache: true })
|
108
|
+
# end
|
109
|
+
#
|
110
|
+
# This will set in the response Cache-Control = public, no-cache.
|
111
|
+
#
|
101
112
|
# When rendering a different template than the default controller/action
|
102
113
|
# style, you can indicate which digest to include in the ETag:
|
103
114
|
#
|
104
115
|
# before_action { fresh_when @article, template: 'widgets/show' }
|
105
116
|
#
|
106
|
-
def fresh_when(object = nil, etag: nil, weak_etag: nil, strong_etag: nil, last_modified: nil, public: false, template: nil)
|
117
|
+
def fresh_when(object = nil, etag: nil, weak_etag: nil, strong_etag: nil, last_modified: nil, public: false, cache_control: {}, template: nil)
|
118
|
+
response.cache_control.delete(:no_store)
|
107
119
|
weak_etag ||= etag || object unless strong_etag
|
108
120
|
last_modified ||= object.try(:updated_at) || object.try(:maximum, :updated_at)
|
109
121
|
|
@@ -117,6 +129,7 @@ module ActionController
|
|
117
129
|
|
118
130
|
response.last_modified = last_modified if last_modified
|
119
131
|
response.cache_control[:public] = true if public
|
132
|
+
response.cache_control.merge!(cache_control)
|
120
133
|
|
121
134
|
head :not_modified if request.fresh?(response)
|
122
135
|
end
|
@@ -147,6 +160,8 @@ module ActionController
|
|
147
160
|
# 304 Not Modified response if last_modified <= If-Modified-Since.
|
148
161
|
# * <tt>:public</tt> By default the Cache-Control header is private, set this to
|
149
162
|
# +true+ if you want your application to be cacheable by other devices (proxy caches).
|
163
|
+
# * <tt>:cache_control</tt> When given will overwrite an existing Cache-Control header.
|
164
|
+
# See https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html for more possibilities.
|
150
165
|
# * <tt>:template</tt> By default, the template digest for the current
|
151
166
|
# controller/action is included in ETags. If the action renders a
|
152
167
|
# different template, you can include its digest instead. If the action
|
@@ -209,6 +224,21 @@ module ActionController
|
|
209
224
|
# end
|
210
225
|
# end
|
211
226
|
#
|
227
|
+
# When overwriting Cache-Control header:
|
228
|
+
#
|
229
|
+
# def show
|
230
|
+
# @article = Article.find(params[:id])
|
231
|
+
#
|
232
|
+
# if stale?(@article, public: true, cache_control: { no_cache: true })
|
233
|
+
# @statistics = @articles.really_expensive_call
|
234
|
+
# respond_to do |format|
|
235
|
+
# # all the supported formats
|
236
|
+
# end
|
237
|
+
# end
|
238
|
+
# end
|
239
|
+
#
|
240
|
+
# This will set in the response Cache-Control = public, no-cache.
|
241
|
+
#
|
212
242
|
# When rendering a different template than the default controller/action
|
213
243
|
# style, you can indicate which digest to include in the ETag:
|
214
244
|
#
|
@@ -244,6 +274,7 @@ module ActionController
|
|
244
274
|
#
|
245
275
|
# The method will also ensure an HTTP Date header for client compatibility.
|
246
276
|
def expires_in(seconds, options = {})
|
277
|
+
response.cache_control.delete(:no_store)
|
247
278
|
response.cache_control.merge!(
|
248
279
|
max_age: seconds,
|
249
280
|
public: options.delete(:public),
|
@@ -280,6 +311,12 @@ module ActionController
|
|
280
311
|
public: public)
|
281
312
|
end
|
282
313
|
|
314
|
+
# Sets an HTTP 1.1 Cache-Control header of <tt>no-store</tt>. This means the
|
315
|
+
# resource may not be stored in any cache.
|
316
|
+
def no_store
|
317
|
+
response.cache_control.replace(no_store: true)
|
318
|
+
end
|
319
|
+
|
283
320
|
private
|
284
321
|
def combine_etags(validator, options)
|
285
322
|
[validator, *etaggers.map { |etagger| instance_exec(options, &etagger) }].compact
|
@@ -3,7 +3,7 @@
|
|
3
3
|
require "action_controller/metal/exceptions"
|
4
4
|
require "action_dispatch/http/content_disposition"
|
5
5
|
|
6
|
-
module ActionController
|
6
|
+
module ActionController # :nodoc:
|
7
7
|
# Methods for sending arbitrary data and for streaming files to the browser,
|
8
8
|
# instead of rendering.
|
9
9
|
module DataStreaming
|
@@ -11,8 +11,8 @@ module ActionController #:nodoc:
|
|
11
11
|
|
12
12
|
include ActionController::Rendering
|
13
13
|
|
14
|
-
DEFAULT_SEND_FILE_TYPE = "application/octet-stream"
|
15
|
-
DEFAULT_SEND_FILE_DISPOSITION = "attachment"
|
14
|
+
DEFAULT_SEND_FILE_TYPE = "application/octet-stream" # :nodoc:
|
15
|
+
DEFAULT_SEND_FILE_DISPOSITION = "attachment" # :nodoc:
|
16
16
|
|
17
17
|
private
|
18
18
|
# Sends the file. This uses a server-appropriate method (such as X-Sendfile)
|
@@ -66,7 +66,7 @@ module ActionController #:nodoc:
|
|
66
66
|
# https://www.mnot.net/cache_docs/ for an overview of web caching and
|
67
67
|
# https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9
|
68
68
|
# for the Cache-Control header spec.
|
69
|
-
def send_file(path, options = {})
|
69
|
+
def send_file(path, options = {}) # :doc:
|
70
70
|
raise MissingFile, "Cannot read file #{path}" unless File.file?(path) && File.readable?(path)
|
71
71
|
|
72
72
|
options[:filename] ||= File.basename(path) unless options[:url_based_filename]
|
@@ -106,7 +106,7 @@ module ActionController #:nodoc:
|
|
106
106
|
# send_data image.data, type: image.content_type, disposition: 'inline'
|
107
107
|
#
|
108
108
|
# See +send_file+ for more information on HTTP Content-* headers and caching.
|
109
|
-
def send_data(data, options = {})
|
109
|
+
def send_data(data, options = {}) # :doc:
|
110
110
|
send_file_headers! options
|
111
111
|
render options.slice(:status, :content_type).merge(body: data)
|
112
112
|
end
|
@@ -138,14 +138,6 @@ module ActionController #:nodoc:
|
|
138
138
|
end
|
139
139
|
|
140
140
|
headers["Content-Transfer-Encoding"] = "binary"
|
141
|
-
|
142
|
-
# Fix a problem with IE 6.0 on opening downloaded files:
|
143
|
-
# If Cache-Control: no-cache is set (which Rails does by default),
|
144
|
-
# IE removes the file it just downloaded from its cache immediately
|
145
|
-
# after it displays the "open/save" dialog, which means that if you
|
146
|
-
# hit "open" the file isn't there anymore when the application that
|
147
|
-
# is called for handling the download is run, so let's workaround that
|
148
|
-
response.cache_control[:public] ||= false
|
149
141
|
end
|
150
142
|
end
|
151
143
|
end
|
@@ -1,20 +1,20 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActionController
|
4
|
-
class ActionControllerError < StandardError
|
4
|
+
class ActionControllerError < StandardError # :nodoc:
|
5
5
|
end
|
6
6
|
|
7
|
-
class BadRequest < ActionControllerError
|
7
|
+
class BadRequest < ActionControllerError # :nodoc:
|
8
8
|
def initialize(msg = nil)
|
9
9
|
super(msg)
|
10
10
|
set_backtrace $!.backtrace if $!
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
-
class RenderError < ActionControllerError
|
14
|
+
class RenderError < ActionControllerError # :nodoc:
|
15
15
|
end
|
16
16
|
|
17
|
-
class RoutingError < ActionControllerError
|
17
|
+
class RoutingError < ActionControllerError # :nodoc:
|
18
18
|
attr_reader :failures
|
19
19
|
def initialize(message, failures = [])
|
20
20
|
super(message)
|
@@ -22,7 +22,7 @@ module ActionController
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
class UrlGenerationError < ActionControllerError
|
25
|
+
class UrlGenerationError < ActionControllerError # :nodoc:
|
26
26
|
attr_reader :routes, :route_name, :method_name
|
27
27
|
|
28
28
|
def initialize(message, routes = nil, route_name = nil, method_name = nil)
|
@@ -33,44 +33,33 @@ module ActionController
|
|
33
33
|
super(message)
|
34
34
|
end
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
@error = error
|
39
|
-
end
|
36
|
+
if defined?(DidYouMean::Correctable) && defined?(DidYouMean::SpellChecker)
|
37
|
+
include DidYouMean::Correctable
|
40
38
|
|
41
39
|
def corrections
|
42
|
-
|
43
|
-
maybe_these =
|
44
|
-
maybe_these -= [
|
45
|
-
|
46
|
-
maybe_these.
|
47
|
-
DidYouMean::Jaro.distance(@error.route_name, n)
|
48
|
-
}.reverse.first(4)
|
49
|
-
else
|
50
|
-
[]
|
40
|
+
@corrections ||= begin
|
41
|
+
maybe_these = routes&.named_routes&.helper_names&.grep(/#{route_name}/) || []
|
42
|
+
maybe_these -= [method_name.to_s] # remove exact match
|
43
|
+
|
44
|
+
DidYouMean::SpellChecker.new(dictionary: maybe_these).correct(route_name)
|
51
45
|
end
|
52
46
|
end
|
53
47
|
end
|
54
|
-
|
55
|
-
# We may not have DYM, and DYM might not let us register error handlers
|
56
|
-
if defined?(DidYouMean) && DidYouMean.respond_to?(:correct_error)
|
57
|
-
DidYouMean.correct_error(self, Correction)
|
58
|
-
end
|
59
48
|
end
|
60
49
|
|
61
|
-
class MethodNotAllowed < ActionControllerError
|
50
|
+
class MethodNotAllowed < ActionControllerError # :nodoc:
|
62
51
|
def initialize(*allowed_methods)
|
63
52
|
super("Only #{allowed_methods.to_sentence} requests are allowed.")
|
64
53
|
end
|
65
54
|
end
|
66
55
|
|
67
|
-
class NotImplemented < MethodNotAllowed
|
56
|
+
class NotImplemented < MethodNotAllowed # :nodoc:
|
68
57
|
end
|
69
58
|
|
70
|
-
class MissingFile < ActionControllerError
|
59
|
+
class MissingFile < ActionControllerError # :nodoc:
|
71
60
|
end
|
72
61
|
|
73
|
-
class SessionOverflowError < ActionControllerError
|
62
|
+
class SessionOverflowError < ActionControllerError # :nodoc:
|
74
63
|
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."
|
75
64
|
|
76
65
|
def initialize(message = nil)
|
@@ -78,10 +67,10 @@ module ActionController
|
|
78
67
|
end
|
79
68
|
end
|
80
69
|
|
81
|
-
class UnknownHttpMethod < ActionControllerError
|
70
|
+
class UnknownHttpMethod < ActionControllerError # :nodoc:
|
82
71
|
end
|
83
72
|
|
84
|
-
class UnknownFormat < ActionControllerError
|
73
|
+
class UnknownFormat < ActionControllerError # :nodoc:
|
85
74
|
end
|
86
75
|
|
87
76
|
# Raised when a nested respond_to is triggered and the content types of each
|
@@ -102,6 +91,6 @@ module ActionController
|
|
102
91
|
end
|
103
92
|
end
|
104
93
|
|
105
|
-
class MissingExactTemplate < UnknownFormat
|
94
|
+
class MissingExactTemplate < UnknownFormat # :nodoc:
|
106
95
|
end
|
107
96
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module ActionController
|
3
|
+
module ActionController # :nodoc:
|
4
4
|
module Flash
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
|
@@ -41,10 +41,14 @@ module ActionController #:nodoc:
|
|
41
41
|
self._flash_types += [type]
|
42
42
|
end
|
43
43
|
end
|
44
|
+
|
45
|
+
def action_methods # :nodoc:
|
46
|
+
@action_methods ||= super - _flash_types.map(&:to_s).to_set
|
47
|
+
end
|
44
48
|
end
|
45
49
|
|
46
50
|
private
|
47
|
-
def redirect_to(options = {}, response_options_and_flash = {})
|
51
|
+
def redirect_to(options = {}, response_options_and_flash = {}) # :doc:
|
48
52
|
self.class._flash_types.each do |flash_type|
|
49
53
|
if type = response_options_and_flash.delete(flash_type)
|
50
54
|
flash[flash_type] = type
|
@@ -2,12 +2,11 @@
|
|
2
2
|
|
3
3
|
require "base64"
|
4
4
|
require "active_support/security_utils"
|
5
|
-
require "active_support/core_ext/array/access"
|
6
5
|
|
7
6
|
module ActionController
|
8
|
-
#
|
7
|
+
# HTTP Basic, Digest and Token authentication.
|
9
8
|
module HttpAuthentication
|
10
|
-
#
|
9
|
+
# HTTP \Basic authentication.
|
11
10
|
#
|
12
11
|
# === Simple \Basic example
|
13
12
|
#
|
@@ -25,8 +24,8 @@ module ActionController
|
|
25
24
|
#
|
26
25
|
# === Advanced \Basic example
|
27
26
|
#
|
28
|
-
# Here is a more advanced \Basic example where only Atom feeds and the XML API
|
29
|
-
#
|
27
|
+
# Here is a more advanced \Basic example where only Atom feeds and the XML API are protected by HTTP authentication.
|
28
|
+
# The regular HTML interface is protected by a session approach:
|
30
29
|
#
|
31
30
|
# class ApplicationController < ActionController::Base
|
32
31
|
# before_action :set_account, :authenticate
|
@@ -135,15 +134,15 @@ module ActionController
|
|
135
134
|
end
|
136
135
|
end
|
137
136
|
|
138
|
-
#
|
137
|
+
# HTTP \Digest authentication.
|
139
138
|
#
|
140
139
|
# === Simple \Digest example
|
141
140
|
#
|
142
|
-
# require "
|
141
|
+
# require "openssl"
|
143
142
|
# class PostsController < ApplicationController
|
144
143
|
# REALM = "SuperSecret"
|
145
144
|
# USERS = {"dhh" => "secret", #plain text password
|
146
|
-
# "dap" => Digest::MD5.hexdigest(["dap",REALM,"secret"].join(":"))} #ha1 digest password
|
145
|
+
# "dap" => OpenSSL::Digest::MD5.hexdigest(["dap",REALM,"secret"].join(":"))} #ha1 digest password
|
147
146
|
#
|
148
147
|
# before_action :authenticate, except: [:index]
|
149
148
|
#
|
@@ -231,12 +230,12 @@ module ActionController
|
|
231
230
|
# of a plain-text password.
|
232
231
|
def expected_response(http_method, uri, credentials, password, password_is_ha1 = true)
|
233
232
|
ha1 = password_is_ha1 ? password : ha1(credentials, password)
|
234
|
-
ha2 = ::Digest::MD5.hexdigest([http_method.to_s.upcase, uri].join(":"))
|
235
|
-
::Digest::MD5.hexdigest([ha1, credentials[:nonce], credentials[:nc], credentials[:cnonce], credentials[:qop], ha2].join(":"))
|
233
|
+
ha2 = OpenSSL::Digest::MD5.hexdigest([http_method.to_s.upcase, uri].join(":"))
|
234
|
+
OpenSSL::Digest::MD5.hexdigest([ha1, credentials[:nonce], credentials[:nc], credentials[:cnonce], credentials[:qop], ha2].join(":"))
|
236
235
|
end
|
237
236
|
|
238
237
|
def ha1(credentials, password)
|
239
|
-
::Digest::MD5.hexdigest([credentials[:username], credentials[:realm], password].join(":"))
|
238
|
+
OpenSSL::Digest::MD5.hexdigest([credentials[:username], credentials[:realm], password].join(":"))
|
240
239
|
end
|
241
240
|
|
242
241
|
def encode_credentials(http_method, credentials, password, password_is_ha1)
|
@@ -310,7 +309,7 @@ module ActionController
|
|
310
309
|
def nonce(secret_key, time = Time.now)
|
311
310
|
t = time.to_i
|
312
311
|
hashed = [t, secret_key]
|
313
|
-
digest = ::Digest::MD5.hexdigest(hashed.join(":"))
|
312
|
+
digest = OpenSSL::Digest::MD5.hexdigest(hashed.join(":"))
|
314
313
|
::Base64.strict_encode64("#{t}:#{digest}")
|
315
314
|
end
|
316
315
|
|
@@ -327,11 +326,11 @@ module ActionController
|
|
327
326
|
|
328
327
|
# Opaque based on digest of secret key
|
329
328
|
def opaque(secret_key)
|
330
|
-
::Digest::MD5.hexdigest(secret_key)
|
329
|
+
OpenSSL::Digest::MD5.hexdigest(secret_key)
|
331
330
|
end
|
332
331
|
end
|
333
332
|
|
334
|
-
#
|
333
|
+
# HTTP Token authentication.
|
335
334
|
#
|
336
335
|
# Simple Token example:
|
337
336
|
#
|
@@ -359,8 +358,8 @@ module ActionController
|
|
359
358
|
# end
|
360
359
|
#
|
361
360
|
#
|
362
|
-
# Here is a more advanced Token example where only Atom feeds and the XML API
|
363
|
-
#
|
361
|
+
# Here is a more advanced Token example where only Atom feeds and the XML API are protected by HTTP token authentication.
|
362
|
+
# The regular HTML interface is protected by a session approach:
|
364
363
|
#
|
365
364
|
# class ApplicationController < ActionController::Base
|
366
365
|
# before_action :set_account, :authenticate
|