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
@@ -172,16 +172,8 @@ module ActionController #:nodoc:
172
172
  @layout_conditions ||= read_inheritable_attribute(:layout_conditions)
173
173
  end
174
174
 
175
- def default_layout(format) #:nodoc:
176
- layout = read_inheritable_attribute(:layout)
177
- return layout unless read_inheritable_attribute(:auto_layout)
178
- @default_layout ||= {}
179
- @default_layout[format] ||= default_layout_with_format(format, layout)
180
- @default_layout[format]
181
- end
182
-
183
175
  def layout_list #:nodoc:
184
- Array(view_paths).sum([]) { |path| Dir["#{path}/layouts/**/*"] }
176
+ Array(view_paths).sum([]) { |path| Dir["#{path.to_str}/layouts/**/*"] }
185
177
  end
186
178
 
187
179
  private
@@ -200,45 +192,38 @@ module ActionController #:nodoc:
200
192
  def normalize_conditions(conditions)
201
193
  conditions.inject({}) {|hash, (key, value)| hash.merge(key => [value].flatten.map {|action| action.to_s})}
202
194
  end
203
-
204
- def default_layout_with_format(format, layout)
205
- list = layout_list
206
- if list.grep(%r{layouts/#{layout}\.#{format}(\.[a-z][0-9a-z]*)+$}).empty?
207
- (!list.grep(%r{layouts/#{layout}\.([a-z][0-9a-z]*)+$}).empty? && format == :html) ? layout : nil
208
- else
209
- layout
210
- end
211
- end
212
195
  end
213
196
 
214
197
  # Returns the name of the active layout. If the layout was specified as a method reference (through a symbol), this method
215
198
  # is called and the return value is used. Likewise if the layout was specified as an inline method (through a proc or method
216
199
  # object). If the layout was defined without a directory, layouts is assumed. So <tt>layout "weblog/standard"</tt> will return
217
200
  # weblog/standard, but <tt>layout "standard"</tt> will return layouts/standard.
218
- def active_layout(passed_layout = nil)
219
- layout = passed_layout || self.class.default_layout(default_template_format)
201
+ def active_layout(passed_layout = nil, options = {})
202
+ layout = passed_layout || default_layout
203
+ return layout if layout.respond_to?(:render)
204
+
220
205
  active_layout = case layout
221
- when String then layout
222
206
  when Symbol then __send__(layout)
223
207
  when Proc then layout.call(self)
208
+ else layout
224
209
  end
225
210
 
226
- # Explicitly passed layout names with slashes are looked up relative to the template root,
227
- # but auto-discovered layouts derived from a nested controller will contain a slash, though be relative
228
- # to the 'layouts' directory so we have to check the file system to infer which case the layout name came from.
229
- if active_layout
230
- if active_layout.include?('/') && ! layout_directory?(active_layout)
231
- active_layout
232
- else
233
- "layouts/#{active_layout}"
234
- end
235
- end
211
+ find_layout(active_layout, default_template_format, options[:html_fallback]) if active_layout
236
212
  end
237
213
 
238
214
  private
239
- def candidate_for_layout?(options)
240
- options.values_at(:text, :xml, :json, :file, :inline, :partial, :nothing, :update).compact.empty? &&
241
- !@template.__send__(:_exempt_from_layout?, options[:template] || default_template_name(options[:action]))
215
+ def default_layout #:nodoc:
216
+ layout = self.class.read_inheritable_attribute(:layout)
217
+ return layout unless self.class.read_inheritable_attribute(:auto_layout)
218
+ find_layout(layout, default_template_format)
219
+ rescue ActionView::MissingTemplate
220
+ nil
221
+ end
222
+
223
+ def find_layout(layout, format, html_fallback=false) #:nodoc:
224
+ view_paths.find_template(layout.to_s =~ /layouts\// ? layout : "layouts/#{layout}", format, html_fallback)
225
+ rescue ActionView::MissingTemplate
226
+ raise if Mime::Type.lookup_by_extension(format.to_s).html?
242
227
  end
243
228
 
244
229
  def pick_layout(options)
@@ -247,9 +232,9 @@ module ActionController #:nodoc:
247
232
  when FalseClass
248
233
  nil
249
234
  when NilClass, TrueClass
250
- active_layout if action_has_layout? && !@template.__send__(:_exempt_from_layout?, default_template_name)
235
+ active_layout if action_has_layout? && candidate_for_layout?(:template => default_template_name)
251
236
  else
252
- active_layout(layout)
237
+ active_layout(layout, :html_fallback => true)
253
238
  end
254
239
  else
255
240
  active_layout if action_has_layout? && candidate_for_layout?(options)
@@ -271,14 +256,26 @@ module ActionController #:nodoc:
271
256
  end
272
257
  end
273
258
 
274
- def layout_directory?(layout_name)
275
- @template.__send__(:_pick_template, "#{File.join('layouts', layout_name)}.#{@template.template_format}") ? true : false
259
+ def candidate_for_layout?(options)
260
+ template = options[:template] || default_template(options[:action])
261
+ if options.values_at(:text, :xml, :json, :file, :inline, :partial, :nothing, :update).compact.empty?
262
+ begin
263
+ template_object = self.view_paths.find_template(template, default_template_format)
264
+ # this restores the behavior from 2.2.2, where response.template.template_format was reset
265
+ # to :html for :js requests with a matching html template.
266
+ # see v2.2.2, ActionView::Base, lines 328-330
267
+ @real_format = :html if response.template.template_format == :js && template_object.format == "html"
268
+ !template_object.exempt_from_layout?
269
+ rescue ActionView::MissingTemplate
270
+ true
271
+ end
272
+ end
276
273
  rescue ActionView::MissingTemplate
277
274
  false
278
275
  end
279
276
 
280
277
  def default_template_format
281
- response.template.template_format
278
+ @real_format || response.template.template_format
282
279
  end
283
280
  end
284
281
  end
@@ -0,0 +1,119 @@
1
+ module ActionController
2
+ class MiddlewareStack < Array
3
+ class Middleware
4
+ def self.new(klass, *args, &block)
5
+ if klass.is_a?(self)
6
+ klass
7
+ else
8
+ super
9
+ end
10
+ end
11
+
12
+ attr_reader :args, :block
13
+
14
+ def initialize(klass, *args, &block)
15
+ @klass = klass
16
+
17
+ options = args.extract_options!
18
+ if options.has_key?(:if)
19
+ @conditional = options.delete(:if)
20
+ else
21
+ @conditional = true
22
+ end
23
+ args << options unless options.empty?
24
+
25
+ @args = args
26
+ @block = block
27
+ end
28
+
29
+ def klass
30
+ if @klass.respond_to?(:call)
31
+ @klass.call
32
+ elsif @klass.is_a?(Class)
33
+ @klass
34
+ else
35
+ @klass.to_s.constantize
36
+ end
37
+ rescue NameError
38
+ @klass
39
+ end
40
+
41
+ def active?
42
+ return false unless klass
43
+
44
+ if @conditional.respond_to?(:call)
45
+ @conditional.call
46
+ else
47
+ @conditional
48
+ end
49
+ end
50
+
51
+ def ==(middleware)
52
+ case middleware
53
+ when Middleware
54
+ klass == middleware.klass
55
+ when Class
56
+ klass == middleware
57
+ else
58
+ klass == middleware.to_s.constantize
59
+ end
60
+ end
61
+
62
+ def inspect
63
+ str = klass.to_s
64
+ args.each { |arg| str += ", #{arg.inspect}" }
65
+ str
66
+ end
67
+
68
+ def build(app)
69
+ if block
70
+ klass.new(app, *build_args, &block)
71
+ else
72
+ klass.new(app, *build_args)
73
+ end
74
+ end
75
+
76
+ private
77
+
78
+ def build_args
79
+ Array(args).map { |arg| arg.respond_to?(:call) ? arg.call : arg }
80
+ end
81
+ end
82
+
83
+ def initialize(*args, &block)
84
+ super(*args)
85
+ block.call(self) if block_given?
86
+ end
87
+
88
+ def insert(index, *args, &block)
89
+ index = self.index(index) unless index.is_a?(Integer)
90
+ middleware = Middleware.new(*args, &block)
91
+ super(index, middleware)
92
+ end
93
+
94
+ alias_method :insert_before, :insert
95
+
96
+ def insert_after(index, *args, &block)
97
+ index = self.index(index) unless index.is_a?(Integer)
98
+ insert(index + 1, *args, &block)
99
+ end
100
+
101
+ def swap(target, *args, &block)
102
+ insert_before(target, *args, &block)
103
+ delete(target)
104
+ end
105
+
106
+ def use(*args, &block)
107
+ middleware = Middleware.new(*args, &block)
108
+ push(middleware)
109
+ end
110
+
111
+ def active
112
+ find_all { |middleware| middleware.active? }
113
+ end
114
+
115
+ def build(app)
116
+ active.reverse.inject(app) { |a, e| e.build(a) }
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,13 @@
1
+ use "Rack::Lock", :if => lambda {
2
+ !ActionController::Base.allow_concurrency
3
+ }
4
+
5
+ use "ActionController::Failsafe"
6
+
7
+ use lambda { ActionController::Base.session_store },
8
+ lambda { ActionController::Base.session_options }
9
+
10
+ use "ActionController::RewindableInput"
11
+ use "ActionController::ParamsParser"
12
+ use "Rack::MethodOverride"
13
+ use "Rack::Head"
@@ -143,12 +143,27 @@ module ActionController #:nodoc:
143
143
  custom(@mime_type_priority.first, &block)
144
144
  end
145
145
  end
146
+
147
+ def self.generate_method_for_mime(mime)
148
+ sym = mime.is_a?(Symbol) ? mime : mime.to_sym
149
+ const = sym.to_s.upcase
150
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
151
+ def #{sym}(&block) # def html(&block)
152
+ custom(Mime::#{const}, &block) # custom(Mime::HTML, &block)
153
+ end # end
154
+ RUBY
155
+ end
146
156
 
147
- def method_missing(symbol, &block)
148
- mime_constant = symbol.to_s.upcase
157
+ Mime::SET.each do |mime|
158
+ generate_method_for_mime(mime)
159
+ end
149
160
 
150
- if Mime::SET.include?(Mime.const_get(mime_constant))
151
- custom(Mime.const_get(mime_constant), &block)
161
+ def method_missing(symbol, &block)
162
+ mime_constant = Mime.const_get(symbol.to_s.upcase)
163
+
164
+ if Mime::SET.include?(mime_constant)
165
+ self.class.generate_method_for_mime(mime_constant)
166
+ send(symbol, &block)
152
167
  else
153
168
  super
154
169
  end
@@ -176,6 +176,14 @@ module Mime
176
176
  end
177
177
  end
178
178
 
179
+ def =~(mime_type)
180
+ return false if mime_type.blank?
181
+ regexp = Regexp.new(Regexp.quote(mime_type.to_s))
182
+ (@synonyms + [ self ]).any? do |synonym|
183
+ synonym.to_s =~ regexp
184
+ end
185
+ end
186
+
179
187
  # Returns true if Action Pack should check requests using this Mime Type for possible request forgery. See
180
188
  # ActionController::RequestForgeryProtection.
181
189
  def verify_request?
@@ -0,0 +1,71 @@
1
+ module ActionController
2
+ class ParamsParser
3
+ ActionController::Base.param_parsers[Mime::XML] = :xml_simple
4
+ ActionController::Base.param_parsers[Mime::JSON] = :json
5
+
6
+ def initialize(app)
7
+ @app = app
8
+ end
9
+
10
+ def call(env)
11
+ if params = parse_formatted_parameters(env)
12
+ env["action_controller.request.request_parameters"] = params
13
+ end
14
+
15
+ @app.call(env)
16
+ end
17
+
18
+ private
19
+ def parse_formatted_parameters(env)
20
+ request = Request.new(env)
21
+
22
+ return false if request.content_length.zero?
23
+
24
+ mime_type = content_type_from_legacy_post_data_format_header(env) || request.content_type
25
+ strategy = ActionController::Base.param_parsers[mime_type]
26
+
27
+ return false unless strategy
28
+
29
+ case strategy
30
+ when Proc
31
+ strategy.call(request.raw_post)
32
+ when :xml_simple, :xml_node
33
+ body = request.raw_post
34
+ body.blank? ? {} : Hash.from_xml(body).with_indifferent_access
35
+ when :yaml
36
+ YAML.load(request.raw_post)
37
+ when :json
38
+ body = request.raw_post
39
+ if body.blank?
40
+ {}
41
+ else
42
+ data = ActiveSupport::JSON.decode(body)
43
+ data = {:_json => data} unless data.is_a?(Hash)
44
+ data.with_indifferent_access
45
+ end
46
+ else
47
+ false
48
+ end
49
+ rescue Exception => e # YAML, XML or Ruby code block errors
50
+ raise
51
+ { "body" => request.raw_post,
52
+ "content_type" => request.content_type,
53
+ "content_length" => request.content_length,
54
+ "exception" => "#{e.message} (#{e.class})",
55
+ "backtrace" => e.backtrace }
56
+ end
57
+
58
+ def content_type_from_legacy_post_data_format_header(env)
59
+ if x_post_format = env['HTTP_X_POST_DATA_FORMAT']
60
+ case x_post_format.to_s.downcase
61
+ when 'yaml'
62
+ return Mime::YAML
63
+ when 'xml'
64
+ return Mime::XML
65
+ end
66
+ end
67
+
68
+ nil
69
+ end
70
+ end
71
+ end
@@ -1,4 +1,3 @@
1
- require 'action_controller/integration'
2
1
  require 'active_support/testing/performance'
3
2
  require 'active_support/testing/default'
4
3
 
@@ -36,12 +36,11 @@ module ActionController
36
36
  #
37
37
  # * <tt>edit_polymorphic_url</tt>, <tt>edit_polymorphic_path</tt>
38
38
  # * <tt>new_polymorphic_url</tt>, <tt>new_polymorphic_path</tt>
39
- # * <tt>formatted_polymorphic_url</tt>, <tt>formatted_polymorphic_path</tt>
40
39
  #
41
40
  # Example usage:
42
41
  #
43
42
  # edit_polymorphic_path(@post) # => "/posts/1/edit"
44
- # formatted_polymorphic_path([@post, :pdf]) # => "/posts/1.pdf"
43
+ # polymorphic_path(@post, :format => :pdf) # => "/posts/1.pdf"
45
44
  module PolymorphicRoutes
46
45
  # Constructs a call to a named RESTful route for the given record and returns the
47
46
  # resulting URL string. For example:
@@ -55,7 +54,7 @@ module ActionController
55
54
  # ==== Options
56
55
  #
57
56
  # * <tt>:action</tt> - Specifies the action prefix for the named route:
58
- # <tt>:new</tt>, <tt>:edit</tt>, or <tt>:formatted</tt>. Default is no prefix.
57
+ # <tt>:new</tt> or <tt>:edit</tt>. Default is no prefix.
59
58
  # * <tt>:routing_type</tt> - Allowed values are <tt>:path</tt> or <tt>:url</tt>.
60
59
  # Default is <tt>:url</tt>.
61
60
  #
@@ -78,9 +77,8 @@ module ActionController
78
77
  end
79
78
 
80
79
  record = extract_record(record_or_hash_or_array)
81
- format = extract_format(record_or_hash_or_array, options)
82
80
  namespace = extract_namespace(record_or_hash_or_array)
83
-
81
+
84
82
  args = case record_or_hash_or_array
85
83
  when Hash; [ record_or_hash_or_array ]
86
84
  when Array; record_or_hash_or_array.dup
@@ -100,11 +98,10 @@ module ActionController
100
98
  end
101
99
 
102
100
  args.delete_if {|arg| arg.is_a?(Symbol) || arg.is_a?(String)}
103
- args << format if format
104
-
101
+
105
102
  named_route = build_named_route_call(record_or_hash_or_array, namespace, inflection, options)
106
103
 
107
- url_options = options.except(:action, :routing_type, :format)
104
+ url_options = options.except(:action, :routing_type)
108
105
  unless url_options.empty?
109
106
  args.last.kind_of?(Hash) ? args.last.merge!(url_options) : args << url_options
110
107
  end
@@ -119,21 +116,37 @@ module ActionController
119
116
  polymorphic_url(record_or_hash_or_array, options)
120
117
  end
121
118
 
122
- %w(edit new formatted).each do |action|
119
+ %w(edit new).each do |action|
123
120
  module_eval <<-EOT, __FILE__, __LINE__
124
- def #{action}_polymorphic_url(record_or_hash, options = {})
125
- polymorphic_url(record_or_hash, options.merge(:action => "#{action}"))
126
- end
127
-
128
- def #{action}_polymorphic_path(record_or_hash, options = {})
129
- polymorphic_url(record_or_hash, options.merge(:action => "#{action}", :routing_type => :path))
130
- end
121
+ def #{action}_polymorphic_url(record_or_hash, options = {}) # def edit_polymorphic_url(record_or_hash, options = {})
122
+ polymorphic_url( # polymorphic_url(
123
+ record_or_hash, # record_or_hash,
124
+ options.merge(:action => "#{action}")) # options.merge(:action => "edit"))
125
+ end # end
126
+ #
127
+ def #{action}_polymorphic_path(record_or_hash, options = {}) # def edit_polymorphic_path(record_or_hash, options = {})
128
+ polymorphic_url( # polymorphic_url(
129
+ record_or_hash, # record_or_hash,
130
+ options.merge(:action => "#{action}", :routing_type => :path)) # options.merge(:action => "edit", :routing_type => :path))
131
+ end # end
131
132
  EOT
132
133
  end
133
134
 
135
+ def formatted_polymorphic_url(record_or_hash, options = {})
136
+ ActiveSupport::Deprecation.warn("formatted_polymorphic_url has been deprecated. Please pass :format to the polymorphic_url method instead", caller)
137
+ options[:format] = record_or_hash.pop if Array === record_or_hash
138
+ polymorphic_url(record_or_hash, options)
139
+ end
140
+
141
+ def formatted_polymorphic_path(record_or_hash, options = {})
142
+ ActiveSupport::Deprecation.warn("formatted_polymorphic_path has been deprecated. Please pass :format to the polymorphic_path method instead", caller)
143
+ options[:format] = record_or_hash.pop if record_or_hash === Array
144
+ polymorphic_url(record_or_hash, options.merge(:routing_type => :path))
145
+ end
146
+
134
147
  private
135
148
  def action_prefix(options)
136
- options[:action] ? "#{options[:action]}_" : options[:format] ? "formatted_" : ""
149
+ options[:action] ? "#{options[:action]}_" : ''
137
150
  end
138
151
 
139
152
  def routing_type(options)
@@ -150,7 +163,8 @@ module ActionController
150
163
  if parent.is_a?(Symbol) || parent.is_a?(String)
151
164
  string << "#{parent}_"
152
165
  else
153
- string << "#{RecordIdentifier.__send__("singular_class_name", parent)}_"
166
+ string << "#{RecordIdentifier.__send__("plural_class_name", parent)}".singularize
167
+ string << "_"
154
168
  end
155
169
  end
156
170
  end
@@ -158,7 +172,9 @@ module ActionController
158
172
  if record.is_a?(Symbol) || record.is_a?(String)
159
173
  route << "#{record}_"
160
174
  else
161
- route << "#{RecordIdentifier.__send__("#{inflection}_class_name", record)}_"
175
+ route << "#{RecordIdentifier.__send__("plural_class_name", record)}"
176
+ route = route.singularize if inflection == :singular
177
+ route << "_"
162
178
  end
163
179
 
164
180
  action_prefix(options) + namespace + route + routing_type(options).to_s
@@ -171,17 +187,7 @@ module ActionController
171
187
  else record_or_hash_or_array
172
188
  end
173
189
  end
174
-
175
- def extract_format(record_or_hash_or_array, options)
176
- if options[:action].to_s == "formatted" && record_or_hash_or_array.is_a?(Array)
177
- record_or_hash_or_array.pop
178
- elsif options[:format]
179
- options[:format]
180
- else
181
- nil
182
- end
183
- end
184
-
190
+
185
191
  # Remove the first symbols from the array and return the url prefix
186
192
  # implied by those symbols.
187
193
  def extract_namespace(record_or_hash_or_array)