actionpack 3.2.22.5 → 4.0.0.beta1

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 (265) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +641 -418
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +5 -288
  5. data/lib/abstract_controller.rb +1 -8
  6. data/lib/abstract_controller/asset_paths.rb +2 -2
  7. data/lib/abstract_controller/base.rb +39 -37
  8. data/lib/abstract_controller/callbacks.rb +101 -82
  9. data/lib/abstract_controller/collector.rb +7 -3
  10. data/lib/abstract_controller/helpers.rb +23 -11
  11. data/lib/abstract_controller/layouts.rb +68 -73
  12. data/lib/abstract_controller/logger.rb +1 -2
  13. data/lib/abstract_controller/rendering.rb +22 -13
  14. data/lib/abstract_controller/translation.rb +16 -1
  15. data/lib/abstract_controller/url_for.rb +6 -6
  16. data/lib/abstract_controller/view_paths.rb +1 -1
  17. data/lib/action_controller.rb +15 -6
  18. data/lib/action_controller/base.rb +46 -22
  19. data/lib/action_controller/caching.rb +46 -33
  20. data/lib/action_controller/caching/fragments.rb +23 -53
  21. data/lib/action_controller/deprecated.rb +5 -1
  22. data/lib/action_controller/deprecated/integration_test.rb +3 -0
  23. data/lib/action_controller/log_subscriber.rb +11 -8
  24. data/lib/action_controller/metal.rb +16 -30
  25. data/lib/action_controller/metal/conditional_get.rb +76 -32
  26. data/lib/action_controller/metal/data_streaming.rb +20 -26
  27. data/lib/action_controller/metal/exceptions.rb +19 -6
  28. data/lib/action_controller/metal/flash.rb +24 -9
  29. data/lib/action_controller/metal/force_ssl.rb +32 -9
  30. data/lib/action_controller/metal/head.rb +25 -4
  31. data/lib/action_controller/metal/helpers.rb +6 -9
  32. data/lib/action_controller/metal/hide_actions.rb +1 -2
  33. data/lib/action_controller/metal/http_authentication.rb +105 -87
  34. data/lib/action_controller/metal/implicit_render.rb +1 -1
  35. data/lib/action_controller/metal/instrumentation.rb +2 -1
  36. data/lib/action_controller/metal/live.rb +141 -0
  37. data/lib/action_controller/metal/mime_responds.rb +161 -47
  38. data/lib/action_controller/metal/params_wrapper.rb +112 -74
  39. data/lib/action_controller/metal/rack_delegation.rb +9 -3
  40. data/lib/action_controller/metal/redirecting.rb +15 -20
  41. data/lib/action_controller/metal/renderers.rb +11 -9
  42. data/lib/action_controller/metal/rendering.rb +8 -0
  43. data/lib/action_controller/metal/request_forgery_protection.rb +112 -19
  44. data/lib/action_controller/metal/responder.rb +20 -19
  45. data/lib/action_controller/metal/streaming.rb +12 -18
  46. data/lib/action_controller/metal/strong_parameters.rb +516 -0
  47. data/lib/action_controller/metal/testing.rb +13 -18
  48. data/lib/action_controller/metal/url_for.rb +27 -25
  49. data/lib/action_controller/model_naming.rb +12 -0
  50. data/lib/action_controller/railtie.rb +33 -17
  51. data/lib/action_controller/railties/helpers.rb +22 -0
  52. data/lib/action_controller/record_identifier.rb +18 -72
  53. data/lib/action_controller/test_case.rb +215 -123
  54. data/lib/action_controller/vendor/html-scanner.rb +4 -19
  55. data/lib/action_dispatch.rb +27 -19
  56. data/lib/action_dispatch/http/cache.rb +63 -11
  57. data/lib/action_dispatch/http/filter_parameters.rb +18 -8
  58. data/lib/action_dispatch/http/filter_redirect.rb +37 -0
  59. data/lib/action_dispatch/http/headers.rb +27 -19
  60. data/lib/action_dispatch/http/mime_negotiation.rb +25 -2
  61. data/lib/action_dispatch/http/mime_type.rb +145 -113
  62. data/lib/action_dispatch/http/mime_types.rb +1 -1
  63. data/lib/action_dispatch/http/parameter_filter.rb +44 -46
  64. data/lib/action_dispatch/http/parameters.rb +12 -5
  65. data/lib/action_dispatch/http/rack_cache.rb +2 -3
  66. data/lib/action_dispatch/http/request.rb +49 -18
  67. data/lib/action_dispatch/http/response.rb +129 -35
  68. data/lib/action_dispatch/http/upload.rb +60 -17
  69. data/lib/action_dispatch/http/url.rb +53 -31
  70. data/lib/action_dispatch/journey.rb +5 -0
  71. data/lib/action_dispatch/journey/backwards.rb +5 -0
  72. data/lib/action_dispatch/journey/formatter.rb +146 -0
  73. data/lib/action_dispatch/journey/gtg/builder.rb +162 -0
  74. data/lib/action_dispatch/journey/gtg/simulator.rb +44 -0
  75. data/lib/action_dispatch/journey/gtg/transition_table.rb +156 -0
  76. data/lib/action_dispatch/journey/nfa/builder.rb +76 -0
  77. data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
  78. data/lib/action_dispatch/journey/nfa/simulator.rb +47 -0
  79. data/lib/action_dispatch/journey/nfa/transition_table.rb +163 -0
  80. data/lib/action_dispatch/journey/nodes/node.rb +124 -0
  81. data/lib/action_dispatch/journey/parser.rb +206 -0
  82. data/lib/action_dispatch/journey/parser.y +47 -0
  83. data/lib/action_dispatch/journey/parser_extras.rb +23 -0
  84. data/lib/action_dispatch/journey/path/pattern.rb +196 -0
  85. data/lib/action_dispatch/journey/route.rb +116 -0
  86. data/lib/action_dispatch/journey/router.rb +164 -0
  87. data/lib/action_dispatch/journey/router/strexp.rb +24 -0
  88. data/lib/action_dispatch/journey/router/utils.rb +54 -0
  89. data/lib/action_dispatch/journey/routes.rb +75 -0
  90. data/lib/action_dispatch/journey/scanner.rb +61 -0
  91. data/lib/action_dispatch/journey/visitors.rb +189 -0
  92. data/lib/action_dispatch/journey/visualizer/fsm.css +34 -0
  93. data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
  94. data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
  95. data/lib/action_dispatch/middleware/callbacks.rb +9 -4
  96. data/lib/action_dispatch/middleware/cookies.rb +168 -57
  97. data/lib/action_dispatch/middleware/debug_exceptions.rb +26 -17
  98. data/lib/action_dispatch/middleware/exception_wrapper.rb +27 -3
  99. data/lib/action_dispatch/middleware/flash.rb +58 -58
  100. data/lib/action_dispatch/middleware/params_parser.rb +14 -29
  101. data/lib/action_dispatch/middleware/public_exceptions.rb +31 -14
  102. data/lib/action_dispatch/middleware/reloader.rb +6 -6
  103. data/lib/action_dispatch/middleware/remote_ip.rb +145 -39
  104. data/lib/action_dispatch/middleware/request_id.rb +2 -6
  105. data/lib/action_dispatch/middleware/session/abstract_store.rb +22 -20
  106. data/lib/action_dispatch/middleware/session/cache_store.rb +3 -3
  107. data/lib/action_dispatch/middleware/session/cookie_store.rb +81 -7
  108. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -3
  109. data/lib/action_dispatch/middleware/show_exceptions.rb +12 -45
  110. data/lib/action_dispatch/middleware/ssl.rb +70 -0
  111. data/lib/action_dispatch/middleware/stack.rb +6 -1
  112. data/lib/action_dispatch/middleware/static.rb +5 -24
  113. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +14 -11
  114. data/lib/action_dispatch/middleware/templates/rescues/_source.erb +25 -0
  115. data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +3 -3
  116. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +15 -9
  117. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +121 -5
  118. data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +7 -2
  119. data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +30 -15
  120. data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +39 -13
  121. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +6 -2
  122. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +16 -0
  123. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +144 -0
  124. data/lib/action_dispatch/railtie.rb +16 -6
  125. data/lib/action_dispatch/request/session.rb +181 -0
  126. data/lib/action_dispatch/routing.rb +41 -40
  127. data/lib/action_dispatch/routing/inspector.rb +240 -0
  128. data/lib/action_dispatch/routing/mapper.rb +501 -273
  129. data/lib/action_dispatch/routing/polymorphic_routes.rb +16 -20
  130. data/lib/action_dispatch/routing/redirection.rb +46 -29
  131. data/lib/action_dispatch/routing/route_set.rb +203 -164
  132. data/lib/action_dispatch/routing/routes_proxy.rb +2 -0
  133. data/lib/action_dispatch/routing/url_for.rb +48 -33
  134. data/lib/action_dispatch/testing/assertions/dom.rb +3 -13
  135. data/lib/action_dispatch/testing/assertions/response.rb +32 -40
  136. data/lib/action_dispatch/testing/assertions/routing.rb +40 -39
  137. data/lib/action_dispatch/testing/assertions/selector.rb +15 -20
  138. data/lib/action_dispatch/testing/assertions/tag.rb +20 -23
  139. data/lib/action_dispatch/testing/integration.rb +41 -22
  140. data/lib/action_dispatch/testing/test_process.rb +9 -6
  141. data/lib/action_dispatch/testing/test_request.rb +7 -3
  142. data/lib/action_pack.rb +1 -1
  143. data/lib/action_pack/version.rb +4 -4
  144. data/lib/action_view.rb +17 -8
  145. data/lib/action_view/base.rb +15 -34
  146. data/lib/action_view/buffers.rb +1 -1
  147. data/lib/action_view/context.rb +4 -4
  148. data/lib/action_view/dependency_tracker.rb +91 -0
  149. data/lib/action_view/digestor.rb +85 -0
  150. data/lib/action_view/flows.rb +1 -4
  151. data/lib/action_view/helpers.rb +2 -4
  152. data/lib/action_view/helpers/active_model_helper.rb +3 -4
  153. data/lib/action_view/helpers/asset_tag_helper.rb +211 -353
  154. data/lib/action_view/helpers/asset_url_helper.rb +354 -0
  155. data/lib/action_view/helpers/atom_feed_helper.rb +13 -10
  156. data/lib/action_view/helpers/cache_helper.rb +150 -18
  157. data/lib/action_view/helpers/capture_helper.rb +42 -29
  158. data/lib/action_view/helpers/csrf_helper.rb +0 -2
  159. data/lib/action_view/helpers/date_helper.rb +268 -247
  160. data/lib/action_view/helpers/debug_helper.rb +10 -11
  161. data/lib/action_view/helpers/form_helper.rb +904 -547
  162. data/lib/action_view/helpers/form_options_helper.rb +341 -166
  163. data/lib/action_view/helpers/form_tag_helper.rb +188 -88
  164. data/lib/action_view/helpers/javascript_helper.rb +23 -16
  165. data/lib/action_view/helpers/number_helper.rb +148 -354
  166. data/lib/action_view/helpers/output_safety_helper.rb +3 -3
  167. data/lib/action_view/helpers/record_tag_helper.rb +17 -22
  168. data/lib/action_view/helpers/rendering_helper.rb +2 -4
  169. data/lib/action_view/helpers/sanitize_helper.rb +3 -6
  170. data/lib/action_view/helpers/tag_helper.rb +43 -37
  171. data/lib/action_view/helpers/tags.rb +39 -0
  172. data/lib/action_view/helpers/tags/base.rb +148 -0
  173. data/lib/action_view/helpers/tags/check_box.rb +64 -0
  174. data/lib/action_view/helpers/tags/checkable.rb +16 -0
  175. data/lib/action_view/helpers/tags/collection_check_boxes.rb +43 -0
  176. data/lib/action_view/helpers/tags/collection_helpers.rb +83 -0
  177. data/lib/action_view/helpers/tags/collection_radio_buttons.rb +36 -0
  178. data/lib/action_view/helpers/tags/collection_select.rb +28 -0
  179. data/lib/action_view/helpers/tags/color_field.rb +25 -0
  180. data/lib/action_view/helpers/tags/date_field.rb +13 -0
  181. data/lib/action_view/helpers/tags/date_select.rb +72 -0
  182. data/lib/action_view/helpers/tags/datetime_field.rb +22 -0
  183. data/lib/action_view/helpers/tags/datetime_local_field.rb +19 -0
  184. data/lib/action_view/helpers/tags/datetime_select.rb +8 -0
  185. data/lib/action_view/helpers/tags/email_field.rb +8 -0
  186. data/lib/action_view/helpers/tags/file_field.rb +8 -0
  187. data/lib/action_view/helpers/tags/grouped_collection_select.rb +29 -0
  188. data/lib/action_view/helpers/tags/hidden_field.rb +8 -0
  189. data/lib/action_view/helpers/tags/label.rb +65 -0
  190. data/lib/action_view/helpers/tags/month_field.rb +13 -0
  191. data/lib/action_view/helpers/tags/number_field.rb +18 -0
  192. data/lib/action_view/helpers/tags/password_field.rb +12 -0
  193. data/lib/action_view/helpers/tags/radio_button.rb +31 -0
  194. data/lib/action_view/helpers/tags/range_field.rb +8 -0
  195. data/lib/action_view/helpers/tags/search_field.rb +24 -0
  196. data/lib/action_view/helpers/tags/select.rb +41 -0
  197. data/lib/action_view/helpers/tags/tel_field.rb +8 -0
  198. data/lib/action_view/helpers/tags/text_area.rb +18 -0
  199. data/lib/action_view/helpers/tags/text_field.rb +29 -0
  200. data/lib/action_view/helpers/tags/time_field.rb +13 -0
  201. data/lib/action_view/helpers/tags/time_select.rb +8 -0
  202. data/lib/action_view/helpers/tags/time_zone_select.rb +20 -0
  203. data/lib/action_view/helpers/tags/url_field.rb +8 -0
  204. data/lib/action_view/helpers/tags/week_field.rb +13 -0
  205. data/lib/action_view/helpers/text_helper.rb +126 -113
  206. data/lib/action_view/helpers/translation_helper.rb +32 -16
  207. data/lib/action_view/helpers/url_helper.rb +200 -271
  208. data/lib/action_view/locale/en.yml +1 -105
  209. data/lib/action_view/log_subscriber.rb +6 -4
  210. data/lib/action_view/lookup_context.rb +15 -39
  211. data/lib/action_view/model_naming.rb +12 -0
  212. data/lib/action_view/path_set.rb +9 -39
  213. data/lib/action_view/railtie.rb +6 -22
  214. data/lib/action_view/record_identifier.rb +84 -0
  215. data/lib/action_view/renderer/abstract_renderer.rb +10 -19
  216. data/lib/action_view/renderer/partial_renderer.rb +144 -81
  217. data/lib/action_view/renderer/renderer.rb +2 -19
  218. data/lib/action_view/renderer/streaming_template_renderer.rb +2 -5
  219. data/lib/action_view/renderer/template_renderer.rb +14 -13
  220. data/lib/action_view/routing_url_for.rb +107 -0
  221. data/lib/action_view/template.rb +22 -21
  222. data/lib/action_view/template/error.rb +22 -12
  223. data/lib/action_view/template/handlers.rb +12 -9
  224. data/lib/action_view/template/handlers/builder.rb +1 -1
  225. data/lib/action_view/template/handlers/erb.rb +11 -16
  226. data/lib/action_view/template/handlers/raw.rb +11 -0
  227. data/lib/action_view/template/resolver.rb +111 -83
  228. data/lib/action_view/template/text.rb +12 -8
  229. data/lib/action_view/template/types.rb +57 -0
  230. data/lib/action_view/test_case.rb +66 -43
  231. data/lib/action_view/testing/resolvers.rb +3 -2
  232. data/lib/action_view/vendor/html-scanner.rb +20 -0
  233. data/lib/{action_controller → action_view}/vendor/html-scanner/html/document.rb +0 -0
  234. data/lib/{action_controller → action_view}/vendor/html-scanner/html/node.rb +12 -12
  235. data/lib/{action_controller → action_view}/vendor/html-scanner/html/sanitizer.rb +18 -7
  236. data/lib/{action_controller → action_view}/vendor/html-scanner/html/selector.rb +1 -1
  237. data/lib/{action_controller → action_view}/vendor/html-scanner/html/tokenizer.rb +1 -1
  238. data/lib/{action_controller → action_view}/vendor/html-scanner/html/version.rb +0 -0
  239. metadata +135 -125
  240. data/lib/action_controller/caching/actions.rb +0 -185
  241. data/lib/action_controller/caching/pages.rb +0 -187
  242. data/lib/action_controller/caching/sweeping.rb +0 -97
  243. data/lib/action_controller/deprecated/performance_test.rb +0 -1
  244. data/lib/action_controller/metal/compatibility.rb +0 -65
  245. data/lib/action_controller/metal/session_management.rb +0 -14
  246. data/lib/action_controller/railties/paths.rb +0 -25
  247. data/lib/action_dispatch/middleware/best_standards_support.rb +0 -30
  248. data/lib/action_dispatch/middleware/body_proxy.rb +0 -30
  249. data/lib/action_dispatch/middleware/head.rb +0 -18
  250. data/lib/action_dispatch/middleware/rescue.rb +0 -26
  251. data/lib/action_dispatch/testing/performance_test.rb +0 -10
  252. data/lib/action_view/asset_paths.rb +0 -142
  253. data/lib/action_view/helpers/asset_paths.rb +0 -7
  254. data/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb +0 -146
  255. data/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb +0 -93
  256. data/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +0 -193
  257. data/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +0 -148
  258. data/lib/sprockets/assets.rake +0 -99
  259. data/lib/sprockets/bootstrap.rb +0 -37
  260. data/lib/sprockets/compressors.rb +0 -83
  261. data/lib/sprockets/helpers.rb +0 -6
  262. data/lib/sprockets/helpers/isolated_helper.rb +0 -13
  263. data/lib/sprockets/helpers/rails_helper.rb +0 -182
  264. data/lib/sprockets/railtie.rb +0 -62
  265. data/lib/sprockets/static_compiler.rb +0 -56
