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
@@ -1,69 +0,0 @@
|
|
1
|
-
require 'test/unit/assertions'
|
2
|
-
|
3
|
-
module ActionController #:nodoc:
|
4
|
-
# In addition to these specific assertions, you also have easy access to various collections that the regular test/unit assertions
|
5
|
-
# can be used against. These collections are:
|
6
|
-
#
|
7
|
-
# * assigns: Instance variables assigned in the action that are available for the view.
|
8
|
-
# * session: Objects being saved in the session.
|
9
|
-
# * flash: The flash objects currently in the session.
|
10
|
-
# * cookies: Cookies being sent to the user on this request.
|
11
|
-
#
|
12
|
-
# These collections can be used just like any other hash:
|
13
|
-
#
|
14
|
-
# assert_not_nil assigns(:person) # makes sure that a @person instance variable was set
|
15
|
-
# assert_equal "Dave", cookies[:name] # makes sure that a cookie called :name was set as "Dave"
|
16
|
-
# assert flash.empty? # makes sure that there's nothing in the flash
|
17
|
-
#
|
18
|
-
# For historic reasons, the assigns hash uses string-based keys. So assigns[:person] won't work, but assigns["person"] will. To
|
19
|
-
# appease our yearning for symbols, though, an alternative accessor has been devised using a method call instead of index referencing.
|
20
|
-
# So assigns(:person) will work just like assigns["person"], but again, assigns[:person] will not work.
|
21
|
-
#
|
22
|
-
# On top of the collections, you have the complete url that a given action redirected to available in redirect_to_url.
|
23
|
-
#
|
24
|
-
# For redirects within the same controller, you can even call follow_redirect and the redirect will be followed, triggering another
|
25
|
-
# action call which can then be asserted against.
|
26
|
-
#
|
27
|
-
# == Manipulating the request collections
|
28
|
-
#
|
29
|
-
# The collections described above link to the response, so you can test if what the actions were expected to do happened. But
|
30
|
-
# sometimes you also want to manipulate these collections in the incoming request. This is really only relevant for sessions
|
31
|
-
# and cookies, though. For sessions, you just do:
|
32
|
-
#
|
33
|
-
# @request.session[:key] = "value"
|
34
|
-
#
|
35
|
-
# For cookies, you need to manually create the cookie, like this:
|
36
|
-
#
|
37
|
-
# @request.cookies["key"] = CGI::Cookie.new("key", "value")
|
38
|
-
#
|
39
|
-
# == Testing named routes
|
40
|
-
#
|
41
|
-
# If you're using named routes, they can be easily tested using the original named routes' methods straight in the test case.
|
42
|
-
# Example:
|
43
|
-
#
|
44
|
-
# assert_redirected_to page_url(:title => 'foo')
|
45
|
-
module Assertions
|
46
|
-
def self.included(klass)
|
47
|
-
%w(response selector tag dom routing model).each do |kind|
|
48
|
-
require "action_controller/assertions/#{kind}_assertions"
|
49
|
-
klass.module_eval { include const_get("#{kind.camelize}Assertions") }
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def clean_backtrace(&block)
|
54
|
-
yield
|
55
|
-
rescue Test::Unit::AssertionFailedError => error
|
56
|
-
framework_path = Regexp.new(File.expand_path("#{File.dirname(__FILE__)}/assertions"))
|
57
|
-
error.backtrace.reject! { |line| File.expand_path(line) =~ framework_path }
|
58
|
-
raise
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
module Test #:nodoc:
|
64
|
-
module Unit #:nodoc:
|
65
|
-
class TestCase #:nodoc:
|
66
|
-
include ActionController::Assertions
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
module ActionController #:nodoc:
|
2
|
-
module Caching
|
3
|
-
module SqlCache
|
4
|
-
def self.included(base) #:nodoc:
|
5
|
-
if defined?(ActiveRecord) && ActiveRecord::Base.respond_to?(:cache)
|
6
|
-
base.alias_method_chain :perform_action, :caching
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
protected
|
11
|
-
def perform_action_with_caching
|
12
|
-
ActiveRecord::Base.cache do
|
13
|
-
perform_action_without_caching
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
@@ -1,53 +0,0 @@
|
|
1
|
-
require 'digest/md5'
|
2
|
-
require 'cgi/session'
|
3
|
-
require 'cgi/session/pstore'
|
4
|
-
|
5
|
-
class CGI #:nodoc:
|
6
|
-
# * Expose the CGI instance to session stores.
|
7
|
-
# * Don't require 'digest/md5' whenever a new session id is generated.
|
8
|
-
class Session #:nodoc:
|
9
|
-
def self.generate_unique_id(constant = nil)
|
10
|
-
ActiveSupport::SecureRandom.hex(16)
|
11
|
-
end
|
12
|
-
|
13
|
-
# Make the CGI instance available to session stores.
|
14
|
-
attr_reader :cgi
|
15
|
-
attr_reader :dbman
|
16
|
-
alias_method :initialize_without_cgi_reader, :initialize
|
17
|
-
def initialize(cgi, options = {})
|
18
|
-
@cgi = cgi
|
19
|
-
initialize_without_cgi_reader(cgi, options)
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
23
|
-
# Create a new session id.
|
24
|
-
def create_new_id
|
25
|
-
@new_session = true
|
26
|
-
self.class.generate_unique_id
|
27
|
-
end
|
28
|
-
|
29
|
-
# * Don't require 'digest/md5' whenever a new session is started.
|
30
|
-
class PStore #:nodoc:
|
31
|
-
def initialize(session, option={})
|
32
|
-
dir = option['tmpdir'] || Dir::tmpdir
|
33
|
-
prefix = option['prefix'] || ''
|
34
|
-
id = session.session_id
|
35
|
-
md5 = Digest::MD5.hexdigest(id)[0,16]
|
36
|
-
path = dir+"/"+prefix+md5
|
37
|
-
path.untaint
|
38
|
-
if File::exist?(path)
|
39
|
-
@hash = nil
|
40
|
-
else
|
41
|
-
unless session.new_session
|
42
|
-
raise CGI::Session::NoSession, "uninitialized session"
|
43
|
-
end
|
44
|
-
@hash = {}
|
45
|
-
end
|
46
|
-
@p = ::PStore.new(path)
|
47
|
-
@p.transaction do |p|
|
48
|
-
File.chmod(0600, p.path)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
@@ -1,169 +0,0 @@
|
|
1
|
-
module ActionController #:nodoc:
|
2
|
-
# Components allow you to call other actions for their rendered response while executing another action. You can either delegate
|
3
|
-
# the entire response rendering or you can mix a partial response in with your other content.
|
4
|
-
#
|
5
|
-
# class WeblogController < ActionController::Base
|
6
|
-
# # Performs a method and then lets hello_world output its render
|
7
|
-
# def delegate_action
|
8
|
-
# do_other_stuff_before_hello_world
|
9
|
-
# render_component :controller => "greeter", :action => "hello_world", :params => { :person => "david" }
|
10
|
-
# end
|
11
|
-
# end
|
12
|
-
#
|
13
|
-
# class GreeterController < ActionController::Base
|
14
|
-
# def hello_world
|
15
|
-
# render :text => "#{params[:person]} says, Hello World!"
|
16
|
-
# end
|
17
|
-
# end
|
18
|
-
#
|
19
|
-
# The same can be done in a view to do a partial rendering:
|
20
|
-
#
|
21
|
-
# Let's see a greeting:
|
22
|
-
# <%= render_component :controller => "greeter", :action => "hello_world" %>
|
23
|
-
#
|
24
|
-
# It is also possible to specify the controller as a class constant, bypassing the inflector
|
25
|
-
# code to compute the controller class at runtime:
|
26
|
-
#
|
27
|
-
# <%= render_component :controller => GreeterController, :action => "hello_world" %>
|
28
|
-
#
|
29
|
-
# == When to use components
|
30
|
-
#
|
31
|
-
# Components should be used with care. They're significantly slower than simply splitting reusable parts into partials and
|
32
|
-
# conceptually more complicated. Don't use components as a way of separating concerns inside a single application. Instead,
|
33
|
-
# reserve components to those rare cases where you truly have reusable view and controller elements that can be employed
|
34
|
-
# across many applications at once.
|
35
|
-
#
|
36
|
-
# So to repeat: Components are a special-purpose approach that can often be replaced with better use of partials and filters.
|
37
|
-
module Components
|
38
|
-
def self.included(base) #:nodoc:
|
39
|
-
base.class_eval do
|
40
|
-
include InstanceMethods
|
41
|
-
include ActiveSupport::Deprecation
|
42
|
-
extend ClassMethods
|
43
|
-
helper HelperMethods
|
44
|
-
|
45
|
-
# If this controller was instantiated to process a component request,
|
46
|
-
# +parent_controller+ points to the instantiator of this controller.
|
47
|
-
attr_accessor :parent_controller
|
48
|
-
|
49
|
-
alias_method_chain :process_cleanup, :components
|
50
|
-
alias_method_chain :set_session_options, :components
|
51
|
-
alias_method_chain :flash, :components
|
52
|
-
|
53
|
-
alias_method :component_request?, :parent_controller
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
module ClassMethods
|
58
|
-
# Track parent controller to identify component requests
|
59
|
-
def process_with_components(request, response, parent_controller = nil) #:nodoc:
|
60
|
-
controller = new
|
61
|
-
controller.parent_controller = parent_controller
|
62
|
-
controller.process(request, response)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
module HelperMethods
|
67
|
-
def render_component(options)
|
68
|
-
@controller.__send__(:render_component_as_string, options)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
module InstanceMethods
|
73
|
-
# Extracts the action_name from the request parameters and performs that action.
|
74
|
-
def process_with_components(request, response, method = :perform_action, *arguments) #:nodoc:
|
75
|
-
flash.discard if component_request?
|
76
|
-
process_without_components(request, response, method, *arguments)
|
77
|
-
end
|
78
|
-
|
79
|
-
protected
|
80
|
-
# Renders the component specified as the response for the current method
|
81
|
-
def render_component(options) #:doc:
|
82
|
-
component_logging(options) do
|
83
|
-
render_for_text(component_response(options, true).body, response.headers["Status"])
|
84
|
-
end
|
85
|
-
end
|
86
|
-
deprecate :render_component => "Please install render_component plugin from http://github.com/rails/render_component/tree/master"
|
87
|
-
|
88
|
-
# Returns the component response as a string
|
89
|
-
def render_component_as_string(options) #:doc:
|
90
|
-
component_logging(options) do
|
91
|
-
response = component_response(options, false)
|
92
|
-
|
93
|
-
if redirected = response.redirected_to
|
94
|
-
render_component_as_string(redirected)
|
95
|
-
else
|
96
|
-
response.body
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
deprecate :render_component_as_string => "Please install render_component plugin from http://github.com/rails/render_component/tree/master"
|
101
|
-
|
102
|
-
def flash_with_components(refresh = false) #:nodoc:
|
103
|
-
if !defined?(@_flash) || refresh
|
104
|
-
@_flash =
|
105
|
-
if defined?(@parent_controller)
|
106
|
-
@parent_controller.flash
|
107
|
-
else
|
108
|
-
flash_without_components
|
109
|
-
end
|
110
|
-
end
|
111
|
-
@_flash
|
112
|
-
end
|
113
|
-
|
114
|
-
private
|
115
|
-
def component_response(options, reuse_response)
|
116
|
-
klass = component_class(options)
|
117
|
-
request = request_for_component(klass.controller_name, options)
|
118
|
-
new_response = reuse_response ? response : response.dup
|
119
|
-
|
120
|
-
klass.process_with_components(request, new_response, self)
|
121
|
-
end
|
122
|
-
|
123
|
-
# determine the controller class for the component request
|
124
|
-
def component_class(options)
|
125
|
-
if controller = options[:controller]
|
126
|
-
controller.is_a?(Class) ? controller : "#{controller.camelize}Controller".constantize
|
127
|
-
else
|
128
|
-
self.class
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
# Create a new request object based on the current request.
|
133
|
-
# The new request inherits the session from the current request,
|
134
|
-
# bypassing any session options set for the component controller's class
|
135
|
-
def request_for_component(controller_name, options)
|
136
|
-
new_request = request.dup
|
137
|
-
new_request.session = request.session
|
138
|
-
|
139
|
-
new_request.instance_variable_set(
|
140
|
-
:@parameters,
|
141
|
-
(options[:params] || {}).with_indifferent_access.update(
|
142
|
-
"controller" => controller_name, "action" => options[:action], "id" => options[:id]
|
143
|
-
)
|
144
|
-
)
|
145
|
-
|
146
|
-
new_request
|
147
|
-
end
|
148
|
-
|
149
|
-
def component_logging(options)
|
150
|
-
if logger
|
151
|
-
logger.info "Start rendering component (#{options.inspect}): "
|
152
|
-
result = yield
|
153
|
-
logger.info "\n\nEnd of component rendering"
|
154
|
-
result
|
155
|
-
else
|
156
|
-
yield
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
|
-
def set_session_options_with_components(request)
|
161
|
-
set_session_options_without_components(request) unless component_request?
|
162
|
-
end
|
163
|
-
|
164
|
-
def process_cleanup_with_components
|
165
|
-
process_cleanup_without_components unless component_request?
|
166
|
-
end
|
167
|
-
end
|
168
|
-
end
|
169
|
-
end
|
@@ -1,297 +0,0 @@
|
|
1
|
-
require 'action_controller/cgi_ext'
|
2
|
-
require 'action_controller/session/cookie_store'
|
3
|
-
require 'action_controller/cgi_process'
|
4
|
-
|
5
|
-
module ActionController #:nodoc:
|
6
|
-
class RackRequest < AbstractRequest #:nodoc:
|
7
|
-
attr_accessor :session_options
|
8
|
-
attr_reader :cgi
|
9
|
-
|
10
|
-
class SessionFixationAttempt < StandardError #:nodoc:
|
11
|
-
end
|
12
|
-
|
13
|
-
DEFAULT_SESSION_OPTIONS = ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS
|
14
|
-
|
15
|
-
def initialize(env, session_options = DEFAULT_SESSION_OPTIONS)
|
16
|
-
@session_options = session_options
|
17
|
-
@env = env
|
18
|
-
@cgi = CGIWrapper.new(self)
|
19
|
-
super()
|
20
|
-
end
|
21
|
-
|
22
|
-
%w[ AUTH_TYPE GATEWAY_INTERFACE PATH_INFO
|
23
|
-
PATH_TRANSLATED REMOTE_HOST
|
24
|
-
REMOTE_IDENT REMOTE_USER SCRIPT_NAME
|
25
|
-
SERVER_NAME SERVER_PROTOCOL
|
26
|
-
|
27
|
-
HTTP_ACCEPT HTTP_ACCEPT_CHARSET HTTP_ACCEPT_ENCODING
|
28
|
-
HTTP_ACCEPT_LANGUAGE HTTP_CACHE_CONTROL HTTP_FROM
|
29
|
-
HTTP_NEGOTIATE HTTP_PRAGMA HTTP_REFERER HTTP_USER_AGENT ].each do |env|
|
30
|
-
define_method(env.sub(/^HTTP_/n, '').downcase) do
|
31
|
-
@env[env]
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def query_string
|
36
|
-
qs = super
|
37
|
-
if !qs.blank?
|
38
|
-
qs
|
39
|
-
else
|
40
|
-
@env['QUERY_STRING']
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def body_stream #:nodoc:
|
45
|
-
@env['rack.input']
|
46
|
-
end
|
47
|
-
|
48
|
-
def key?(key)
|
49
|
-
@env.key?(key)
|
50
|
-
end
|
51
|
-
|
52
|
-
def cookies
|
53
|
-
return {} unless @env["HTTP_COOKIE"]
|
54
|
-
|
55
|
-
unless @env["rack.request.cookie_string"] == @env["HTTP_COOKIE"]
|
56
|
-
@env["rack.request.cookie_string"] = @env["HTTP_COOKIE"]
|
57
|
-
@env["rack.request.cookie_hash"] = CGI::Cookie::parse(@env["rack.request.cookie_string"])
|
58
|
-
end
|
59
|
-
|
60
|
-
@env["rack.request.cookie_hash"]
|
61
|
-
end
|
62
|
-
|
63
|
-
def server_port
|
64
|
-
@env['SERVER_PORT'].to_i
|
65
|
-
end
|
66
|
-
|
67
|
-
def server_software
|
68
|
-
@env['SERVER_SOFTWARE'].split("/").first
|
69
|
-
end
|
70
|
-
|
71
|
-
def session
|
72
|
-
unless defined?(@session)
|
73
|
-
if @session_options == false
|
74
|
-
@session = Hash.new
|
75
|
-
else
|
76
|
-
stale_session_check! do
|
77
|
-
if cookie_only? && query_parameters[session_options_with_string_keys['session_key']]
|
78
|
-
raise SessionFixationAttempt
|
79
|
-
end
|
80
|
-
case value = session_options_with_string_keys['new_session']
|
81
|
-
when true
|
82
|
-
@session = new_session
|
83
|
-
when false
|
84
|
-
begin
|
85
|
-
@session = CGI::Session.new(@cgi, session_options_with_string_keys)
|
86
|
-
# CGI::Session raises ArgumentError if 'new_session' == false
|
87
|
-
# and no session cookie or query param is present.
|
88
|
-
rescue ArgumentError
|
89
|
-
@session = Hash.new
|
90
|
-
end
|
91
|
-
when nil
|
92
|
-
@session = CGI::Session.new(@cgi, session_options_with_string_keys)
|
93
|
-
else
|
94
|
-
raise ArgumentError, "Invalid new_session option: #{value}"
|
95
|
-
end
|
96
|
-
@session['__valid_session']
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
@session
|
101
|
-
end
|
102
|
-
|
103
|
-
def reset_session
|
104
|
-
@session.delete if defined?(@session) && @session.is_a?(CGI::Session)
|
105
|
-
@session = new_session
|
106
|
-
end
|
107
|
-
|
108
|
-
private
|
109
|
-
# Delete an old session if it exists then create a new one.
|
110
|
-
def new_session
|
111
|
-
if @session_options == false
|
112
|
-
Hash.new
|
113
|
-
else
|
114
|
-
CGI::Session.new(@cgi, session_options_with_string_keys.merge("new_session" => false)).delete rescue nil
|
115
|
-
CGI::Session.new(@cgi, session_options_with_string_keys.merge("new_session" => true))
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
def cookie_only?
|
120
|
-
session_options_with_string_keys['cookie_only']
|
121
|
-
end
|
122
|
-
|
123
|
-
def stale_session_check!
|
124
|
-
yield
|
125
|
-
rescue ArgumentError => argument_error
|
126
|
-
if argument_error.message =~ %r{undefined class/module ([\w:]*\w)}
|
127
|
-
begin
|
128
|
-
# Note that the regexp does not allow $1 to end with a ':'
|
129
|
-
$1.constantize
|
130
|
-
rescue LoadError, NameError => const_error
|
131
|
-
raise ActionController::SessionRestoreError, <<-end_msg
|
132
|
-
Session contains objects whose class definition isn\'t available.
|
133
|
-
Remember to require the classes for all objects kept in the session.
|
134
|
-
(Original exception: #{const_error.message} [#{const_error.class}])
|
135
|
-
end_msg
|
136
|
-
end
|
137
|
-
|
138
|
-
retry
|
139
|
-
else
|
140
|
-
raise
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
def session_options_with_string_keys
|
145
|
-
@session_options_with_string_keys ||= DEFAULT_SESSION_OPTIONS.merge(@session_options).stringify_keys
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
class RackResponse < AbstractResponse #:nodoc:
|
150
|
-
def initialize(request)
|
151
|
-
@cgi = request.cgi
|
152
|
-
@writer = lambda { |x| @body << x }
|
153
|
-
@block = nil
|
154
|
-
super()
|
155
|
-
end
|
156
|
-
|
157
|
-
# Retrieve status from instance variable if has already been delete
|
158
|
-
def status
|
159
|
-
@status || super
|
160
|
-
end
|
161
|
-
|
162
|
-
def out(output = $stdout, &block)
|
163
|
-
# Nasty hack because CGI sessions are closed after the normal
|
164
|
-
# prepare! statement
|
165
|
-
set_cookies!
|
166
|
-
|
167
|
-
@block = block
|
168
|
-
@status = headers.delete("Status")
|
169
|
-
if [204, 304].include?(status.to_i)
|
170
|
-
headers.delete("Content-Type")
|
171
|
-
[status, headers.to_hash, []]
|
172
|
-
else
|
173
|
-
[status, headers.to_hash, self]
|
174
|
-
end
|
175
|
-
end
|
176
|
-
alias to_a out
|
177
|
-
|
178
|
-
def each(&callback)
|
179
|
-
if @body.respond_to?(:call)
|
180
|
-
@writer = lambda { |x| callback.call(x) }
|
181
|
-
@body.call(self, self)
|
182
|
-
elsif @body.is_a?(String)
|
183
|
-
@body.each_line(&callback)
|
184
|
-
else
|
185
|
-
@body.each(&callback)
|
186
|
-
end
|
187
|
-
|
188
|
-
@writer = callback
|
189
|
-
@block.call(self) if @block
|
190
|
-
end
|
191
|
-
|
192
|
-
def write(str)
|
193
|
-
@writer.call str.to_s
|
194
|
-
str
|
195
|
-
end
|
196
|
-
|
197
|
-
def close
|
198
|
-
@body.close if @body.respond_to?(:close)
|
199
|
-
end
|
200
|
-
|
201
|
-
def empty?
|
202
|
-
@block == nil && @body.empty?
|
203
|
-
end
|
204
|
-
|
205
|
-
def prepare!
|
206
|
-
super
|
207
|
-
|
208
|
-
convert_language!
|
209
|
-
convert_expires!
|
210
|
-
set_status!
|
211
|
-
# set_cookies!
|
212
|
-
end
|
213
|
-
|
214
|
-
private
|
215
|
-
def convert_language!
|
216
|
-
headers["Content-Language"] = headers.delete("language") if headers["language"]
|
217
|
-
end
|
218
|
-
|
219
|
-
def convert_expires!
|
220
|
-
headers["Expires"] = headers.delete("") if headers["expires"]
|
221
|
-
end
|
222
|
-
|
223
|
-
def convert_content_type!
|
224
|
-
super
|
225
|
-
headers['Content-Type'] = headers.delete('type') || "text/html"
|
226
|
-
headers['Content-Type'] += "; charset=" + headers.delete('charset') if headers['charset']
|
227
|
-
end
|
228
|
-
|
229
|
-
def set_content_length!
|
230
|
-
super
|
231
|
-
headers["Content-Length"] = headers["Content-Length"].to_s if headers["Content-Length"]
|
232
|
-
end
|
233
|
-
|
234
|
-
def set_status!
|
235
|
-
self.status ||= "200 OK"
|
236
|
-
end
|
237
|
-
|
238
|
-
def set_cookies!
|
239
|
-
# Convert 'cookie' header to 'Set-Cookie' headers.
|
240
|
-
# Because Set-Cookie header can appear more the once in the response body,
|
241
|
-
# we store it in a line break separated string that will be translated to
|
242
|
-
# multiple Set-Cookie header by the handler.
|
243
|
-
if cookie = headers.delete('cookie')
|
244
|
-
cookies = []
|
245
|
-
|
246
|
-
case cookie
|
247
|
-
when Array then cookie.each { |c| cookies << c.to_s }
|
248
|
-
when Hash then cookie.each { |_, c| cookies << c.to_s }
|
249
|
-
else cookies << cookie.to_s
|
250
|
-
end
|
251
|
-
|
252
|
-
@cgi.output_cookies.each { |c| cookies << c.to_s } if @cgi.output_cookies
|
253
|
-
|
254
|
-
headers['Set-Cookie'] = [headers['Set-Cookie'], cookies].flatten.compact
|
255
|
-
end
|
256
|
-
end
|
257
|
-
end
|
258
|
-
|
259
|
-
class CGIWrapper < ::CGI
|
260
|
-
attr_reader :output_cookies
|
261
|
-
|
262
|
-
def initialize(request, *args)
|
263
|
-
@request = request
|
264
|
-
@args = *args
|
265
|
-
@input = request.body
|
266
|
-
|
267
|
-
super *args
|
268
|
-
end
|
269
|
-
|
270
|
-
def params
|
271
|
-
@params ||= @request.params
|
272
|
-
end
|
273
|
-
|
274
|
-
def cookies
|
275
|
-
@request.cookies
|
276
|
-
end
|
277
|
-
|
278
|
-
def query_string
|
279
|
-
@request.query_string
|
280
|
-
end
|
281
|
-
|
282
|
-
# Used to wrap the normal args variable used inside CGI.
|
283
|
-
def args
|
284
|
-
@args
|
285
|
-
end
|
286
|
-
|
287
|
-
# Used to wrap the normal env_table variable used inside CGI.
|
288
|
-
def env_table
|
289
|
-
@request.env
|
290
|
-
end
|
291
|
-
|
292
|
-
# Used to wrap the normal stdinput variable used inside CGI.
|
293
|
-
def stdinput
|
294
|
-
@input
|
295
|
-
end
|
296
|
-
end
|
297
|
-
end
|