actionpack 2.1.2 → 2.2.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- data/CHANGELOG +223 -7
- data/README +6 -12
- data/Rakefile +11 -11
- data/lib/action_controller.rb +9 -9
- data/lib/action_controller/assertions/response_assertions.rb +29 -78
- data/lib/action_controller/assertions/routing_assertions.rb +33 -33
- data/lib/action_controller/assertions/selector_assertions.rb +9 -5
- data/lib/action_controller/base.rb +227 -161
- data/lib/action_controller/benchmarking.rb +37 -24
- data/lib/action_controller/caching/actions.rb +53 -21
- data/lib/action_controller/caching/fragments.rb +10 -36
- data/lib/action_controller/caching/sweeping.rb +3 -3
- data/lib/action_controller/cgi_ext/session.rb +2 -22
- data/lib/action_controller/cgi_process.rb +8 -46
- data/lib/action_controller/components.rb +4 -1
- data/lib/action_controller/cookies.rb +10 -0
- data/lib/action_controller/dispatcher.rb +49 -15
- data/lib/action_controller/filters.rb +48 -10
- data/lib/action_controller/headers.rb +16 -14
- data/lib/action_controller/helpers.rb +2 -2
- data/lib/action_controller/http_authentication.rb +1 -1
- data/lib/action_controller/integration.rb +57 -60
- data/lib/action_controller/layout.rb +27 -53
- data/lib/action_controller/mime_responds.rb +5 -1
- data/lib/action_controller/mime_type.rb +64 -42
- data/lib/action_controller/mime_types.rb +2 -1
- data/lib/action_controller/performance_test.rb +16 -0
- data/lib/action_controller/polymorphic_routes.rb +16 -9
- data/lib/action_controller/rack_process.rb +303 -0
- data/lib/action_controller/request.rb +205 -97
- data/lib/action_controller/request_forgery_protection.rb +2 -2
- data/lib/action_controller/request_profiler.rb +0 -0
- data/lib/action_controller/rescue.rb +20 -115
- data/lib/action_controller/resources.rb +186 -83
- data/lib/action_controller/response.rb +140 -26
- data/lib/action_controller/routing.rb +28 -30
- data/lib/action_controller/routing/builder.rb +45 -54
- data/lib/action_controller/routing/optimisations.rb +31 -21
- data/lib/action_controller/routing/recognition_optimisation.rb +33 -27
- data/lib/action_controller/routing/route.rb +162 -147
- data/lib/action_controller/routing/route_set.rb +8 -7
- data/lib/action_controller/routing/routing_ext.rb +4 -1
- data/lib/action_controller/routing/segments.rb +50 -21
- data/lib/action_controller/session/cookie_store.rb +3 -2
- data/lib/action_controller/session/drb_server.rb +7 -7
- data/lib/action_controller/session_management.rb +6 -2
- data/lib/action_controller/streaming.rb +15 -8
- data/lib/action_controller/templates/rescues/diagnostics.erb +2 -2
- data/lib/action_controller/templates/rescues/template_error.erb +2 -2
- data/lib/action_controller/test_case.rb +66 -2
- data/lib/action_controller/test_process.rb +71 -66
- data/lib/action_controller/translation.rb +13 -0
- data/lib/action_controller/url_rewriter.rb +90 -13
- data/lib/action_controller/vendor/html-scanner/html/node.rb +9 -2
- data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +1 -1
- data/lib/action_controller/vendor/html-scanner/html/selector.rb +2 -2
- data/lib/action_controller/verification.rb +2 -2
- data/lib/action_pack/version.rb +1 -1
- data/lib/action_view.rb +19 -11
- data/lib/action_view/base.rb +184 -150
- data/lib/action_view/helpers.rb +38 -0
- data/lib/action_view/helpers/active_record_helper.rb +56 -27
- data/lib/action_view/helpers/asset_tag_helper.rb +356 -153
- data/lib/action_view/helpers/atom_feed_helper.rb +74 -19
- data/lib/action_view/helpers/benchmark_helper.rb +3 -3
- data/lib/action_view/helpers/cache_helper.rb +1 -2
- data/lib/action_view/helpers/capture_helper.rb +19 -44
- data/lib/action_view/helpers/date_helper.rb +486 -296
- data/lib/action_view/helpers/debug_helper.rb +20 -13
- data/lib/action_view/helpers/form_helper.rb +71 -30
- data/lib/action_view/helpers/form_options_helper.rb +15 -85
- data/lib/action_view/helpers/form_tag_helper.rb +61 -38
- data/lib/action_view/helpers/javascript_helper.rb +80 -89
- data/lib/action_view/helpers/number_helper.rb +179 -74
- data/lib/action_view/helpers/prototype_helper.rb +216 -201
- data/lib/action_view/helpers/record_tag_helper.rb +4 -5
- data/lib/action_view/helpers/sanitize_helper.rb +65 -33
- data/lib/action_view/helpers/scriptaculous_helper.rb +2 -2
- data/lib/action_view/helpers/tag_helper.rb +39 -22
- data/lib/action_view/helpers/text_helper.rb +212 -118
- data/lib/action_view/helpers/translation_helper.rb +21 -0
- data/lib/action_view/helpers/url_helper.rb +100 -58
- data/lib/action_view/inline_template.rb +13 -14
- data/lib/action_view/locale/en.yml +91 -0
- data/lib/action_view/partials.rb +100 -55
- data/lib/action_view/paths.rb +125 -0
- data/lib/action_view/renderable.rb +102 -0
- data/lib/action_view/renderable_partial.rb +48 -0
- data/lib/action_view/template.rb +90 -101
- data/lib/action_view/template_error.rb +11 -21
- data/lib/action_view/template_handler.rb +8 -28
- data/lib/action_view/template_handlers.rb +45 -0
- data/lib/action_view/template_handlers/builder.rb +5 -15
- data/lib/action_view/template_handlers/erb.rb +9 -6
- data/lib/action_view/template_handlers/rjs.rb +2 -17
- data/lib/action_view/test_case.rb +7 -4
- data/test/abstract_unit.rb +4 -1
- data/test/active_record_unit.rb +28 -30
- data/test/activerecord/render_partial_with_record_identification_test.rb +25 -12
- data/test/controller/action_pack_assertions_test.rb +8 -37
- data/test/controller/addresses_render_test.rb +0 -3
- data/test/controller/assert_select_test.rb +51 -24
- data/test/controller/base_test.rb +4 -4
- data/test/controller/caching_test.rb +136 -66
- data/test/controller/capture_test.rb +1 -21
- data/test/controller/cgi_test.rb +157 -10
- data/test/controller/components_test.rb +41 -25
- data/test/controller/content_type_test.rb +49 -17
- data/test/controller/cookie_test.rb +1 -1
- data/test/controller/deprecation/deprecated_base_methods_test.rb +0 -3
- data/test/controller/dispatcher_test.rb +9 -1
- data/test/controller/filter_params_test.rb +2 -2
- data/test/controller/filters_test.rb +13 -13
- data/test/controller/html-scanner/cdata_node_test.rb +15 -0
- data/test/controller/html-scanner/node_test.rb +21 -0
- data/test/controller/html-scanner/sanitizer_test.rb +14 -0
- data/test/controller/integration_test.rb +167 -6
- data/test/controller/layout_test.rb +11 -68
- data/test/controller/logging_test.rb +46 -0
- data/test/controller/mime_responds_test.rb +61 -59
- data/test/controller/mime_type_test.rb +6 -6
- data/test/controller/polymorphic_routes_test.rb +37 -2
- data/test/controller/rack_test.rb +323 -0
- data/test/controller/redirect_test.rb +72 -71
- data/test/controller/render_test.rb +1120 -108
- data/test/controller/request_forgery_protection_test.rb +66 -52
- data/test/controller/request_test.rb +103 -146
- data/test/controller/rescue_test.rb +20 -24
- data/test/controller/resources_test.rb +408 -25
- data/test/controller/routing_test.rb +1774 -1774
- data/test/controller/send_file_test.rb +0 -4
- data/test/controller/session/cookie_store_test.rb +53 -1
- data/test/controller/test_test.rb +15 -37
- data/test/controller/translation_test.rb +26 -0
- data/test/controller/url_rewriter_test.rb +27 -28
- data/test/controller/view_paths_test.rb +48 -47
- data/test/fixtures/_top_level_partial.html.erb +1 -0
- data/test/fixtures/_top_level_partial_only.erb +1 -0
- data/test/fixtures/developers/_developer.erb +1 -0
- data/test/fixtures/fun/games/_game.erb +1 -0
- data/test/fixtures/fun/serious/games/_game.erb +1 -0
- data/test/fixtures/functional_caching/formatted_fragment_cached.html.erb +3 -0
- data/test/fixtures/functional_caching/formatted_fragment_cached.js.rjs +6 -0
- data/test/fixtures/functional_caching/formatted_fragment_cached.xml.builder +5 -0
- data/test/fixtures/functional_caching/inline_fragment_cached.html.erb +2 -0
- data/test/fixtures/layouts/_column.html.erb +2 -0
- data/test/fixtures/projects/_project.erb +1 -0
- data/test/fixtures/public/javascripts/subdir/subdir.js +1 -0
- data/test/fixtures/public/stylesheets/subdir/subdir.css +1 -0
- data/test/fixtures/replies/_reply.erb +1 -0
- data/test/fixtures/test/_counter.html.erb +1 -0
- data/test/fixtures/test/_customer.erb +1 -1
- data/test/fixtures/test/_customer_with_var.erb +1 -0
- data/test/fixtures/test/_layout_for_block_with_args.html.erb +3 -0
- data/test/fixtures/test/_local_inspector.html.erb +1 -0
- data/test/fixtures/test/_partial_with_only_html_version.html.erb +1 -0
- data/test/fixtures/test/hello.builder +1 -1
- data/test/fixtures/test/hyphen-ated.erb +1 -0
- data/test/fixtures/test/implicit_content_type.atom.builder +2 -0
- data/test/fixtures/test/nested_layout.erb +3 -0
- data/test/fixtures/test/non_erb_block_content_for.builder +1 -1
- data/test/fixtures/test/sub_template_raise.html.erb +1 -0
- data/test/fixtures/test/template.erb +1 -0
- data/test/fixtures/test/using_layout_around_block_with_args.html.erb +1 -0
- data/test/template/active_record_helper_i18n_test.rb +46 -0
- data/test/template/active_record_helper_test.rb +24 -24
- data/test/template/asset_tag_helper_test.rb +161 -29
- data/test/template/atom_feed_helper_test.rb +114 -5
- data/test/template/compiled_templates_test.rb +59 -0
- data/test/template/date_helper_i18n_test.rb +113 -0
- data/test/template/date_helper_test.rb +403 -109
- data/test/template/form_helper_test.rb +213 -154
- data/test/template/form_options_helper_test.rb +249 -897
- data/test/template/form_tag_helper_test.rb +80 -32
- data/test/template/javascript_helper_test.rb +17 -18
- data/test/template/number_helper_i18n_test.rb +54 -0
- data/test/template/number_helper_test.rb +43 -13
- data/test/template/prototype_helper_test.rb +101 -84
- data/test/template/record_tag_helper_test.rb +24 -20
- data/test/template/render_test.rb +193 -0
- data/test/template/sanitize_helper_test.rb +3 -3
- data/test/template/tag_helper_test.rb +34 -14
- data/test/template/text_helper_test.rb +83 -9
- data/test/template/translation_helper_test.rb +28 -0
- data/test/template/url_helper_test.rb +55 -18
- metadata +57 -18
- data/lib/action_view/helpers/javascripts/controls.js +0 -963
- data/lib/action_view/helpers/javascripts/dragdrop.js +0 -972
- data/lib/action_view/helpers/javascripts/effects.js +0 -1120
- data/lib/action_view/helpers/javascripts/prototype.js +0 -4225
- data/lib/action_view/partial_template.rb +0 -70
- data/lib/action_view/template_finder.rb +0 -177
- data/lib/action_view/template_handlers/compilable.rb +0 -128
- data/test/controller/custom_handler_test.rb +0 -45
- data/test/controller/new_render_test.rb +0 -945
- data/test/fixtures/test/block_content_for.erb +0 -2
- data/test/fixtures/test/erb_content_for.erb +0 -2
- data/test/template/deprecated_erb_variable_test.rb +0 -9
- data/test/template/template_finder_test.rb +0 -73
- data/test/template/template_object_test.rb +0 -95
@@ -24,7 +24,7 @@ module ActionController #:nodoc:
|
|
24
24
|
if logger && logger.level == log_level
|
25
25
|
result = nil
|
26
26
|
seconds = Benchmark.realtime { result = use_silence ? silence { yield } : yield }
|
27
|
-
logger.add(log_level, "#{title} (#{'%.
|
27
|
+
logger.add(log_level, "#{title} (#{('%.1f' % (seconds * 1000))}ms)")
|
28
28
|
result
|
29
29
|
else
|
30
30
|
yield
|
@@ -42,53 +42,66 @@ module ActionController #:nodoc:
|
|
42
42
|
|
43
43
|
protected
|
44
44
|
def render_with_benchmark(options = nil, extra_options = {}, &block)
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
45
|
+
if logger
|
46
|
+
if Object.const_defined?("ActiveRecord") && ActiveRecord::Base.connected?
|
47
|
+
db_runtime = ActiveRecord::Base.connection.reset_runtime
|
48
|
+
end
|
49
49
|
|
50
50
|
render_output = nil
|
51
|
-
@
|
51
|
+
@view_runtime = Benchmark::realtime { render_output = render_without_benchmark(options, extra_options, &block) }
|
52
52
|
|
53
53
|
if Object.const_defined?("ActiveRecord") && ActiveRecord::Base.connected?
|
54
54
|
@db_rt_before_render = db_runtime
|
55
55
|
@db_rt_after_render = ActiveRecord::Base.connection.reset_runtime
|
56
|
-
@
|
56
|
+
@view_runtime -= @db_rt_after_render
|
57
57
|
end
|
58
58
|
|
59
59
|
render_output
|
60
|
+
else
|
61
|
+
render_without_benchmark(options, extra_options, &block)
|
60
62
|
end
|
61
63
|
end
|
62
64
|
|
63
65
|
private
|
64
66
|
def perform_action_with_benchmark
|
65
|
-
|
66
|
-
perform_action_without_benchmark
|
67
|
-
|
68
|
-
|
67
|
+
if logger
|
68
|
+
seconds = [ Benchmark::measure{ perform_action_without_benchmark }.real, 0.0001 ].max
|
69
|
+
logging_view = defined?(@view_runtime)
|
70
|
+
logging_active_record = Object.const_defined?("ActiveRecord") && ActiveRecord::Base.connected?
|
71
|
+
|
72
|
+
log_message = "Completed in #{sprintf("%.0f", seconds * 1000)}ms"
|
73
|
+
|
74
|
+
if logging_view || logging_active_record
|
75
|
+
log_message << " ("
|
76
|
+
log_message << view_runtime if logging_view
|
77
|
+
|
78
|
+
if logging_active_record
|
79
|
+
log_message << ", " if logging_view
|
80
|
+
log_message << active_record_runtime + ")"
|
81
|
+
else
|
82
|
+
")"
|
83
|
+
end
|
84
|
+
end
|
69
85
|
|
70
|
-
log_message = "Completed in #{sprintf("%.5f", runtime)} (#{(1 / runtime).floor} reqs/sec)"
|
71
|
-
log_message << rendering_runtime(runtime) if defined?(@rendering_runtime)
|
72
|
-
log_message << active_record_runtime(runtime) if Object.const_defined?("ActiveRecord") && ActiveRecord::Base.connected?
|
73
86
|
log_message << " | #{headers["Status"]}"
|
74
87
|
log_message << " [#{complete_request_uri rescue "unknown"}]"
|
75
88
|
|
76
89
|
logger.info(log_message)
|
77
|
-
response.headers["X-Runtime"] = sprintf("%.
|
90
|
+
response.headers["X-Runtime"] = "#{sprintf("%.0f", seconds * 1000)}ms"
|
91
|
+
else
|
92
|
+
perform_action_without_benchmark
|
78
93
|
end
|
79
94
|
end
|
80
95
|
|
81
|
-
def
|
82
|
-
|
83
|
-
" | Rendering: %.5f (%d%%)" % [@rendering_runtime, percentage.to_i]
|
96
|
+
def view_runtime
|
97
|
+
"View: %.0f" % (@view_runtime * 1000)
|
84
98
|
end
|
85
99
|
|
86
|
-
def active_record_runtime
|
87
|
-
db_runtime
|
88
|
-
db_runtime
|
89
|
-
db_runtime
|
90
|
-
|
91
|
-
" | DB: %.5f (%d%%)" % [db_runtime, db_percentage.to_i]
|
100
|
+
def active_record_runtime
|
101
|
+
db_runtime = ActiveRecord::Base.connection.reset_runtime
|
102
|
+
db_runtime += @db_rt_before_render if @db_rt_before_render
|
103
|
+
db_runtime += @db_rt_after_render if @db_rt_after_render
|
104
|
+
"DB: %.0f" % (db_runtime * 1000)
|
92
105
|
end
|
93
106
|
end
|
94
107
|
end
|
@@ -27,19 +27,23 @@ module ActionController #:nodoc:
|
|
27
27
|
# You can set modify the default action cache path by passing a :cache_path option. This will be passed directly to ActionCachePath.path_for. This is handy
|
28
28
|
# for actions with multiple possible routes that should be cached differently. If a block is given, it is called with the current controller instance.
|
29
29
|
#
|
30
|
-
# And you can also use :if to pass a Proc that specifies when the action should be cached.
|
30
|
+
# And you can also use :if (or :unless) to pass a Proc that specifies when the action should be cached.
|
31
|
+
#
|
32
|
+
# Finally, if you are using memcached, you can also pass :expires_in.
|
31
33
|
#
|
32
34
|
# class ListsController < ApplicationController
|
33
35
|
# before_filter :authenticate, :except => :public
|
34
36
|
# caches_page :public
|
35
37
|
# caches_action :index, :if => Proc.new { |c| !c.request.format.json? } # cache if is not a JSON request
|
36
|
-
# caches_action :show, :cache_path => { :project => 1 }
|
38
|
+
# caches_action :show, :cache_path => { :project => 1 }, :expires_in => 1.hour
|
37
39
|
# caches_action :feed, :cache_path => Proc.new { |controller|
|
38
40
|
# controller.params[:user_id] ?
|
39
|
-
# controller.send(:user_list_url,
|
40
|
-
# controller.send(:list_url,
|
41
|
+
# controller.send(:user_list_url, controller.params[:user_id], controller.params[:id]) :
|
42
|
+
# controller.send(:list_url, controller.params[:id]) }
|
41
43
|
# end
|
42
44
|
#
|
45
|
+
# If you pass :layout => false, it will only cache your action content. It is useful when your layout has dynamic information.
|
46
|
+
#
|
43
47
|
module Actions
|
44
48
|
def self.included(base) #:nodoc:
|
45
49
|
base.extend(ClassMethods)
|
@@ -54,7 +58,10 @@ module ActionController #:nodoc:
|
|
54
58
|
def caches_action(*actions)
|
55
59
|
return unless cache_configured?
|
56
60
|
options = actions.extract_options!
|
57
|
-
|
61
|
+
filter_options = { :only => actions, :if => options.delete(:if), :unless => options.delete(:unless) }
|
62
|
+
|
63
|
+
cache_filter = ActionCacheFilter.new(:layout => options.delete(:layout), :cache_path => options.delete(:cache_path), :store_options => options)
|
64
|
+
around_filter(cache_filter, filter_options)
|
58
65
|
end
|
59
66
|
end
|
60
67
|
|
@@ -64,10 +71,10 @@ module ActionController #:nodoc:
|
|
64
71
|
|
65
72
|
if options[:action].is_a?(Array)
|
66
73
|
options[:action].dup.each do |action|
|
67
|
-
expire_fragment(ActionCachePath.path_for(self, options.merge({ :action => action })))
|
74
|
+
expire_fragment(ActionCachePath.path_for(self, options.merge({ :action => action }), false))
|
68
75
|
end
|
69
76
|
else
|
70
|
-
expire_fragment(ActionCachePath.path_for(self, options))
|
77
|
+
expire_fragment(ActionCachePath.path_for(self, options, false))
|
71
78
|
end
|
72
79
|
end
|
73
80
|
|
@@ -77,11 +84,13 @@ module ActionController #:nodoc:
|
|
77
84
|
end
|
78
85
|
|
79
86
|
def before(controller)
|
80
|
-
cache_path = ActionCachePath.new(controller, path_options_for(controller, @options))
|
81
|
-
if cache = controller.read_fragment(cache_path.path)
|
87
|
+
cache_path = ActionCachePath.new(controller, path_options_for(controller, @options.slice(:cache_path)))
|
88
|
+
if cache = controller.read_fragment(cache_path.path, @options[:store_options])
|
82
89
|
controller.rendered_action_cache = true
|
83
90
|
set_content_type!(controller, cache_path.extension)
|
84
|
-
|
91
|
+
options = { :text => cache }
|
92
|
+
options.merge!(:layout => true) if cache_layout?
|
93
|
+
controller.__send__(:render, options)
|
85
94
|
false
|
86
95
|
else
|
87
96
|
controller.action_cache_path = cache_path
|
@@ -90,7 +99,8 @@ module ActionController #:nodoc:
|
|
90
99
|
|
91
100
|
def after(controller)
|
92
101
|
return if controller.rendered_action_cache || !caching_allowed(controller)
|
93
|
-
|
102
|
+
action_content = cache_layout? ? content_for_layout(controller) : controller.response.body
|
103
|
+
controller.write_fragment(controller.action_cache_path.path, action_content, @options[:store_options])
|
94
104
|
end
|
95
105
|
|
96
106
|
private
|
@@ -105,22 +115,38 @@ module ActionController #:nodoc:
|
|
105
115
|
def caching_allowed(controller)
|
106
116
|
controller.request.get? && controller.response.headers['Status'].to_i == 200
|
107
117
|
end
|
118
|
+
|
119
|
+
def cache_layout?
|
120
|
+
@options[:layout] == false
|
121
|
+
end
|
122
|
+
|
123
|
+
def content_for_layout(controller)
|
124
|
+
controller.response.layout && controller.response.template.instance_variable_get('@cached_content_for_layout')
|
125
|
+
end
|
108
126
|
end
|
109
127
|
|
110
128
|
class ActionCachePath
|
111
129
|
attr_reader :path, :extension
|
112
130
|
|
113
131
|
class << self
|
114
|
-
def path_for(controller, options)
|
115
|
-
new(controller, options).path
|
132
|
+
def path_for(controller, options, infer_extension=true)
|
133
|
+
new(controller, options, infer_extension).path
|
116
134
|
end
|
117
135
|
end
|
118
|
-
|
119
|
-
|
120
|
-
|
136
|
+
|
137
|
+
# When true, infer_extension will look up the cache path extension from the request's path & format.
|
138
|
+
# This is desirable when reading and writing the cache, but not when expiring the cache - expire_action should expire the same files regardless of the request format.
|
139
|
+
def initialize(controller, options = {}, infer_extension=true)
|
140
|
+
if infer_extension and options.is_a? Hash
|
141
|
+
request_extension = extract_extension(controller.request)
|
142
|
+
options = options.reverse_merge(:format => request_extension)
|
143
|
+
end
|
121
144
|
path = controller.url_for(options).split('://').last
|
122
145
|
normalize!(path)
|
123
|
-
|
146
|
+
if infer_extension
|
147
|
+
@extension = request_extension
|
148
|
+
add_extension!(path, @extension)
|
149
|
+
end
|
124
150
|
@path = URI.unescape(path)
|
125
151
|
end
|
126
152
|
|
@@ -130,13 +156,19 @@ module ActionController #:nodoc:
|
|
130
156
|
end
|
131
157
|
|
132
158
|
def add_extension!(path, extension)
|
133
|
-
path << ".#{extension}" if extension
|
159
|
+
path << ".#{extension}" if extension and !path.ends_with?(extension)
|
134
160
|
end
|
135
|
-
|
136
|
-
def extract_extension(
|
161
|
+
|
162
|
+
def extract_extension(request)
|
137
163
|
# Don't want just what comes after the last '.' to accommodate multi part extensions
|
138
164
|
# such as tar.gz.
|
139
|
-
|
165
|
+
extension = request.path[/^[^.]+\.(.+)$/, 1]
|
166
|
+
|
167
|
+
# If there's no extension in the path, check request.format
|
168
|
+
if extension.nil?
|
169
|
+
extension = request.cache_format
|
170
|
+
end
|
171
|
+
extension
|
140
172
|
end
|
141
173
|
end
|
142
174
|
end
|
@@ -2,7 +2,7 @@ module ActionController #:nodoc:
|
|
2
2
|
module Caching
|
3
3
|
# Fragment caching is used for caching various blocks within templates without caching the entire action as a whole. This is useful when
|
4
4
|
# certain elements of an action change frequently or depend on complicated state while other parts rarely change or can be shared amongst multiple
|
5
|
-
# parties. The caching is
|
5
|
+
# parties. The caching is done using the cache helper available in the Action View. A template with caching might look something like:
|
6
6
|
#
|
7
7
|
# <b>Hello <%= @name %></b>
|
8
8
|
# <% cache do %>
|
@@ -26,32 +26,6 @@ module ActionController #:nodoc:
|
|
26
26
|
#
|
27
27
|
# expire_fragment(:controller => "topics", :action => "list", :action_suffix => "all_topics")
|
28
28
|
module Fragments
|
29
|
-
def self.included(base) #:nodoc:
|
30
|
-
base.class_eval do
|
31
|
-
class << self
|
32
|
-
def fragment_cache_store=(store_option) #:nodoc:
|
33
|
-
ActiveSupport::Deprecation.warn('The fragment_cache_store= method is now use cache_store=')
|
34
|
-
self.cache_store = store_option
|
35
|
-
end
|
36
|
-
|
37
|
-
def fragment_cache_store #:nodoc:
|
38
|
-
ActiveSupport::Deprecation.warn('The fragment_cache_store method is now use cache_store')
|
39
|
-
cache_store
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def fragment_cache_store=(store_option) #:nodoc:
|
44
|
-
ActiveSupport::Deprecation.warn('The fragment_cache_store= method is now use cache_store=')
|
45
|
-
self.cache_store = store_option
|
46
|
-
end
|
47
|
-
|
48
|
-
def fragment_cache_store #:nodoc:
|
49
|
-
ActiveSupport::Deprecation.warn('The fragment_cache_store method is now use cache_store')
|
50
|
-
cache_store
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
29
|
# Given a key (as described in <tt>expire_fragment</tt>), returns a key suitable for use in reading,
|
56
30
|
# writing, or expiring a cached fragment. If the key is a hash, the generated key is the return
|
57
31
|
# value of url_for on that hash (without the protocol). All keys are prefixed with "views/" and uses
|
@@ -60,17 +34,17 @@ module ActionController #:nodoc:
|
|
60
34
|
ActiveSupport::Cache.expand_cache_key(key.is_a?(Hash) ? url_for(key).split("://").last : key, :views)
|
61
35
|
end
|
62
36
|
|
63
|
-
def fragment_for(
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
37
|
+
def fragment_for(buffer, name = {}, options = nil, &block) #:nodoc:
|
38
|
+
if perform_caching
|
39
|
+
if cache = read_fragment(name, options)
|
40
|
+
buffer.concat(cache)
|
41
|
+
else
|
42
|
+
pos = buffer.length
|
43
|
+
block.call
|
44
|
+
write_fragment(name, buffer[pos..-1], options)
|
45
|
+
end
|
70
46
|
else
|
71
|
-
pos = buffer.length
|
72
47
|
block.call
|
73
|
-
write_fragment(name, buffer[pos..-1], options)
|
74
48
|
end
|
75
49
|
end
|
76
50
|
|
@@ -83,13 +83,13 @@ module ActionController #:nodoc:
|
|
83
83
|
controller_callback_method_name = "#{timing}_#{controller.controller_name.underscore}"
|
84
84
|
action_callback_method_name = "#{controller_callback_method_name}_#{controller.action_name}"
|
85
85
|
|
86
|
-
|
87
|
-
|
86
|
+
__send__(controller_callback_method_name) if respond_to?(controller_callback_method_name, true)
|
87
|
+
__send__(action_callback_method_name) if respond_to?(action_callback_method_name, true)
|
88
88
|
end
|
89
89
|
|
90
90
|
def method_missing(method, *arguments)
|
91
91
|
return if @controller.nil?
|
92
|
-
@controller.
|
92
|
+
@controller.__send__(method, *arguments)
|
93
93
|
end
|
94
94
|
end
|
95
95
|
end
|
@@ -6,28 +6,8 @@ class CGI #:nodoc:
|
|
6
6
|
# * Expose the CGI instance to session stores.
|
7
7
|
# * Don't require 'digest/md5' whenever a new session id is generated.
|
8
8
|
class Session #:nodoc:
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
# Generate a 32-character unique id using SecureRandom.
|
13
|
-
# This is used to generate session ids but may be reused elsewhere.
|
14
|
-
def self.generate_unique_id(constant = nil)
|
15
|
-
SecureRandom.hex(16)
|
16
|
-
end
|
17
|
-
rescue LoadError
|
18
|
-
# Generate an 32-character unique id based on a hash of the current time,
|
19
|
-
# a random number, the process id, and a constant string. This is used
|
20
|
-
# to generate session ids but may be reused elsewhere.
|
21
|
-
def self.generate_unique_id(constant = 'foobar')
|
22
|
-
md5 = Digest::MD5.new
|
23
|
-
now = Time.now
|
24
|
-
md5 << now.to_s
|
25
|
-
md5 << String(now.usec)
|
26
|
-
md5 << String(rand(0))
|
27
|
-
md5 << String($$)
|
28
|
-
md5 << constant
|
29
|
-
md5.hexdigest
|
30
|
-
end
|
9
|
+
def self.generate_unique_id(constant = nil)
|
10
|
+
ActiveSupport::SecureRandom.hex(16)
|
31
11
|
end
|
32
12
|
|
33
13
|
# Make the CGI instance available to session stores.
|
@@ -42,13 +42,14 @@ module ActionController #:nodoc:
|
|
42
42
|
:prefix => "ruby_sess.", # prefix session file names
|
43
43
|
:session_path => "/", # available to all paths in app
|
44
44
|
:session_key => "_session_id",
|
45
|
-
:cookie_only => true
|
46
|
-
|
45
|
+
:cookie_only => true,
|
46
|
+
:session_http_only=> true
|
47
|
+
}
|
47
48
|
|
48
49
|
def initialize(cgi, session_options = {})
|
49
50
|
@cgi = cgi
|
50
51
|
@session_options = session_options
|
51
|
-
@env = @cgi.
|
52
|
+
@env = @cgi.__send__(:env_table)
|
52
53
|
super()
|
53
54
|
end
|
54
55
|
|
@@ -61,53 +62,14 @@ module ActionController #:nodoc:
|
|
61
62
|
end
|
62
63
|
end
|
63
64
|
|
64
|
-
|
65
|
-
|
66
|
-
def body
|
67
|
-
if raw_post = env['RAW_POST_DATA']
|
68
|
-
raw_post.force_encoding(Encoding::BINARY) if raw_post.respond_to?(:force_encoding)
|
69
|
-
StringIO.new(raw_post)
|
70
|
-
else
|
71
|
-
@cgi.stdinput
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
def query_parameters
|
76
|
-
@query_parameters ||= self.class.parse_query_parameters(query_string)
|
77
|
-
end
|
78
|
-
|
79
|
-
def request_parameters
|
80
|
-
@request_parameters ||= parse_formatted_request_parameters
|
65
|
+
def body_stream #:nodoc:
|
66
|
+
@cgi.stdinput
|
81
67
|
end
|
82
68
|
|
83
69
|
def cookies
|
84
70
|
@cgi.cookies.freeze
|
85
71
|
end
|
86
72
|
|
87
|
-
def host_with_port_without_standard_port_handling
|
88
|
-
if forwarded = env["HTTP_X_FORWARDED_HOST"]
|
89
|
-
forwarded.split(/,\s?/).last
|
90
|
-
elsif http_host = env['HTTP_HOST']
|
91
|
-
http_host
|
92
|
-
elsif server_name = env['SERVER_NAME']
|
93
|
-
server_name
|
94
|
-
else
|
95
|
-
"#{env['SERVER_ADDR']}:#{env['SERVER_PORT']}"
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
def host
|
100
|
-
host_with_port_without_standard_port_handling.sub(/:\d+$/, '')
|
101
|
-
end
|
102
|
-
|
103
|
-
def port
|
104
|
-
if host_with_port_without_standard_port_handling =~ /:(\d+)$/
|
105
|
-
$1.to_i
|
106
|
-
else
|
107
|
-
standard_port
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
73
|
def session
|
112
74
|
unless defined?(@session)
|
113
75
|
if @session_options == false
|
@@ -146,7 +108,7 @@ module ActionController #:nodoc:
|
|
146
108
|
end
|
147
109
|
|
148
110
|
def method_missing(method_id, *arguments)
|
149
|
-
@cgi.
|
111
|
+
@cgi.__send__(method_id, *arguments) rescue super
|
150
112
|
end
|
151
113
|
|
152
114
|
private
|
@@ -203,7 +165,7 @@ end_msg
|
|
203
165
|
begin
|
204
166
|
output.write(@cgi.header(@headers))
|
205
167
|
|
206
|
-
if @cgi.
|
168
|
+
if @cgi.__send__(:env_table)['REQUEST_METHOD'] == 'HEAD'
|
207
169
|
return
|
208
170
|
elsif @body.respond_to?(:call)
|
209
171
|
# Flush the output now in case the @body Proc uses
|