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.

Files changed (264) hide show
  1. data/CHANGELOG +433 -375
  2. data/MIT-LICENSE +1 -1
  3. data/README +21 -75
  4. data/Rakefile +1 -1
  5. data/lib/action_controller.rb +80 -43
  6. data/lib/action_controller/assertions/model_assertions.rb +1 -0
  7. data/lib/action_controller/assertions/response_assertions.rb +43 -16
  8. data/lib/action_controller/assertions/routing_assertions.rb +1 -1
  9. data/lib/action_controller/assertions/selector_assertions.rb +17 -12
  10. data/lib/action_controller/assertions/tag_assertions.rb +1 -4
  11. data/lib/action_controller/base.rb +153 -82
  12. data/lib/action_controller/benchmarking.rb +9 -9
  13. data/lib/action_controller/caching.rb +9 -11
  14. data/lib/action_controller/caching/actions.rb +11 -18
  15. data/lib/action_controller/caching/fragments.rb +28 -20
  16. data/lib/action_controller/caching/pages.rb +13 -15
  17. data/lib/action_controller/caching/sweeping.rb +2 -2
  18. data/lib/action_controller/cgi_ext.rb +0 -1
  19. data/lib/action_controller/cgi_ext/cookie.rb +2 -0
  20. data/lib/action_controller/cgi_process.rb +54 -162
  21. data/lib/action_controller/cookies.rb +13 -25
  22. data/lib/action_controller/dispatcher.rb +43 -122
  23. data/lib/action_controller/failsafe.rb +52 -0
  24. data/lib/action_controller/flash.rb +38 -47
  25. data/lib/action_controller/helpers.rb +13 -9
  26. data/lib/action_controller/http_authentication.rb +203 -23
  27. data/lib/action_controller/integration.rb +126 -70
  28. data/lib/action_controller/layout.rb +36 -39
  29. data/lib/action_controller/middleware_stack.rb +119 -0
  30. data/lib/action_controller/middlewares.rb +13 -0
  31. data/lib/action_controller/mime_responds.rb +19 -4
  32. data/lib/action_controller/mime_type.rb +8 -0
  33. data/lib/action_controller/params_parser.rb +71 -0
  34. data/lib/action_controller/performance_test.rb +0 -1
  35. data/lib/action_controller/polymorphic_routes.rb +36 -30
  36. data/lib/action_controller/reloader.rb +14 -0
  37. data/lib/action_controller/request.rb +107 -499
  38. data/lib/action_controller/request_forgery_protection.rb +7 -39
  39. data/lib/action_controller/rescue.rb +55 -35
  40. data/lib/action_controller/resources.rb +34 -31
  41. data/lib/action_controller/response.rb +99 -57
  42. data/lib/action_controller/rewindable_input.rb +28 -0
  43. data/lib/action_controller/routing.rb +7 -7
  44. data/lib/action_controller/routing/builder.rb +4 -1
  45. data/lib/action_controller/routing/optimisations.rb +1 -1
  46. data/lib/action_controller/routing/recognition_optimisation.rb +1 -2
  47. data/lib/action_controller/routing/route.rb +15 -5
  48. data/lib/action_controller/routing/route_set.rb +82 -35
  49. data/lib/action_controller/routing/segments.rb +35 -0
  50. data/lib/action_controller/session/abstract_store.rb +181 -0
  51. data/lib/action_controller/session/cookie_store.rb +197 -175
  52. data/lib/action_controller/session/mem_cache_store.rb +36 -83
  53. data/lib/action_controller/session_management.rb +26 -134
  54. data/lib/action_controller/streaming.rb +24 -7
  55. data/lib/action_controller/templates/rescues/diagnostics.erb +2 -2
  56. data/lib/action_controller/templates/rescues/template_error.erb +2 -2
  57. data/lib/action_controller/test_case.rb +87 -30
  58. data/lib/action_controller/test_process.rb +145 -104
  59. data/lib/action_controller/uploaded_file.rb +44 -0
  60. data/lib/action_controller/url_rewriter.rb +3 -6
  61. data/lib/action_controller/vendor/html-scanner.rb +16 -0
  62. data/lib/action_controller/vendor/html-scanner/html/selector.rb +1 -1
  63. data/lib/action_controller/vendor/rack-1.0/rack.rb +89 -0
  64. data/lib/action_controller/vendor/rack-1.0/rack/adapter/camping.rb +22 -0
  65. data/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/handler.rb +37 -0
  66. data/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/request.rb +37 -0
  67. data/lib/action_controller/vendor/rack-1.0/rack/auth/basic.rb +58 -0
  68. data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/md5.rb +124 -0
  69. data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/nonce.rb +51 -0
  70. data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/params.rb +55 -0
  71. data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/request.rb +40 -0
  72. data/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb +480 -0
  73. data/lib/action_controller/vendor/rack-1.0/rack/builder.rb +63 -0
  74. data/lib/action_controller/vendor/rack-1.0/rack/cascade.rb +36 -0
  75. data/lib/action_controller/vendor/rack-1.0/rack/chunked.rb +49 -0
  76. data/lib/action_controller/vendor/rack-1.0/rack/commonlogger.rb +61 -0
  77. data/lib/action_controller/vendor/rack-1.0/rack/conditionalget.rb +45 -0
  78. data/lib/action_controller/vendor/rack-1.0/rack/content_length.rb +29 -0
  79. data/lib/action_controller/vendor/rack-1.0/rack/content_type.rb +23 -0
  80. data/lib/action_controller/vendor/rack-1.0/rack/deflater.rb +85 -0
  81. data/lib/action_controller/vendor/rack-1.0/rack/directory.rb +153 -0
  82. data/lib/action_controller/vendor/rack-1.0/rack/file.rb +88 -0
  83. data/lib/action_controller/vendor/rack-1.0/rack/handler.rb +48 -0
  84. data/lib/action_controller/vendor/rack-1.0/rack/handler/cgi.rb +61 -0
  85. data/lib/action_controller/vendor/rack-1.0/rack/handler/evented_mongrel.rb +8 -0
  86. data/lib/action_controller/vendor/rack-1.0/rack/handler/fastcgi.rb +89 -0
  87. data/lib/action_controller/vendor/rack-1.0/rack/handler/lsws.rb +55 -0
  88. data/lib/action_controller/vendor/rack-1.0/rack/handler/mongrel.rb +84 -0
  89. data/lib/action_controller/vendor/rack-1.0/rack/handler/scgi.rb +59 -0
  90. data/lib/action_controller/vendor/rack-1.0/rack/handler/swiftiplied_mongrel.rb +8 -0
  91. data/lib/action_controller/vendor/rack-1.0/rack/handler/thin.rb +18 -0
  92. data/lib/action_controller/vendor/rack-1.0/rack/handler/webrick.rb +67 -0
  93. data/lib/action_controller/vendor/rack-1.0/rack/head.rb +19 -0
  94. data/lib/action_controller/vendor/rack-1.0/rack/lint.rb +462 -0
  95. data/lib/action_controller/vendor/rack-1.0/rack/lobster.rb +65 -0
  96. data/lib/action_controller/vendor/rack-1.0/rack/lock.rb +16 -0
  97. data/lib/action_controller/vendor/rack-1.0/rack/methodoverride.rb +27 -0
  98. data/lib/action_controller/vendor/rack-1.0/rack/mime.rb +204 -0
  99. data/lib/action_controller/vendor/rack-1.0/rack/mock.rb +160 -0
  100. data/lib/action_controller/vendor/rack-1.0/rack/recursive.rb +57 -0
  101. data/lib/action_controller/vendor/rack-1.0/rack/reloader.rb +64 -0
  102. data/lib/action_controller/vendor/rack-1.0/rack/request.rb +241 -0
  103. data/lib/action_controller/vendor/rack-1.0/rack/response.rb +179 -0
  104. data/lib/action_controller/vendor/rack-1.0/rack/session/abstract/id.rb +142 -0
  105. data/lib/action_controller/vendor/rack-1.0/rack/session/cookie.rb +91 -0
  106. data/lib/action_controller/vendor/rack-1.0/rack/session/memcache.rb +109 -0
  107. data/lib/action_controller/vendor/rack-1.0/rack/session/pool.rb +100 -0
  108. data/lib/action_controller/vendor/rack-1.0/rack/showexceptions.rb +349 -0
  109. data/lib/action_controller/vendor/rack-1.0/rack/showstatus.rb +106 -0
  110. data/lib/action_controller/vendor/rack-1.0/rack/static.rb +38 -0
  111. data/lib/action_controller/vendor/rack-1.0/rack/urlmap.rb +55 -0
  112. data/lib/action_controller/vendor/rack-1.0/rack/utils.rb +392 -0
  113. data/lib/action_controller/verification.rb +1 -1
  114. data/lib/action_pack.rb +1 -1
  115. data/lib/action_pack/version.rb +2 -2
  116. data/lib/action_view.rb +22 -17
  117. data/lib/action_view/base.rb +53 -79
  118. data/lib/action_view/erb/util.rb +38 -0
  119. data/lib/action_view/helpers.rb +24 -5
  120. data/lib/action_view/helpers/active_record_helper.rb +2 -2
  121. data/lib/action_view/helpers/asset_tag_helper.rb +81 -50
  122. data/lib/action_view/helpers/atom_feed_helper.rb +1 -1
  123. data/lib/action_view/helpers/benchmark_helper.rb +26 -5
  124. data/lib/action_view/helpers/date_helper.rb +82 -7
  125. data/lib/action_view/helpers/form_helper.rb +295 -64
  126. data/lib/action_view/helpers/form_options_helper.rb +160 -18
  127. data/lib/action_view/helpers/form_tag_helper.rb +2 -2
  128. data/lib/action_view/helpers/number_helper.rb +31 -18
  129. data/lib/action_view/helpers/prototype_helper.rb +2 -12
  130. data/lib/action_view/helpers/sanitize_helper.rb +0 -10
  131. data/lib/action_view/helpers/scriptaculous_helper.rb +1 -0
  132. data/lib/action_view/helpers/tag_helper.rb +3 -4
  133. data/lib/action_view/helpers/text_helper.rb +99 -122
  134. data/lib/action_view/helpers/translation_helper.rb +19 -1
  135. data/lib/action_view/helpers/url_helper.rb +25 -2
  136. data/lib/action_view/inline_template.rb +1 -1
  137. data/lib/action_view/locale/en.yml +19 -1
  138. data/lib/action_view/partials.rb +46 -9
  139. data/lib/action_view/paths.rb +28 -84
  140. data/lib/action_view/reloadable_template.rb +117 -0
  141. data/lib/action_view/renderable.rb +28 -35
  142. data/lib/action_view/renderable_partial.rb +3 -4
  143. data/lib/action_view/template.rb +172 -31
  144. data/lib/action_view/template_error.rb +8 -9
  145. data/lib/action_view/template_handler.rb +1 -1
  146. data/lib/action_view/template_handlers.rb +9 -6
  147. data/lib/action_view/template_handlers/erb.rb +2 -39
  148. data/lib/action_view/template_handlers/rjs.rb +1 -0
  149. data/lib/action_view/test_case.rb +27 -1
  150. data/test/abstract_unit.rb +23 -17
  151. data/test/active_record_unit.rb +5 -4
  152. data/test/activerecord/active_record_store_test.rb +139 -106
  153. data/test/activerecord/render_partial_with_record_identification_test.rb +5 -21
  154. data/test/controller/action_pack_assertions_test.rb +25 -23
  155. data/test/controller/addresses_render_test.rb +3 -6
  156. data/test/controller/assert_select_test.rb +83 -70
  157. data/test/controller/base_test.rb +11 -13
  158. data/test/controller/benchmark_test.rb +3 -3
  159. data/test/controller/caching_test.rb +34 -24
  160. data/test/controller/capture_test.rb +3 -6
  161. data/test/controller/content_type_test.rb +3 -6
  162. data/test/controller/cookie_test.rb +31 -66
  163. data/test/controller/deprecation/deprecated_base_methods_test.rb +9 -11
  164. data/test/controller/dispatcher_test.rb +23 -28
  165. data/test/controller/fake_models.rb +8 -0
  166. data/test/controller/filters_test.rb +6 -2
  167. data/test/controller/flash_test.rb +2 -6
  168. data/test/controller/helper_test.rb +15 -1
  169. data/test/controller/html-scanner/document_test.rb +1 -1
  170. data/test/controller/html-scanner/sanitizer_test.rb +1 -1
  171. data/test/controller/http_basic_authentication_test.rb +88 -0
  172. data/test/controller/http_digest_authentication_test.rb +178 -0
  173. data/test/controller/integration_test.rb +56 -52
  174. data/test/controller/layout_test.rb +46 -44
  175. data/test/controller/middleware_stack_test.rb +90 -0
  176. data/test/controller/mime_responds_test.rb +7 -11
  177. data/test/controller/mime_type_test.rb +9 -0
  178. data/test/controller/polymorphic_routes_test.rb +235 -151
  179. data/test/controller/rack_test.rb +52 -81
  180. data/test/controller/redirect_test.rb +6 -14
  181. data/test/controller/render_test.rb +273 -60
  182. data/test/controller/request/json_params_parsing_test.rb +45 -0
  183. data/test/controller/request/multipart_params_parsing_test.rb +223 -0
  184. data/test/controller/request/query_string_parsing_test.rb +120 -0
  185. data/test/controller/request/url_encoded_params_parsing_test.rb +184 -0
  186. data/test/controller/request/xml_params_parsing_test.rb +88 -0
  187. data/test/controller/request_forgery_protection_test.rb +17 -98
  188. data/test/controller/request_test.rb +45 -530
  189. data/test/controller/rescue_test.rb +45 -22
  190. data/test/controller/resources_test.rb +112 -37
  191. data/test/controller/routing_test.rb +1442 -1384
  192. data/test/controller/selector_test.rb +3 -3
  193. data/test/controller/send_file_test.rb +30 -3
  194. data/test/controller/session/cookie_store_test.rb +169 -240
  195. data/test/controller/session/mem_cache_store_test.rb +94 -148
  196. data/test/controller/session/test_session_test.rb +58 -0
  197. data/test/controller/test_test.rb +32 -13
  198. data/test/controller/url_rewriter_test.rb +54 -4
  199. data/test/controller/verification_test.rb +1 -1
  200. data/test/controller/view_paths_test.rb +15 -15
  201. data/test/controller/webservice_test.rb +178 -147
  202. data/test/fixtures/alternate_helpers/foo_helper.rb +3 -0
  203. data/test/fixtures/layout_tests/alt/layouts/alt.rhtml +0 -0
  204. data/test/fixtures/layouts/default_html.html.erb +1 -0
  205. data/test/fixtures/layouts/xhr.html.erb +2 -0
  206. data/test/fixtures/multipart/empty +10 -0
  207. data/test/fixtures/multipart/hello.txt +1 -0
  208. data/test/fixtures/multipart/none +9 -0
  209. data/test/fixtures/public/500.da.html +1 -0
  210. data/test/fixtures/quiz/questions/_question.html.erb +1 -0
  211. data/test/fixtures/replies.yml +1 -1
  212. data/test/fixtures/test/_one.html.erb +1 -0
  213. data/test/fixtures/test/_two.html.erb +1 -0
  214. data/test/fixtures/test/dont_pick_me +1 -0
  215. data/test/fixtures/test/hello.builder +1 -1
  216. data/test/fixtures/test/hello_world.da.html.erb +1 -0
  217. data/test/fixtures/test/hello_world.erb~ +1 -0
  218. data/test/fixtures/test/hello_world.pt-BR.html.erb +1 -0
  219. data/test/fixtures/test/malformed/malformed.en.html.erb~ +1 -0
  220. data/test/fixtures/test/malformed/malformed.erb~ +1 -0
  221. data/test/fixtures/test/malformed/malformed.html.erb~ +1 -0
  222. data/test/fixtures/test/render_explicit_html_template.js.rjs +1 -0
  223. data/test/fixtures/test/render_implicit_html_template.js.rjs +1 -0
  224. data/test/fixtures/test/render_implicit_html_template_from_xhr_request.da.html.erb +1 -0
  225. data/test/fixtures/test/render_implicit_html_template_from_xhr_request.html.erb +1 -0
  226. data/test/fixtures/test/render_implicit_js_template_without_layout.js.erb +1 -0
  227. data/test/fixtures/test/utf8.html.erb +2 -0
  228. data/test/template/active_record_helper_i18n_test.rb +31 -33
  229. data/test/template/active_record_helper_test.rb +34 -0
  230. data/test/template/asset_tag_helper_test.rb +52 -14
  231. data/test/template/atom_feed_helper_test.rb +3 -5
  232. data/test/template/benchmark_helper_test.rb +50 -24
  233. data/test/template/compiled_templates_test.rb +177 -33
  234. data/test/template/date_helper_i18n_test.rb +88 -81
  235. data/test/template/date_helper_test.rb +427 -43
  236. data/test/template/form_helper_test.rb +243 -44
  237. data/test/template/form_options_helper_test.rb +631 -565
  238. data/test/template/form_tag_helper_test.rb +9 -2
  239. data/test/template/javascript_helper_test.rb +0 -5
  240. data/test/template/number_helper_i18n_test.rb +60 -48
  241. data/test/template/number_helper_test.rb +1 -0
  242. data/test/template/render_test.rb +117 -35
  243. data/test/template/test_test.rb +4 -6
  244. data/test/template/text_helper_test.rb +129 -50
  245. data/test/template/translation_helper_test.rb +23 -19
  246. data/test/template/url_helper_test.rb +35 -2
  247. data/test/view/test_case_test.rb +8 -0
  248. metadata +197 -23
  249. data/lib/action_controller/assertions.rb +0 -69
  250. data/lib/action_controller/caching/sql_cache.rb +0 -18
  251. data/lib/action_controller/cgi_ext/session.rb +0 -53
  252. data/lib/action_controller/components.rb +0 -169
  253. data/lib/action_controller/rack_process.rb +0 -297
  254. data/lib/action_controller/request_profiler.rb +0 -169
  255. data/lib/action_controller/session/active_record_store.rb +0 -340
  256. data/lib/action_controller/session/drb_server.rb +0 -32
  257. data/lib/action_controller/session/drb_store.rb +0 -35
  258. data/test/controller/cgi_test.rb +0 -269
  259. data/test/controller/components_test.rb +0 -156
  260. data/test/controller/http_authentication_test.rb +0 -54
  261. data/test/controller/integration_upload_test.rb +0 -43
  262. data/test/controller/session_fixation_test.rb +0 -89
  263. data/test/controller/session_management_test.rb +0 -178
  264. 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