actionpack 4.2.11.1 → 6.1.3.2
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 +291 -489
- 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 +81 -51
- 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 +61 -33
- data/lib/abstract_controller/collector.rb +9 -13
- data/lib/abstract_controller/error.rb +6 -0
- data/lib/abstract_controller/helpers.rb +115 -99
- data/lib/abstract_controller/logger.rb +2 -0
- data/lib/abstract_controller/railties/routes_helpers.rb +21 -3
- data/lib/abstract_controller/rendering.rb +48 -47
- data/lib/abstract_controller/translation.rb +17 -8
- data/lib/abstract_controller/url_for.rb +2 -0
- data/lib/abstract_controller.rb +13 -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 +29 -24
- data/lib/action_controller/caching.rb +12 -57
- data/lib/action_controller/form_builder.rb +50 -0
- data/lib/action_controller/log_subscriber.rb +17 -19
- data/lib/action_controller/metal/basic_implicit_render.rb +13 -0
- data/lib/action_controller/metal/conditional_get.rb +134 -46
- data/lib/action_controller/metal/content_security_policy.rb +51 -0
- data/lib/action_controller/metal/cookies.rb +6 -4
- data/lib/action_controller/metal/data_streaming.rb +30 -50
- 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 +21 -16
- data/lib/action_controller/metal/exceptions.rb +63 -15
- data/lib/action_controller/metal/flash.rb +9 -8
- data/lib/action_controller/metal/head.rb +26 -21
- data/lib/action_controller/metal/helpers.rb +37 -18
- data/lib/action_controller/metal/http_authentication.rb +81 -73
- data/lib/action_controller/metal/implicit_render.rb +53 -9
- data/lib/action_controller/metal/instrumentation.rb +32 -35
- data/lib/action_controller/metal/live.rb +102 -120
- data/lib/action_controller/metal/logging.rb +20 -0
- data/lib/action_controller/metal/mime_responds.rb +49 -47
- data/lib/action_controller/metal/parameter_encoding.rb +82 -0
- data/lib/action_controller/metal/params_wrapper.rb +83 -66
- data/lib/action_controller/metal/permissions_policy.rb +46 -0
- 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 +77 -50
- data/lib/action_controller/metal/request_forgery_protection.rb +267 -103
- data/lib/action_controller/metal/rescue.rb +10 -17
- data/lib/action_controller/metal/streaming.rb +12 -11
- data/lib/action_controller/metal/strong_parameters.rb +714 -186
- 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 +141 -0
- data/lib/action_controller/template_assertions.rb +11 -0
- data/lib/action_controller/test_case.rb +296 -422
- data/lib/action_controller.rb +34 -23
- data/lib/action_dispatch/http/cache.rb +107 -56
- data/lib/action_dispatch/http/content_disposition.rb +45 -0
- data/lib/action_dispatch/http/content_security_policy.rb +286 -0
- data/lib/action_dispatch/http/filter_parameters.rb +32 -25
- data/lib/action_dispatch/http/filter_redirect.rb +10 -12
- data/lib/action_dispatch/http/headers.rb +55 -22
- data/lib/action_dispatch/http/mime_negotiation.rb +79 -51
- data/lib/action_dispatch/http/mime_type.rb +153 -121
- data/lib/action_dispatch/http/mime_types.rb +20 -6
- data/lib/action_dispatch/http/parameters.rb +90 -40
- data/lib/action_dispatch/http/permissions_policy.rb +173 -0
- data/lib/action_dispatch/http/rack_cache.rb +2 -0
- data/lib/action_dispatch/http/request.rb +226 -121
- data/lib/action_dispatch/http/response.rb +248 -113
- data/lib/action_dispatch/http/upload.rb +21 -7
- data/lib/action_dispatch/http/url.rb +182 -100
- data/lib/action_dispatch/journey/formatter.rb +90 -43
- data/lib/action_dispatch/journey/gtg/builder.rb +28 -41
- data/lib/action_dispatch/journey/gtg/simulator.rb +11 -16
- data/lib/action_dispatch/journey/gtg/transition_table.rb +23 -21
- data/lib/action_dispatch/journey/nfa/dot.rb +3 -14
- data/lib/action_dispatch/journey/nodes/node.rb +29 -15
- data/lib/action_dispatch/journey/parser.rb +17 -16
- data/lib/action_dispatch/journey/parser.y +4 -3
- data/lib/action_dispatch/journey/parser_extras.rb +12 -4
- data/lib/action_dispatch/journey/path/pattern.rb +58 -54
- data/lib/action_dispatch/journey/route.rb +100 -32
- data/lib/action_dispatch/journey/router/utils.rb +29 -18
- data/lib/action_dispatch/journey/router.rb +55 -51
- 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 +5 -5
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +46 -0
- data/lib/action_dispatch/middleware/callbacks.rb +3 -6
- data/lib/action_dispatch/middleware/cookies.rb +347 -217
- data/lib/action_dispatch/middleware/debug_exceptions.rb +135 -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 +115 -71
- 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 +130 -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 +53 -45
- data/lib/action_dispatch/middleware/request_id.rb +17 -10
- 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 +74 -75
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -2
- data/lib/action_dispatch/middleware/show_exceptions.rb +28 -23
- data/lib/action_dispatch/middleware/ssl.rb +118 -35
- data/lib/action_dispatch/middleware/stack.rb +82 -41
- data/lib/action_dispatch/middleware/static.rb +156 -89
- 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/_message_and_suggestions.html.erb +22 -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 +23 -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 +105 -8
- 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/rescues/unknown_action.html.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 +87 -64
- data/lib/action_dispatch/railtie.rb +27 -13
- data/lib/action_dispatch/request/session.rb +109 -61
- data/lib/action_dispatch/request/utils.rb +90 -23
- data/lib/action_dispatch/routing/endpoint.rb +9 -2
- data/lib/action_dispatch/routing/inspector.rb +141 -102
- data/lib/action_dispatch/routing/mapper.rb +811 -473
- data/lib/action_dispatch/routing/polymorphic_routes.rb +167 -143
- data/lib/action_dispatch/routing/redirection.rb +37 -27
- data/lib/action_dispatch/routing/route_set.rb +363 -331
- data/lib/action_dispatch/routing/routes_proxy.rb +32 -5
- data/lib/action_dispatch/routing/url_for.rb +66 -26
- data/lib/action_dispatch/routing.rb +36 -36
- data/lib/action_dispatch/system_test_case.rb +190 -0
- data/lib/action_dispatch/system_testing/browser.rb +86 -0
- data/lib/action_dispatch/system_testing/driver.rb +67 -0
- data/lib/action_dispatch/system_testing/server.rb +31 -0
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +138 -0
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +29 -0
- data/lib/action_dispatch/testing/assertion_response.rb +46 -0
- data/lib/action_dispatch/testing/assertions/response.rb +44 -22
- data/lib/action_dispatch/testing/assertions/routing.rb +47 -31
- data/lib/action_dispatch/testing/assertions.rb +6 -4
- data/lib/action_dispatch/testing/integration.rb +391 -220
- data/lib/action_dispatch/testing/request_encoder.rb +55 -0
- data/lib/action_dispatch/testing/test_process.rb +53 -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 +35 -21
- 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 +78 -48
- data/lib/action_controller/metal/force_ssl.rb +0 -97
- 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/http/parameter_filter.rb +0 -72
- data/lib/action_dispatch/journey/backwards.rb +0 -5
- data/lib/action_dispatch/journey/nfa/builder.rb +0 -76
- data/lib/action_dispatch/journey/nfa/simulator.rb +0 -47
- data/lib/action_dispatch/journey/nfa/transition_table.rb +0 -163
- 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,31 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActionController
|
2
4
|
module Testing
|
3
5
|
extend ActiveSupport::Concern
|
4
6
|
|
5
|
-
include RackDelegation
|
6
|
-
|
7
|
-
# TODO : Rewrite tests using controller.headers= to use Rack env
|
8
|
-
def headers=(new_headers)
|
9
|
-
@_response ||= ActionDispatch::Response.new
|
10
|
-
@_response.headers.replace(new_headers)
|
11
|
-
end
|
12
|
-
|
13
7
|
# Behavior specific to functional tests
|
14
8
|
module Functional # :nodoc:
|
15
|
-
def set_response!(request)
|
16
|
-
end
|
17
|
-
|
18
9
|
def recycle!
|
19
10
|
@_url_options = nil
|
20
11
|
self.formats = nil
|
21
12
|
self.params = nil
|
22
13
|
end
|
23
14
|
end
|
24
|
-
|
25
|
-
module ClassMethods
|
26
|
-
def before_filters
|
27
|
-
_process_action_callbacks.find_all{|x| x.kind == :before}.map{|x| x.name}
|
28
|
-
end
|
29
|
-
end
|
30
15
|
end
|
31
16
|
end
|
@@ -1,10 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActionController
|
2
4
|
# Includes +url_for+ into the host class. The class has to provide a +RouteSet+ by implementing
|
3
5
|
# the <tt>_routes</tt> method. Otherwise, an exception will be raised.
|
4
6
|
#
|
5
7
|
# In addition to <tt>AbstractController::UrlFor</tt>, this module accesses the HTTP layer to define
|
6
|
-
#
|
7
|
-
# to implement +env+
|
8
|
+
# URL options like the +host+. In order to do so, this module requires the host class
|
9
|
+
# to implement +env+ which needs to be Rack-compatible and +request+
|
10
|
+
# which is either an instance of +ActionDispatch::Request+ or an object
|
11
|
+
# that responds to the +host+, +optional_port+, +protocol+ and
|
12
|
+
# +symbolized_path_parameter+ methods.
|
8
13
|
#
|
9
14
|
# class RootUrl
|
10
15
|
# include ActionController::UrlFor
|
@@ -24,21 +29,25 @@ module ActionController
|
|
24
29
|
|
25
30
|
def url_options
|
26
31
|
@_url_options ||= {
|
27
|
-
:
|
28
|
-
:
|
29
|
-
:
|
30
|
-
:
|
32
|
+
host: request.host,
|
33
|
+
port: request.optional_port,
|
34
|
+
protocol: request.protocol,
|
35
|
+
_recall: request.path_parameters
|
31
36
|
}.merge!(super).freeze
|
32
37
|
|
33
|
-
if (same_origin = _routes.equal?(
|
34
|
-
(script_name =
|
35
|
-
(original_script_name =
|
38
|
+
if (same_origin = _routes.equal?(request.routes)) ||
|
39
|
+
(script_name = request.engine_script_name(_routes)) ||
|
40
|
+
(original_script_name = request.original_script_name)
|
36
41
|
|
37
42
|
options = @_url_options.dup
|
38
43
|
if original_script_name
|
39
44
|
options[:original_script_name] = original_script_name
|
40
45
|
else
|
41
|
-
|
46
|
+
if same_origin
|
47
|
+
options[:script_name] = request.script_name.empty? ? "" : request.script_name.dup
|
48
|
+
else
|
49
|
+
options[:script_name] = script_name
|
50
|
+
end
|
42
51
|
end
|
43
52
|
options.freeze
|
44
53
|
else
|
@@ -1,5 +1,9 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/array/extract_options"
|
4
|
+
require "action_dispatch/middleware/stack"
|
5
|
+
require "action_dispatch/http/request"
|
6
|
+
require "action_dispatch/http/response"
|
3
7
|
|
4
8
|
module ActionController
|
5
9
|
# Extend ActionDispatch middleware stack to make it aware of options
|
@@ -11,32 +15,49 @@ module ActionController
|
|
11
15
|
#
|
12
16
|
class MiddlewareStack < ActionDispatch::MiddlewareStack #:nodoc:
|
13
17
|
class Middleware < ActionDispatch::MiddlewareStack::Middleware #:nodoc:
|
14
|
-
def initialize(klass,
|
15
|
-
|
16
|
-
@
|
17
|
-
|
18
|
-
args << options unless options.empty?
|
19
|
-
super
|
18
|
+
def initialize(klass, args, actions, strategy, block)
|
19
|
+
@actions = actions
|
20
|
+
@strategy = strategy
|
21
|
+
super(klass, args, block)
|
20
22
|
end
|
21
23
|
|
22
24
|
def valid?(action)
|
23
|
-
|
24
|
-
@only.include?(action)
|
25
|
-
elsif @except.present?
|
26
|
-
!@except.include?(action)
|
27
|
-
else
|
28
|
-
true
|
29
|
-
end
|
25
|
+
@strategy.call @actions, action
|
30
26
|
end
|
31
27
|
end
|
32
28
|
|
33
|
-
def build(action, app =
|
29
|
+
def build(action, app = nil, &block)
|
34
30
|
action = action.to_s
|
35
31
|
|
36
|
-
middlewares.reverse.inject(app) do |a, middleware|
|
32
|
+
middlewares.reverse.inject(app || block) do |a, middleware|
|
37
33
|
middleware.valid?(action) ? middleware.build(a) : a
|
38
34
|
end
|
39
35
|
end
|
36
|
+
|
37
|
+
private
|
38
|
+
INCLUDE = ->(list, action) { list.include? action }
|
39
|
+
EXCLUDE = ->(list, action) { !list.include? action }
|
40
|
+
NULL = ->(list, action) { true }
|
41
|
+
|
42
|
+
def build_middleware(klass, args, block)
|
43
|
+
options = args.extract_options!
|
44
|
+
only = Array(options.delete(:only)).map(&:to_s)
|
45
|
+
except = Array(options.delete(:except)).map(&:to_s)
|
46
|
+
args << options unless options.empty?
|
47
|
+
|
48
|
+
strategy = NULL
|
49
|
+
list = nil
|
50
|
+
|
51
|
+
if only.any?
|
52
|
+
strategy = INCLUDE
|
53
|
+
list = only
|
54
|
+
elsif except.any?
|
55
|
+
strategy = EXCLUDE
|
56
|
+
list = except
|
57
|
+
end
|
58
|
+
|
59
|
+
Middleware.new(klass, args, list, strategy, block)
|
60
|
+
end
|
40
61
|
end
|
41
62
|
|
42
63
|
# <tt>ActionController::Metal</tt> is the simplest possible controller, providing a
|
@@ -98,12 +119,6 @@ module ActionController
|
|
98
119
|
class Metal < AbstractController::Base
|
99
120
|
abstract!
|
100
121
|
|
101
|
-
attr_internal_writer :env
|
102
|
-
|
103
|
-
def env
|
104
|
-
@_env ||= {}
|
105
|
-
end
|
106
|
-
|
107
122
|
# Returns the last part of the controller's name, underscored, without the ending
|
108
123
|
# <tt>Controller</tt>. For instance, PostsController returns <tt>posts</tt>.
|
109
124
|
# Namespaces are left out, so Admin::PostsController returns <tt>posts</tt> as well.
|
@@ -111,26 +126,30 @@ module ActionController
|
|
111
126
|
# ==== Returns
|
112
127
|
# * <tt>string</tt>
|
113
128
|
def self.controller_name
|
114
|
-
@controller_name ||= name.demodulize.
|
129
|
+
@controller_name ||= (name.demodulize.delete_suffix("Controller").underscore unless anonymous?)
|
115
130
|
end
|
116
131
|
|
117
|
-
|
132
|
+
def self.make_response!(request)
|
133
|
+
ActionDispatch::Response.new.tap do |res|
|
134
|
+
res.request = request
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def self.action_encoding_template(action) # :nodoc:
|
139
|
+
false
|
140
|
+
end
|
141
|
+
|
142
|
+
# Delegates to the class' <tt>controller_name</tt>.
|
118
143
|
def controller_name
|
119
144
|
self.class.controller_name
|
120
145
|
end
|
121
146
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
# environment and response manually for performance reasons.
|
127
|
-
|
128
|
-
attr_internal :headers, :response, :request
|
129
|
-
delegate :session, :to => "@_request"
|
147
|
+
attr_internal :response, :request
|
148
|
+
delegate :session, to: "@_request"
|
149
|
+
delegate :headers, :status=, :location=, :content_type=,
|
150
|
+
:status, :location, :content_type, :media_type, to: "@_response"
|
130
151
|
|
131
152
|
def initialize
|
132
|
-
@_headers = {"Content-Type" => "text/html"}
|
133
|
-
@_status = 200
|
134
153
|
@_request = nil
|
135
154
|
@_response = nil
|
136
155
|
@_routes = nil
|
@@ -145,74 +164,65 @@ module ActionController
|
|
145
164
|
@_params = val
|
146
165
|
end
|
147
166
|
|
148
|
-
|
149
|
-
# provided to reduce the dependency on the RackDelegation module
|
150
|
-
# in Renderer and Redirector.
|
151
|
-
|
152
|
-
def content_type=(type)
|
153
|
-
headers["Content-Type"] = type.to_s
|
154
|
-
end
|
155
|
-
|
156
|
-
def content_type
|
157
|
-
headers["Content-Type"]
|
158
|
-
end
|
159
|
-
|
160
|
-
def location
|
161
|
-
headers["Location"]
|
162
|
-
end
|
163
|
-
|
164
|
-
def location=(url)
|
165
|
-
headers["Location"] = url
|
166
|
-
end
|
167
|
+
alias :response_code :status # :nodoc:
|
167
168
|
|
168
|
-
# Basic url_for that can be overridden for more robust functionality
|
169
|
+
# Basic url_for that can be overridden for more robust functionality.
|
169
170
|
def url_for(string)
|
170
171
|
string
|
171
172
|
end
|
172
173
|
|
173
|
-
def status
|
174
|
-
@_status
|
175
|
-
end
|
176
|
-
alias :response_code :status # :nodoc:
|
177
|
-
|
178
|
-
def status=(status)
|
179
|
-
@_status = Rack::Utils.status_code(status)
|
180
|
-
end
|
181
|
-
|
182
174
|
def response_body=(body)
|
183
175
|
body = [body] unless body.nil? || body.respond_to?(:each)
|
176
|
+
response.reset_body!
|
177
|
+
return unless body
|
178
|
+
response.body = body
|
184
179
|
super
|
185
180
|
end
|
186
181
|
|
187
182
|
# Tests if render or redirect has already happened.
|
188
183
|
def performed?
|
189
|
-
response_body ||
|
184
|
+
response_body || response.committed?
|
190
185
|
end
|
191
186
|
|
192
|
-
def dispatch(name, request) #:nodoc:
|
193
|
-
|
194
|
-
|
195
|
-
@_env['action_controller.instance'] = self
|
187
|
+
def dispatch(name, request, response) #:nodoc:
|
188
|
+
set_request!(request)
|
189
|
+
set_response!(response)
|
196
190
|
process(name)
|
191
|
+
request.commit_flash
|
197
192
|
to_a
|
198
193
|
end
|
199
194
|
|
195
|
+
def set_response!(response) # :nodoc:
|
196
|
+
@_response = response
|
197
|
+
end
|
198
|
+
|
199
|
+
def set_request!(request) #:nodoc:
|
200
|
+
@_request = request
|
201
|
+
@_request.controller_instance = self
|
202
|
+
end
|
203
|
+
|
200
204
|
def to_a #:nodoc:
|
201
|
-
response
|
205
|
+
response.to_a
|
202
206
|
end
|
203
207
|
|
204
|
-
|
205
|
-
|
208
|
+
def reset_session
|
209
|
+
@_request.reset_session
|
210
|
+
end
|
211
|
+
|
212
|
+
class_attribute :middleware_stack, default: ActionController::MiddlewareStack.new
|
206
213
|
|
207
214
|
def self.inherited(base) # :nodoc:
|
208
215
|
base.middleware_stack = middleware_stack.dup
|
209
216
|
super
|
210
217
|
end
|
211
218
|
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
219
|
+
class << self
|
220
|
+
# Pushes the given Rack middleware and its arguments to the bottom of the
|
221
|
+
# middleware stack.
|
222
|
+
def use(*args, &block)
|
223
|
+
middleware_stack.use(*args, &block)
|
224
|
+
end
|
225
|
+
ruby2_keywords(:use) if respond_to?(:ruby2_keywords, true)
|
216
226
|
end
|
217
227
|
|
218
228
|
# Alias for +middleware_stack+.
|
@@ -220,21 +230,28 @@ module ActionController
|
|
220
230
|
middleware_stack
|
221
231
|
end
|
222
232
|
|
223
|
-
#
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
233
|
+
# Returns a Rack endpoint for the given action name.
|
234
|
+
def self.action(name)
|
235
|
+
app = lambda { |env|
|
236
|
+
req = ActionDispatch::Request.new(env)
|
237
|
+
res = make_response! req
|
238
|
+
new.dispatch(name, req, res)
|
239
|
+
}
|
240
|
+
|
241
|
+
if middleware_stack.any?
|
242
|
+
middleware_stack.build(name, app)
|
243
|
+
else
|
244
|
+
app
|
245
|
+
end
|
228
246
|
end
|
229
247
|
|
230
|
-
#
|
231
|
-
|
248
|
+
# Direct dispatch to the controller. Instantiates the controller, then
|
249
|
+
# executes the action named +name+.
|
250
|
+
def self.dispatch(name, req, res)
|
232
251
|
if middleware_stack.any?
|
233
|
-
middleware_stack.build(name)
|
234
|
-
new.dispatch(name, klass.new(env))
|
235
|
-
end
|
252
|
+
middleware_stack.build(name) { |env| new.dispatch(name, req, res) }.call req.env
|
236
253
|
else
|
237
|
-
|
254
|
+
new.dispatch(name, req, res)
|
238
255
|
end
|
239
256
|
end
|
240
257
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "rails"
|
2
4
|
require "action_controller"
|
3
5
|
require "action_dispatch/railtie"
|
@@ -11,7 +13,7 @@ module ActionController
|
|
11
13
|
|
12
14
|
config.eager_load_namespaces << ActionController
|
13
15
|
|
14
|
-
initializer "action_controller.assets_config", :
|
16
|
+
initializer "action_controller.assets_config", group: :all do |app|
|
15
17
|
app.config.action_controller.assets_dir ||= app.config.paths["public"].first
|
16
18
|
end
|
17
19
|
|
@@ -22,13 +24,15 @@ module ActionController
|
|
22
24
|
initializer "action_controller.parameters_config" do |app|
|
23
25
|
options = app.config.action_controller
|
24
26
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
27
|
+
ActiveSupport.on_load(:action_controller, run_once: true) do
|
28
|
+
ActionController::Parameters.permit_all_parameters = options.delete(:permit_all_parameters) { false }
|
29
|
+
if app.config.action_controller[:always_permitted_parameters]
|
30
|
+
ActionController::Parameters.always_permitted_parameters =
|
31
|
+
app.config.action_controller.delete(:always_permitted_parameters)
|
32
|
+
end
|
33
|
+
ActionController::Parameters.action_on_unpermitted_parameters = options.delete(:action_on_unpermitted_parameters) do
|
34
|
+
(Rails.env.test? || Rails.env.development?) ? :log : false
|
35
|
+
end
|
32
36
|
end
|
33
37
|
end
|
34
38
|
|
@@ -42,7 +46,7 @@ module ActionController
|
|
42
46
|
options.javascripts_dir ||= paths["public/javascripts"].first
|
43
47
|
options.stylesheets_dir ||= paths["public/stylesheets"].first
|
44
48
|
|
45
|
-
# Ensure readers methods get compiled
|
49
|
+
# Ensure readers methods get compiled.
|
46
50
|
options.asset_host ||= app.config.asset_host
|
47
51
|
options.relative_url_root ||= app.config.relative_url_root
|
48
52
|
|
@@ -51,7 +55,7 @@ module ActionController
|
|
51
55
|
extend ::AbstractController::Railties::RoutesHelpers.with(app.routes)
|
52
56
|
extend ::ActionController::Railties::Helpers
|
53
57
|
|
54
|
-
options.each do |k,v|
|
58
|
+
options.each do |k, v|
|
55
59
|
k = "#{k}="
|
56
60
|
if respond_to?(k)
|
57
61
|
send(k, v)
|
@@ -67,5 +71,19 @@ module ActionController
|
|
67
71
|
config.compile_methods! if config.respond_to?(:compile_methods!)
|
68
72
|
end
|
69
73
|
end
|
74
|
+
|
75
|
+
initializer "action_controller.request_forgery_protection" do |app|
|
76
|
+
ActiveSupport.on_load(:action_controller_base) do
|
77
|
+
if app.config.action_controller.default_protect_from_forgery
|
78
|
+
protect_from_forgery with: :exception
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
initializer "action_controller.eager_load_actions" do
|
84
|
+
ActiveSupport.on_load(:after_initialize) do
|
85
|
+
ActionController::Metal.descendants.each(&:action_methods) if config.eager_load
|
86
|
+
end
|
87
|
+
end
|
70
88
|
end
|
71
89
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActionController
|
2
4
|
module Railties
|
3
5
|
module Helpers
|
@@ -5,7 +7,7 @@ module ActionController
|
|
5
7
|
super
|
6
8
|
return unless klass.respond_to?(:helpers_path=)
|
7
9
|
|
8
|
-
if namespace = klass.
|
10
|
+
if namespace = klass.module_parents.detect { |m| m.respond_to?(:railtie_helpers_paths) }
|
9
11
|
paths = namespace.railtie_helpers_paths
|
10
12
|
else
|
11
13
|
paths = ActionController::Helpers.helpers_path
|
@@ -0,0 +1,141 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionController
|
4
|
+
# ActionController::Renderer allows you to render arbitrary templates
|
5
|
+
# without requirement of being in controller actions.
|
6
|
+
#
|
7
|
+
# You get a concrete renderer class by invoking ActionController::Base#renderer.
|
8
|
+
# For example:
|
9
|
+
#
|
10
|
+
# ApplicationController.renderer
|
11
|
+
#
|
12
|
+
# It allows you to call method #render directly.
|
13
|
+
#
|
14
|
+
# ApplicationController.renderer.render template: '...'
|
15
|
+
#
|
16
|
+
# You can use this shortcut in a controller, instead of the previous example:
|
17
|
+
#
|
18
|
+
# ApplicationController.render template: '...'
|
19
|
+
#
|
20
|
+
# #render allows you to use the same options that you can use when rendering in a controller.
|
21
|
+
# For example:
|
22
|
+
#
|
23
|
+
# FooController.render :action, locals: { ... }, assigns: { ... }
|
24
|
+
#
|
25
|
+
# The template will be rendered in a Rack environment which is accessible through
|
26
|
+
# ActionController::Renderer#env. You can set it up in two ways:
|
27
|
+
#
|
28
|
+
# * by changing renderer defaults, like
|
29
|
+
#
|
30
|
+
# ApplicationController.renderer.defaults # => hash with default Rack environment
|
31
|
+
#
|
32
|
+
# * by initializing an instance of renderer by passing it a custom environment.
|
33
|
+
#
|
34
|
+
# ApplicationController.renderer.new(method: 'post', https: true)
|
35
|
+
#
|
36
|
+
class Renderer
|
37
|
+
attr_reader :defaults, :controller
|
38
|
+
|
39
|
+
DEFAULTS = {
|
40
|
+
http_host: "example.org",
|
41
|
+
https: false,
|
42
|
+
method: "get",
|
43
|
+
script_name: "",
|
44
|
+
input: ""
|
45
|
+
}.freeze
|
46
|
+
|
47
|
+
# Create a new renderer instance for a specific controller class.
|
48
|
+
def self.for(controller, env = {}, defaults = DEFAULTS.dup)
|
49
|
+
new(controller, env, defaults)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Create a new renderer for the same controller but with a new env.
|
53
|
+
def new(env = {})
|
54
|
+
self.class.new controller, env, defaults
|
55
|
+
end
|
56
|
+
|
57
|
+
# Create a new renderer for the same controller but with new defaults.
|
58
|
+
def with_defaults(defaults)
|
59
|
+
self.class.new controller, @env, self.defaults.merge(defaults)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Accepts a custom Rack environment to render templates in.
|
63
|
+
# It will be merged with the default Rack environment defined by
|
64
|
+
# +ActionController::Renderer::DEFAULTS+.
|
65
|
+
def initialize(controller, env, defaults)
|
66
|
+
@controller = controller
|
67
|
+
@defaults = defaults
|
68
|
+
@env = normalize_keys defaults, env
|
69
|
+
end
|
70
|
+
|
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 an ERB template string.
|
78
|
+
# * <tt>:plain</tt> - Renders provided text and sets the content type as <tt>text/plain</tt>.
|
79
|
+
# * <tt>:html</tt> - Renders the provided HTML safe string, otherwise
|
80
|
+
# performs HTML escape on the string first. Sets the content type as <tt>text/html</tt>.
|
81
|
+
# * <tt>:json</tt> - Renders the provided hash or object in JSON. You don't
|
82
|
+
# need to call <tt>.to_json</tt> on the object you want to render.
|
83
|
+
# * <tt>:body</tt> - Renders provided text and sets content type of <tt>text/plain</tt>.
|
84
|
+
#
|
85
|
+
# If no <tt>options</tt> hash is passed or if <tt>:update</tt> is specified, then:
|
86
|
+
#
|
87
|
+
# If an object responding to +render_in+ is passed, +render_in+ is called on the object,
|
88
|
+
# passing in the current view context.
|
89
|
+
#
|
90
|
+
# Otherwise, a partial is rendered using the second parameter as the locals hash.
|
91
|
+
def render(*args)
|
92
|
+
raise "missing controller" unless controller
|
93
|
+
|
94
|
+
request = ActionDispatch::Request.new @env
|
95
|
+
request.routes = controller._routes
|
96
|
+
|
97
|
+
instance = controller.new
|
98
|
+
instance.set_request! request
|
99
|
+
instance.set_response! controller.make_response!(request)
|
100
|
+
instance.render_to_string(*args)
|
101
|
+
end
|
102
|
+
alias_method :render_to_string, :render # :nodoc:
|
103
|
+
|
104
|
+
private
|
105
|
+
def normalize_keys(defaults, env)
|
106
|
+
new_env = {}
|
107
|
+
env.each_pair { |k, v| new_env[rack_key_for(k)] = rack_value_for(k, v) }
|
108
|
+
|
109
|
+
defaults.each_pair do |k, v|
|
110
|
+
key = rack_key_for(k)
|
111
|
+
new_env[key] = rack_value_for(k, v) unless new_env.key?(key)
|
112
|
+
end
|
113
|
+
|
114
|
+
new_env["rack.url_scheme"] = new_env["HTTPS"] == "on" ? "https" : "http"
|
115
|
+
new_env
|
116
|
+
end
|
117
|
+
|
118
|
+
RACK_KEY_TRANSLATION = {
|
119
|
+
http_host: "HTTP_HOST",
|
120
|
+
https: "HTTPS",
|
121
|
+
method: "REQUEST_METHOD",
|
122
|
+
script_name: "SCRIPT_NAME",
|
123
|
+
input: "rack.input"
|
124
|
+
}
|
125
|
+
|
126
|
+
def rack_key_for(key)
|
127
|
+
RACK_KEY_TRANSLATION[key] || key.to_s
|
128
|
+
end
|
129
|
+
|
130
|
+
def rack_value_for(key, value)
|
131
|
+
case key
|
132
|
+
when :https
|
133
|
+
value ? "on" : "off"
|
134
|
+
when :method
|
135
|
+
-value.upcase
|
136
|
+
else
|
137
|
+
value
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionController
|
4
|
+
module TemplateAssertions # :nodoc:
|
5
|
+
def assert_template(options = {}, message = nil)
|
6
|
+
raise NoMethodError,
|
7
|
+
"assert_template has been extracted to a gem. To continue using it,
|
8
|
+
add `gem 'rails-controller-testing'` to your Gemfile."
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|