actionpack 2.2.3 → 2.3.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 +433 -375
- data/MIT-LICENSE +1 -1
- data/README +21 -75
- data/Rakefile +1 -1
- data/lib/action_controller.rb +80 -43
- data/lib/action_controller/assertions/model_assertions.rb +1 -0
- data/lib/action_controller/assertions/response_assertions.rb +43 -16
- data/lib/action_controller/assertions/routing_assertions.rb +1 -1
- data/lib/action_controller/assertions/selector_assertions.rb +17 -12
- data/lib/action_controller/assertions/tag_assertions.rb +1 -4
- data/lib/action_controller/base.rb +153 -82
- data/lib/action_controller/benchmarking.rb +9 -9
- data/lib/action_controller/caching.rb +9 -11
- data/lib/action_controller/caching/actions.rb +11 -18
- data/lib/action_controller/caching/fragments.rb +28 -20
- data/lib/action_controller/caching/pages.rb +13 -15
- data/lib/action_controller/caching/sweeping.rb +2 -2
- data/lib/action_controller/cgi_ext.rb +0 -1
- data/lib/action_controller/cgi_ext/cookie.rb +2 -0
- data/lib/action_controller/cgi_process.rb +54 -162
- data/lib/action_controller/cookies.rb +13 -25
- data/lib/action_controller/dispatcher.rb +43 -122
- data/lib/action_controller/failsafe.rb +52 -0
- data/lib/action_controller/flash.rb +38 -47
- data/lib/action_controller/helpers.rb +13 -9
- data/lib/action_controller/http_authentication.rb +203 -23
- data/lib/action_controller/integration.rb +126 -70
- data/lib/action_controller/layout.rb +36 -39
- data/lib/action_controller/middleware_stack.rb +119 -0
- data/lib/action_controller/middlewares.rb +13 -0
- data/lib/action_controller/mime_responds.rb +19 -4
- data/lib/action_controller/mime_type.rb +8 -0
- data/lib/action_controller/params_parser.rb +71 -0
- data/lib/action_controller/performance_test.rb +0 -1
- data/lib/action_controller/polymorphic_routes.rb +36 -30
- data/lib/action_controller/reloader.rb +14 -0
- data/lib/action_controller/request.rb +107 -499
- data/lib/action_controller/request_forgery_protection.rb +7 -39
- data/lib/action_controller/rescue.rb +55 -35
- data/lib/action_controller/resources.rb +34 -31
- data/lib/action_controller/response.rb +99 -57
- data/lib/action_controller/rewindable_input.rb +28 -0
- data/lib/action_controller/routing.rb +7 -7
- data/lib/action_controller/routing/builder.rb +4 -1
- data/lib/action_controller/routing/optimisations.rb +1 -1
- data/lib/action_controller/routing/recognition_optimisation.rb +1 -2
- data/lib/action_controller/routing/route.rb +15 -5
- data/lib/action_controller/routing/route_set.rb +82 -35
- data/lib/action_controller/routing/segments.rb +35 -0
- data/lib/action_controller/session/abstract_store.rb +181 -0
- data/lib/action_controller/session/cookie_store.rb +197 -175
- data/lib/action_controller/session/mem_cache_store.rb +36 -83
- data/lib/action_controller/session_management.rb +26 -134
- data/lib/action_controller/streaming.rb +24 -7
- 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 +87 -30
- data/lib/action_controller/test_process.rb +145 -104
- data/lib/action_controller/uploaded_file.rb +44 -0
- data/lib/action_controller/url_rewriter.rb +3 -6
- data/lib/action_controller/vendor/html-scanner.rb +16 -0
- data/lib/action_controller/vendor/html-scanner/html/selector.rb +1 -1
- data/lib/action_controller/vendor/rack-1.0/rack.rb +89 -0
- data/lib/action_controller/vendor/rack-1.0/rack/adapter/camping.rb +22 -0
- data/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/handler.rb +37 -0
- data/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/request.rb +37 -0
- data/lib/action_controller/vendor/rack-1.0/rack/auth/basic.rb +58 -0
- data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/md5.rb +124 -0
- data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/nonce.rb +51 -0
- data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/params.rb +55 -0
- data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/request.rb +40 -0
- data/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb +480 -0
- data/lib/action_controller/vendor/rack-1.0/rack/builder.rb +63 -0
- data/lib/action_controller/vendor/rack-1.0/rack/cascade.rb +36 -0
- data/lib/action_controller/vendor/rack-1.0/rack/chunked.rb +49 -0
- data/lib/action_controller/vendor/rack-1.0/rack/commonlogger.rb +61 -0
- data/lib/action_controller/vendor/rack-1.0/rack/conditionalget.rb +45 -0
- data/lib/action_controller/vendor/rack-1.0/rack/content_length.rb +29 -0
- data/lib/action_controller/vendor/rack-1.0/rack/content_type.rb +23 -0
- data/lib/action_controller/vendor/rack-1.0/rack/deflater.rb +85 -0
- data/lib/action_controller/vendor/rack-1.0/rack/directory.rb +153 -0
- data/lib/action_controller/vendor/rack-1.0/rack/file.rb +88 -0
- data/lib/action_controller/vendor/rack-1.0/rack/handler.rb +48 -0
- data/lib/action_controller/vendor/rack-1.0/rack/handler/cgi.rb +61 -0
- data/lib/action_controller/vendor/rack-1.0/rack/handler/evented_mongrel.rb +8 -0
- data/lib/action_controller/vendor/rack-1.0/rack/handler/fastcgi.rb +89 -0
- data/lib/action_controller/vendor/rack-1.0/rack/handler/lsws.rb +55 -0
- data/lib/action_controller/vendor/rack-1.0/rack/handler/mongrel.rb +84 -0
- data/lib/action_controller/vendor/rack-1.0/rack/handler/scgi.rb +59 -0
- data/lib/action_controller/vendor/rack-1.0/rack/handler/swiftiplied_mongrel.rb +8 -0
- data/lib/action_controller/vendor/rack-1.0/rack/handler/thin.rb +18 -0
- data/lib/action_controller/vendor/rack-1.0/rack/handler/webrick.rb +67 -0
- data/lib/action_controller/vendor/rack-1.0/rack/head.rb +19 -0
- data/lib/action_controller/vendor/rack-1.0/rack/lint.rb +462 -0
- data/lib/action_controller/vendor/rack-1.0/rack/lobster.rb +65 -0
- data/lib/action_controller/vendor/rack-1.0/rack/lock.rb +16 -0
- data/lib/action_controller/vendor/rack-1.0/rack/methodoverride.rb +27 -0
- data/lib/action_controller/vendor/rack-1.0/rack/mime.rb +204 -0
- data/lib/action_controller/vendor/rack-1.0/rack/mock.rb +160 -0
- data/lib/action_controller/vendor/rack-1.0/rack/recursive.rb +57 -0
- data/lib/action_controller/vendor/rack-1.0/rack/reloader.rb +64 -0
- data/lib/action_controller/vendor/rack-1.0/rack/request.rb +241 -0
- data/lib/action_controller/vendor/rack-1.0/rack/response.rb +179 -0
- data/lib/action_controller/vendor/rack-1.0/rack/session/abstract/id.rb +142 -0
- data/lib/action_controller/vendor/rack-1.0/rack/session/cookie.rb +91 -0
- data/lib/action_controller/vendor/rack-1.0/rack/session/memcache.rb +109 -0
- data/lib/action_controller/vendor/rack-1.0/rack/session/pool.rb +100 -0
- data/lib/action_controller/vendor/rack-1.0/rack/showexceptions.rb +349 -0
- data/lib/action_controller/vendor/rack-1.0/rack/showstatus.rb +106 -0
- data/lib/action_controller/vendor/rack-1.0/rack/static.rb +38 -0
- data/lib/action_controller/vendor/rack-1.0/rack/urlmap.rb +55 -0
- data/lib/action_controller/vendor/rack-1.0/rack/utils.rb +392 -0
- data/lib/action_controller/verification.rb +1 -1
- data/lib/action_pack.rb +1 -1
- data/lib/action_pack/version.rb +2 -2
- data/lib/action_view.rb +22 -17
- data/lib/action_view/base.rb +53 -79
- data/lib/action_view/erb/util.rb +38 -0
- data/lib/action_view/helpers.rb +24 -5
- data/lib/action_view/helpers/active_record_helper.rb +2 -2
- data/lib/action_view/helpers/asset_tag_helper.rb +81 -50
- data/lib/action_view/helpers/atom_feed_helper.rb +1 -1
- data/lib/action_view/helpers/benchmark_helper.rb +26 -5
- data/lib/action_view/helpers/date_helper.rb +82 -7
- data/lib/action_view/helpers/form_helper.rb +295 -64
- data/lib/action_view/helpers/form_options_helper.rb +160 -18
- data/lib/action_view/helpers/form_tag_helper.rb +2 -2
- data/lib/action_view/helpers/number_helper.rb +31 -18
- data/lib/action_view/helpers/prototype_helper.rb +2 -12
- data/lib/action_view/helpers/sanitize_helper.rb +0 -10
- data/lib/action_view/helpers/scriptaculous_helper.rb +1 -0
- data/lib/action_view/helpers/tag_helper.rb +3 -4
- data/lib/action_view/helpers/text_helper.rb +99 -122
- data/lib/action_view/helpers/translation_helper.rb +19 -1
- data/lib/action_view/helpers/url_helper.rb +25 -2
- data/lib/action_view/inline_template.rb +1 -1
- data/lib/action_view/locale/en.yml +19 -1
- data/lib/action_view/partials.rb +46 -9
- data/lib/action_view/paths.rb +28 -84
- data/lib/action_view/reloadable_template.rb +117 -0
- data/lib/action_view/renderable.rb +28 -35
- data/lib/action_view/renderable_partial.rb +3 -4
- data/lib/action_view/template.rb +172 -31
- data/lib/action_view/template_error.rb +8 -9
- data/lib/action_view/template_handler.rb +1 -1
- data/lib/action_view/template_handlers.rb +9 -6
- data/lib/action_view/template_handlers/erb.rb +2 -39
- data/lib/action_view/template_handlers/rjs.rb +1 -0
- data/lib/action_view/test_case.rb +27 -1
- data/test/abstract_unit.rb +23 -17
- data/test/active_record_unit.rb +5 -4
- data/test/activerecord/active_record_store_test.rb +139 -106
- data/test/activerecord/render_partial_with_record_identification_test.rb +5 -21
- data/test/controller/action_pack_assertions_test.rb +25 -23
- data/test/controller/addresses_render_test.rb +3 -6
- data/test/controller/assert_select_test.rb +83 -70
- data/test/controller/base_test.rb +11 -13
- data/test/controller/benchmark_test.rb +3 -3
- data/test/controller/caching_test.rb +34 -24
- data/test/controller/capture_test.rb +3 -6
- data/test/controller/content_type_test.rb +3 -6
- data/test/controller/cookie_test.rb +31 -66
- data/test/controller/deprecation/deprecated_base_methods_test.rb +9 -11
- data/test/controller/dispatcher_test.rb +23 -28
- data/test/controller/fake_models.rb +8 -0
- data/test/controller/filters_test.rb +6 -2
- data/test/controller/flash_test.rb +2 -6
- data/test/controller/helper_test.rb +15 -1
- data/test/controller/html-scanner/document_test.rb +1 -1
- data/test/controller/html-scanner/sanitizer_test.rb +1 -1
- data/test/controller/http_basic_authentication_test.rb +88 -0
- data/test/controller/http_digest_authentication_test.rb +178 -0
- data/test/controller/integration_test.rb +56 -52
- data/test/controller/layout_test.rb +46 -44
- data/test/controller/middleware_stack_test.rb +90 -0
- data/test/controller/mime_responds_test.rb +7 -11
- data/test/controller/mime_type_test.rb +9 -0
- data/test/controller/polymorphic_routes_test.rb +235 -151
- data/test/controller/rack_test.rb +52 -81
- data/test/controller/redirect_test.rb +6 -14
- data/test/controller/render_test.rb +273 -60
- data/test/controller/request/json_params_parsing_test.rb +45 -0
- data/test/controller/request/multipart_params_parsing_test.rb +223 -0
- data/test/controller/request/query_string_parsing_test.rb +120 -0
- data/test/controller/request/url_encoded_params_parsing_test.rb +184 -0
- data/test/controller/request/xml_params_parsing_test.rb +88 -0
- data/test/controller/request_forgery_protection_test.rb +17 -98
- data/test/controller/request_test.rb +45 -530
- data/test/controller/rescue_test.rb +45 -22
- data/test/controller/resources_test.rb +112 -37
- data/test/controller/routing_test.rb +1442 -1384
- data/test/controller/selector_test.rb +3 -3
- data/test/controller/send_file_test.rb +30 -3
- data/test/controller/session/cookie_store_test.rb +169 -240
- data/test/controller/session/mem_cache_store_test.rb +94 -148
- data/test/controller/session/test_session_test.rb +58 -0
- data/test/controller/test_test.rb +32 -13
- data/test/controller/url_rewriter_test.rb +54 -4
- data/test/controller/verification_test.rb +1 -1
- data/test/controller/view_paths_test.rb +15 -15
- data/test/controller/webservice_test.rb +178 -147
- data/test/fixtures/alternate_helpers/foo_helper.rb +3 -0
- data/test/fixtures/layout_tests/alt/layouts/alt.rhtml +0 -0
- data/test/fixtures/layouts/default_html.html.erb +1 -0
- data/test/fixtures/layouts/xhr.html.erb +2 -0
- data/test/fixtures/multipart/empty +10 -0
- data/test/fixtures/multipart/hello.txt +1 -0
- data/test/fixtures/multipart/none +9 -0
- data/test/fixtures/public/500.da.html +1 -0
- data/test/fixtures/quiz/questions/_question.html.erb +1 -0
- data/test/fixtures/replies.yml +1 -1
- data/test/fixtures/test/_one.html.erb +1 -0
- data/test/fixtures/test/_two.html.erb +1 -0
- data/test/fixtures/test/dont_pick_me +1 -0
- data/test/fixtures/test/hello.builder +1 -1
- data/test/fixtures/test/hello_world.da.html.erb +1 -0
- data/test/fixtures/test/hello_world.erb~ +1 -0
- data/test/fixtures/test/hello_world.pt-BR.html.erb +1 -0
- data/test/fixtures/test/malformed/malformed.en.html.erb~ +1 -0
- data/test/fixtures/test/malformed/malformed.erb~ +1 -0
- data/test/fixtures/test/malformed/malformed.html.erb~ +1 -0
- data/test/fixtures/test/render_explicit_html_template.js.rjs +1 -0
- data/test/fixtures/test/render_implicit_html_template.js.rjs +1 -0
- data/test/fixtures/test/render_implicit_html_template_from_xhr_request.da.html.erb +1 -0
- data/test/fixtures/test/render_implicit_html_template_from_xhr_request.html.erb +1 -0
- data/test/fixtures/test/render_implicit_js_template_without_layout.js.erb +1 -0
- data/test/fixtures/test/utf8.html.erb +2 -0
- data/test/template/active_record_helper_i18n_test.rb +31 -33
- data/test/template/active_record_helper_test.rb +34 -0
- data/test/template/asset_tag_helper_test.rb +52 -14
- data/test/template/atom_feed_helper_test.rb +3 -5
- data/test/template/benchmark_helper_test.rb +50 -24
- data/test/template/compiled_templates_test.rb +177 -33
- data/test/template/date_helper_i18n_test.rb +88 -81
- data/test/template/date_helper_test.rb +427 -43
- data/test/template/form_helper_test.rb +243 -44
- data/test/template/form_options_helper_test.rb +631 -565
- data/test/template/form_tag_helper_test.rb +9 -2
- data/test/template/javascript_helper_test.rb +0 -5
- data/test/template/number_helper_i18n_test.rb +60 -48
- data/test/template/number_helper_test.rb +1 -0
- data/test/template/render_test.rb +117 -35
- data/test/template/test_test.rb +4 -6
- data/test/template/text_helper_test.rb +129 -50
- data/test/template/translation_helper_test.rb +23 -19
- data/test/template/url_helper_test.rb +35 -2
- data/test/view/test_case_test.rb +8 -0
- metadata +197 -23
- data/lib/action_controller/assertions.rb +0 -69
- data/lib/action_controller/caching/sql_cache.rb +0 -18
- data/lib/action_controller/cgi_ext/session.rb +0 -53
- data/lib/action_controller/components.rb +0 -169
- data/lib/action_controller/rack_process.rb +0 -297
- data/lib/action_controller/request_profiler.rb +0 -169
- data/lib/action_controller/session/active_record_store.rb +0 -340
- data/lib/action_controller/session/drb_server.rb +0 -32
- data/lib/action_controller/session/drb_store.rb +0 -35
- data/test/controller/cgi_test.rb +0 -269
- data/test/controller/components_test.rb +0 -156
- data/test/controller/http_authentication_test.rb +0 -54
- data/test/controller/integration_upload_test.rb +0 -43
- data/test/controller/session_fixation_test.rb +0 -89
- data/test/controller/session_management_test.rb +0 -178
- data/test/fixtures/test/hello_world.js +0 -1
@@ -134,7 +134,7 @@ module ActionController
|
|
134
134
|
path = "/#{path}" unless path.first == '/'
|
135
135
|
|
136
136
|
# Assume given controller
|
137
|
-
request = ActionController::TestRequest.new
|
137
|
+
request = ActionController::TestRequest.new
|
138
138
|
request.env["REQUEST_METHOD"] = request_method.to_s.upcase if request_method
|
139
139
|
request.path = path
|
140
140
|
|
@@ -3,9 +3,6 @@
|
|
3
3
|
# Under MIT and/or CC By license.
|
4
4
|
#++
|
5
5
|
|
6
|
-
require 'rexml/document'
|
7
|
-
require 'html/document'
|
8
|
-
|
9
6
|
module ActionController
|
10
7
|
module Assertions
|
11
8
|
unless const_defined?(:NO_STRIP)
|
@@ -112,20 +109,27 @@ module ActionController
|
|
112
109
|
# starting from (and including) that element and all its children in
|
113
110
|
# depth-first order.
|
114
111
|
#
|
115
|
-
# If no element if specified, calling +assert_select+
|
116
|
-
# response HTML
|
117
|
-
#
|
112
|
+
# If no element if specified, calling +assert_select+ selects from the
|
113
|
+
# response HTML unless +assert_select+ is called from within an +assert_select+ block.
|
114
|
+
#
|
115
|
+
# When called with a block +assert_select+ passes an array of selected elements
|
116
|
+
# to the block. Calling +assert_select+ from the block, with no element specified,
|
117
|
+
# runs the assertion on the complete set of elements selected by the enclosing assertion.
|
118
|
+
# Alternatively the array may be iterated through so that +assert_select+ can be called
|
119
|
+
# separately for each element.
|
120
|
+
#
|
118
121
|
#
|
119
122
|
# ==== Example
|
120
|
-
#
|
123
|
+
# If the response contains two ordered lists, each with four list elements then:
|
124
|
+
# assert_select "ol" do |elements|
|
121
125
|
# elements.each do |element|
|
122
|
-
# assert_select element, "li"
|
126
|
+
# assert_select element, "li", 4
|
123
127
|
# end
|
124
128
|
# end
|
125
129
|
#
|
126
|
-
#
|
127
|
-
# assert_select "ol
|
128
|
-
# assert_select "li"
|
130
|
+
# will pass, as will:
|
131
|
+
# assert_select "ol" do
|
132
|
+
# assert_select "li", 8
|
129
133
|
# end
|
130
134
|
#
|
131
135
|
# The selector may be a CSS selector expression (String), an expression
|
@@ -405,6 +409,7 @@ module ActionController
|
|
405
409
|
if rjs_type
|
406
410
|
if rjs_type == :insert
|
407
411
|
position = args.shift
|
412
|
+
id = args.shift
|
408
413
|
insertion = "insert_#{position}".to_sym
|
409
414
|
raise ArgumentError, "Unknown RJS insertion type #{position}" unless RJS_STATEMENTS[insertion]
|
410
415
|
statement = "(#{RJS_STATEMENTS[insertion]})"
|
@@ -590,7 +595,7 @@ module ActionController
|
|
590
595
|
def response_from_page_or_rjs()
|
591
596
|
content_type = @response.content_type
|
592
597
|
|
593
|
-
if content_type &&
|
598
|
+
if content_type && Mime::JS =~ content_type
|
594
599
|
body = @response.body.dup
|
595
600
|
root = HTML::Node.new(nil)
|
596
601
|
|
@@ -1,6 +1,3 @@
|
|
1
|
-
require 'rexml/document'
|
2
|
-
require 'html/document'
|
3
|
-
|
4
1
|
module ActionController
|
5
2
|
module Assertions
|
6
3
|
# Pair of assertions to testing elements in the HTML output of the response.
|
@@ -127,4 +124,4 @@ module ActionController
|
|
127
124
|
end
|
128
125
|
end
|
129
126
|
end
|
130
|
-
end
|
127
|
+
end
|
@@ -1,12 +1,3 @@
|
|
1
|
-
require 'action_controller/mime_type'
|
2
|
-
require 'action_controller/request'
|
3
|
-
require 'action_controller/response'
|
4
|
-
require 'action_controller/routing'
|
5
|
-
require 'action_controller/resources'
|
6
|
-
require 'action_controller/url_rewriter'
|
7
|
-
require 'action_controller/status_codes'
|
8
|
-
require 'action_view'
|
9
|
-
require 'drb'
|
10
1
|
require 'set'
|
11
2
|
|
12
3
|
module ActionController #:nodoc:
|
@@ -31,7 +22,7 @@ module ActionController #:nodoc:
|
|
31
22
|
attr_reader :allowed_methods
|
32
23
|
|
33
24
|
def initialize(*allowed_methods)
|
34
|
-
super("Only #{allowed_methods.to_sentence} requests are allowed.")
|
25
|
+
super("Only #{allowed_methods.to_sentence(:locale => :en)} requests are allowed.")
|
35
26
|
@allowed_methods = allowed_methods
|
36
27
|
end
|
37
28
|
|
@@ -173,8 +164,8 @@ module ActionController #:nodoc:
|
|
173
164
|
#
|
174
165
|
# Other options for session storage are:
|
175
166
|
#
|
176
|
-
# *
|
177
|
-
# unlike CookieStore, hides your session contents from the user. To use
|
167
|
+
# * ActiveRecord::SessionStore - Sessions are stored in your database, which works better than PStore with multiple app servers and,
|
168
|
+
# unlike CookieStore, hides your session contents from the user. To use ActiveRecord::SessionStore, set
|
178
169
|
#
|
179
170
|
# config.action_controller.session_store = :active_record_store
|
180
171
|
#
|
@@ -263,7 +254,7 @@ module ActionController #:nodoc:
|
|
263
254
|
cattr_reader :protected_instance_variables
|
264
255
|
# Controller specific instance variables which will not be accessible inside views.
|
265
256
|
@@protected_instance_variables = %w(@assigns @performed_redirect @performed_render @variables_added @request_origin @url @parent_controller
|
266
|
-
@action_name @before_filter_chain_aborted @action_cache_path @_session @
|
257
|
+
@action_name @before_filter_chain_aborted @action_cache_path @_session @_headers @_params
|
267
258
|
@_flash @_response)
|
268
259
|
|
269
260
|
# Prepends all the URL-generating helpers from AssetHelper. This makes it possible to easily move javascripts, stylesheets,
|
@@ -310,10 +301,7 @@ module ActionController #:nodoc:
|
|
310
301
|
# A YAML parser is also available and can be turned on with:
|
311
302
|
#
|
312
303
|
# ActionController::Base.param_parsers[Mime::YAML] = :yaml
|
313
|
-
@@param_parsers = {
|
314
|
-
Mime::URL_ENCODED_FORM => :url_encoded_form,
|
315
|
-
Mime::XML => :xml_simple,
|
316
|
-
Mime::JSON => :json }
|
304
|
+
@@param_parsers = {}
|
317
305
|
cattr_accessor :param_parsers
|
318
306
|
|
319
307
|
# Controls the default charset for all renders.
|
@@ -336,6 +324,10 @@ module ActionController #:nodoc:
|
|
336
324
|
# sets it to <tt>:authenticity_token</tt> by default.
|
337
325
|
cattr_accessor :request_forgery_protection_token
|
338
326
|
|
327
|
+
# Controls the IP Spoofing check when determining the remote IP.
|
328
|
+
@@ip_spoofing_check = true
|
329
|
+
cattr_accessor :ip_spoofing_check
|
330
|
+
|
339
331
|
# Indicates whether or not optimise the generated named
|
340
332
|
# route helper methods
|
341
333
|
cattr_accessor :optimise_named_routes
|
@@ -387,6 +379,13 @@ module ActionController #:nodoc:
|
|
387
379
|
attr_accessor :action_name
|
388
380
|
|
389
381
|
class << self
|
382
|
+
def call(env)
|
383
|
+
# HACK: For global rescue to have access to the original request and response
|
384
|
+
request = env["action_controller.rescue.request"] ||= Request.new(env)
|
385
|
+
response = env["action_controller.rescue.response"] ||= Response.new
|
386
|
+
process(request, response)
|
387
|
+
end
|
388
|
+
|
390
389
|
# Factory for the standard create, process loop where the controller is discarded after processing.
|
391
390
|
def process(request, response) #:nodoc:
|
392
391
|
new.process(request, response)
|
@@ -507,7 +506,7 @@ module ActionController #:nodoc:
|
|
507
506
|
protected :filter_parameters
|
508
507
|
end
|
509
508
|
|
510
|
-
delegate :exempt_from_layout, :to => 'ActionView::
|
509
|
+
delegate :exempt_from_layout, :to => 'ActionView::Template'
|
511
510
|
end
|
512
511
|
|
513
512
|
public
|
@@ -529,7 +528,7 @@ module ActionController #:nodoc:
|
|
529
528
|
end
|
530
529
|
|
531
530
|
def send_response
|
532
|
-
response.prepare!
|
531
|
+
response.prepare!
|
533
532
|
response
|
534
533
|
end
|
535
534
|
|
@@ -645,7 +644,7 @@ module ActionController #:nodoc:
|
|
645
644
|
end
|
646
645
|
|
647
646
|
def session_enabled?
|
648
|
-
|
647
|
+
ActiveSupport::Deprecation.warn("Sessions are now lazy loaded. So if you don't access them, consider them disabled.", caller)
|
649
648
|
end
|
650
649
|
|
651
650
|
self.view_paths = []
|
@@ -785,9 +784,37 @@ module ActionController #:nodoc:
|
|
785
784
|
# # placed in "app/views/layouts/special.r(html|xml)"
|
786
785
|
# render :text => "Hi there!", :layout => "special"
|
787
786
|
#
|
788
|
-
#
|
789
|
-
#
|
790
|
-
#
|
787
|
+
# === Streaming data and/or controlling the page generation
|
788
|
+
#
|
789
|
+
# The <tt>:text</tt> option can also accept a Proc object, which can be used to:
|
790
|
+
#
|
791
|
+
# 1. stream on-the-fly generated data to the browser. Note that you should
|
792
|
+
# use the methods provided by ActionController::Steaming instead if you
|
793
|
+
# want to stream a buffer or a file.
|
794
|
+
# 2. manually control the page generation. This should generally be avoided,
|
795
|
+
# as it violates the separation between code and content, and because almost
|
796
|
+
# everything that can be done with this method can also be done more cleanly
|
797
|
+
# using one of the other rendering methods, most notably templates.
|
798
|
+
#
|
799
|
+
# Two arguments are passed to the proc, a <tt>response</tt> object and an
|
800
|
+
# <tt>output</tt> object. The response object is equivalent to the return
|
801
|
+
# value of the ActionController::Base#response method, and can be used to
|
802
|
+
# control various things in the HTTP response, such as setting the
|
803
|
+
# Content-Type header. The output object is an writable <tt>IO</tt>-like
|
804
|
+
# object, so one can call <tt>write</tt> and <tt>flush</tt> on it.
|
805
|
+
#
|
806
|
+
# The following example demonstrates how one can stream a large amount of
|
807
|
+
# on-the-fly generated data to the browser:
|
808
|
+
#
|
809
|
+
# # Streams about 180 MB of generated data to the browser.
|
810
|
+
# render :text => proc { |response, output|
|
811
|
+
# 10_000_000.times do |i|
|
812
|
+
# output.write("This is line #{i}\n")
|
813
|
+
# output.flush
|
814
|
+
# end
|
815
|
+
# }
|
816
|
+
#
|
817
|
+
# Another example:
|
791
818
|
#
|
792
819
|
# # Renders "Hello from code!"
|
793
820
|
# render :text => proc { |response, output| output.write("Hello from code!") }
|
@@ -864,20 +891,31 @@ module ActionController #:nodoc:
|
|
864
891
|
def render(options = nil, extra_options = {}, &block) #:doc:
|
865
892
|
raise DoubleRenderError, "Can only render or redirect once per action" if performed?
|
866
893
|
|
894
|
+
validate_render_arguments(options, extra_options, block_given?)
|
895
|
+
|
867
896
|
if options.nil?
|
868
|
-
|
869
|
-
elsif
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
897
|
+
options = { :template => default_template, :layout => true }
|
898
|
+
elsif options == :update
|
899
|
+
options = extra_options.merge({ :update => true })
|
900
|
+
elsif options.is_a?(String) || options.is_a?(Symbol)
|
901
|
+
case options.to_s.index('/')
|
902
|
+
when 0
|
903
|
+
extra_options[:file] = options
|
904
|
+
when nil
|
905
|
+
extra_options[:action] = options
|
906
|
+
else
|
907
|
+
extra_options[:template] = options
|
876
908
|
end
|
909
|
+
|
910
|
+
options = extra_options
|
911
|
+
elsif !options.is_a?(Hash)
|
912
|
+
extra_options[:partial] = options
|
913
|
+
options = extra_options
|
877
914
|
end
|
878
915
|
|
879
|
-
|
880
|
-
|
916
|
+
layout = pick_layout(options)
|
917
|
+
response.layout = layout.path_without_format_and_extension if layout
|
918
|
+
logger.info("Rendering template within #{layout.path_without_format_and_extension}") if logger && layout
|
881
919
|
|
882
920
|
if content_type = options[:content_type]
|
883
921
|
response.content_type = content_type.to_s
|
@@ -902,7 +940,7 @@ module ActionController #:nodoc:
|
|
902
940
|
render_for_text(@template.render(options.merge(:layout => layout)), options[:status])
|
903
941
|
|
904
942
|
elsif action_name = options[:action]
|
905
|
-
render_for_file(
|
943
|
+
render_for_file(default_template(action_name.to_s), options[:status], layout)
|
906
944
|
|
907
945
|
elsif xml = options[:xml]
|
908
946
|
response.content_type ||= Mime::XML
|
@@ -937,7 +975,7 @@ module ActionController #:nodoc:
|
|
937
975
|
render_for_text(nil, options[:status])
|
938
976
|
|
939
977
|
else
|
940
|
-
render_for_file(
|
978
|
+
render_for_file(default_template, options[:status], layout)
|
941
979
|
end
|
942
980
|
end
|
943
981
|
end
|
@@ -994,7 +1032,7 @@ module ActionController #:nodoc:
|
|
994
1032
|
@performed_redirect = false
|
995
1033
|
response.redirected_to = nil
|
996
1034
|
response.redirected_to_method_params = nil
|
997
|
-
response.
|
1035
|
+
response.status = DEFAULT_RENDER_STATUS_CODE
|
998
1036
|
response.headers.delete('Location')
|
999
1037
|
end
|
1000
1038
|
|
@@ -1065,7 +1103,6 @@ module ActionController #:nodoc:
|
|
1065
1103
|
end
|
1066
1104
|
|
1067
1105
|
response.redirected_to = options
|
1068
|
-
logger.info("Redirected to #{options}") if logger && logger.info?
|
1069
1106
|
|
1070
1107
|
case options
|
1071
1108
|
# The scheme name consist of a letter followed by any combination of
|
@@ -1088,6 +1125,7 @@ module ActionController #:nodoc:
|
|
1088
1125
|
|
1089
1126
|
def redirect_to_full_url(url, status)
|
1090
1127
|
raise DoubleRenderError if performed?
|
1128
|
+
logger.info("Redirected to #{url}") if logger && logger.info?
|
1091
1129
|
response.redirect(url, interpret_status(status))
|
1092
1130
|
@performed_redirect = true
|
1093
1131
|
end
|
@@ -1097,6 +1135,11 @@ module ActionController #:nodoc:
|
|
1097
1135
|
# request is considered stale and should be generated from scratch. Otherwise,
|
1098
1136
|
# it's fresh and we don't need to generate anything and a reply of "304 Not Modified" is sent.
|
1099
1137
|
#
|
1138
|
+
# Parameters:
|
1139
|
+
# * <tt>:etag</tt>
|
1140
|
+
# * <tt>:last_modified</tt>
|
1141
|
+
# * <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).
|
1142
|
+
#
|
1100
1143
|
# Example:
|
1101
1144
|
#
|
1102
1145
|
# def show
|
@@ -1115,22 +1158,36 @@ module ActionController #:nodoc:
|
|
1115
1158
|
end
|
1116
1159
|
|
1117
1160
|
# Sets the etag, last_modified, or both on the response and renders a
|
1118
|
-
# "304 Not Modified" response if the request is already fresh.
|
1161
|
+
# "304 Not Modified" response if the request is already fresh.
|
1162
|
+
#
|
1163
|
+
# Parameters:
|
1164
|
+
# * <tt>:etag</tt>
|
1165
|
+
# * <tt>:last_modified</tt>
|
1166
|
+
# * <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).
|
1119
1167
|
#
|
1120
1168
|
# Example:
|
1121
1169
|
#
|
1122
1170
|
# def show
|
1123
1171
|
# @article = Article.find(params[:id])
|
1124
|
-
# fresh_when(:etag => @article, :last_modified => @article.created_at.utc)
|
1172
|
+
# fresh_when(:etag => @article, :last_modified => @article.created_at.utc, :public => true)
|
1125
1173
|
# end
|
1126
|
-
#
|
1127
|
-
# This will render the show template if the request isn't sending a matching etag or
|
1174
|
+
#
|
1175
|
+
# This will render the show template if the request isn't sending a matching etag or
|
1128
1176
|
# If-Modified-Since header and just a "304 Not Modified" response if there's a match.
|
1177
|
+
#
|
1129
1178
|
def fresh_when(options)
|
1130
|
-
options.assert_valid_keys(:etag, :last_modified)
|
1179
|
+
options.assert_valid_keys(:etag, :last_modified, :public)
|
1131
1180
|
|
1132
1181
|
response.etag = options[:etag] if options[:etag]
|
1133
1182
|
response.last_modified = options[:last_modified] if options[:last_modified]
|
1183
|
+
|
1184
|
+
if options[:public]
|
1185
|
+
cache_control = response.headers["Cache-Control"].split(",").map {|k| k.strip }
|
1186
|
+
cache_control.delete("private")
|
1187
|
+
cache_control.delete("no-cache")
|
1188
|
+
cache_control << "public"
|
1189
|
+
response.headers["Cache-Control"] = cache_control.join(', ')
|
1190
|
+
end
|
1134
1191
|
|
1135
1192
|
if request.fresh?(response)
|
1136
1193
|
head :not_modified
|
@@ -1142,15 +1199,26 @@ module ActionController #:nodoc:
|
|
1142
1199
|
#
|
1143
1200
|
# Examples:
|
1144
1201
|
# expires_in 20.minutes
|
1145
|
-
# expires_in 3.hours, :
|
1146
|
-
# expires in 3.hours, 'max-stale' => 5.hours, :
|
1202
|
+
# expires_in 3.hours, :public => true
|
1203
|
+
# expires in 3.hours, 'max-stale' => 5.hours, :public => true
|
1147
1204
|
#
|
1148
1205
|
# This method will overwrite an existing Cache-Control header.
|
1149
1206
|
# See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html for more possibilities.
|
1150
1207
|
def expires_in(seconds, options = {}) #:doc:
|
1151
|
-
|
1152
|
-
|
1153
|
-
cache_control
|
1208
|
+
cache_control = response.headers["Cache-Control"].split(",").map {|k| k.strip }
|
1209
|
+
|
1210
|
+
cache_control << "max-age=#{seconds}"
|
1211
|
+
cache_control.delete("no-cache")
|
1212
|
+
if options[:public]
|
1213
|
+
cache_control.delete("private")
|
1214
|
+
cache_control << "public"
|
1215
|
+
else
|
1216
|
+
cache_control << "private"
|
1217
|
+
end
|
1218
|
+
|
1219
|
+
# This allows for additional headers to be passed through like 'max-stale' => 5.hours
|
1220
|
+
cache_control += options.symbolize_keys.reject{|k,v| k == :public || k == :private }.map{ |k,v| v == true ? k.to_s : "#{k.to_s}=#{v.to_s}"}
|
1221
|
+
|
1154
1222
|
response.headers["Cache-Control"] = cache_control.join(', ')
|
1155
1223
|
end
|
1156
1224
|
|
@@ -1164,23 +1232,19 @@ module ActionController #:nodoc:
|
|
1164
1232
|
def reset_session #:doc:
|
1165
1233
|
request.reset_session
|
1166
1234
|
@_session = request.session
|
1167
|
-
#http://rails.lighthouseapp.com/projects/8994/tickets/1558-memory-problem-on-reset_session-in-around_filter#ticket-1558-1
|
1168
|
-
#MRI appears to have a GC related memory leak to do with the finalizer that is defined on CGI::Session
|
1169
|
-
ObjectSpace.undefine_finalizer(@_session)
|
1170
|
-
response.session = @_session
|
1171
1235
|
end
|
1172
1236
|
|
1173
|
-
|
1174
1237
|
private
|
1175
1238
|
def render_for_file(template_path, status = nil, layout = nil, locals = {}) #:nodoc:
|
1176
|
-
|
1239
|
+
path = template_path.respond_to?(:path_without_format_and_extension) ? template_path.path_without_format_and_extension : template_path
|
1240
|
+
logger.info("Rendering #{path}" + (status ? " (#{status})" : '')) if logger
|
1177
1241
|
render_for_text @template.render(:file => template_path, :locals => locals, :layout => layout), status
|
1178
1242
|
end
|
1179
1243
|
|
1180
1244
|
def render_for_text(text = nil, status = nil, append_response = false) #:nodoc:
|
1181
1245
|
@performed_render = true
|
1182
1246
|
|
1183
|
-
response.
|
1247
|
+
response.status = interpret_status(status || DEFAULT_RENDER_STATUS_CODE)
|
1184
1248
|
|
1185
1249
|
if append_response
|
1186
1250
|
response.body ||= ''
|
@@ -1194,6 +1258,16 @@ module ActionController #:nodoc:
|
|
1194
1258
|
end
|
1195
1259
|
end
|
1196
1260
|
|
1261
|
+
def validate_render_arguments(options, extra_options, has_block)
|
1262
|
+
if options && (has_block && options != :update) && !options.is_a?(String) && !options.is_a?(Hash) && !options.is_a?(Symbol)
|
1263
|
+
raise RenderError, "You called render with invalid options : #{options.inspect}"
|
1264
|
+
end
|
1265
|
+
|
1266
|
+
if !extra_options.is_a?(Hash)
|
1267
|
+
raise RenderError, "You called render with invalid options : #{options.inspect}, #{extra_options.inspect}"
|
1268
|
+
end
|
1269
|
+
end
|
1270
|
+
|
1197
1271
|
def initialize_template_class(response)
|
1198
1272
|
response.template = ActionView::Base.new(self.class.view_paths, {}, self)
|
1199
1273
|
response.template.helpers.send :include, self.class.master_helper_module
|
@@ -1202,7 +1276,7 @@ module ActionController #:nodoc:
|
|
1202
1276
|
end
|
1203
1277
|
|
1204
1278
|
def assign_shortcuts(request, response)
|
1205
|
-
@_request, @_params
|
1279
|
+
@_request, @_params = request, request.parameters
|
1206
1280
|
|
1207
1281
|
@_response = response
|
1208
1282
|
@_response.session = request.session
|
@@ -1220,11 +1294,10 @@ module ActionController #:nodoc:
|
|
1220
1294
|
def log_processing
|
1221
1295
|
if logger && logger.info?
|
1222
1296
|
log_processing_for_request_id
|
1223
|
-
log_processing_for_session_id
|
1224
1297
|
log_processing_for_parameters
|
1225
1298
|
end
|
1226
1299
|
end
|
1227
|
-
|
1300
|
+
|
1228
1301
|
def log_processing_for_request_id
|
1229
1302
|
request_id = "\n\nProcessing #{self.class.name}\##{action_name} "
|
1230
1303
|
request_id << "to #{params[:format]} " if params[:format]
|
@@ -1233,17 +1306,10 @@ module ActionController #:nodoc:
|
|
1233
1306
|
logger.info(request_id)
|
1234
1307
|
end
|
1235
1308
|
|
1236
|
-
def log_processing_for_session_id
|
1237
|
-
if @_session && @_session.respond_to?(:session_id) && @_session.respond_to?(:dbman) &&
|
1238
|
-
!@_session.dbman.is_a?(CGI::Session::CookieStore)
|
1239
|
-
logger.info " Session ID: #{@_session.session_id}"
|
1240
|
-
end
|
1241
|
-
end
|
1242
|
-
|
1243
1309
|
def log_processing_for_parameters
|
1244
1310
|
parameters = respond_to?(:filter_parameters) ? filter_parameters(params) : params.dup
|
1245
1311
|
parameters = parameters.except!(:controller, :action, :format, :_method)
|
1246
|
-
|
1312
|
+
|
1247
1313
|
logger.info " Parameters: #{parameters.inspect}" unless parameters.empty?
|
1248
1314
|
end
|
1249
1315
|
|
@@ -1258,10 +1324,17 @@ module ActionController #:nodoc:
|
|
1258
1324
|
elsif respond_to? :method_missing
|
1259
1325
|
method_missing action_name
|
1260
1326
|
default_render unless performed?
|
1261
|
-
elsif template_exists?
|
1262
|
-
default_render
|
1263
1327
|
else
|
1264
|
-
|
1328
|
+
begin
|
1329
|
+
default_render
|
1330
|
+
rescue ActionView::MissingTemplate => e
|
1331
|
+
# Was the implicit template missing, or was it another template?
|
1332
|
+
if e.path == default_template_name
|
1333
|
+
raise UnknownAction, "No action responded to #{action_name}. Actions: #{action_methods.sort.to_sentence(:locale => :en)}", caller
|
1334
|
+
else
|
1335
|
+
raise e
|
1336
|
+
end
|
1337
|
+
end
|
1265
1338
|
end
|
1266
1339
|
end
|
1267
1340
|
|
@@ -1273,11 +1346,6 @@ module ActionController #:nodoc:
|
|
1273
1346
|
@action_name = (params['action'] || 'index')
|
1274
1347
|
end
|
1275
1348
|
|
1276
|
-
def assign_default_content_type_and_charset
|
1277
|
-
response.assign_default_content_type_and_charset!
|
1278
|
-
end
|
1279
|
-
deprecate :assign_default_content_type_and_charset => :'response.assign_default_content_type_and_charset!'
|
1280
|
-
|
1281
1349
|
def action_methods
|
1282
1350
|
self.class.action_methods
|
1283
1351
|
end
|
@@ -1308,14 +1376,8 @@ module ActionController #:nodoc:
|
|
1308
1376
|
"#{request.protocol}#{request.host}#{request.request_uri}"
|
1309
1377
|
end
|
1310
1378
|
|
1311
|
-
def
|
1312
|
-
|
1313
|
-
end
|
1314
|
-
|
1315
|
-
def template_exists?(template_name = default_template_name)
|
1316
|
-
@template.send(:_pick_template, template_name) ? true : false
|
1317
|
-
rescue ActionView::MissingTemplate
|
1318
|
-
false
|
1379
|
+
def default_template(action_name = self.action_name)
|
1380
|
+
self.view_paths.find_template(default_template_name(action_name), default_template_format)
|
1319
1381
|
end
|
1320
1382
|
|
1321
1383
|
def default_template_name(action_name = self.action_name)
|
@@ -1337,7 +1399,16 @@ module ActionController #:nodoc:
|
|
1337
1399
|
end
|
1338
1400
|
|
1339
1401
|
def process_cleanup
|
1340
|
-
close_session
|
1341
1402
|
end
|
1342
1403
|
end
|
1404
|
+
|
1405
|
+
Base.class_eval do
|
1406
|
+
[ Filters, Layout, Benchmarking, Rescue, Flash, MimeResponds, Helpers,
|
1407
|
+
Cookies, Caching, Verification, Streaming, SessionManagement,
|
1408
|
+
HttpAuthentication::Basic::ControllerMethods, HttpAuthentication::Digest::ControllerMethods,
|
1409
|
+
RecordIdentifier, RequestForgeryProtection, Translation
|
1410
|
+
].each do |mod|
|
1411
|
+
include mod
|
1412
|
+
end
|
1413
|
+
end
|
1343
1414
|
end
|