@@ -1,14 +1,19 @@
1
1
  require 'action_dispatch/middleware/session/abstract_store'
2
- require 'rack/session/memcache'
2
+ begin
3
+ require 'rack/session/dalli'
4
+ rescue LoadError => e
5
+ $stderr.puts "You don't have dalli installed in your application. Please add it to your Gemfile and run bundle install"
6
+ raise e
7
+ end
3
8
 
4
9
  module ActionDispatch
5
10
  module Session
6
- class MemCacheStore < Rack::Session::Memcache
11
+ class MemCacheStore < Rack::Session::Dalli
7
12
  include Compatibility
8
13
  include StaleSessionCheck
14
+ include SessionObject
9
15
 
10
16
  def initialize(app, options = {})
11
- require 'memcache'
12
17
  options[:expire_after] ||= options[:expires]
13
18
  super
14
19
  end
@@ -1,73 +1,40 @@
1
1
  require 'action_dispatch/http/request'
2
2
  require 'action_dispatch/middleware/exception_wrapper'
3
- require 'active_support/deprecation'
4
3
 
5
4
  module ActionDispatch
6
5
  # This middleware rescues any exception returned by the application
7
6
  # and calls an exceptions app that will wrap it in a format for the end user.
8
7
  #
9
8
  # The exceptions app should be passed as parameter on initialization
