actionpack 3.2.22.5 → 4.0.0.beta1
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 +641 -418
- data/MIT-LICENSE +1 -1
- data/README.rdoc +5 -288
- data/lib/abstract_controller.rb +1 -8
- data/lib/abstract_controller/asset_paths.rb +2 -2
- data/lib/abstract_controller/base.rb +39 -37
- data/lib/abstract_controller/callbacks.rb +101 -82
- data/lib/abstract_controller/collector.rb +7 -3
- data/lib/abstract_controller/helpers.rb +23 -11
- data/lib/abstract_controller/layouts.rb +68 -73
- data/lib/abstract_controller/logger.rb +1 -2
- data/lib/abstract_controller/rendering.rb +22 -13
- data/lib/abstract_controller/translation.rb +16 -1
- data/lib/abstract_controller/url_for.rb +6 -6
- data/lib/abstract_controller/view_paths.rb +1 -1
- data/lib/action_controller.rb +15 -6
- data/lib/action_controller/base.rb +46 -22
- data/lib/action_controller/caching.rb +46 -33
- data/lib/action_controller/caching/fragments.rb +23 -53
- data/lib/action_controller/deprecated.rb +5 -1
- data/lib/action_controller/deprecated/integration_test.rb +3 -0
- data/lib/action_controller/log_subscriber.rb +11 -8
- data/lib/action_controller/metal.rb +16 -30
- data/lib/action_controller/metal/conditional_get.rb +76 -32
- data/lib/action_controller/metal/data_streaming.rb +20 -26
- data/lib/action_controller/metal/exceptions.rb +19 -6
- data/lib/action_controller/metal/flash.rb +24 -9
- data/lib/action_controller/metal/force_ssl.rb +32 -9
- data/lib/action_controller/metal/head.rb +25 -4
- data/lib/action_controller/metal/helpers.rb +6 -9
- data/lib/action_controller/metal/hide_actions.rb +1 -2
- data/lib/action_controller/metal/http_authentication.rb +105 -87
- data/lib/action_controller/metal/implicit_render.rb +1 -1
- data/lib/action_controller/metal/instrumentation.rb +2 -1
- data/lib/action_controller/metal/live.rb +141 -0
- data/lib/action_controller/metal/mime_responds.rb +161 -47
- data/lib/action_controller/metal/params_wrapper.rb +112 -74
- data/lib/action_controller/metal/rack_delegation.rb +9 -3
- data/lib/action_controller/metal/redirecting.rb +15 -20
- data/lib/action_controller/metal/renderers.rb +11 -9
- data/lib/action_controller/metal/rendering.rb +8 -0
- data/lib/action_controller/metal/request_forgery_protection.rb +112 -19
- data/lib/action_controller/metal/responder.rb +20 -19
- data/lib/action_controller/metal/streaming.rb +12 -18
- data/lib/action_controller/metal/strong_parameters.rb +516 -0
- data/lib/action_controller/metal/testing.rb +13 -18
- data/lib/action_controller/metal/url_for.rb +27 -25
- data/lib/action_controller/model_naming.rb +12 -0
- data/lib/action_controller/railtie.rb +33 -17
- data/lib/action_controller/railties/helpers.rb +22 -0
- data/lib/action_controller/record_identifier.rb +18 -72
- data/lib/action_controller/test_case.rb +215 -123
- data/lib/action_controller/vendor/html-scanner.rb +4 -19
- data/lib/action_dispatch.rb +27 -19
- data/lib/action_dispatch/http/cache.rb +63 -11
- data/lib/action_dispatch/http/filter_parameters.rb +18 -8
- data/lib/action_dispatch/http/filter_redirect.rb +37 -0
- data/lib/action_dispatch/http/headers.rb +27 -19
- data/lib/action_dispatch/http/mime_negotiation.rb +25 -2
- data/lib/action_dispatch/http/mime_type.rb +145 -113
- data/lib/action_dispatch/http/mime_types.rb +1 -1
- data/lib/action_dispatch/http/parameter_filter.rb +44 -46
- data/lib/action_dispatch/http/parameters.rb +12 -5
- data/lib/action_dispatch/http/rack_cache.rb +2 -3
- data/lib/action_dispatch/http/request.rb +49 -18
- data/lib/action_dispatch/http/response.rb +129 -35
- data/lib/action_dispatch/http/upload.rb +60 -17
- data/lib/action_dispatch/http/url.rb +53 -31
- data/lib/action_dispatch/journey.rb +5 -0
- data/lib/action_dispatch/journey/backwards.rb +5 -0
- data/lib/action_dispatch/journey/formatter.rb +146 -0
- data/lib/action_dispatch/journey/gtg/builder.rb +162 -0
- data/lib/action_dispatch/journey/gtg/simulator.rb +44 -0
- data/lib/action_dispatch/journey/gtg/transition_table.rb +156 -0
- data/lib/action_dispatch/journey/nfa/builder.rb +76 -0
- data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
- data/lib/action_dispatch/journey/nfa/simulator.rb +47 -0
- data/lib/action_dispatch/journey/nfa/transition_table.rb +163 -0
- data/lib/action_dispatch/journey/nodes/node.rb +124 -0
- data/lib/action_dispatch/journey/parser.rb +206 -0
- data/lib/action_dispatch/journey/parser.y +47 -0
- data/lib/action_dispatch/journey/parser_extras.rb +23 -0
- data/lib/action_dispatch/journey/path/pattern.rb +196 -0
- data/lib/action_dispatch/journey/route.rb +116 -0
- data/lib/action_dispatch/journey/router.rb +164 -0
- data/lib/action_dispatch/journey/router/strexp.rb +24 -0
- data/lib/action_dispatch/journey/router/utils.rb +54 -0
- data/lib/action_dispatch/journey/routes.rb +75 -0
- data/lib/action_dispatch/journey/scanner.rb +61 -0
- data/lib/action_dispatch/journey/visitors.rb +189 -0
- data/lib/action_dispatch/journey/visualizer/fsm.css +34 -0
- data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
- data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
- data/lib/action_dispatch/middleware/callbacks.rb +9 -4
- data/lib/action_dispatch/middleware/cookies.rb +168 -57
- data/lib/action_dispatch/middleware/debug_exceptions.rb +26 -17
- data/lib/action_dispatch/middleware/exception_wrapper.rb +27 -3
- data/lib/action_dispatch/middleware/flash.rb +58 -58
- data/lib/action_dispatch/middleware/params_parser.rb +14 -29
- data/lib/action_dispatch/middleware/public_exceptions.rb +31 -14
- data/lib/action_dispatch/middleware/reloader.rb +6 -6
- data/lib/action_dispatch/middleware/remote_ip.rb +145 -39
- data/lib/action_dispatch/middleware/request_id.rb +2 -6
- data/lib/action_dispatch/middleware/session/abstract_store.rb +22 -20
- data/lib/action_dispatch/middleware/session/cache_store.rb +3 -3
- data/lib/action_dispatch/middleware/session/cookie_store.rb +81 -7
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -3
- data/lib/action_dispatch/middleware/show_exceptions.rb +12 -45
- data/lib/action_dispatch/middleware/ssl.rb +70 -0
- data/lib/action_dispatch/middleware/stack.rb +6 -1
- data/lib/action_dispatch/middleware/static.rb +5 -24
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +14 -11
- data/lib/action_dispatch/middleware/templates/rescues/_source.erb +25 -0
- data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +15 -9
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +121 -5
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +7 -2
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +30 -15
- data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +39 -13
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +6 -2
- data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +16 -0
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +144 -0
- data/lib/action_dispatch/railtie.rb +16 -6
- data/lib/action_dispatch/request/session.rb +181 -0
- data/lib/action_dispatch/routing.rb +41 -40
- data/lib/action_dispatch/routing/inspector.rb +240 -0
- data/lib/action_dispatch/routing/mapper.rb +501 -273
- data/lib/action_dispatch/routing/polymorphic_routes.rb +16 -20
- data/lib/action_dispatch/routing/redirection.rb +46 -29
- data/lib/action_dispatch/routing/route_set.rb +203 -164
- data/lib/action_dispatch/routing/routes_proxy.rb +2 -0
- data/lib/action_dispatch/routing/url_for.rb +48 -33
- data/lib/action_dispatch/testing/assertions/dom.rb +3 -13
- data/lib/action_dispatch/testing/assertions/response.rb +32 -40
- data/lib/action_dispatch/testing/assertions/routing.rb +40 -39
- data/lib/action_dispatch/testing/assertions/selector.rb +15 -20
- data/lib/action_dispatch/testing/assertions/tag.rb +20 -23
- data/lib/action_dispatch/testing/integration.rb +41 -22
- data/lib/action_dispatch/testing/test_process.rb +9 -6
- data/lib/action_dispatch/testing/test_request.rb +7 -3
- data/lib/action_pack.rb +1 -1
- data/lib/action_pack/version.rb +4 -4
- data/lib/action_view.rb +17 -8
- data/lib/action_view/base.rb +15 -34
- data/lib/action_view/buffers.rb +1 -1
- data/lib/action_view/context.rb +4 -4
- data/lib/action_view/dependency_tracker.rb +91 -0
- data/lib/action_view/digestor.rb +85 -0
- data/lib/action_view/flows.rb +1 -4
- data/lib/action_view/helpers.rb +2 -4
- data/lib/action_view/helpers/active_model_helper.rb +3 -4
- data/lib/action_view/helpers/asset_tag_helper.rb +211 -353
- data/lib/action_view/helpers/asset_url_helper.rb +354 -0
- data/lib/action_view/helpers/atom_feed_helper.rb +13 -10
- data/lib/action_view/helpers/cache_helper.rb +150 -18
- data/lib/action_view/helpers/capture_helper.rb +42 -29
- data/lib/action_view/helpers/csrf_helper.rb +0 -2
- data/lib/action_view/helpers/date_helper.rb +268 -247
- data/lib/action_view/helpers/debug_helper.rb +10 -11
- data/lib/action_view/helpers/form_helper.rb +904 -547
- data/lib/action_view/helpers/form_options_helper.rb +341 -166
- data/lib/action_view/helpers/form_tag_helper.rb +188 -88
- data/lib/action_view/helpers/javascript_helper.rb +23 -16
- data/lib/action_view/helpers/number_helper.rb +148 -354
- data/lib/action_view/helpers/output_safety_helper.rb +3 -3
- data/lib/action_view/helpers/record_tag_helper.rb +17 -22
- data/lib/action_view/helpers/rendering_helper.rb +2 -4
- data/lib/action_view/helpers/sanitize_helper.rb +3 -6
- data/lib/action_view/helpers/tag_helper.rb +43 -37
- data/lib/action_view/helpers/tags.rb +39 -0
- data/lib/action_view/helpers/tags/base.rb +148 -0
- data/lib/action_view/helpers/tags/check_box.rb +64 -0
- data/lib/action_view/helpers/tags/checkable.rb +16 -0
- data/lib/action_view/helpers/tags/collection_check_boxes.rb +43 -0
- data/lib/action_view/helpers/tags/collection_helpers.rb +83 -0
- data/lib/action_view/helpers/tags/collection_radio_buttons.rb +36 -0
- data/lib/action_view/helpers/tags/collection_select.rb +28 -0
- data/lib/action_view/helpers/tags/color_field.rb +25 -0
- data/lib/action_view/helpers/tags/date_field.rb +13 -0
- data/lib/action_view/helpers/tags/date_select.rb +72 -0
- data/lib/action_view/helpers/tags/datetime_field.rb +22 -0
- data/lib/action_view/helpers/tags/datetime_local_field.rb +19 -0
- data/lib/action_view/helpers/tags/datetime_select.rb +8 -0
- data/lib/action_view/helpers/tags/email_field.rb +8 -0
- data/lib/action_view/helpers/tags/file_field.rb +8 -0
- data/lib/action_view/helpers/tags/grouped_collection_select.rb +29 -0
- data/lib/action_view/helpers/tags/hidden_field.rb +8 -0
- data/lib/action_view/helpers/tags/label.rb +65 -0
- data/lib/action_view/helpers/tags/month_field.rb +13 -0
- data/lib/action_view/helpers/tags/number_field.rb +18 -0
- data/lib/action_view/helpers/tags/password_field.rb +12 -0
- data/lib/action_view/helpers/tags/radio_button.rb +31 -0
- data/lib/action_view/helpers/tags/range_field.rb +8 -0
- data/lib/action_view/helpers/tags/search_field.rb +24 -0
- data/lib/action_view/helpers/tags/select.rb +41 -0
- data/lib/action_view/helpers/tags/tel_field.rb +8 -0
- data/lib/action_view/helpers/tags/text_area.rb +18 -0
- data/lib/action_view/helpers/tags/text_field.rb +29 -0
- data/lib/action_view/helpers/tags/time_field.rb +13 -0
- data/lib/action_view/helpers/tags/time_select.rb +8 -0
- data/lib/action_view/helpers/tags/time_zone_select.rb +20 -0
- data/lib/action_view/helpers/tags/url_field.rb +8 -0
- data/lib/action_view/helpers/tags/week_field.rb +13 -0
- data/lib/action_view/helpers/text_helper.rb +126 -113
- data/lib/action_view/helpers/translation_helper.rb +32 -16
- data/lib/action_view/helpers/url_helper.rb +200 -271
- data/lib/action_view/locale/en.yml +1 -105
- data/lib/action_view/log_subscriber.rb +6 -4
- data/lib/action_view/lookup_context.rb +15 -39
- data/lib/action_view/model_naming.rb +12 -0
- data/lib/action_view/path_set.rb +9 -39
- data/lib/action_view/railtie.rb +6 -22
- data/lib/action_view/record_identifier.rb +84 -0
- data/lib/action_view/renderer/abstract_renderer.rb +10 -19
- data/lib/action_view/renderer/partial_renderer.rb +144 -81
- data/lib/action_view/renderer/renderer.rb +2 -19
- data/lib/action_view/renderer/streaming_template_renderer.rb +2 -5
- data/lib/action_view/renderer/template_renderer.rb +14 -13
- data/lib/action_view/routing_url_for.rb +107 -0
- data/lib/action_view/template.rb +22 -21
- data/lib/action_view/template/error.rb +22 -12
- data/lib/action_view/template/handlers.rb +12 -9
- data/lib/action_view/template/handlers/builder.rb +1 -1
- data/lib/action_view/template/handlers/erb.rb +11 -16
- data/lib/action_view/template/handlers/raw.rb +11 -0
- data/lib/action_view/template/resolver.rb +111 -83
- data/lib/action_view/template/text.rb +12 -8
- data/lib/action_view/template/types.rb +57 -0
- data/lib/action_view/test_case.rb +66 -43
- data/lib/action_view/testing/resolvers.rb +3 -2
- data/lib/action_view/vendor/html-scanner.rb +20 -0
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/document.rb +0 -0
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/node.rb +12 -12
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/sanitizer.rb +18 -7
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/selector.rb +1 -1
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/tokenizer.rb +1 -1
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/version.rb +0 -0
- metadata +135 -125
- data/lib/action_controller/caching/actions.rb +0 -185
- data/lib/action_controller/caching/pages.rb +0 -187
- data/lib/action_controller/caching/sweeping.rb +0 -97
- data/lib/action_controller/deprecated/performance_test.rb +0 -1
- data/lib/action_controller/metal/compatibility.rb +0 -65
- data/lib/action_controller/metal/session_management.rb +0 -14
- data/lib/action_controller/railties/paths.rb +0 -25
- data/lib/action_dispatch/middleware/best_standards_support.rb +0 -30
- data/lib/action_dispatch/middleware/body_proxy.rb +0 -30
- data/lib/action_dispatch/middleware/head.rb +0 -18
- data/lib/action_dispatch/middleware/rescue.rb +0 -26
- data/lib/action_dispatch/testing/performance_test.rb +0 -10
- data/lib/action_view/asset_paths.rb +0 -142
- data/lib/action_view/helpers/asset_paths.rb +0 -7
- data/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb +0 -146
- data/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb +0 -93
- data/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +0 -193
- data/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +0 -148
- data/lib/sprockets/assets.rake +0 -99
- data/lib/sprockets/bootstrap.rb +0 -37
- data/lib/sprockets/compressors.rb +0 -83
- data/lib/sprockets/helpers.rb +0 -6
- data/lib/sprockets/helpers/isolated_helper.rb +0 -13
- data/lib/sprockets/helpers/rails_helper.rb +0 -182
- data/lib/sprockets/railtie.rb +0 -62
- data/lib/sprockets/static_compiler.rb +0 -56
@@ -1,59 +1,29 @@
|
|
1
|
-
module ActionController
|
1
|
+
module ActionController
|
2
2
|
module Caching
|
3
|
-
# Fragment caching is used for caching various blocks within
|
3
|
+
# Fragment caching is used for caching various blocks within
|
4
4
|
# views without caching the entire action as a whole. This is
|
5
|
-
# useful when certain elements of an action change frequently or
|
6
|
-
# depend on complicated state while other parts rarely change or
|
5
|
+
# useful when certain elements of an action change frequently or
|
6
|
+
# depend on complicated state while other parts rarely change or
|
7
7
|
# can be shared amongst multiple parties. The caching is done using
|
8
|
-
# the
|
9
|
-
#
|
8
|
+
# the +cache+ helper available in the Action View. See
|
9
|
+
# ActionView::Helpers::CacheHelper for more information.
|
10
10
|
#
|
11
|
-
#
|
11
|
+
# While it's strongly recommended that you use key-based cache
|
12
|
+
# expiration (see links in CacheHelper for more information),
|
13
|
+
# it is also possible to manually expire caches. For example:
|
12
14
|
#
|
13
|
-
#
|
14
|
-
# All the topics in the system:
|
15
|
-
# <%= render :partial => "topic", :collection => Topic.all %>
|
16
|
-
# <% end %>
|
17
|
-
#
|
18
|
-
# This cache will bind the name of the action that called it, so if
|
19
|
-
# this code was part of the view for the topics/list action, you
|
20
|
-
# would be able to invalidate it using:
|
21
|
-
#
|
22
|
-
# expire_fragment(:controller => "topics", :action => "list")
|
23
|
-
#
|
24
|
-
# This default behavior is limited if you need to cache multiple
|
25
|
-
# fragments per action or if the action itself is cached using
|
26
|
-
# <tt>caches_action</tt>. To remedy this, there is an option to
|
27
|
-
# qualify the name of the cached fragment by using the
|
28
|
-
# <tt>:action_suffix</tt> option:
|
29
|
-
#
|
30
|
-
# <% cache(:action => "list", :action_suffix => "all_topics") do %>
|
31
|
-
#
|
32
|
-
# That would result in a name such as
|
33
|
-
# <tt>/topics/list/all_topics</tt>, avoiding conflicts with the
|
34
|
-
# action cache and with any fragments that use a different suffix.
|
35
|
-
# Note that the URL doesn't have to really exist or be callable
|
36
|
-
# - the url_for system is just used to generate unique cache names
|
37
|
-
# that we can refer to when we need to expire the cache.
|
38
|
-
#
|
39
|
-
# The expiration call for this example is:
|
40
|
-
#
|
41
|
-
# expire_fragment(:controller => "topics",
|
42
|
-
# :action => "list",
|
43
|
-
# :action_suffix => "all_topics")
|
15
|
+
# expire_fragment('name_of_cache')
|
44
16
|
module Fragments
|
45
|
-
# Given a key (as described in
|
46
|
-
# a key suitable for use in reading, writing, or expiring a
|
47
|
-
# cached fragment.
|
48
|
-
# return value of url_for on that hash (without the protocol).
|
49
|
-
# All keys are prefixed with <tt>views/</tt> and uses
|
17
|
+
# Given a key (as described in +expire_fragment+), returns
|
18
|
+
# a key suitable for use in reading, writing, or expiring a
|
19
|
+
# cached fragment. All keys are prefixed with <tt>views/</tt> and uses
|
50
20
|
# ActiveSupport::Cache.expand_cache_key for the expansion.
|
51
21
|
def fragment_cache_key(key)
|
52
22
|
ActiveSupport::Cache.expand_cache_key(key.is_a?(Hash) ? url_for(key).split("://").last : key, :views)
|
53
23
|
end
|
54
24
|
|
55
|
-
# Writes
|
56
|
-
#
|
25
|
+
# Writes +content+ to the location signified by
|
26
|
+
# +key+ (see +expire_fragment+ for acceptable formats).
|
57
27
|
def write_fragment(key, content, options = nil)
|
58
28
|
return content unless cache_configured?
|
59
29
|
|
@@ -65,8 +35,8 @@ module ActionController #:nodoc:
|
|
65
35
|
content
|
66
36
|
end
|
67
37
|
|
68
|
-
# Reads a cached fragment from the location signified by
|
69
|
-
# (see
|
38
|
+
# Reads a cached fragment from the location signified by +key+
|
39
|
+
# (see +expire_fragment+ for acceptable formats).
|
70
40
|
def read_fragment(key, options = nil)
|
71
41
|
return unless cache_configured?
|
72
42
|
|
@@ -77,8 +47,8 @@ module ActionController #:nodoc:
|
|
77
47
|
end
|
78
48
|
end
|
79
49
|
|
80
|
-
# Check if a cached fragment from the location signified by
|
81
|
-
#
|
50
|
+
# Check if a cached fragment from the location signified by
|
51
|
+
# +key+ exists (see +expire_fragment+ for acceptable formats).
|
82
52
|
def fragment_exist?(key, options = nil)
|
83
53
|
return unless cache_configured?
|
84
54
|
key = fragment_cache_key(key)
|
@@ -95,7 +65,7 @@ module ActionController #:nodoc:
|
|
95
65
|
# * String - This would normally take the form of a path, like
|
96
66
|
# <tt>pages/45/notes</tt>.
|
97
67
|
# * Hash - Treated as an implicit call to +url_for+, like
|
98
|
-
# <tt>{:
|
68
|
+
# <tt>{ controller: 'pages', action: 'notes', id: 45}</tt>
|
99
69
|
# * Regexp - Will remove any fragment that matches, so
|
100
70
|
# <tt>%r{pages/\d*/notes}</tt> might remove all notes. Make sure you
|
101
71
|
# don't use anchors in the regex (<tt>^</tt> or <tt>$</tt>) because
|
@@ -104,8 +74,8 @@ module ActionController #:nodoc:
|
|
104
74
|
# only supported on caches that can iterate over all keys (unlike
|
105
75
|
# memcached).
|
106
76
|
#
|
107
|
-
# +options+ is passed through to the cache store's
|
108
|
-
# method (or <tt>delete_matched</tt>, for Regexp keys.
|
77
|
+
# +options+ is passed through to the cache store's +delete+
|
78
|
+
# method (or <tt>delete_matched</tt>, for Regexp keys).
|
109
79
|
def expire_fragment(key, options = nil)
|
110
80
|
return unless cache_configured?
|
111
81
|
key = fragment_cache_key(key) unless key.is_a?(Regexp)
|
@@ -119,7 +89,7 @@ module ActionController #:nodoc:
|
|
119
89
|
end
|
120
90
|
end
|
121
91
|
|
122
|
-
def instrument_fragment_cache(name, key)
|
92
|
+
def instrument_fragment_cache(name, key) # :nodoc:
|
123
93
|
ActiveSupport::Notifications.instrument("#{name}.action_controller", :key => key){ yield }
|
124
94
|
end
|
125
95
|
end
|
@@ -1,3 +1,7 @@
|
|
1
1
|
ActionController::AbstractRequest = ActionController::Request = ActionDispatch::Request
|
2
2
|
ActionController::AbstractResponse = ActionController::Response = ActionDispatch::Response
|
3
|
-
ActionController::Routing = ActionDispatch::Routing
|
3
|
+
ActionController::Routing = ActionDispatch::Routing
|
4
|
+
|
5
|
+
ActiveSupport::Deprecation.warn 'ActionController::AbstractRequest and ActionController::Request are deprecated and will be removed, use ActionDispatch::Request instead.'
|
6
|
+
ActiveSupport::Deprecation.warn 'ActionController::AbstractResponse and ActionController::Response are deprecated and will be removed, use ActionDispatch::Response instead.'
|
7
|
+
ActiveSupport::Deprecation.warn 'ActionController::Routing is deprecated and will be removed, use ActionDispatch::Routing instead.'
|
@@ -1,2 +1,5 @@
|
|
1
1
|
ActionController::Integration = ActionDispatch::Integration
|
2
2
|
ActionController::IntegrationTest = ActionDispatch::IntegrationTest
|
3
|
+
|
4
|
+
ActiveSupport::Deprecation.warn 'ActionController::Integration is deprecated and will be removed, use ActionDispatch::Integration instead.'
|
5
|
+
ActiveSupport::Deprecation.warn 'ActionController::IntegrationTest is deprecated and will be removed, use ActionDispatch::IntegrationTest instead.'
|
@@ -1,10 +1,11 @@
|
|
1
|
-
require 'active_support/core_ext/object/blank'
|
2
1
|
|
3
2
|
module ActionController
|
4
3
|
class LogSubscriber < ActiveSupport::LogSubscriber
|
5
4
|
INTERNAL_PARAMS = %w(controller action format _method only_path)
|
6
5
|
|
7
6
|
def start_processing(event)
|
7
|
+
return unless logger.info?
|
8
|
+
|
8
9
|
payload = event.payload
|
9
10
|
params = payload[:params].except(*INTERNAL_PARAMS)
|
10
11
|
format = payload[:format]
|
@@ -15,6 +16,8 @@ module ActionController
|
|
15
16
|
end
|
16
17
|
|
17
18
|
def process_action(event)
|
19
|
+
return unless logger.info?
|
20
|
+
|
18
21
|
payload = event.payload
|
19
22
|
additions = ActionController::Base.log_process_action(payload)
|
20
23
|
|
@@ -23,36 +26,36 @@ module ActionController
|
|
23
26
|
exception_class_name = payload[:exception].first
|
24
27
|
status = ActionDispatch::ExceptionWrapper.status_code_for_exception(exception_class_name)
|
25
28
|
end
|
26
|
-
message = "Completed #{status} #{Rack::Utils::HTTP_STATUS_CODES[status]} in #{
|
29
|
+
message = "Completed #{status} #{Rack::Utils::HTTP_STATUS_CODES[status]} in #{event.duration.round}ms"
|
27
30
|
message << " (#{additions.join(" | ")})" unless additions.blank?
|
28
31
|
|
29
32
|
info(message)
|
30
33
|
end
|
31
34
|
|
32
35
|
def halted_callback(event)
|
33
|
-
info
|
36
|
+
info("Filter chain halted as #{event.payload[:filter]} rendered or redirected")
|
34
37
|
end
|
35
38
|
|
36
39
|
def send_file(event)
|
37
|
-
info("Sent file #{event.payload[:path]} (#{
|
40
|
+
info("Sent file #{event.payload[:path]} (#{event.duration.round(1)}ms)")
|
38
41
|
end
|
39
42
|
|
40
43
|
def redirect_to(event)
|
41
|
-
info
|
44
|
+
info("Redirected to #{event.payload[:location]}")
|
42
45
|
end
|
43
46
|
|
44
47
|
def send_data(event)
|
45
|
-
info("Sent data #{event.payload[:filename]}
|
48
|
+
info("Sent data #{event.payload[:filename]} (#{event.duration.round(1)}ms)")
|
46
49
|
end
|
47
50
|
|
48
51
|
%w(write_fragment read_fragment exist_fragment?
|
49
52
|
expire_fragment expire_page write_page).each do |method|
|
50
53
|
class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
51
54
|
def #{method}(event)
|
55
|
+
return unless logger.info?
|
52
56
|
key_or_path = event.payload[:key] || event.payload[:path]
|
53
57
|
human_name = #{method.to_s.humanize.inspect}
|
54
|
-
|
55
|
-
info("\#{human_name} \#{key_or_path} \#{duration}")
|
58
|
+
info("\#{human_name} \#{key_or_path} (\#{event.duration.round(1)}ms)")
|
56
59
|
end
|
57
60
|
METHOD
|
58
61
|
end
|
@@ -1,5 +1,4 @@
|
|
1
|
-
require 'active_support/core_ext/
|
2
|
-
require 'active_support/core_ext/object/blank'
|
1
|
+
require 'active_support/core_ext/array/extract_options'
|
3
2
|
require 'action_dispatch/middleware/stack'
|
4
3
|
|
5
4
|
module ActionController
|
@@ -7,7 +6,7 @@ module ActionController
|
|
7
6
|
# allowing the following syntax in controllers:
|
8
7
|
#
|
9
8
|
# class PostsController < ApplicationController
|
10
|
-
# use AuthenticationMiddleware, :
|
9
|
+
# use AuthenticationMiddleware, except: [:index, :show]
|
11
10
|
# end
|
12
11
|
#
|
13
12
|
class MiddlewareStack < ActionDispatch::MiddlewareStack #:nodoc:
|
@@ -58,7 +57,7 @@ module ActionController
|
|
58
57
|
# And then to route requests to your metal controller, you would add
|
59
58
|
# something like this to <tt>config/routes.rb</tt>:
|
60
59
|
#
|
61
|
-
# match 'hello', :
|
60
|
+
# match 'hello', to: HelloController.action(:index)
|
62
61
|
#
|
63
62
|
# The +action+ method returns a valid Rack application for the \Rails
|
64
63
|
# router to dispatch to.
|
@@ -114,7 +113,7 @@ module ActionController
|
|
114
113
|
# ==== Returns
|
115
114
|
# * <tt>string</tt>
|
116
115
|
def self.controller_name
|
117
|
-
@controller_name ||=
|
116
|
+
@controller_name ||= name.demodulize.sub(/Controller$/, '').underscore
|
118
117
|
end
|
119
118
|
|
120
119
|
# Delegates to the class' <tt>controller_name</tt>
|
@@ -181,19 +180,13 @@ module ActionController
|
|
181
180
|
@_status = Rack::Utils.status_code(status)
|
182
181
|
end
|
183
182
|
|
184
|
-
def response_body=(
|
185
|
-
body =
|
186
|
-
|
187
|
-
elsif val.nil? || val.respond_to?(:each)
|
188
|
-
val
|
189
|
-
else
|
190
|
-
[val]
|
191
|
-
end
|
192
|
-
super body
|
183
|
+
def response_body=(body)
|
184
|
+
body = [body] unless body.nil? || body.respond_to?(:each)
|
185
|
+
super
|
193
186
|
end
|
194
187
|
|
195
188
|
def performed?
|
196
|
-
response_body
|
189
|
+
response_body || (response && response.committed?)
|
197
190
|
end
|
198
191
|
|
199
192
|
def dispatch(name, request) #:nodoc:
|
@@ -211,36 +204,29 @@ module ActionController
|
|
211
204
|
class_attribute :middleware_stack
|
212
205
|
self.middleware_stack = ActionController::MiddlewareStack.new
|
213
206
|
|
214
|
-
def self.inherited(base) #nodoc:
|
215
|
-
base.middleware_stack =
|
207
|
+
def self.inherited(base) # :nodoc:
|
208
|
+
base.middleware_stack = middleware_stack.dup
|
216
209
|
super
|
217
210
|
end
|
218
211
|
|
219
|
-
#
|
212
|
+
# Pushes the given Rack middleware and its arguments to the bottom of the
|
213
|
+
# middleware stack.
|
220
214
|
def self.use(*args, &block)
|
221
215
|
middleware_stack.use(*args, &block)
|
222
216
|
end
|
223
217
|
|
224
|
-
# Alias for middleware_stack
|
218
|
+
# Alias for +middleware_stack+.
|
225
219
|
def self.middleware
|
226
220
|
middleware_stack
|
227
221
|
end
|
228
222
|
|
229
|
-
# Makes the controller a
|
230
|
-
#
|
223
|
+
# Makes the controller a Rack endpoint that runs the action in the given
|
224
|
+
# +env+'s +action_dispatch.request.path_parameters+ key.
|
231
225
|
def self.call(env)
|
232
226
|
action(env['action_dispatch.request.path_parameters'][:action]).call(env)
|
233
227
|
end
|
234
228
|
|
235
|
-
#
|
236
|
-
# multiple calls into MyController.action will return the same object
|
237
|
-
# for the same action.
|
238
|
-
#
|
239
|
-
# ==== Parameters
|
240
|
-
# * <tt>action</tt> - An action name
|
241
|
-
#
|
242
|
-
# ==== Returns
|
243
|
-
# * <tt>proc</tt> - A rack application
|
229
|
+
# Returns a Rack endpoint for the given action name.
|
244
230
|
def self.action(name, klass = ActionDispatch::Request)
|
245
231
|
middleware_stack.build(name.to_s) do |env|
|
246
232
|
new.dispatch(name, klass.new(env))
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'active_support/core_ext/hash/keys'
|
2
|
+
|
1
3
|
module ActionController
|
2
4
|
module ConditionalGet
|
3
5
|
extend ActiveSupport::Concern
|
@@ -5,25 +7,53 @@ module ActionController
|
|
5
7
|
include RackDelegation
|
6
8
|
include Head
|
7
9
|
|
8
|
-
|
10
|
+
included do
|
11
|
+
class_attribute :etaggers
|
12
|
+
self.etaggers = []
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
# Allows you to consider additional controller-wide information when generating an etag.
|
17
|
+
# For example, if you serve pages tailored depending on who's logged in at the moment, you
|
18
|
+
# may want to add the current user id to be part of the etag to prevent authorized displaying
|
19
|
+
# of cached pages.
|
20
|
+
#
|
21
|
+
# class InvoicesController < ApplicationController
|
22
|
+
# etag { current_user.try :id }
|
23
|
+
#
|
24
|
+
# def show
|
25
|
+
# # Etag will differ even for the same invoice when it's viewed by a different current_user
|
26
|
+
# @invoice = Invoice.find(params[:id])
|
27
|
+
# fresh_when(@invoice)
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
def etag(&etagger)
|
31
|
+
self.etaggers += [etagger]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Sets the etag, +last_modified+, or both on the response and renders a
|
9
36
|
# <tt>304 Not Modified</tt> response if the request is already fresh.
|
10
37
|
#
|
11
|
-
# Parameters:
|
12
|
-
# * <tt>:etag</tt>
|
13
|
-
# * <tt>:last_modified</tt>
|
14
|
-
# * <tt>:public</tt> By default the Cache-Control header is private, set this to true if you want your application to be cachable by other devices (proxy caches).
|
38
|
+
# === Parameters:
|
15
39
|
#
|
16
|
-
#
|
40
|
+
# * <tt>:etag</tt>.
|
41
|
+
# * <tt>:last_modified</tt>.
|
42
|
+
# * <tt>:public</tt> By default the Cache-Control header is private, set this to
|
43
|
+
# +true+ if you want your application to be cachable by other devices (proxy caches).
|
44
|
+
#
|
45
|
+
# === Example:
|
17
46
|
#
|
18
47
|
# def show
|
19
48
|
# @article = Article.find(params[:id])
|
20
|
-
# fresh_when(:
|
49
|
+
# fresh_when(etag: @article, last_modified: @article.created_at, public: true)
|
21
50
|
# end
|
22
51
|
#
|
23
52
|
# This will render the show template if the request isn't sending a matching etag or
|
24
53
|
# If-Modified-Since header and just a <tt>304 Not Modified</tt> response if there's a match.
|
25
54
|
#
|
26
|
-
# You can also just pass a record where last_modified will be set by calling
|
55
|
+
# You can also just pass a record where +last_modified+ will be set by calling
|
56
|
+
# +updated_at+ and the etag by passing the object itself.
|
27
57
|
#
|
28
58
|
# def show
|
29
59
|
# @article = Article.find(params[:id])
|
@@ -34,7 +64,7 @@ module ActionController
|
|
34
64
|
#
|
35
65
|
# def show
|
36
66
|
# @article = Article.find(params[:id])
|
37
|
-
# fresh_when(@article, :
|
67
|
+
# fresh_when(@article, public: true)
|
38
68
|
# end
|
39
69
|
def fresh_when(record_or_options, additional_options = {})
|
40
70
|
if record_or_options.is_a? Hash
|
@@ -42,32 +72,34 @@ module ActionController
|
|
42
72
|
options.assert_valid_keys(:etag, :last_modified, :public)
|
43
73
|
else
|
44
74
|
record = record_or_options
|
45
|
-
options = { :
|
75
|
+
options = { etag: record, last_modified: record.try(:updated_at) }.merge!(additional_options)
|
46
76
|
end
|
47
77
|
|
48
|
-
response.etag = options[:etag]
|
49
|
-
response.last_modified = options[:last_modified]
|
50
|
-
response.cache_control[:public] = true
|
78
|
+
response.etag = combine_etags(options[:etag]) if options[:etag]
|
79
|
+
response.last_modified = options[:last_modified] if options[:last_modified]
|
80
|
+
response.cache_control[:public] = true if options[:public]
|
51
81
|
|
52
82
|
head :not_modified if request.fresh?(response)
|
53
83
|
end
|
54
84
|
|
55
|
-
# Sets the etag and/or last_modified on the response and checks it against
|
85
|
+
# Sets the +etag+ and/or +last_modified+ on the response and checks it against
|
56
86
|
# the client request. If the request doesn't match the options provided, the
|
57
87
|
# request is considered stale and should be generated from scratch. Otherwise,
|
58
88
|
# it's fresh and we don't need to generate anything and a reply of <tt>304 Not Modified</tt> is sent.
|
59
89
|
#
|
60
|
-
# Parameters:
|
61
|
-
#
|
62
|
-
# * <tt>:
|
63
|
-
# * <tt>:
|
90
|
+
# === Parameters:
|
91
|
+
#
|
92
|
+
# * <tt>:etag</tt>.
|
93
|
+
# * <tt>:last_modified</tt>.
|
94
|
+
# * <tt>:public</tt> By default the Cache-Control header is private, set this to
|
95
|
+
# +true+ if you want your application to be cachable by other devices (proxy caches).
|
64
96
|
#
|
65
|
-
# Example:
|
97
|
+
# === Example:
|
66
98
|
#
|
67
99
|
# def show
|
68
100
|
# @article = Article.find(params[:id])
|
69
101
|
#
|
70
|
-
# if stale?(:
|
102
|
+
# if stale?(etag: @article, last_modified: @article.created_at)
|
71
103
|
# @statistics = @article.really_expensive_call
|
72
104
|
# respond_to do |format|
|
73
105
|
# # all the supported formats
|
@@ -75,7 +107,8 @@ module ActionController
|
|
75
107
|
# end
|
76
108
|
# end
|
77
109
|
#
|
78
|
-
# You can also just pass a record where last_modified will be set by calling
|
110
|
+
# You can also just pass a record where +last_modified+ will be set by calling
|
111
|
+
# updated_at and the etag by passing the object itself.
|
79
112
|
#
|
80
113
|
# def show
|
81
114
|
# @article = Article.find(params[:id])
|
@@ -93,7 +126,7 @@ module ActionController
|
|
93
126
|
# def show
|
94
127
|
# @article = Article.find(params[:id])
|
95
128
|
#
|
96
|
-
# if stale?(@article, :
|
129
|
+
# if stale?(@article, public: true)
|
97
130
|
# @statistics = @article.really_expensive_call
|
98
131
|
# respond_to do |format|
|
99
132
|
# # all the supported formats
|
@@ -105,27 +138,38 @@ module ActionController
|
|
105
138
|
!request.fresh?(response)
|
106
139
|
end
|
107
140
|
|
108
|
-
# Sets a HTTP 1.1 Cache-Control header. Defaults to issuing a
|
109
|
-
# intermediate caches must not cache the response.
|
141
|
+
# Sets a HTTP 1.1 Cache-Control header. Defaults to issuing a +private+
|
142
|
+
# instruction, so that intermediate caches must not cache the response.
|
110
143
|
#
|
111
|
-
# Examples:
|
112
144
|
# expires_in 20.minutes
|
113
|
-
# expires_in 3.hours, :
|
114
|
-
# expires_in 3.hours,
|
145
|
+
# expires_in 3.hours, public: true
|
146
|
+
# expires_in 3.hours, public: true, must_revalidate: true
|
115
147
|
#
|
116
148
|
# This method will overwrite an existing Cache-Control header.
|
117
149
|
# See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html for more possibilities.
|
118
|
-
|
119
|
-
|
150
|
+
#
|
151
|
+
# The method will also ensure a HTTP Date header for client compatibility.
|
152
|
+
def expires_in(seconds, options = {})
|
153
|
+
response.cache_control.merge!(
|
154
|
+
:max_age => seconds,
|
155
|
+
:public => options.delete(:public),
|
156
|
+
:must_revalidate => options.delete(:must_revalidate)
|
157
|
+
)
|
120
158
|
options.delete(:private)
|
121
159
|
|
122
160
|
response.cache_control[:extras] = options.map {|k,v| "#{k}=#{v}"}
|
161
|
+
response.date = Time.now unless response.date?
|
123
162
|
end
|
124
163
|
|
125
|
-
# Sets a HTTP 1.1 Cache-Control header of <tt>no-cache</tt> so no caching should
|
126
|
-
# intermediate caches (like caching proxy servers).
|
127
|
-
def expires_now
|
164
|
+
# Sets a HTTP 1.1 Cache-Control header of <tt>no-cache</tt> so no caching should
|
165
|
+
# occur by the browser or intermediate caches (like caching proxy servers).
|
166
|
+
def expires_now
|
128
167
|
response.cache_control.replace(:no_cache => true)
|
129
168
|
end
|
169
|
+
|
170
|
+
private
|
171
|
+
def combine_etags(etag)
|
172
|
+
[ etag, *etaggers.map { |etagger| instance_exec(&etagger) }.compact ]
|
173
|
+
end
|
130
174
|
end
|
131
175
|
end
|