actionpack 4.2.10 → 5.0.0
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 +553 -401
- data/MIT-LICENSE +1 -1
- data/README.rdoc +2 -3
- data/lib/abstract_controller/base.rb +28 -38
- data/lib/{action_controller → abstract_controller}/caching/fragments.rb +51 -11
- data/lib/abstract_controller/caching.rb +62 -0
- data/lib/abstract_controller/callbacks.rb +52 -19
- data/lib/abstract_controller/collector.rb +4 -9
- data/lib/abstract_controller/error.rb +4 -0
- data/lib/abstract_controller/helpers.rb +4 -3
- data/lib/abstract_controller/railties/routes_helpers.rb +2 -2
- data/lib/abstract_controller/rendering.rb +28 -18
- data/lib/abstract_controller/translation.rb +8 -7
- data/lib/abstract_controller.rb +6 -2
- data/lib/action_controller/api/api_rendering.rb +14 -0
- data/lib/action_controller/api.rb +147 -0
- data/lib/action_controller/base.rb +10 -13
- data/lib/action_controller/caching.rb +13 -58
- data/lib/action_controller/form_builder.rb +48 -0
- data/lib/action_controller/log_subscriber.rb +3 -10
- data/lib/action_controller/metal/basic_implicit_render.rb +11 -0
- data/lib/action_controller/metal/conditional_get.rb +106 -34
- data/lib/action_controller/metal/cookies.rb +1 -3
- data/lib/action_controller/metal/data_streaming.rb +11 -32
- data/lib/action_controller/metal/etag_with_template_digest.rb +1 -1
- data/lib/action_controller/metal/exceptions.rb +11 -6
- data/lib/action_controller/metal/force_ssl.rb +10 -10
- data/lib/action_controller/metal/head.rb +14 -8
- data/lib/action_controller/metal/helpers.rb +15 -6
- data/lib/action_controller/metal/http_authentication.rb +44 -35
- data/lib/action_controller/metal/implicit_render.rb +61 -6
- data/lib/action_controller/metal/instrumentation.rb +5 -5
- data/lib/action_controller/metal/live.rb +66 -88
- data/lib/action_controller/metal/mime_responds.rb +27 -42
- data/lib/action_controller/metal/params_wrapper.rb +8 -8
- data/lib/action_controller/metal/redirecting.rb +32 -9
- data/lib/action_controller/metal/renderers.rb +85 -40
- data/lib/action_controller/metal/rendering.rb +38 -6
- data/lib/action_controller/metal/request_forgery_protection.rb +126 -48
- data/lib/action_controller/metal/rescue.rb +3 -12
- data/lib/action_controller/metal/streaming.rb +4 -4
- data/lib/action_controller/metal/strong_parameters.rb +293 -90
- data/lib/action_controller/metal/testing.rb +1 -12
- data/lib/action_controller/metal/url_for.rb +12 -5
- data/lib/action_controller/metal.rb +88 -63
- data/lib/action_controller/renderer.rb +111 -0
- data/lib/action_controller/template_assertions.rb +9 -0
- data/lib/action_controller/test_case.rb +288 -368
- data/lib/action_controller.rb +12 -9
- data/lib/action_dispatch/http/cache.rb +73 -34
- data/lib/action_dispatch/http/filter_parameters.rb +15 -11
- data/lib/action_dispatch/http/filter_redirect.rb +7 -8
- data/lib/action_dispatch/http/headers.rb +44 -13
- data/lib/action_dispatch/http/mime_negotiation.rb +41 -23
- data/lib/action_dispatch/http/mime_type.rb +126 -90
- data/lib/action_dispatch/http/mime_types.rb +3 -4
- data/lib/action_dispatch/http/parameter_filter.rb +18 -8
- data/lib/action_dispatch/http/parameters.rb +54 -41
- data/lib/action_dispatch/http/request.rb +149 -82
- data/lib/action_dispatch/http/response.rb +206 -102
- data/lib/action_dispatch/http/url.rb +117 -8
- data/lib/action_dispatch/journey/formatter.rb +39 -28
- data/lib/action_dispatch/journey/gtg/transition_table.rb +1 -1
- data/lib/action_dispatch/journey/nfa/dot.rb +0 -2
- data/lib/action_dispatch/journey/nfa/transition_table.rb +1 -46
- data/lib/action_dispatch/journey/nodes/node.rb +14 -4
- data/lib/action_dispatch/journey/parser_extras.rb +4 -0
- data/lib/action_dispatch/journey/path/pattern.rb +38 -42
- data/lib/action_dispatch/journey/route.rb +74 -19
- data/lib/action_dispatch/journey/router/utils.rb +5 -5
- data/lib/action_dispatch/journey/router.rb +5 -9
- data/lib/action_dispatch/journey/routes.rb +14 -15
- data/lib/action_dispatch/journey/visitors.rb +86 -43
- data/lib/action_dispatch/middleware/callbacks.rb +10 -1
- data/lib/action_dispatch/middleware/cookies.rb +189 -135
- data/lib/action_dispatch/middleware/debug_exceptions.rb +124 -49
- data/lib/action_dispatch/middleware/exception_wrapper.rb +21 -21
- data/lib/action_dispatch/middleware/executor.rb +19 -0
- data/lib/action_dispatch/middleware/flash.rb +66 -45
- data/lib/action_dispatch/middleware/params_parser.rb +32 -46
- data/lib/action_dispatch/middleware/public_exceptions.rb +2 -2
- data/lib/action_dispatch/middleware/reloader.rb +14 -58
- data/lib/action_dispatch/middleware/remote_ip.rb +29 -19
- data/lib/action_dispatch/middleware/request_id.rb +11 -6
- data/lib/action_dispatch/middleware/session/abstract_store.rb +23 -11
- data/lib/action_dispatch/middleware/session/cache_store.rb +9 -6
- data/lib/action_dispatch/middleware/session/cookie_store.rb +30 -24
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +4 -0
- data/lib/action_dispatch/middleware/show_exceptions.rb +11 -9
- data/lib/action_dispatch/middleware/ssl.rb +115 -36
- data/lib/action_dispatch/middleware/stack.rb +44 -40
- data/lib/action_dispatch/middleware/static.rb +51 -35
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +2 -14
- data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -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 +59 -63
- data/lib/action_dispatch/railtie.rb +2 -2
- data/lib/action_dispatch/request/session.rb +69 -33
- data/lib/action_dispatch/request/utils.rb +51 -19
- data/lib/action_dispatch/routing/inspector.rb +32 -43
- data/lib/action_dispatch/routing/mapper.rb +491 -338
- data/lib/action_dispatch/routing/polymorphic_routes.rb +8 -14
- data/lib/action_dispatch/routing/redirection.rb +3 -3
- data/lib/action_dispatch/routing/route_set.rb +145 -238
- data/lib/action_dispatch/routing/url_for.rb +27 -10
- data/lib/action_dispatch/routing.rb +17 -13
- data/lib/action_dispatch/testing/assertion_response.rb +45 -0
- data/lib/action_dispatch/testing/assertions/response.rb +38 -20
- data/lib/action_dispatch/testing/assertions/routing.rb +11 -10
- data/lib/action_dispatch/testing/assertions.rb +1 -1
- data/lib/action_dispatch/testing/integration.rb +368 -97
- data/lib/action_dispatch/testing/test_process.rb +5 -6
- data/lib/action_dispatch/testing/test_request.rb +22 -31
- data/lib/action_dispatch/testing/test_response.rb +7 -4
- data/lib/action_dispatch.rb +3 -1
- data/lib/action_pack/gem_version.rb +3 -3
- data/lib/action_pack.rb +1 -1
- metadata +30 -34
- 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/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
- /data/lib/action_dispatch/middleware/templates/rescues/{_source.erb → _source.html.erb} +0 -0
@@ -3,7 +3,7 @@ require 'delegate'
|
|
3
3
|
require 'active_support/json'
|
4
4
|
|
5
5
|
module ActionController
|
6
|
-
# Mix this module
|
6
|
+
# Mix this module into your controller, and all actions in that controller
|
7
7
|
# will be able to stream data to the client as it's written.
|
8
8
|
#
|
9
9
|
# class MyController < ActionController::Base
|
@@ -20,7 +20,7 @@ module ActionController
|
|
20
20
|
# end
|
21
21
|
# end
|
22
22
|
#
|
23
|
-
# There are a few caveats with this
|
23
|
+
# There are a few caveats with this module. You *cannot* write headers after the
|
24
24
|
# response has been committed (Response#committed? will return truthy).
|
25
25
|
# Calling +write+ or +close+ on the response stream will cause the response
|
26
26
|
# object to be committed. Make sure all headers are set before calling write
|
@@ -33,6 +33,20 @@ module ActionController
|
|
33
33
|
# the main thread. Make sure your actions are thread safe, and this shouldn't
|
34
34
|
# be a problem (don't share state across threads, etc).
|
35
35
|
module Live
|
36
|
+
extend ActiveSupport::Concern
|
37
|
+
|
38
|
+
module ClassMethods
|
39
|
+
def make_response!(request)
|
40
|
+
if request.get_header("HTTP_VERSION") == "HTTP/1.0"
|
41
|
+
super
|
42
|
+
else
|
43
|
+
Live::Response.new.tap do |res|
|
44
|
+
res.request = request
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
36
50
|
# This class provides the ability to write an SSE (Server Sent Event)
|
37
51
|
# to an IO stream. The class is initialized with a stream and can be used
|
38
52
|
# to either write a JSON string or an object which can be converted to JSON.
|
@@ -102,7 +116,7 @@ module ActionController
|
|
102
116
|
end
|
103
117
|
end
|
104
118
|
|
105
|
-
message = json.gsub(
|
119
|
+
message = json.gsub("\n".freeze, "\ndata: ".freeze)
|
106
120
|
@stream.write "data: #{message}\n\n"
|
107
121
|
end
|
108
122
|
end
|
@@ -131,8 +145,8 @@ module ActionController
|
|
131
145
|
|
132
146
|
def write(string)
|
133
147
|
unless @response.committed?
|
134
|
-
@response.
|
135
|
-
@response.
|
148
|
+
@response.set_header "Cache-Control", "no-cache"
|
149
|
+
@response.delete_header "Content-Length"
|
136
150
|
end
|
137
151
|
|
138
152
|
super
|
@@ -149,14 +163,6 @@ module ActionController
|
|
149
163
|
end
|
150
164
|
end
|
151
165
|
|
152
|
-
def each
|
153
|
-
@response.sending!
|
154
|
-
while str = @buf.pop
|
155
|
-
yield str
|
156
|
-
end
|
157
|
-
@response.sent!
|
158
|
-
end
|
159
|
-
|
160
166
|
# Write a 'close' event to the buffer; the producer/writing thread
|
161
167
|
# uses this to notify us that it's finished supplying content.
|
162
168
|
#
|
@@ -189,12 +195,6 @@ module ActionController
|
|
189
195
|
!@aborted
|
190
196
|
end
|
191
197
|
|
192
|
-
def await_close
|
193
|
-
synchronize do
|
194
|
-
@cv.wait_until { @closed }
|
195
|
-
end
|
196
|
-
end
|
197
|
-
|
198
198
|
def on_error(&block)
|
199
199
|
@error_callback = block
|
200
200
|
end
|
@@ -202,32 +202,17 @@ module ActionController
|
|
202
202
|
def call_on_error
|
203
203
|
@error_callback.call
|
204
204
|
end
|
205
|
-
end
|
206
205
|
|
207
|
-
|
208
|
-
class Header < DelegateClass(Hash) # :nodoc:
|
209
|
-
def initialize(response, header)
|
210
|
-
@response = response
|
211
|
-
super(header)
|
212
|
-
end
|
206
|
+
private
|
213
207
|
|
214
|
-
def
|
215
|
-
|
216
|
-
|
208
|
+
def each_chunk(&block)
|
209
|
+
while str = @buf.pop
|
210
|
+
yield str
|
217
211
|
end
|
218
|
-
|
219
|
-
super
|
220
|
-
end
|
221
|
-
|
222
|
-
def merge(other)
|
223
|
-
self.class.new @response, __getobj__.merge(other)
|
224
212
|
end
|
213
|
+
end
|
225
214
|
|
226
|
-
|
227
|
-
__getobj__.dup
|
228
|
-
end
|
229
|
-
end
|
230
|
-
|
215
|
+
class Response < ActionDispatch::Response #:nodoc: all
|
231
216
|
private
|
232
217
|
|
233
218
|
def before_committed
|
@@ -237,25 +222,11 @@ module ActionController
|
|
237
222
|
jar.write self unless committed?
|
238
223
|
end
|
239
224
|
|
240
|
-
def before_sending
|
241
|
-
super
|
242
|
-
request.cookie_jar.commit!
|
243
|
-
headers.freeze
|
244
|
-
end
|
245
|
-
|
246
225
|
def build_buffer(response, body)
|
247
226
|
buf = Live::Buffer.new response
|
248
227
|
body.each { |part| buf.write part }
|
249
228
|
buf
|
250
229
|
end
|
251
|
-
|
252
|
-
def merge_default_headers(original, default)
|
253
|
-
Header.new self, super
|
254
|
-
end
|
255
|
-
|
256
|
-
def handle_conditional_get!
|
257
|
-
super unless committed?
|
258
|
-
end
|
259
230
|
end
|
260
231
|
|
261
232
|
def process(name)
|
@@ -266,39 +237,55 @@ module ActionController
|
|
266
237
|
# This processes the action in a child thread. It lets us return the
|
267
238
|
# response code and headers back up the rack stack, and still process
|
268
239
|
# the body in parallel with sending data to the client
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
240
|
+
new_controller_thread {
|
241
|
+
ActiveSupport::Dependencies.interlock.running do
|
242
|
+
t2 = Thread.current
|
243
|
+
|
244
|
+
# Since we're processing the view in a different thread, copy the
|
245
|
+
# thread locals from the main thread to the child thread. :'(
|
246
|
+
locals.each { |k,v| t2[k] = v }
|
247
|
+
|
248
|
+
begin
|
249
|
+
super(name)
|
250
|
+
rescue => e
|
251
|
+
if @_response.committed?
|
252
|
+
begin
|
253
|
+
@_response.stream.write(ActionView::Base.streaming_completion_on_exception) if request.format == :html
|
254
|
+
@_response.stream.call_on_error
|
255
|
+
rescue => exception
|
256
|
+
log_error(exception)
|
257
|
+
ensure
|
258
|
+
log_error(e)
|
259
|
+
@_response.stream.close
|
260
|
+
end
|
261
|
+
else
|
262
|
+
error = e
|
289
263
|
end
|
290
|
-
|
291
|
-
|
264
|
+
ensure
|
265
|
+
@_response.commit!
|
292
266
|
end
|
293
|
-
ensure
|
294
|
-
@_response.commit!
|
295
267
|
end
|
296
268
|
}
|
297
269
|
|
298
|
-
|
270
|
+
ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
|
271
|
+
@_response.await_commit
|
272
|
+
end
|
273
|
+
|
299
274
|
raise error if error
|
300
275
|
end
|
301
276
|
|
277
|
+
# Spawn a new thread to serve up the controller in. This is to get
|
278
|
+
# around the fact that Rack isn't based around IOs and we need to use
|
279
|
+
# a thread to stream data from the response bodies. Nobody should call
|
280
|
+
# this method except in Rails internals. Seriously!
|
281
|
+
def new_controller_thread # :nodoc:
|
282
|
+
Thread.new {
|
283
|
+
t2 = Thread.current
|
284
|
+
t2.abort_on_exception = true
|
285
|
+
yield
|
286
|
+
}
|
287
|
+
end
|
288
|
+
|
302
289
|
def log_error(exception)
|
303
290
|
logger = ActionController::Base.logger
|
304
291
|
return unless logger
|
@@ -315,14 +302,5 @@ module ActionController
|
|
315
302
|
super
|
316
303
|
response.close if response
|
317
304
|
end
|
318
|
-
|
319
|
-
def set_response!(request)
|
320
|
-
if request.env["HTTP_VERSION"] == "HTTP/1.0"
|
321
|
-
super
|
322
|
-
else
|
323
|
-
@_response = Live::Response.new
|
324
|
-
@_response.request = request
|
325
|
-
end
|
326
|
-
end
|
327
305
|
end
|
328
306
|
end
|
@@ -2,28 +2,6 @@ require 'abstract_controller/collector'
|
|
2
2
|
|
3
3
|
module ActionController #:nodoc:
|
4
4
|
module MimeResponds
|
5
|
-
extend ActiveSupport::Concern
|
6
|
-
|
7
|
-
# :stopdoc:
|
8
|
-
module ClassMethods
|
9
|
-
def respond_to(*)
|
10
|
-
raise NoMethodError, "The controller-level `respond_to' feature has " \
|
11
|
-
"been extracted to the `responders` gem. Add it to your Gemfile to " \
|
12
|
-
"continue using this feature:\n" \
|
13
|
-
" gem 'responders', '~> 2.0'\n" \
|
14
|
-
"Consult the Rails upgrade guide for details."
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
def respond_with(*)
|
19
|
-
raise NoMethodError, "The `respond_with' feature has been extracted " \
|
20
|
-
"to the `responders` gem. Add it to your Gemfile to continue using " \
|
21
|
-
"this feature:\n" \
|
22
|
-
" gem 'responders', '~> 2.0'\n" \
|
23
|
-
"Consult the Rails upgrade guide for details."
|
24
|
-
end
|
25
|
-
# :startdoc:
|
26
|
-
|
27
5
|
# Without web-service support, an action which collects the data for displaying a list of people
|
28
6
|
# might look something like this:
|
29
7
|
#
|
@@ -31,6 +9,13 @@ module ActionController #:nodoc:
|
|
31
9
|
# @people = Person.all
|
32
10
|
# end
|
33
11
|
#
|
12
|
+
# That action implicitly responds to all formats, but formats can also be whitelisted:
|
13
|
+
#
|
14
|
+
# def index
|
15
|
+
# @people = Person.all
|
16
|
+
# respond_to :html, :js
|
17
|
+
# end
|
18
|
+
#
|
34
19
|
# Here's the same action, with web-service support baked in:
|
35
20
|
#
|
36
21
|
# def index
|
@@ -38,11 +23,12 @@ module ActionController #:nodoc:
|
|
38
23
|
#
|
39
24
|
# respond_to do |format|
|
40
25
|
# format.html
|
26
|
+
# format.js
|
41
27
|
# format.xml { render xml: @people }
|
42
28
|
# end
|
43
29
|
# end
|
44
30
|
#
|
45
|
-
# What that says is, "if the client wants HTML in response to this action, just respond as we
|
31
|
+
# What that says is, "if the client wants HTML or JS in response to this action, just respond as we
|
46
32
|
# would have before, but if the client wants XML, return them the list of people in XML format."
|
47
33
|
# (Rails determines the desired response format from the HTTP Accept header submitted by the client.)
|
48
34
|
#
|
@@ -113,11 +99,11 @@ module ActionController #:nodoc:
|
|
113
99
|
# and accept Rails' defaults, life will be much easier.
|
114
100
|
#
|
115
101
|
# If you need to use a MIME type which isn't supported by default, you can register your own handlers in
|
116
|
-
# config/initializers/mime_types.rb as follows.
|
102
|
+
# +config/initializers/mime_types.rb+ as follows.
|
117
103
|
#
|
118
104
|
# Mime::Type.register "image/jpg", :jpg
|
119
105
|
#
|
120
|
-
# Respond to also allows you to specify a common block for different formats by using any
|
106
|
+
# Respond to also allows you to specify a common block for different formats by using +any+:
|
121
107
|
#
|
122
108
|
# def index
|
123
109
|
# @people = Person.all
|
@@ -173,21 +159,21 @@ module ActionController #:nodoc:
|
|
173
159
|
# format.html.none { render "trash" }
|
174
160
|
# end
|
175
161
|
#
|
176
|
-
# Variants also support common
|
162
|
+
# Variants also support common +any+/+all+ block that formats have.
|
177
163
|
#
|
178
164
|
# It works for both inline:
|
179
165
|
#
|
180
166
|
# respond_to do |format|
|
181
|
-
# format.html.any { render
|
182
|
-
# format.html.phone { render
|
167
|
+
# format.html.any { render html: "any" }
|
168
|
+
# format.html.phone { render html: "phone" }
|
183
169
|
# end
|
184
170
|
#
|
185
171
|
# and block syntax:
|
186
172
|
#
|
187
173
|
# respond_to do |format|
|
188
174
|
# format.html do |variant|
|
189
|
-
# variant.any(:tablet, :phablet){ render
|
190
|
-
# variant.phone { render
|
175
|
+
# variant.any(:tablet, :phablet){ render html: "any" }
|
176
|
+
# variant.phone { render html: "phone" }
|
191
177
|
# end
|
192
178
|
# end
|
193
179
|
#
|
@@ -196,15 +182,12 @@ module ActionController #:nodoc:
|
|
196
182
|
# request.variant = [:tablet, :phone]
|
197
183
|
#
|
198
184
|
# which will work similarly to formats and MIME types negotiation. If there will be no
|
199
|
-
#
|
185
|
+
# +:tablet+ variant declared, +:phone+ variant will be picked:
|
200
186
|
#
|
201
187
|
# respond_to do |format|
|
202
188
|
# format.html.none
|
203
189
|
# format.html.phone # this gets rendered
|
204
190
|
# end
|
205
|
-
#
|
206
|
-
# Be sure to check the documentation of <tt>ActionController::MimeResponds.respond_to</tt>
|
207
|
-
# for more examples.
|
208
191
|
def respond_to(*mimes)
|
209
192
|
raise ArgumentError, "respond_to takes either types or a block, never both" if mimes.any? && block_given?
|
210
193
|
|
@@ -213,8 +196,9 @@ module ActionController #:nodoc:
|
|
213
196
|
|
214
197
|
if format = collector.negotiate_format(request)
|
215
198
|
_process_format(format)
|
199
|
+
_set_rendered_content_type format
|
216
200
|
response = collector.response
|
217
|
-
response
|
201
|
+
response.call if response
|
218
202
|
else
|
219
203
|
raise ActionController::UnknownFormat
|
220
204
|
end
|
@@ -250,7 +234,7 @@ module ActionController #:nodoc:
|
|
250
234
|
@responses = {}
|
251
235
|
@variant = variant
|
252
236
|
|
253
|
-
mimes.each { |mime| @responses[
|
237
|
+
mimes.each { |mime| @responses[Mime[mime]] = nil }
|
254
238
|
end
|
255
239
|
|
256
240
|
def any(*args, &block)
|
@@ -310,16 +294,17 @@ module ActionController #:nodoc:
|
|
310
294
|
end
|
311
295
|
|
312
296
|
def variant
|
313
|
-
if @variant.
|
297
|
+
if @variant.empty?
|
314
298
|
@variants[:none] || @variants[:any]
|
315
|
-
elsif (@variants.keys & @variant).any?
|
316
|
-
@variant.each do |v|
|
317
|
-
return @variants[v] if @variants.key?(v)
|
318
|
-
end
|
319
299
|
else
|
320
|
-
@variants[
|
300
|
+
@variants[variant_key]
|
321
301
|
end
|
322
302
|
end
|
303
|
+
|
304
|
+
private
|
305
|
+
def variant_key
|
306
|
+
@variant.find { |variant| @variants.key?(variant) } || :any
|
307
|
+
end
|
323
308
|
end
|
324
309
|
end
|
325
310
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'active_support/core_ext/hash/slice'
|
2
2
|
require 'active_support/core_ext/hash/except'
|
3
3
|
require 'active_support/core_ext/module/anonymous'
|
4
|
-
require 'active_support/core_ext/struct'
|
5
4
|
require 'action_dispatch/http/mime_type'
|
6
5
|
|
7
6
|
module ActionController
|
@@ -9,8 +8,7 @@ module ActionController
|
|
9
8
|
# submit requests without having to specify any root elements.
|
10
9
|
#
|
11
10
|
# This functionality is enabled in +config/initializers/wrap_parameters.rb+
|
12
|
-
# and can be customized.
|
13
|
-
# need to be created for the functionality to be enabled.
|
11
|
+
# and can be customized.
|
14
12
|
#
|
15
13
|
# You could also turn it on per controller by setting the format array to
|
16
14
|
# a non-empty array:
|
@@ -42,7 +40,7 @@ module ActionController
|
|
42
40
|
# wrap_parameters :person, include: [:username, :password]
|
43
41
|
# end
|
44
42
|
#
|
45
|
-
# On
|
43
|
+
# On Active Record models with no +:include+ or +:exclude+ option set,
|
46
44
|
# it will only wrap the parameters returned by the class method
|
47
45
|
# <tt>attribute_names</tt>.
|
48
46
|
#
|
@@ -86,7 +84,7 @@ module ActionController
|
|
86
84
|
new name, format, include, exclude, nil, nil
|
87
85
|
end
|
88
86
|
|
89
|
-
def initialize(name, format, include, exclude, klass, model) # nodoc
|
87
|
+
def initialize(name, format, include, exclude, klass, model) # :nodoc:
|
90
88
|
super
|
91
89
|
@include_set = include
|
92
90
|
@name_set = name
|
@@ -132,7 +130,7 @@ module ActionController
|
|
132
130
|
private
|
133
131
|
# Determine the wrapper model from the controller's name. By convention,
|
134
132
|
# this could be done by trying to find the defined model that has the
|
135
|
-
# same
|
133
|
+
# same singular name as the controller. For example, +UsersController+
|
136
134
|
# will try to find if the +User+ model exists.
|
137
135
|
#
|
138
136
|
# This method also does namespace lookup. Foo::Bar::UsersController will
|
@@ -252,7 +250,7 @@ module ActionController
|
|
252
250
|
|
253
251
|
private
|
254
252
|
|
255
|
-
# Returns the wrapper key which will be used to
|
253
|
+
# Returns the wrapper key which will be used to store wrapped parameters.
|
256
254
|
def _wrapper_key
|
257
255
|
_wrapper_options.name
|
258
256
|
end
|
@@ -278,7 +276,9 @@ module ActionController
|
|
278
276
|
|
279
277
|
# Checks if we should perform parameters wrapping.
|
280
278
|
def _wrapper_enabled?
|
281
|
-
|
279
|
+
return false unless request.has_content_type?
|
280
|
+
|
281
|
+
ref = request.content_mime_type.ref
|
282
282
|
_wrapper_formats.include?(ref) && _wrapper_key && !request.request_parameters[_wrapper_key]
|
283
283
|
end
|
284
284
|
end
|
@@ -11,7 +11,6 @@ module ActionController
|
|
11
11
|
extend ActiveSupport::Concern
|
12
12
|
|
13
13
|
include AbstractController::Logger
|
14
|
-
include ActionController::RackDelegation
|
15
14
|
include ActionController::UrlFor
|
16
15
|
|
17
16
|
# Redirects the browser to the target specified in +options+. This parameter can be any one of:
|
@@ -21,8 +20,6 @@ module ActionController
|
|
21
20
|
# * <tt>String</tt> starting with <tt>protocol://</tt> (like <tt>http://</tt>) or a protocol relative reference (like <tt>//</tt>) - Is passed straight through as the target for redirection.
|
22
21
|
# * <tt>String</tt> not containing a protocol - The current protocol and host is prepended to the string.
|
23
22
|
# * <tt>Proc</tt> - A block that will be executed in the controller's context. Should return any option accepted by +redirect_to+.
|
24
|
-
# * <tt>:back</tt> - Back to the page that issued the request. Useful for forms that are triggered from multiple places.
|
25
|
-
# Short-hand for <tt>redirect_to(request.env["HTTP_REFERER"])</tt>
|
26
23
|
#
|
27
24
|
# === Examples:
|
28
25
|
#
|
@@ -31,7 +28,6 @@ module ActionController
|
|
31
28
|
# redirect_to "http://www.rubyonrails.org"
|
32
29
|
# redirect_to "/images/screenshot.jpg"
|
33
30
|
# redirect_to articles_url
|
34
|
-
# redirect_to :back
|
35
31
|
# redirect_to proc { edit_post_url(@post) }
|
36
32
|
#
|
37
33
|
# The redirection happens as a "302 Found" header unless otherwise specified using the <tt>:status</tt> option:
|
@@ -62,13 +58,8 @@ module ActionController
|
|
62
58
|
# redirect_to post_url(@post), status: 301, flash: { updated_post_id: @post.id }
|
63
59
|
# redirect_to({ action: 'atom' }, alert: "Something serious happened")
|
64
60
|
#
|
65
|
-
# When using <tt>redirect_to :back</tt>, if there is no referrer,
|
66
|
-
# <tt>ActionController::RedirectBackError</tt> will be raised. You
|
67
|
-
# may specify some fallback behavior for this case by rescuing
|
68
|
-
# <tt>ActionController::RedirectBackError</tt>.
|
69
61
|
def redirect_to(options = {}, response_status = {}) #:doc:
|
70
62
|
raise ActionControllerError.new("Cannot redirect to nil!") unless options
|
71
|
-
raise ActionControllerError.new("Cannot redirect to a parameter hash!") if options.is_a?(ActionController::Parameters)
|
72
63
|
raise AbstractController::DoubleRenderError if response_body
|
73
64
|
|
74
65
|
self.status = _extract_redirect_to_status(options, response_status)
|
@@ -76,6 +67,32 @@ module ActionController
|
|
76
67
|
self.response_body = "<html><body>You are being <a href=\"#{ERB::Util.unwrapped_html_escape(location)}\">redirected</a>.</body></html>"
|
77
68
|
end
|
78
69
|
|
70
|
+
# Redirects the browser to the page that issued the request (the referrer)
|
71
|
+
# if possible, otherwise redirects to the provided default fallback
|
72
|
+
# location.
|
73
|
+
#
|
74
|
+
# The referrer information is pulled from the HTTP `Referer` (sic) header on
|
75
|
+
# the request. This is an optional header and its presence on the request is
|
76
|
+
# subject to browser security settings and user preferences. If the request
|
77
|
+
# is missing this header, the <tt>fallback_location</tt> will be used.
|
78
|
+
#
|
79
|
+
# redirect_back fallback_location: { action: "show", id: 5 }
|
80
|
+
# redirect_back fallback_location: post
|
81
|
+
# redirect_back fallback_location: "http://www.rubyonrails.org"
|
82
|
+
# redirect_back fallback_location: "/images/screenshot.jpg"
|
83
|
+
# redirect_back fallback_location: articles_url
|
84
|
+
# redirect_back fallback_location: proc { edit_post_url(@post) }
|
85
|
+
#
|
86
|
+
# All options that can be passed to <tt>redirect_to</tt> are accepted as
|
87
|
+
# options and the behavior is identical.
|
88
|
+
def redirect_back(fallback_location:, **args)
|
89
|
+
if referer = request.headers["Referer"]
|
90
|
+
redirect_to referer, **args
|
91
|
+
else
|
92
|
+
redirect_to fallback_location, **args
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
79
96
|
def _compute_redirect_to_location(request, options) #:nodoc:
|
80
97
|
case options
|
81
98
|
# The scheme name consist of a letter followed by any combination of
|
@@ -88,6 +105,12 @@ module ActionController
|
|
88
105
|
when String
|
89
106
|
request.protocol + request.host_with_port + options
|
90
107
|
when :back
|
108
|
+
ActiveSupport::Deprecation.warn(<<-MESSAGE.squish)
|
109
|
+
`redirect_to :back` is deprecated and will be removed from Rails 5.1.
|
110
|
+
Please use `redirect_back(fallback_location: fallback_location)` where
|
111
|
+
`fallback_location` represents the location to use if the request has
|
112
|
+
no HTTP referer information.
|
113
|
+
MESSAGE
|
91
114
|
request.headers["Referer"] or raise RedirectBackError
|
92
115
|
when Proc
|
93
116
|
_compute_redirect_to_location request, options.call
|