actionpack 3.0.0.beta → 3.0.0.beta2
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.
- data/CHANGELOG +291 -260
- data/lib/abstract_controller.rb +5 -2
- data/lib/abstract_controller/assigns.rb +21 -0
- data/lib/abstract_controller/base.rb +13 -5
- data/lib/abstract_controller/collector.rb +2 -0
- data/lib/abstract_controller/helpers.rb +4 -14
- data/lib/abstract_controller/layouts.rb +50 -99
- data/lib/abstract_controller/logger.rb +2 -2
- data/lib/abstract_controller/rendering.rb +105 -173
- data/lib/abstract_controller/view_paths.rb +69 -0
- data/lib/action_controller.rb +1 -2
- data/lib/action_controller/base.rb +10 -32
- data/lib/action_controller/caching.rb +19 -18
- data/lib/action_controller/caching/actions.rb +17 -11
- data/lib/action_controller/caching/fragments.rb +5 -17
- data/lib/action_controller/caching/pages.rb +24 -24
- data/lib/action_controller/caching/sweeping.rb +1 -3
- data/lib/action_controller/deprecated.rb +0 -2
- data/lib/action_controller/deprecated/base.rb +143 -0
- data/lib/action_controller/metal.rb +29 -26
- data/lib/action_controller/metal/compatibility.rb +18 -87
- data/lib/action_controller/metal/cookies.rb +0 -1
- data/lib/action_controller/metal/head.rb +1 -0
- data/lib/action_controller/metal/helpers.rb +2 -2
- data/lib/action_controller/metal/hide_actions.rb +4 -6
- data/lib/action_controller/metal/http_authentication.rb +18 -33
- data/lib/action_controller/metal/implicit_render.rb +21 -0
- data/lib/action_controller/metal/instrumentation.rb +1 -1
- data/lib/action_controller/metal/mime_responds.rb +2 -1
- data/lib/action_controller/metal/rack_delegation.rb +3 -8
- data/lib/action_controller/metal/redirecting.rb +2 -1
- data/lib/action_controller/metal/renderers.rb +4 -2
- data/lib/action_controller/metal/rendering.rb +31 -44
- data/lib/action_controller/metal/request_forgery_protection.rb +41 -4
- data/lib/action_controller/metal/responder.rb +2 -0
- data/lib/action_controller/metal/session_management.rb +0 -36
- data/lib/action_controller/metal/streaming.rb +20 -47
- data/lib/action_controller/metal/testing.rb +0 -1
- data/lib/action_controller/metal/url_for.rb +11 -148
- data/lib/action_controller/middleware.rb +2 -1
- data/lib/action_controller/polymorphic_routes.rb +1 -2
- data/lib/action_controller/railtie.rb +63 -10
- data/lib/action_controller/railties/{subscriber.rb → log_subscriber.rb} +5 -12
- data/lib/action_controller/railties/url_helpers.rb +14 -0
- data/lib/action_controller/record_identifier.rb +20 -1
- data/lib/action_controller/test_case.rb +123 -12
- data/lib/action_dispatch.rb +1 -0
- data/lib/action_dispatch/http/cache.rb +20 -3
- data/lib/action_dispatch/http/filter_parameters.rb +40 -25
- data/lib/action_dispatch/http/mime_negotiation.rb +6 -17
- data/lib/action_dispatch/http/mime_type.rb +2 -7
- data/lib/action_dispatch/http/request.rb +12 -33
- data/lib/action_dispatch/http/response.rb +35 -15
- data/lib/action_dispatch/http/upload.rb +2 -0
- data/lib/action_dispatch/http/url.rb +5 -32
- data/lib/action_dispatch/middleware/callbacks.rb +1 -1
- data/lib/action_dispatch/middleware/cookies.rb +4 -3
- data/lib/action_dispatch/middleware/params_parser.rb +4 -3
- data/lib/action_dispatch/middleware/remote_ip.rb +51 -0
- data/lib/action_dispatch/middleware/session/abstract_store.rb +1 -0
- data/lib/action_dispatch/middleware/session/cookie_store.rb +6 -8
- data/lib/action_dispatch/middleware/show_exceptions.rb +0 -14
- data/lib/action_dispatch/middleware/stack.rb +6 -2
- data/lib/action_dispatch/railtie.rb +3 -1
- data/lib/action_dispatch/routing.rb +2 -0
- data/lib/action_dispatch/routing/deprecated_mapper.rb +35 -7
- data/lib/action_dispatch/routing/mapper.rb +134 -48
- data/lib/action_dispatch/routing/route.rb +2 -2
- data/lib/action_dispatch/routing/route_set.rb +217 -158
- data/lib/action_dispatch/routing/url_for.rb +139 -0
- data/lib/action_dispatch/testing/assertions/response.rb +14 -61
- data/lib/action_dispatch/testing/assertions/routing.rb +25 -14
- data/lib/action_dispatch/testing/integration.rb +32 -50
- data/lib/action_dispatch/testing/performance_test.rb +3 -1
- data/lib/action_dispatch/testing/test_process.rb +2 -0
- data/lib/action_dispatch/testing/test_request.rb +2 -0
- data/lib/action_pack/version.rb +4 -3
- data/lib/action_view.rb +11 -6
- data/lib/action_view/base.rb +33 -121
- data/lib/action_view/context.rb +0 -2
- data/lib/action_view/helpers.rb +26 -23
- data/lib/action_view/helpers/active_model_helper.rb +28 -18
- data/lib/action_view/helpers/asset_tag_helper.rb +109 -54
- data/lib/action_view/helpers/atom_feed_helper.rb +2 -2
- data/lib/action_view/helpers/cache_helper.rb +22 -1
- data/lib/action_view/helpers/capture_helper.rb +22 -22
- data/lib/action_view/helpers/date_helper.rb +6 -5
- data/lib/action_view/helpers/form_helper.rb +78 -63
- data/lib/action_view/helpers/form_options_helper.rb +6 -4
- data/lib/action_view/helpers/form_tag_helper.rb +26 -15
- data/lib/action_view/helpers/javascript_helper.rb +90 -10
- data/lib/action_view/helpers/number_helper.rb +315 -118
- data/lib/action_view/helpers/prototype_helper.rb +19 -46
- data/lib/action_view/helpers/record_tag_helper.rb +4 -4
- data/lib/action_view/helpers/tag_helper.rb +7 -24
- data/lib/action_view/helpers/text_helper.rb +8 -7
- data/lib/action_view/helpers/translation_helper.rb +7 -5
- data/lib/action_view/helpers/url_helper.rb +19 -16
- data/lib/action_view/locale/en.yml +45 -6
- data/lib/action_view/lookup_context.rb +190 -0
- data/lib/action_view/paths.rb +22 -63
- data/lib/action_view/railtie.rb +14 -4
- data/lib/action_view/railties/{subscriber.rb → log_subscriber.rb} +1 -1
- data/lib/action_view/render/layouts.rb +73 -0
- data/lib/action_view/render/partials.rb +15 -41
- data/lib/action_view/render/rendering.rb +27 -78
- data/lib/action_view/template.rb +20 -24
- data/lib/action_view/template/error.rb +22 -2
- data/lib/action_view/template/handlers/erb.rb +33 -9
- data/lib/action_view/template/handlers/rjs.rb +1 -2
- data/lib/action_view/template/resolver.rb +46 -104
- data/lib/action_view/template/text.rb +5 -12
- data/lib/action_view/test_case.rb +14 -23
- metadata +83 -40
- data/lib/abstract_controller/compatibility.rb +0 -18
- data/lib/abstract_controller/localized_cache.rb +0 -49
- data/lib/action_controller/metal/configuration.rb +0 -28
- data/lib/action_controller/url_rewriter.rb +0 -76
@@ -92,8 +92,7 @@ module ActionController
|
|
92
92
|
inflection = if options[:action].to_s == "new"
|
93
93
|
args.pop
|
94
94
|
:singular
|
95
|
-
elsif (record.respond_to?(:
|
96
|
-
(record.respond_to?(:destroyed?) && record.destroyed?)
|
95
|
+
elsif (record.respond_to?(:persisted?) && !record.persisted?)
|
97
96
|
args.pop
|
98
97
|
:plural
|
99
98
|
elsif record.is_a?(Class)
|
@@ -1,30 +1,83 @@
|
|
1
|
-
require "action_controller"
|
2
1
|
require "rails"
|
2
|
+
require "action_controller"
|
3
|
+
require "action_dispatch/railtie"
|
3
4
|
require "action_view/railtie"
|
5
|
+
require "active_support/core_ext/class/subclasses"
|
6
|
+
require "active_support/deprecation/proxy_wrappers"
|
7
|
+
require "active_support/deprecation"
|
8
|
+
|
9
|
+
require "action_controller/railties/log_subscriber"
|
10
|
+
require "action_controller/railties/url_helpers"
|
4
11
|
|
5
12
|
module ActionController
|
6
13
|
class Railtie < Rails::Railtie
|
7
|
-
|
14
|
+
config.action_controller = ActiveSupport::OrderedOptions.new
|
15
|
+
|
16
|
+
ad = config.action_dispatch
|
17
|
+
config.action_controller.singleton_class.send(:define_method, :session) do
|
18
|
+
ActiveSupport::Deprecation.warn "config.action_controller.session has been " \
|
19
|
+
"renamed to config.action_dispatch.session.", caller
|
20
|
+
ad.session
|
21
|
+
end
|
8
22
|
|
9
|
-
|
10
|
-
|
23
|
+
config.action_controller.singleton_class.send(:define_method, :session=) do |val|
|
24
|
+
ActiveSupport::Deprecation.warn "config.action_controller.session has been " \
|
25
|
+
"renamed to config.action_dispatch.session.", caller
|
26
|
+
ad.session = val
|
27
|
+
end
|
28
|
+
|
29
|
+
config.action_controller.singleton_class.send(:define_method, :session_store) do
|
30
|
+
ActiveSupport::Deprecation.warn "config.action_controller.session_store has been " \
|
31
|
+
"renamed to config.action_dispatch.session_store.", caller
|
32
|
+
ad.session_store
|
33
|
+
end
|
34
|
+
|
35
|
+
config.action_controller.singleton_class.send(:define_method, :session_store=) do |val|
|
36
|
+
ActiveSupport::Deprecation.warn "config.action_controller.session_store has been " \
|
37
|
+
"renamed to config.action_dispatch.session_store.", caller
|
38
|
+
ad.session_store = val
|
39
|
+
end
|
40
|
+
|
41
|
+
log_subscriber :action_controller, ActionController::Railties::LogSubscriber.new
|
11
42
|
|
12
43
|
initializer "action_controller.logger" do
|
13
|
-
|
44
|
+
ActiveSupport.on_load(:action_controller) { self.logger ||= Rails.logger }
|
14
45
|
end
|
15
46
|
|
16
47
|
initializer "action_controller.set_configs" do |app|
|
17
|
-
app.config.
|
18
|
-
|
48
|
+
paths = app.config.paths
|
49
|
+
ac = app.config.action_controller
|
50
|
+
|
51
|
+
ac.assets_dir = paths.public.to_a.first
|
52
|
+
ac.javascripts_dir = paths.public.javascripts.to_a.first
|
53
|
+
ac.stylesheets_dir = paths.public.stylesheets.to_a.first
|
54
|
+
ac.secret = app.config.cookie_secret
|
55
|
+
|
56
|
+
ActiveSupport.on_load(:action_controller) do
|
57
|
+
self.config.merge!(ac)
|
19
58
|
end
|
20
59
|
end
|
21
60
|
|
22
61
|
initializer "action_controller.initialize_framework_caches" do
|
23
|
-
|
62
|
+
ActiveSupport.on_load(:action_controller) { self.cache_store ||= RAILS_CACHE }
|
24
63
|
end
|
25
64
|
|
26
65
|
initializer "action_controller.set_helpers_path" do |app|
|
27
|
-
|
66
|
+
ActiveSupport.on_load(:action_controller) do
|
67
|
+
self.helpers_path = app.config.paths.app.helpers.to_a
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
initializer "action_controller.url_helpers" do |app|
|
72
|
+
ActiveSupport.on_load(:action_controller) do
|
73
|
+
extend ::ActionController::Railties::UrlHelpers.with(app.routes)
|
74
|
+
end
|
75
|
+
|
76
|
+
message = "ActionController::Routing::Routes is deprecated. " \
|
77
|
+
"Instead, use Rails.application.routes"
|
78
|
+
|
79
|
+
proxy = ActiveSupport::Deprecation::DeprecatedObjectProxy.new(app.routes, message)
|
80
|
+
ActionController::Routing::Routes = proxy
|
28
81
|
end
|
29
82
|
end
|
30
|
-
end
|
83
|
+
end
|
@@ -1,6 +1,8 @@
|
|
1
|
+
require 'active_support/core_ext/object/blank'
|
2
|
+
|
1
3
|
module ActionController
|
2
4
|
module Railties
|
3
|
-
class
|
5
|
+
class LogSubscriber < Rails::LogSubscriber
|
4
6
|
INTERNAL_PARAMS = %w(controller action format _method only_path)
|
5
7
|
|
6
8
|
def start_processing(event)
|
@@ -15,23 +17,14 @@ module ActionController
|
|
15
17
|
payload = event.payload
|
16
18
|
additions = ActionController::Base.log_process_action(payload)
|
17
19
|
|
18
|
-
message = "Completed in %.0fms" % event.duration
|
20
|
+
message = "Completed #{payload[:status]} #{Rack::Utils::HTTP_STATUS_CODES[payload[:status]]} in %.0fms" % event.duration
|
19
21
|
message << " (#{additions.join(" | ")})" unless additions.blank?
|
20
|
-
message << " with #{payload[:status]}"
|
21
22
|
|
22
23
|
info(message)
|
23
24
|
end
|
24
25
|
|
25
26
|
def send_file(event)
|
26
|
-
message =
|
27
|
-
header = ActionController::Streaming::X_SENDFILE_HEADER
|
28
|
-
"Sent #{header} header %s"
|
29
|
-
elsif event.payload[:stream]
|
30
|
-
"Streamed file %s"
|
31
|
-
else
|
32
|
-
"Sent file %s"
|
33
|
-
end
|
34
|
-
|
27
|
+
message = "Sent file %s"
|
35
28
|
message << " (%.1fms)"
|
36
29
|
info(message % [event.payload[:path], event.duration])
|
37
30
|
end
|
@@ -60,13 +60,32 @@ module ActionController
|
|
60
60
|
#
|
61
61
|
# dom_id(Post.find(45), :edit) # => "edit_post_45"
|
62
62
|
def dom_id(record, prefix = nil)
|
63
|
-
if record_id = record
|
63
|
+
if record_id = record_key_for_dom_id(record)
|
64
64
|
"#{dom_class(record, prefix)}#{JOIN}#{record_id}"
|
65
65
|
else
|
66
66
|
dom_class(record, prefix || NEW)
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
|
+
# Returns a string representation of the key attribute(s) that is suitable for use in an HTML DOM id.
|
71
|
+
# This can be overwritten to customize the default generated string representation if desired.
|
72
|
+
# If you need to read back a key from a dom_id in order to query for the underlying database record,
|
73
|
+
# you should write a helper like 'person_record_from_dom_id' that will extract the key either based
|
74
|
+
# on the default implementation (which just joins all key attributes with '-') or on your own
|
75
|
+
# overwritten version of the method. By default, this implementation passes the key string through a
|
76
|
+
# method that replaces all characters that are invalid inside DOM ids, with valid ones. You need to
|
77
|
+
# make sure yourself that your dom ids are valid, in case you overwrite this method.
|
78
|
+
def record_key_for_dom_id(record)
|
79
|
+
record = record.to_model if record.respond_to?(:to_model)
|
80
|
+
key = record.to_key
|
81
|
+
key ? sanitize_dom_id(key.join('_')) : key
|
82
|
+
end
|
83
|
+
|
84
|
+
# Replaces characters that are invalid in HTML DOM ids with valid ones.
|
85
|
+
def sanitize_dom_id(candidate_id)
|
86
|
+
candidate_id # TODO implement conversion to valid DOM id values
|
87
|
+
end
|
88
|
+
|
70
89
|
# Returns the plural class name of a record or class. Examples:
|
71
90
|
#
|
72
91
|
# plural_class_name(post) # => "posts"
|
@@ -1,7 +1,108 @@
|
|
1
1
|
require 'rack/session/abstract/id'
|
2
|
-
require '
|
2
|
+
require 'active_support/core_ext/object/blank'
|
3
3
|
|
4
4
|
module ActionController
|
5
|
+
module TemplateAssertions
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
setup :setup_subscriptions
|
10
|
+
teardown :teardown_subscriptions
|
11
|
+
end
|
12
|
+
|
13
|
+
def setup_subscriptions
|
14
|
+
@partials = Hash.new(0)
|
15
|
+
@templates = Hash.new(0)
|
16
|
+
@layouts = Hash.new(0)
|
17
|
+
|
18
|
+
ActiveSupport::Notifications.subscribe("action_view.render_template") do |name, start, finish, id, payload|
|
19
|
+
path = payload[:layout]
|
20
|
+
@layouts[path] += 1
|
21
|
+
end
|
22
|
+
|
23
|
+
ActiveSupport::Notifications.subscribe("action_view.render_template!") do |name, start, finish, id, payload|
|
24
|
+
path = payload[:virtual_path]
|
25
|
+
next unless path
|
26
|
+
partial = path =~ /^.*\/_[^\/]*$/
|
27
|
+
if partial
|
28
|
+
@partials[path] += 1
|
29
|
+
@partials[path.split("/").last] += 1
|
30
|
+
@templates[path] += 1
|
31
|
+
else
|
32
|
+
@templates[path] += 1
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def teardown_subscriptions
|
38
|
+
ActiveSupport::Notifications.unsubscribe("action_view.render_template!")
|
39
|
+
end
|
40
|
+
|
41
|
+
# Asserts that the request was rendered with the appropriate template file or partials
|
42
|
+
#
|
43
|
+
# ==== Examples
|
44
|
+
#
|
45
|
+
# # assert that the "new" view template was rendered
|
46
|
+
# assert_template "new"
|
47
|
+
#
|
48
|
+
# # assert that the "_customer" partial was rendered twice
|
49
|
+
# assert_template :partial => '_customer', :count => 2
|
50
|
+
#
|
51
|
+
# # assert that no partials were rendered
|
52
|
+
# assert_template :partial => false
|
53
|
+
#
|
54
|
+
def assert_template(options = {}, message = nil)
|
55
|
+
validate_request!
|
56
|
+
|
57
|
+
case options
|
58
|
+
when NilClass, String
|
59
|
+
rendered = @templates
|
60
|
+
msg = build_message(message,
|
61
|
+
"expecting <?> but rendering with <?>",
|
62
|
+
options, rendered.keys.join(', '))
|
63
|
+
assert_block(msg) do
|
64
|
+
if options.nil?
|
65
|
+
@templates.blank?
|
66
|
+
else
|
67
|
+
rendered.any? { |t,num| t.match(options) }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
when Hash
|
71
|
+
if expected_partial = options[:partial]
|
72
|
+
if expected_count = options[:count]
|
73
|
+
actual_count = @partials[expected_partial]
|
74
|
+
# actual_count = found.nil? ? 0 : found[1]
|
75
|
+
msg = build_message(message,
|
76
|
+
"expecting ? to be rendered ? time(s) but rendered ? time(s)",
|
77
|
+
expected_partial, expected_count, actual_count)
|
78
|
+
assert(actual_count == expected_count.to_i, msg)
|
79
|
+
elsif options.key?(:layout)
|
80
|
+
msg = build_message(message,
|
81
|
+
"expecting layout <?> but action rendered <?>",
|
82
|
+
expected_layout, @layouts.keys)
|
83
|
+
|
84
|
+
case layout = options[:layout]
|
85
|
+
when String
|
86
|
+
assert(@layouts.include?(expected_layout), msg)
|
87
|
+
when Regexp
|
88
|
+
assert(@layouts.any? {|l| l =~ layout }, msg)
|
89
|
+
when nil
|
90
|
+
assert(@layouts.empty?, msg)
|
91
|
+
end
|
92
|
+
else
|
93
|
+
msg = build_message(message,
|
94
|
+
"expecting partial <?> but action rendered <?>",
|
95
|
+
options[:partial], @partials.keys)
|
96
|
+
assert(@partials.include?(expected_partial), msg)
|
97
|
+
end
|
98
|
+
else
|
99
|
+
assert @partials.empty?,
|
100
|
+
"Expected no partials to be rendered"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
5
106
|
class TestRequest < ActionDispatch::TestRequest #:nodoc:
|
6
107
|
def initialize(env = {})
|
7
108
|
super
|
@@ -17,9 +118,9 @@ module ActionController
|
|
17
118
|
end
|
18
119
|
end
|
19
120
|
|
20
|
-
def assign_parameters(controller_path, action, parameters = {})
|
121
|
+
def assign_parameters(routes, controller_path, action, parameters = {})
|
21
122
|
parameters = parameters.symbolize_keys.merge(:controller => controller_path, :action => action)
|
22
|
-
extra_keys =
|
123
|
+
extra_keys = routes.extra_keys(parameters)
|
23
124
|
non_path_parameters = get? ? query_parameters : request_parameters
|
24
125
|
parameters.each do |key, value|
|
25
126
|
if value.is_a? Fixnum
|
@@ -181,6 +282,7 @@ module ActionController
|
|
181
282
|
# assert_redirected_to page_url(:title => 'foo')
|
182
283
|
class TestCase < ActiveSupport::TestCase
|
183
284
|
include ActionDispatch::TestProcess
|
285
|
+
include ActionController::TemplateAssertions
|
184
286
|
|
185
287
|
# Executes a request simulating GET HTTP method and set/volley the response
|
186
288
|
def get(action, parameters = nil, session = nil, flash = nil)
|
@@ -220,7 +322,7 @@ module ActionController
|
|
220
322
|
def process(action, parameters = nil, session = nil, flash = nil, http_method = 'GET')
|
221
323
|
# Sanity check for required instance variables so we can give an
|
222
324
|
# understandable error message.
|
223
|
-
%w(@controller @request @response).each do |iv_name|
|
325
|
+
%w(@routes @controller @request @response).each do |iv_name|
|
224
326
|
if !(instance_variable_names.include?(iv_name) || instance_variable_names.include?(iv_name.to_sym)) || instance_variable_get(iv_name).nil?
|
225
327
|
raise "#{iv_name} is nil: make sure you set it in your test's setup method."
|
226
328
|
end
|
@@ -236,7 +338,7 @@ module ActionController
|
|
236
338
|
@request.env['REQUEST_METHOD'] = http_method
|
237
339
|
|
238
340
|
parameters ||= {}
|
239
|
-
@request.assign_parameters(@controller.class.name.underscore.sub(/_controller$/, ''), action.to_s, parameters)
|
341
|
+
@request.assign_parameters(@routes, @controller.class.name.underscore.sub(/_controller$/, ''), action.to_s, parameters)
|
240
342
|
|
241
343
|
@request.session = ActionController::TestSession.new(session) unless session.nil?
|
242
344
|
@request.session["flash"] = @request.flash.update(flash || {})
|
@@ -322,6 +424,8 @@ module ActionController
|
|
322
424
|
@controller ||= klass.new rescue nil
|
323
425
|
end
|
324
426
|
|
427
|
+
@request.env.delete('PATH_INFO')
|
428
|
+
|
325
429
|
if @controller
|
326
430
|
@controller.request = @request
|
327
431
|
@controller.params = {}
|
@@ -335,13 +439,20 @@ module ActionController
|
|
335
439
|
|
336
440
|
private
|
337
441
|
def build_request_uri(action, parameters)
|
338
|
-
unless @request.env[
|
339
|
-
options = @controller.__send__(:
|
340
|
-
options.update(
|
341
|
-
|
342
|
-
|
343
|
-
|
442
|
+
unless @request.env["PATH_INFO"]
|
443
|
+
options = @controller.__send__(:url_options).merge(parameters)
|
444
|
+
options.update(
|
445
|
+
:only_path => true,
|
446
|
+
:action => action,
|
447
|
+
:relative_url_root => nil,
|
448
|
+
:_path_segments => @request.symbolized_path_parameters)
|
449
|
+
|
450
|
+
url, query_string = @routes.url_for(options).split("?", 2)
|
451
|
+
|
452
|
+
@request.env["SCRIPT_NAME"] = @controller.config.relative_url_root
|
453
|
+
@request.env["PATH_INFO"] = url
|
454
|
+
@request.env["QUERY_STRING"] = query_string || ""
|
344
455
|
end
|
345
456
|
end
|
346
|
-
|
457
|
+
end
|
347
458
|
end
|
data/lib/action_dispatch.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'active_support/core_ext/object/blank'
|
2
|
+
|
1
3
|
module ActionDispatch
|
2
4
|
module Http
|
3
5
|
module Cache
|
@@ -37,8 +39,21 @@ module ActionDispatch
|
|
37
39
|
end
|
38
40
|
|
39
41
|
module Response
|
40
|
-
|
41
|
-
|
42
|
+
attr_reader :cache_control
|
43
|
+
|
44
|
+
def initialize(*)
|
45
|
+
status, header, body = super
|
46
|
+
|
47
|
+
@cache_control = {}
|
48
|
+
@etag = self["ETag"]
|
49
|
+
|
50
|
+
if cache_control = self["Cache-Control"]
|
51
|
+
cache_control.split(/,\s*/).each do |segment|
|
52
|
+
first, last = segment.split("=")
|
53
|
+
last ||= true
|
54
|
+
@cache_control[first.to_sym] = last
|
55
|
+
end
|
56
|
+
end
|
42
57
|
end
|
43
58
|
|
44
59
|
def last_modified
|
@@ -65,7 +80,7 @@ module ActionDispatch
|
|
65
80
|
|
66
81
|
def etag=(etag)
|
67
82
|
key = ActiveSupport::Cache.expand_cache_key(etag)
|
68
|
-
@etag = %("#{Digest::MD5.hexdigest(key)}")
|
83
|
+
@etag = self["ETag"] = %("#{Digest::MD5.hexdigest(key)}")
|
69
84
|
end
|
70
85
|
|
71
86
|
private
|
@@ -100,6 +115,8 @@ module ActionDispatch
|
|
100
115
|
def set_conditional_cache_control!
|
101
116
|
control = @cache_control
|
102
117
|
|
118
|
+
return if self["Cache-Control"].present?
|
119
|
+
|
103
120
|
if control.empty?
|
104
121
|
headers["Cache-Control"] = DEFAULT_CACHE_CONTROL
|
105
122
|
elsif @cache_control[:no_cache]
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'active_support/core_ext/object/blank'
|
2
2
|
require 'active_support/core_ext/hash/keys'
|
3
|
+
require 'active_support/core_ext/object/duplicable'
|
3
4
|
|
4
5
|
module ActionDispatch
|
5
6
|
module Http
|
@@ -25,9 +26,15 @@ module ActionDispatch
|
|
25
26
|
module FilterParameters
|
26
27
|
extend ActiveSupport::Concern
|
27
28
|
|
29
|
+
@@compiled_parameter_filter_for = {}
|
30
|
+
|
28
31
|
# Return a hash of parameters with all sensitive data replaced.
|
29
32
|
def filtered_parameters
|
30
|
-
@filtered_parameters ||=
|
33
|
+
@filtered_parameters ||= if filtering_parameters?
|
34
|
+
process_parameter_filter(parameters)
|
35
|
+
else
|
36
|
+
parameters.dup
|
37
|
+
end
|
31
38
|
end
|
32
39
|
alias :fitered_params :filtered_parameters
|
33
40
|
|
@@ -46,10 +53,18 @@ module ActionDispatch
|
|
46
53
|
|
47
54
|
protected
|
48
55
|
|
49
|
-
def
|
56
|
+
def filtering_parameters? #:nodoc:
|
57
|
+
@env["action_dispatch.parameter_filter"].present?
|
58
|
+
end
|
59
|
+
|
60
|
+
def process_parameter_filter(params) #:nodoc:
|
61
|
+
compiled_parameter_filter_for(@env["action_dispatch.parameter_filter"]).call(params)
|
62
|
+
end
|
63
|
+
|
64
|
+
def compile_parameter_filter(filters) #:nodoc:
|
50
65
|
strings, regexps, blocks = [], [], []
|
51
66
|
|
52
|
-
|
67
|
+
filters.each do |item|
|
53
68
|
case item
|
54
69
|
when NilClass
|
55
70
|
when Proc
|
@@ -65,34 +80,34 @@ module ActionDispatch
|
|
65
80
|
[regexps, blocks]
|
66
81
|
end
|
67
82
|
|
68
|
-
def
|
69
|
-
|
70
|
-
|
83
|
+
def compiled_parameter_filter_for(filters) #:nodoc:
|
84
|
+
@@compiled_parameter_filter_for[filters] ||= begin
|
85
|
+
regexps, blocks = compile_parameter_filter(filters)
|
71
86
|
|
72
|
-
|
73
|
-
|
87
|
+
lambda do |original_params|
|
88
|
+
filtered_params = {}
|
74
89
|
|
75
|
-
|
76
|
-
|
90
|
+
original_params.each do |key, value|
|
91
|
+
if regexps.find { |r| key =~ r }
|
92
|
+
value = '[FILTERED]'
|
93
|
+
elsif value.is_a?(Hash)
|
94
|
+
value = process_parameter_filter(value)
|
95
|
+
elsif value.is_a?(Array)
|
96
|
+
value = value.map { |v| v.is_a?(Hash) ? process_parameter_filter(v) : v }
|
97
|
+
elsif blocks.present?
|
98
|
+
key = key.dup
|
99
|
+
value = value.dup if value.duplicable?
|
100
|
+
blocks.each { |b| b.call(key, value) }
|
101
|
+
end
|
77
102
|
|
78
|
-
|
79
|
-
|
80
|
-
value = '[FILTERED]'
|
81
|
-
elsif value.is_a?(Hash)
|
82
|
-
value = process_parameter_filter(value)
|
83
|
-
elsif value.is_a?(Array)
|
84
|
-
value = value.map { |i| process_parameter_filter(i) }
|
85
|
-
elsif blocks.present?
|
86
|
-
key = key.dup
|
87
|
-
value = value.dup if value.duplicable?
|
88
|
-
blocks.each { |b| b.call(key, value) }
|
89
|
-
end
|
103
|
+
filtered_params[key] = value
|
104
|
+
end
|
90
105
|
|
91
|
-
|
106
|
+
filtered_params
|
107
|
+
end
|
92
108
|
end
|
93
|
-
|
94
|
-
filtered_params
|
95
109
|
end
|
110
|
+
|
96
111
|
end
|
97
112
|
end
|
98
113
|
end
|