10
- # of ShowExceptions. Everytime there is an exception, ShowExceptions will
9
+ # of ShowExceptions. Every time there is an exception, ShowExceptions will
11
10
  # store the exception in env["action_dispatch.exception"], rewrite the
12
11
  # PATH_INFO to the exception status code and call the rack app.
13
- #
12
+ #
14
13
  # If the application returns a "X-Cascade" pass response, this middleware
15
14
  # will send an empty response as result with the correct status code.
16
15
  # If any exception happens inside the exceptions app, this middleware
17
16
  # catches the exceptions and returns a FAILSAFE_RESPONSE.
18
17
  class ShowExceptions
19
- FAILSAFE_RESPONSE = [500, {'Content-Type' => 'text/html'},
20
- ["<html><body><h1>500 Internal Server Error</h1>" <<
21
- "If you are the administrator of this website, then please read this web " <<
22
- "application's log file and/or the web server's log file to find out what " <<
23
- "went wrong.</body></html>"]]
24
-
25
- class << self
26
- def rescue_responses
27
- ActiveSupport::Deprecation.warn "ActionDispatch::ShowExceptions.rescue_responses is deprecated. " \
28
- "Please configure your exceptions using a railtie or in your application config instead."
29
- ExceptionWrapper.rescue_responses
30
- end
31
-
32
- def rescue_templates
33
- ActiveSupport::Deprecation.warn "ActionDispatch::ShowExceptions.rescue_templates is deprecated. " \
34
- "Please configure your exceptions using a railtie or in your application config instead."
35
- ExceptionWrapper.rescue_templates
36
- end
37
- end
38
-
39
- def initialize(app, exceptions_app = nil)
40
- if [true, false].include?(exceptions_app)
41
- ActiveSupport::Deprecation.warn "Passing consider_all_requests_local option to ActionDispatch::ShowExceptions middleware no longer works"
42
- exceptions_app = nil
43
- end
44
-
45
- if exceptions_app.nil?
46
- raise ArgumentError, "You need to pass an exceptions_app when initializing ActionDispatch::ShowExceptions. " \
47
- "In case you want to render pages from a public path, you can use ActionDispatch::PublicExceptions.new('path/to/public')"
48
- end
18
+ FAILSAFE_RESPONSE = [500, { 'Content-Type' => 'text/plain' },
19
+ ["500 Internal Server Error\n" \
20
+ "If you are the administrator of this website, then please read this web " \
21
+ "application's log file and/or the web server's log file to find out what " \
22
+ "went wrong."]]
49
23
 
