actionpack 4.2.11.1 → 5.2.4
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 +279 -497
- data/MIT-LICENSE +1 -1
- data/README.rdoc +6 -7
- data/lib/abstract_controller/asset_paths.rb +2 -0
- data/lib/abstract_controller/base.rb +45 -49
- data/lib/{action_controller → abstract_controller}/caching/fragments.rb +78 -15
- data/lib/abstract_controller/caching.rb +66 -0
- data/lib/abstract_controller/callbacks.rb +47 -31
- data/lib/abstract_controller/collector.rb +8 -11
- data/lib/abstract_controller/error.rb +6 -0
- data/lib/abstract_controller/helpers.rb +25 -25
- data/lib/abstract_controller/logger.rb +2 -0
- data/lib/abstract_controller/railties/routes_helpers.rb +4 -2
- data/lib/abstract_controller/rendering.rb +42 -41
- data/lib/abstract_controller/translation.rb +10 -7
- 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 +149 -0
- data/lib/action_controller/base.rb +27 -19
- data/lib/action_controller/caching.rb +14 -57
- data/lib/action_controller/form_builder.rb +50 -0
- data/lib/action_controller/log_subscriber.rb +10 -15
- data/lib/action_controller/metal/basic_implicit_render.rb +13 -0
- data/lib/action_controller/metal/conditional_get.rb +118 -44
- data/lib/action_controller/metal/content_security_policy.rb +52 -0
- data/lib/action_controller/metal/cookies.rb +3 -3
- data/lib/action_controller/metal/data_streaming.rb +27 -46
- 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 +8 -14
- data/lib/action_controller/metal/flash.rb +4 -3
- data/lib/action_controller/metal/force_ssl.rb +23 -21
- data/lib/action_controller/metal/head.rb +21 -19
- data/lib/action_controller/metal/helpers.rb +24 -14
- data/lib/action_controller/metal/http_authentication.rb +64 -57
- data/lib/action_controller/metal/implicit_render.rb +62 -8
- data/lib/action_controller/metal/instrumentation.rb +19 -21
- data/lib/action_controller/metal/live.rb +90 -106
- data/lib/action_controller/metal/mime_responds.rb +33 -46
- data/lib/action_controller/metal/parameter_encoding.rb +51 -0
- data/lib/action_controller/metal/params_wrapper.rb +61 -53
- data/lib/action_controller/metal/redirecting.rb +49 -28
- data/lib/action_controller/metal/renderers.rb +87 -44
- data/lib/action_controller/metal/rendering.rb +72 -50
- data/lib/action_controller/metal/request_forgery_protection.rb +203 -92
- data/lib/action_controller/metal/rescue.rb +9 -16
- data/lib/action_controller/metal/streaming.rb +12 -10
- data/lib/action_controller/metal/strong_parameters.rb +582 -165
- 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 +98 -83
- data/lib/action_controller/railtie.rb +28 -10
- data/lib/action_controller/railties/helpers.rb +2 -0
- data/lib/action_controller/renderer.rb +117 -0
- data/lib/action_controller/template_assertions.rb +11 -0
- data/lib/action_controller/test_case.rb +280 -411
- data/lib/action_controller.rb +29 -21
- data/lib/action_dispatch/http/cache.rb +93 -47
- data/lib/action_dispatch/http/content_security_policy.rb +272 -0
- data/lib/action_dispatch/http/filter_parameters.rb +26 -20
- data/lib/action_dispatch/http/filter_redirect.rb +10 -11
- data/lib/action_dispatch/http/headers.rb +55 -22
- data/lib/action_dispatch/http/mime_negotiation.rb +56 -41
- data/lib/action_dispatch/http/mime_type.rb +134 -121
- data/lib/action_dispatch/http/mime_types.rb +20 -6
- data/lib/action_dispatch/http/parameter_filter.rb +25 -11
- data/lib/action_dispatch/http/parameters.rb +98 -39
- data/lib/action_dispatch/http/rack_cache.rb +2 -0
- data/lib/action_dispatch/http/request.rb +200 -118
- data/lib/action_dispatch/http/response.rb +225 -110
- data/lib/action_dispatch/http/upload.rb +12 -6
- data/lib/action_dispatch/http/url.rb +110 -28
- data/lib/action_dispatch/journey/formatter.rb +55 -32
- data/lib/action_dispatch/journey/gtg/builder.rb +7 -5
- data/lib/action_dispatch/journey/gtg/simulator.rb +3 -9
- data/lib/action_dispatch/journey/gtg/transition_table.rb +17 -16
- 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 -1
- data/lib/action_dispatch/journey/nfa/transition_table.rb +5 -48
- data/lib/action_dispatch/journey/nodes/node.rb +18 -6
- 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 +50 -44
- data/lib/action_dispatch/journey/route.rb +106 -28
- data/lib/action_dispatch/journey/router/utils.rb +20 -11
- data/lib/action_dispatch/journey/router.rb +35 -23
- data/lib/action_dispatch/journey/routes.rb +18 -16
- data/lib/action_dispatch/journey/scanner.rb +18 -15
- data/lib/action_dispatch/journey/visitors.rb +99 -52
- data/lib/action_dispatch/journey.rb +7 -5
- data/lib/action_dispatch/middleware/callbacks.rb +1 -2
- data/lib/action_dispatch/middleware/cookies.rb +304 -193
- data/lib/action_dispatch/middleware/debug_exceptions.rb +152 -57
- data/lib/action_dispatch/middleware/debug_locks.rb +124 -0
- data/lib/action_dispatch/middleware/exception_wrapper.rb +68 -69
- data/lib/action_dispatch/middleware/executor.rb +21 -0
- data/lib/action_dispatch/middleware/flash.rb +78 -54
- data/lib/action_dispatch/middleware/public_exceptions.rb +27 -25
- data/lib/action_dispatch/middleware/reloader.rb +5 -91
- data/lib/action_dispatch/middleware/remote_ip.rb +41 -31
- data/lib/action_dispatch/middleware/request_id.rb +17 -9
- data/lib/action_dispatch/middleware/session/abstract_store.rb +28 -26
- data/lib/action_dispatch/middleware/session/cache_store.rb +14 -9
- data/lib/action_dispatch/middleware/session/cookie_store.rb +62 -67
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -2
- data/lib/action_dispatch/middleware/show_exceptions.rb +26 -22
- data/lib/action_dispatch/middleware/ssl.rb +114 -36
- data/lib/action_dispatch/middleware/stack.rb +31 -44
- data/lib/action_dispatch/middleware/static.rb +57 -50
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +2 -14
- data/lib/action_dispatch/middleware/templates/rescues/{_source.erb → _source.html.erb} +0 -0
- data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +21 -0
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +13 -0
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +1 -0
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +1 -1
- 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 +64 -64
- data/lib/action_dispatch/railtie.rb +19 -11
- data/lib/action_dispatch/request/session.rb +99 -58
- 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 +58 -67
- data/lib/action_dispatch/routing/mapper.rb +733 -447
- data/lib/action_dispatch/routing/polymorphic_routes.rb +161 -139
- data/lib/action_dispatch/routing/redirection.rb +36 -26
- data/lib/action_dispatch/routing/route_set.rb +321 -291
- data/lib/action_dispatch/routing/routes_proxy.rb +32 -5
- data/lib/action_dispatch/routing/url_for.rb +65 -25
- data/lib/action_dispatch/routing.rb +17 -18
- data/lib/action_dispatch/system_test_case.rb +147 -0
- data/lib/action_dispatch/system_testing/browser.rb +49 -0
- data/lib/action_dispatch/system_testing/driver.rb +59 -0
- data/lib/action_dispatch/system_testing/server.rb +31 -0
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +96 -0
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +31 -0
- data/lib/action_dispatch/system_testing/test_helpers/undef_methods.rb +26 -0
- data/lib/action_dispatch/testing/assertion_response.rb +47 -0
- data/lib/action_dispatch/testing/assertions/response.rb +45 -20
- data/lib/action_dispatch/testing/assertions/routing.rb +30 -26
- data/lib/action_dispatch/testing/assertions.rb +6 -4
- data/lib/action_dispatch/testing/integration.rb +347 -209
- 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 +35 -7
- data/lib/action_dispatch.rb +26 -19
- data/lib/action_pack/gem_version.rb +5 -3
- data/lib/action_pack/version.rb +3 -1
- data/lib/action_pack.rb +4 -2
- metadata +50 -38
- 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,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? ? "".freeze : 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,50 @@ 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
|
+
|
39
|
+
INCLUDE = ->(list, action) { list.include? action }
|
40
|
+
EXCLUDE = ->(list, action) { !list.include? action }
|
41
|
+
NULL = ->(list, action) { true }
|
42
|
+
|
43
|
+
def build_middleware(klass, args, block)
|
44
|
+
options = args.extract_options!
|
45
|
+
only = Array(options.delete(:only)).map(&:to_s)
|
46
|
+
except = Array(options.delete(:except)).map(&:to_s)
|
47
|
+
args << options unless options.empty?
|
48
|
+
|
49
|
+
strategy = NULL
|
50
|
+
list = nil
|
51
|
+
|
52
|
+
if only.any?
|
53
|
+
strategy = INCLUDE
|
54
|
+
list = only
|
55
|
+
elsif except.any?
|
56
|
+
strategy = EXCLUDE
|
57
|
+
list = except
|
58
|
+
end
|
59
|
+
|
60
|
+
Middleware.new(klass, args, list, strategy, block)
|
61
|
+
end
|
40
62
|
end
|
41
63
|
|
42
64
|
# <tt>ActionController::Metal</tt> is the simplest possible controller, providing a
|
@@ -98,12 +120,6 @@ module ActionController
|
|
98
120
|
class Metal < AbstractController::Base
|
99
121
|
abstract!
|
100
122
|
|
101
|
-
attr_internal_writer :env
|
102
|
-
|
103
|
-
def env
|
104
|
-
@_env ||= {}
|
105
|
-
end
|
106
|
-
|
107
123
|
# Returns the last part of the controller's name, underscored, without the ending
|
108
124
|
# <tt>Controller</tt>. For instance, PostsController returns <tt>posts</tt>.
|
109
125
|
# Namespaces are left out, so Admin::PostsController returns <tt>posts</tt> as well.
|
@@ -111,26 +127,30 @@ module ActionController
|
|
111
127
|
# ==== Returns
|
112
128
|
# * <tt>string</tt>
|
113
129
|
def self.controller_name
|
114
|
-
@controller_name ||= name.demodulize.sub(/Controller$/,
|
130
|
+
@controller_name ||= name.demodulize.sub(/Controller$/, "").underscore
|
131
|
+
end
|
132
|
+
|
133
|
+
def self.make_response!(request)
|
134
|
+
ActionDispatch::Response.new.tap do |res|
|
135
|
+
res.request = request
|
136
|
+
end
|
115
137
|
end
|
116
138
|
|
117
|
-
|
139
|
+
def self.binary_params_for?(action) # :nodoc:
|
140
|
+
false
|
141
|
+
end
|
142
|
+
|
143
|
+
# Delegates to the class' <tt>controller_name</tt>.
|
118
144
|
def controller_name
|
119
145
|
self.class.controller_name
|
120
146
|
end
|
121
147
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
# environment and response manually for performance reasons.
|
127
|
-
|
128
|
-
attr_internal :headers, :response, :request
|
129
|
-
delegate :session, :to => "@_request"
|
148
|
+
attr_internal :response, :request
|
149
|
+
delegate :session, to: "@_request"
|
150
|
+
delegate :headers, :status=, :location=, :content_type=,
|
151
|
+
:status, :location, :content_type, to: "@_response"
|
130
152
|
|
131
153
|
def initialize
|
132
|
-
@_headers = {"Content-Type" => "text/html"}
|
133
|
-
@_status = 200
|
134
154
|
@_request = nil
|
135
155
|
@_response = nil
|
136
156
|
@_routes = nil
|
@@ -145,64 +165,52 @@ module ActionController
|
|
145
165
|
@_params = val
|
146
166
|
end
|
147
167
|
|
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
|
168
|
+
alias :response_code :status # :nodoc:
|
167
169
|
|
168
|
-
# Basic url_for that can be overridden for more robust functionality
|
170
|
+
# Basic url_for that can be overridden for more robust functionality.
|
169
171
|
def url_for(string)
|
170
172
|
string
|
171
173
|
end
|
172
174
|
|
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
175
|
def response_body=(body)
|
183
176
|
body = [body] unless body.nil? || body.respond_to?(:each)
|
177
|
+
response.reset_body!
|
178
|
+
return unless body
|
179
|
+
response.body = body
|
184
180
|
super
|
185
181
|
end
|
186
182
|
|
187
183
|
# Tests if render or redirect has already happened.
|
188
184
|
def performed?
|
189
|
-
response_body ||
|
185
|
+
response_body || response.committed?
|
190
186
|
end
|
191
187
|
|
192
|
-
def dispatch(name, request) #:nodoc:
|
193
|
-
|
194
|
-
|
195
|
-
@_env['action_controller.instance'] = self
|
188
|
+
def dispatch(name, request, response) #:nodoc:
|
189
|
+
set_request!(request)
|
190
|
+
set_response!(response)
|
196
191
|
process(name)
|
192
|
+
request.commit_flash
|
197
193
|
to_a
|
198
194
|
end
|
199
195
|
|
196
|
+
def set_response!(response) # :nodoc:
|
197
|
+
@_response = response
|
198
|
+
end
|
199
|
+
|
200
|
+
def set_request!(request) #:nodoc:
|
201
|
+
@_request = request
|
202
|
+
@_request.controller_instance = self
|
203
|
+
end
|
204
|
+
|
200
205
|
def to_a #:nodoc:
|
201
|
-
response
|
206
|
+
response.to_a
|
202
207
|
end
|
203
208
|
|
204
|
-
|
205
|
-
|
209
|
+
def reset_session
|
210
|
+
@_request.reset_session
|
211
|
+
end
|
212
|
+
|
213
|
+
class_attribute :middleware_stack, default: ActionController::MiddlewareStack.new
|
206
214
|
|
207
215
|
def self.inherited(base) # :nodoc:
|
208
216
|
base.middleware_stack = middleware_stack.dup
|
@@ -220,21 +228,28 @@ module ActionController
|
|
220
228
|
middleware_stack
|
221
229
|
end
|
222
230
|
|
223
|
-
#
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
231
|
+
# Returns a Rack endpoint for the given action name.
|
232
|
+
def self.action(name)
|
233
|
+
app = lambda { |env|
|
234
|
+
req = ActionDispatch::Request.new(env)
|
235
|
+
res = make_response! req
|
236
|
+
new.dispatch(name, req, res)
|
237
|
+
}
|
238
|
+
|
239
|
+
if middleware_stack.any?
|
240
|
+
middleware_stack.build(name, app)
|
241
|
+
else
|
242
|
+
app
|
243
|
+
end
|
228
244
|
end
|
229
245
|
|
230
|
-
#
|
231
|
-
|
246
|
+
# Direct dispatch to the controller. Instantiates the controller, then
|
247
|
+
# executes the action named +name+.
|
248
|
+
def self.dispatch(name, req, res)
|
232
249
|
if middleware_stack.any?
|
233
|
-
middleware_stack.build(name)
|
234
|
-
new.dispatch(name, klass.new(env))
|
235
|
-
end
|
250
|
+
middleware_stack.build(name) { |env| new.dispatch(name, req, res) }.call req.env
|
236
251
|
else
|
237
|
-
|
252
|
+
new.dispatch(name, req, res)
|
238
253
|
end
|
239
254
|
end
|
240
255
|
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
|
@@ -0,0 +1,117 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/hash/keys"
|
4
|
+
|
5
|
+
module ActionController
|
6
|
+
# ActionController::Renderer allows you to render arbitrary templates
|
7
|
+
# without requirement of being in controller actions.
|
8
|
+
#
|
9
|
+
# You get a concrete renderer class by invoking ActionController::Base#renderer.
|
10
|
+
# For example:
|
11
|
+
#
|
12
|
+
# ApplicationController.renderer
|
13
|
+
#
|
14
|
+
# It allows you to call method #render directly.
|
15
|
+
#
|
16
|
+
# ApplicationController.renderer.render template: '...'
|
17
|
+
#
|
18
|
+
# You can use this shortcut in a controller, instead of the previous example:
|
19
|
+
#
|
20
|
+
# ApplicationController.render template: '...'
|
21
|
+
#
|
22
|
+
# #render allows you to use the same options that you can use when rendering in a controller.
|
23
|
+
# For example:
|
24
|
+
#
|
25
|
+
# FooController.render :action, locals: { ... }, assigns: { ... }
|
26
|
+
#
|
27
|
+
# The template will be rendered in a Rack environment which is accessible through
|
28
|
+
# ActionController::Renderer#env. You can set it up in two ways:
|
29
|
+
#
|
30
|
+
# * by changing renderer defaults, like
|
31
|
+
#
|
32
|
+
# ApplicationController.renderer.defaults # => hash with default Rack environment
|
33
|
+
#
|
34
|
+
# * by initializing an instance of renderer by passing it a custom environment.
|
35
|
+
#
|
36
|
+
# ApplicationController.renderer.new(method: 'post', https: true)
|
37
|
+
#
|
38
|
+
class Renderer
|
39
|
+
attr_reader :defaults, :controller
|
40
|
+
|
41
|
+
DEFAULTS = {
|
42
|
+
http_host: "example.org",
|
43
|
+
https: false,
|
44
|
+
method: "get",
|
45
|
+
script_name: "",
|
46
|
+
input: ""
|
47
|
+
}.freeze
|
48
|
+
|
49
|
+
# Create a new renderer instance for a specific controller class.
|
50
|
+
def self.for(controller, env = {}, defaults = DEFAULTS.dup)
|
51
|
+
new(controller, env, defaults)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Create a new renderer for the same controller but with a new env.
|
55
|
+
def new(env = {})
|
56
|
+
self.class.new controller, env, defaults
|
57
|
+
end
|
58
|
+
|
59
|
+
# Create a new renderer for the same controller but with new defaults.
|
60
|
+
def with_defaults(defaults)
|
61
|
+
self.class.new controller, @env, self.defaults.merge(defaults)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Accepts a custom Rack environment to render templates in.
|
65
|
+
# It will be merged with the default Rack environment defined by
|
66
|
+
# +ActionController::Renderer::DEFAULTS+.
|
67
|
+
def initialize(controller, env, defaults)
|
68
|
+
@controller = controller
|
69
|
+
@defaults = defaults
|
70
|
+
@env = normalize_keys defaults.merge(env)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Render templates with any options from ActionController::Base#render_to_string.
|
74
|
+
def render(*args)
|
75
|
+
raise "missing controller" unless controller
|
76
|
+
|
77
|
+
request = ActionDispatch::Request.new @env
|
78
|
+
request.routes = controller._routes
|
79
|
+
|
80
|
+
instance = controller.new
|
81
|
+
instance.set_request! request
|
82
|
+
instance.set_response! controller.make_response!(request)
|
83
|
+
instance.render_to_string(*args)
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
def normalize_keys(env)
|
88
|
+
new_env = {}
|
89
|
+
env.each_pair { |k, v| new_env[rack_key_for(k)] = rack_value_for(k, v) }
|
90
|
+
new_env["rack.url_scheme"] = new_env["HTTPS"] == "on" ? "https" : "http"
|
91
|
+
new_env
|
92
|
+
end
|
93
|
+
|
94
|
+
RACK_KEY_TRANSLATION = {
|
95
|
+
http_host: "HTTP_HOST",
|
96
|
+
https: "HTTPS",
|
97
|
+
method: "REQUEST_METHOD",
|
98
|
+
script_name: "SCRIPT_NAME",
|
99
|
+
input: "rack.input"
|
100
|
+
}
|
101
|
+
|
102
|
+
IDENTITY = ->(_) { _ }
|
103
|
+
|
104
|
+
RACK_VALUE_TRANSLATION = {
|
105
|
+
https: ->(v) { v ? "on" : "off" },
|
106
|
+
method: ->(v) { v.upcase },
|
107
|
+
}
|
108
|
+
|
109
|
+
def rack_key_for(key)
|
110
|
+
RACK_KEY_TRANSLATION.fetch(key, key.to_s)
|
111
|
+
end
|
112
|
+
|
113
|
+
def rack_value_for(key, value)
|
114
|
+
RACK_VALUE_TRANSLATION.fetch(key, IDENTITY).call value
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionController
|
4
|
+
module TemplateAssertions
|
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
|