24
+ def initialize(app, exceptions_app)
50
25
  @app = app
51
26
  @exceptions_app = exceptions_app
52
27
  end
53
28
 
54
29
  def call(env)
55
- begin
56
- response = @app.call(env)
57
- rescue Exception => exception
58
- raise exception if env['action_dispatch.show_exceptions'] == false
59
- end
60
-
61
- response || render_exception(env, exception)
30
+ @app.call(env)
31
+ rescue Exception => exception
32
+ raise exception if env['action_dispatch.show_exceptions'] == false
33
+ render_exception(env, exception)
62
34
  end
63
35
 
64
36
  private
65
37
 
66
- # Define this method because some plugins were monkey patching it.
67
- # Remove this after 3.2 is out with the other deprecations in this class.
68
- def status_code(*)
69
- end
70
-
71
38
  def render_exception(env, exception)
72
39
  wrapper = ExceptionWrapper.new(env, exception)
73
40
  status = wrapper.status_code
@@ -0,0 +1,70 @@
1
+ module ActionDispatch
2
+ class SSL
3
+ YEAR = 31536000
4
+
5
+ def self.default_hsts_options
6
+ { :expires => YEAR, :subdomains => false }
7
+ end
8
+
9
+ def initialize(app, options = {})
10
+ @app = app
11
+
12
+ @hsts = options.fetch(:hsts, {})
13
+ @hsts = {} if @hsts == true
14
+ @hsts = self.class.default_hsts_options.merge(@hsts) if @hsts
15
+
16
+ @host = options[:host]
17
+ @port = options[:port]
18
+ end
19
+
20
+ def call(env)
21
+ request = Request.new(env)
22
+
23
+ if request.ssl?
24
+ status, headers, body = @app.call(env)
25
+ headers = hsts_headers.merge(headers)
26
+ flag_cookies_as_secure!(headers)
27
+ [status, headers, body]
28
+ else
29
+ redirect_to_https(request)
30
+ end
31
+ end
32
+
33
+ private
34
+ def redirect_to_https(request)
35
+ url = URI(request.url)
36
+ url.scheme = "https"
37
+ url.host = @host if @host
38
+ url.port = @port if @port
39
+ headers = hsts_headers.merge('Content-Type' => 'text/html',
40
+ 'Location' => url.to_s)
41
+
42
+ [301, headers, []]
43
+ end
44
+
45
+ # http://tools.ietf.org/html/draft-hodges-strict-transport-sec-02
46
+ def hsts_headers
47
+ if @hsts
48
+ value = "max-age=#{@hsts[:expires].to_i}"
49
+ value += "; includeSubDomains" if @hsts[:subdomains]
50
+ { 'Strict-Transport-Security' => value }
51
+ else
52
+ {}
53
+ end
54
+ end
55
+
56
+ def flag_cookies_as_secure!(headers)
57
+ if cookies = headers['Set-Cookie']
58
+ cookies = cookies.split("\n")
59
+
60
+ headers['Set-Cookie'] = cookies.map { |cookie|
61
+ if cookie !~ /;\s+secure(;|$)/
62
+ "#{cookie}; secure"
63
+ else
64
+ cookie
65
+ end
66
+ }.join("\n")
67
+ end
68
+ end
69
+ end
70
+ end
@@ -75,6 +75,11 @@ module ActionDispatch
75
75
  middlewares[i]
76
76
  end
77
77
 
78
+ def unshift(*args, &block)
79
+ middleware = self.class::Middleware.new(*args, &block)
80
+ middlewares.unshift(middleware)
81
+ end
82
+
78
83
  def initialize_copy(other)
79
84
  self.middlewares = other.middlewares.dup
80
85
  end
@@ -110,7 +115,7 @@ module ActionDispatch
110
115
  def build(app = nil, &block)
111
116
  app ||= block
112
117
  raise "MiddlewareStack#build requires an app" unless app
113
- middlewares.reverse.inject(app) { |a, e| e.build(a) }
118
+ middlewares.freeze.reverse.inject(app) { |a, e| e.build(a) }
114
119
  end
115
120
 
116
121
  protected
@@ -1,4 +1,5 @@
1
1
  require 'rack/utils'
2
+ require 'active_support/core_ext/uri'
2
3
 
3
4
  module ActionDispatch
4
5
  class FileHandler
@@ -12,11 +13,11 @@ module ActionDispatch
12
13
  def match?(path)
13
14
  path = path.dup
14
15
 
15
- full_path = path.empty? ? @root : File.join(@root, escape_glob_chars(clean_path_info(unescape_path(path))))
16
+ full_path = path.empty? ? @root : File.join(@root, escape_glob_chars(unescape_path(path)))
16
17
  paths = "#{full_path}#{ext}"
17
18
 
18
19
  matches = Dir[paths]
19
- match = matches.detect { |m| File.file?(m) && File.readable?(m) }
20
+ match = matches.detect { |m| File.file?(m) }
20
21
  if match
21
22
  match.sub!(@compiled_root, '')
22
23
  ::Rack::Utils.escape(match)
@@ -29,7 +30,7 @@ module ActionDispatch
29
30
 
30
31
  def ext
31
32
  @ext ||= begin
32
- ext = ::ActionController::Base.page_cache_extension
33
+ ext = ::ActionController::Base.default_static_extension
33
34
  "{,#{ext},/index#{ext}}"
34
35
  end
35
36
  end
@@ -40,27 +41,7 @@ module ActionDispatch
40
41
 
41
42
  def escape_glob_chars(path)
42
43
  path.force_encoding('binary') if path.respond_to? :force_encoding
43
- path.gsub(/[*?{}\[\]\\]/, "\\\\\\&")
44
- end
45
-
46
- private
47
-
48
- PATH_SEPS = Regexp.union(*[::File::SEPARATOR, ::File::ALT_SEPARATOR].compact)
49
-
50
- def clean_path_info(path_info)
51
- path_info.force_encoding('binary') if path_info.respond_to? :force_encoding
52
- parts = path_info.split PATH_SEPS
53
-
54
- clean = []
55
-
56
- parts.each do |part|
57
- next if part.empty? || part == '.'
58
- part == '..' ? clean.pop : clean << part
59
- end
60
-
61
- clean.unshift '/' if parts.empty? || parts.first.empty?
62
-
63
- ::File.join(*clean)
44
+ path.gsub(/[*?{}\[\]]/, "\\\\\\&")
64
45
  end
65
46
  end
66
47
 
@@ -1,8 +1,8 @@
1
1
  <% unless @exception.blamed_files.blank? %>
2
2
  <% if (hide = @exception.blamed_files.length > 8) %>
3
- <a href="#" onclick="document.getElementById('blame_trace').style.display='block'; return false;">Show blamed files</a>
3
+ <a href="#" onclick="return toggleTrace()">Toggle blamed files</a>
4
4
  <% end %>
5
- <pre id="blame_trace" <%='style="display:none"' if hide %>><code><%=h @exception.describe_blame %></code></pre>
5
+ <pre id="blame_trace" <%='style="display:none"' if hide %>><code><%= @exception.describe_blame %></code></pre>
6
6
  <% end %>
7
7
 
8
8
  <%
@@ -12,20 +12,23 @@
12
12
 
13
13
  request_dump = clean_params.empty? ? 'None' : clean_params.inspect.gsub(',', ",\n")
14
14
 
15
- def debug_hash(hash)
16
- hash.sort_by { |k, v| k.to_s }.map { |k, v| "#{k}: #{v.inspect rescue $!.message}" }.join("\n")
15
+ def debug_hash(object)
16
+ object.to_hash.sort_by { |k, v| k.to_s }.map { |k, v| "#{k}: #{v.inspect rescue $!.message}" }.join("\n")
17
17
  end unless self.class.method_defined?(:debug_hash)
18
18
  %>
19
19
 
20
20
  <h2 style="margin-top: 30px">Request</h2>
21
- <p><b>Parameters</b>: <pre><%=h request_dump %></pre></p>
21
+ <p><b>Parameters</b>:</p> <pre><%= request_dump %></pre>
22
22
 
23
- <p><a href="#" onclick="document.getElementById('session_dump').style.display='block'; return false;">Show session dump</a></p>
24
- <div id="session_dump" style="display:none"><pre><%= debug_hash @request.session %></pre></div>
25
-
26
- <p><a href="#" onclick="document.getElementById('env_dump').style.display='block'; return false;">Show env dump</a></p>
27
- <div id="env_dump" style="display:none"><pre><%= debug_hash @request.env.slice(*@request.class::ENV_METHODS) %></pre></div>
23
+ <div class="details">
24
+ <div class="summary"><a href="#" onclick="return toggleSessionDump()">Toggle session dump</a></div>
25
+ <div id="session_dump" style="display:none"><pre><%= debug_hash @request.session %></pre></div>
26
+ </div>
28
27
 
28
+ <div class="details">
29
+ <div class="summary"><a href="#" onclick="return toggleEnvDump()">Toggle env dump</a></div>
30
+ <div id="env_dump" style="display:none"><pre><%= debug_hash @request.env.slice(*@request.class::ENV_METHODS) %></pre></div>
31
+ </div>
29
32
 
30
33
  <h2 style="margin-top: 30px">Response</h2>
31
- <p><b>Headers</b>: <pre><%=h defined?(@response) ? @response.headers.inspect.gsub(',', ",\n") : 'None' %></pre></p>
34
+ <p><b>Headers</b>:</p> <pre><%= defined?(@response) ? @response.headers.inspect.gsub(',', ",\n") : 'None' %></pre>
@@ -0,0 +1,25 @@
1
+ <% if @source_extract %>
2
+ <div class="source">
3
+ <div class="info">
4
+ Extracted source (around line <strong>#<%= @line_number %></strong>):
5
+ </div>
6
+ <div class="data">
7
+ <table cellpadding="0" cellspacing="0" class="lines">
8
+ <tr>
9
+ <td>
10
+ <pre class="line_numbers">
11
+ <% @source_extract.keys.each do |line_number| %>
12
+ <span><%= line_number -%></span>
13
+ <% end %>
14
+ </pre>
15
+ </td>
16
+ <td width="100%">
17
+ <pre>
18
+ <% @source_extract.each do |line, source| -%><div class="line<%= " active" if line == @line_number -%>"><%= source -%></div><% end -%>
19
+ </pre>
20
+ </td>
21
+ </tr>
22
+ </table>
23
+ </div>
24
+ </div>
25
+ <% end %>
@@ -12,15 +12,15 @@
12
12
  <div id="traces">
13
13
  <% names.each do |name| %>
14
14
  <%
15
- show = "document.getElementById('#{name.gsub(/\s/, '-')}').style.display='block';"
16
- hide = (names - [name]).collect {|hide_name| "document.getElementById('#{hide_name.gsub(/\s/, '-')}').style.display='none';"}
15
+ show = "show('#{name.gsub(/\s/, '-')}');"
16
+ hide = (names - [name]).collect {|hide_name| "hide('#{hide_name.gsub(/\s/, '-')}');"}
17
17
  %>
18
18
  <a href="#" onclick="<%= hide.join %><%= show %>; return false;"><%= name %></a> <%= '|' unless names.last == name %>
19
19
  <% end %>
20
20
 
21
21
  <% traces.each do |name, trace| %>
22
22
  <div id="<%= name.gsub(/\s/, '-') %>" style="display: <%= (name == "Application Trace") ? 'block' : 'none' %>;">
23
- <pre><code><%=h trace.join "\n" %></code></pre>
23
+ <pre><code><%= trace.join "\n" %></code></pre>
24
24
  </div>
25
25
  <% end %>
26
26
  </div>
@@ -1,10 +1,16 @@
1
- <h1>
2
- <%=h @exception.class.to_s %>
3
- <% if @request.parameters['controller'] %>
4
- in <%=h @request.parameters['controller'].camelize %>Controller<% if @request.parameters['action'] %>#<%=h @request.parameters['action'] %><% end %>
5
- <% end %>
6
- </h1>
7
- <pre><%=h @exception.message %></pre>
1
+ <header>
2
+ <h1>
3
+ <%= @exception.class.to_s %>
4
+ <% if @request.parameters['controller'] %>
5
+ in <%= @request.parameters['controller'].camelize %>Controller<% if @request.parameters['action'] %>#<%= @request.parameters['action'] %><% end %>
6
+ <% end %>
7
+ </h1>
8
+ </header>
8
9
 
9
- <%= render :template => "rescues/_trace" %>
10
- <%= render :template => "rescues/_request_and_response" %>
10
+ <div id="container">
11
+ <h2><%= @exception.message %></h2>
12
+
13
+ <%= render template: "rescues/_source" %>
14
+ <%= render template: "rescues/_trace" %>
15
+ <%= render template: "rescues/_request_and_response" %>
16
+ </div>
@@ -4,7 +4,11 @@
4
4
  <meta charset="utf-8" />
5
5
  <title>Action Controller: Exception caught</title>
6
6
  <style>
7
- body { background-color: #fff; color: #333; }
7
+ body {
8
+ background-color: #FAFAFA;
9
+ color: #333;
10
+ margin: 0px;
11
+ }
8
12
 
9
13
  body, p, ol, ul, td {
10
14
  font-family: helvetica, verdana, arial, sans-serif;
@@ -13,16 +17,128 @@
13
17
  }
14
18
 
15
19
  pre {
16
- background-color: #eee;
17
- padding: 10px;
18
20
  font-size: 11px;
19
21
  white-space: pre-wrap;
20
22
  }
21
23
 
22
- a { color: #000; }
24
+ pre.box {
25
+ border: 1px solid #EEE;
26
+ padding: 10px;
27
+ margin: 0px;
28
+ width: 958px;
29
+ }
30
+
31
+ header {
32
+ color: #F0F0F0;
33
+ background: #C52F24;
34
+ padding: 0.5em 1.5em;
35
+ }
36
+
37
+ h2 {
38
+ color: #C52F24;
39
+ line-height: 25px;
40
+ }
41
+
42
+ .details {
43
+ border: 1px solid #D0D0D0;
44
+ border-radius: 4px;
45
+ margin: 1em 0px;
46
+ display: block;
47
+ width: 978px;
48
+ }
49
+
50
+ .summary {
51
+ padding: 8px 15px;
52
+ border-bottom: 1px solid #D0D0D0;
53
+ display: block;
54
+ }
55
+
56
+ .details pre {
57
+ margin: 5px;
58
+ border: none;
59
+ }
60
+
61
+ #container {
62
+ box-sizing: border-box;
63
+ width: 100%;
64
+ padding: 0 1.5em;
65
+ }
66
+
67
+ .source * {
68
+ margin: 0px;
69
+ padding: 0px;
70
+ }
71
+
72
+ .source {
73
+ border: 1px solid #D9D9D9;
74
+ background: #ECECEC;
75
+ width: 978px;
76
+ }
77
+
78
+ .source pre {
79
+ padding: 10px 0px;
80
+ border: none;
81
+ }
82
+
83
+ .source .data {
84
+ font-size: 80%;
85
+ overflow: auto;
86
+ background-color: #FFF;
87
+ }
88
+
89
+ .info {
90
+ padding: 0.5em;
91
+ }
92
+
93
+ .source .data .line_numbers {
94
+ background-color: #ECECEC;
95
+ color: #AAA;
96
+ padding: 1em .5em;
97
+ border-right: 1px solid #DDD;
98
+ text-align: right;
99
+ }
100
+
101
+ .line {
102
+ padding-left: 10px;
103
+ }
104
+
105
+ .line:hover {
106
+ background-color: #F6F6F6;
107
+ }
108
+
109
+ .line.active {
110
+ background-color: #FFCCCC;
111
+ }
112
+
113
+ a { color: #980905; }
23
114
  a:visited { color: #666; }
24
- a:hover { color: #fff; background-color:#000; }
115
+ a:hover { color: #C52F24; }
116
+
117
+ <%= yield :style %>
25
118
  </style>
119
+
120
+ <script>
121
+ var toggle = function(id) {
122
+ var s = document.getElementById(id).style;
123
+ s.display = s.display == 'none' ? 'block' : 'none';
124
+ return false;
125
+ }
126
+ var show = function(id) {
127
+ document.getElementById(id).style.display = 'block';
128
+ }
129
+ var hide = function(id) {
130
+ document.getElementById(id).style.display = 'none';
131
+ }
132
+ var toggleTrace = function() {
133
+ return toggle('blame_trace');
134
+ }
135
+ var toggleSessionDump = function() {
136
+ return toggle('session_dump');
137
+ }
138
+ var toggleEnvDump = function() {
139
+ return toggle('env_dump');
140
+ }
141
+ </script>
26
142
  </head>
27
143
  <body>
28
144