actionpack 4.0.1 → 4.2.11.1

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 (241) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +402 -1173
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +7 -7
  5. data/lib/abstract_controller/base.rb +39 -7
  6. data/lib/abstract_controller/callbacks.rb +32 -53
  7. data/lib/abstract_controller/collector.rb +11 -1
  8. data/lib/abstract_controller/helpers.rb +26 -16
  9. data/lib/abstract_controller/railties/routes_helpers.rb +3 -3
  10. data/lib/abstract_controller/rendering.rb +57 -127
  11. data/lib/abstract_controller/url_for.rb +1 -1
  12. data/lib/abstract_controller.rb +1 -2
  13. data/lib/action_controller/base.rb +19 -10
  14. data/lib/action_controller/caching/fragments.rb +7 -1
  15. data/lib/action_controller/caching.rb +2 -12
  16. data/lib/action_controller/log_subscriber.rb +29 -20
  17. data/lib/action_controller/metal/conditional_get.rb +37 -12
  18. data/lib/action_controller/metal/data_streaming.rb +1 -1
  19. data/lib/action_controller/metal/etag_with_template_digest.rb +50 -0
  20. data/lib/action_controller/metal/exceptions.rb +1 -1
  21. data/lib/action_controller/metal/flash.rb +17 -0
  22. data/lib/action_controller/metal/force_ssl.rb +2 -2
  23. data/lib/action_controller/metal/head.rb +8 -6
  24. data/lib/action_controller/metal/helpers.rb +6 -2
  25. data/lib/action_controller/metal/http_authentication.rb +45 -23
  26. data/lib/action_controller/metal/instrumentation.rb +9 -6
  27. data/lib/action_controller/metal/live.rb +173 -20
  28. data/lib/action_controller/metal/mime_responds.rb +127 -232
  29. data/lib/action_controller/metal/params_wrapper.rb +16 -9
  30. data/lib/action_controller/metal/rack_delegation.rb +1 -1
  31. data/lib/action_controller/metal/redirecting.rb +34 -26
  32. data/lib/action_controller/metal/renderers.rb +39 -12
  33. data/lib/action_controller/metal/rendering.rb +41 -14
  34. data/lib/action_controller/metal/request_forgery_protection.rb +147 -19
  35. data/lib/action_controller/metal/streaming.rb +19 -21
  36. data/lib/action_controller/metal/strong_parameters.rb +166 -22
  37. data/lib/action_controller/metal/testing.rb +0 -1
  38. data/lib/action_controller/metal/url_for.rb +11 -12
  39. data/lib/action_controller/metal.rb +14 -8
  40. data/lib/action_controller/model_naming.rb +1 -1
  41. data/lib/action_controller/railtie.rb +5 -1
  42. data/lib/action_controller/test_case.rb +160 -94
  43. data/lib/action_controller.rb +2 -18
  44. data/lib/action_dispatch/http/cache.rb +5 -4
  45. data/lib/action_dispatch/http/filter_parameters.rb +2 -2
  46. data/lib/action_dispatch/http/filter_redirect.rb +5 -4
  47. data/lib/action_dispatch/http/headers.rb +46 -10
  48. data/lib/action_dispatch/http/mime_negotiation.rb +31 -4
  49. data/lib/action_dispatch/http/mime_type.rb +25 -26
  50. data/lib/action_dispatch/http/mime_types.rb +1 -0
  51. data/lib/action_dispatch/http/parameter_filter.rb +1 -1
  52. data/lib/action_dispatch/http/parameters.rb +25 -41
  53. data/lib/action_dispatch/http/request.rb +49 -32
  54. data/lib/action_dispatch/http/response.rb +127 -25
  55. data/lib/action_dispatch/http/upload.rb +9 -21
  56. data/lib/action_dispatch/http/url.rb +97 -70
  57. data/lib/action_dispatch/journey/formatter.rb +35 -19
  58. data/lib/action_dispatch/journey/gtg/builder.rb +3 -3
  59. data/lib/action_dispatch/journey/gtg/simulator.rb +10 -7
  60. data/lib/action_dispatch/journey/gtg/transition_table.rb +23 -33
  61. data/lib/action_dispatch/journey/nfa/dot.rb +2 -2
  62. data/lib/action_dispatch/journey/nfa/simulator.rb +1 -1
  63. data/lib/action_dispatch/journey/nfa/transition_table.rb +5 -5
  64. data/lib/action_dispatch/journey/nodes/node.rb +4 -0
  65. data/lib/action_dispatch/journey/parser.rb +51 -59
  66. data/lib/action_dispatch/journey/parser.y +12 -10
  67. data/lib/action_dispatch/journey/path/pattern.rb +16 -19
  68. data/lib/action_dispatch/journey/route.rb +8 -19
  69. data/lib/action_dispatch/journey/router/strexp.rb +9 -6
  70. data/lib/action_dispatch/journey/router/utils.rb +54 -18
  71. data/lib/action_dispatch/journey/router.rb +53 -75
  72. data/lib/action_dispatch/journey/routes.rb +4 -0
  73. data/lib/action_dispatch/journey/scanner.rb +5 -5
  74. data/lib/action_dispatch/journey/visitors.rb +81 -60
  75. data/lib/action_dispatch/journey/visualizer/fsm.css +0 -4
  76. data/lib/action_dispatch/journey/visualizer/index.html.erb +2 -2
  77. data/lib/action_dispatch/middleware/callbacks.rb +7 -7
  78. data/lib/action_dispatch/middleware/cookies.rb +119 -43
  79. data/lib/action_dispatch/middleware/debug_exceptions.rb +32 -13
  80. data/lib/action_dispatch/middleware/exception_wrapper.rb +60 -20
  81. data/lib/action_dispatch/middleware/flash.rb +37 -24
  82. data/lib/action_dispatch/middleware/params_parser.rb +2 -2
  83. data/lib/action_dispatch/middleware/public_exceptions.rb +12 -3
  84. data/lib/action_dispatch/middleware/reloader.rb +11 -2
  85. data/lib/action_dispatch/middleware/remote_ip.rb +40 -54
  86. data/lib/action_dispatch/middleware/request_id.rb +1 -1
  87. data/lib/action_dispatch/middleware/session/cache_store.rb +3 -3
  88. data/lib/action_dispatch/middleware/session/cookie_store.rb +8 -7
  89. data/lib/action_dispatch/middleware/show_exceptions.rb +6 -2
  90. data/lib/action_dispatch/middleware/ssl.rb +10 -7
  91. data/lib/action_dispatch/middleware/static.rb +79 -23
  92. data/lib/action_dispatch/middleware/templates/rescues/{_request_and_response.erb → _request_and_response.html.erb} +0 -0
  93. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +23 -0
  94. data/lib/action_dispatch/middleware/templates/rescues/_source.erb +21 -19
  95. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +52 -0
  96. data/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb +9 -0
  97. data/lib/action_dispatch/middleware/templates/rescues/{diagnostics.erb → diagnostics.html.erb} +1 -1
  98. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +9 -0
  99. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +6 -0
  100. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +11 -0
  101. data/lib/action_dispatch/middleware/templates/rescues/missing_template.text.erb +3 -0
  102. data/lib/action_dispatch/middleware/templates/rescues/{routing_error.erb → routing_error.html.erb} +3 -1
  103. data/lib/action_dispatch/middleware/templates/rescues/routing_error.text.erb +11 -0
  104. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +20 -0
  105. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +7 -0
  106. data/lib/action_dispatch/middleware/templates/rescues/{unknown_action.erb → unknown_action.html.erb} +1 -1
  107. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +3 -0
  108. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +120 -64
  109. data/lib/action_dispatch/railtie.rb +5 -2
  110. data/lib/action_dispatch/request/session.rb +12 -0
  111. data/lib/action_dispatch/request/utils.rb +35 -0
  112. data/lib/action_dispatch/routing/endpoint.rb +10 -0
  113. data/lib/action_dispatch/routing/inspector.rb +11 -17
  114. data/lib/action_dispatch/routing/mapper.rb +519 -312
  115. data/lib/action_dispatch/routing/polymorphic_routes.rb +204 -79
  116. data/lib/action_dispatch/routing/redirection.rb +51 -26
  117. data/lib/action_dispatch/routing/route_set.rb +331 -206
  118. data/lib/action_dispatch/routing/routes_proxy.rb +5 -4
  119. data/lib/action_dispatch/routing/url_for.rb +19 -5
  120. data/lib/action_dispatch/routing.rb +9 -6
  121. data/lib/action_dispatch/testing/assertions/dom.rb +2 -26
  122. data/lib/action_dispatch/testing/assertions/response.rb +9 -15
  123. data/lib/action_dispatch/testing/assertions/routing.rb +22 -22
  124. data/lib/action_dispatch/testing/assertions/selector.rb +2 -429
  125. data/lib/action_dispatch/testing/assertions/tag.rb +2 -134
  126. data/lib/action_dispatch/testing/assertions.rb +11 -7
  127. data/lib/action_dispatch/testing/integration.rb +31 -29
  128. data/lib/action_dispatch/testing/test_request.rb +1 -1
  129. data/lib/action_dispatch/testing/test_response.rb +1 -5
  130. data/lib/action_dispatch.rb +5 -8
  131. data/lib/action_pack/gem_version.rb +15 -0
  132. data/lib/action_pack/version.rb +4 -7
  133. data/lib/action_pack.rb +1 -1
  134. metadata +77 -159
  135. data/lib/abstract_controller/layouts.rb +0 -423
  136. data/lib/abstract_controller/view_paths.rb +0 -96
  137. data/lib/action_controller/deprecated/integration_test.rb +0 -5
  138. data/lib/action_controller/deprecated.rb +0 -7
  139. data/lib/action_controller/metal/responder.rb +0 -287
  140. data/lib/action_controller/record_identifier.rb +0 -31
  141. data/lib/action_controller/vendor/html-scanner.rb +0 -5
  142. data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +0 -24
  143. data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +0 -7
  144. data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +0 -43
  145. data/lib/action_view/base.rb +0 -201
  146. data/lib/action_view/buffers.rb +0 -49
  147. data/lib/action_view/context.rb +0 -36
  148. data/lib/action_view/dependency_tracker.rb +0 -93
  149. data/lib/action_view/digestor.rb +0 -113
  150. data/lib/action_view/flows.rb +0 -76
  151. data/lib/action_view/helpers/active_model_helper.rb +0 -49
  152. data/lib/action_view/helpers/asset_tag_helper.rb +0 -320
  153. data/lib/action_view/helpers/asset_url_helper.rb +0 -355
  154. data/lib/action_view/helpers/atom_feed_helper.rb +0 -203
  155. data/lib/action_view/helpers/cache_helper.rb +0 -196
  156. data/lib/action_view/helpers/capture_helper.rb +0 -216
  157. data/lib/action_view/helpers/controller_helper.rb +0 -25
  158. data/lib/action_view/helpers/csrf_helper.rb +0 -30
  159. data/lib/action_view/helpers/date_helper.rb +0 -1083
  160. data/lib/action_view/helpers/debug_helper.rb +0 -39
  161. data/lib/action_view/helpers/form_helper.rb +0 -1880
  162. data/lib/action_view/helpers/form_options_helper.rb +0 -838
  163. data/lib/action_view/helpers/form_tag_helper.rb +0 -785
  164. data/lib/action_view/helpers/javascript_helper.rb +0 -117
  165. data/lib/action_view/helpers/number_helper.rb +0 -441
  166. data/lib/action_view/helpers/output_safety_helper.rb +0 -38
  167. data/lib/action_view/helpers/record_tag_helper.rb +0 -106
  168. data/lib/action_view/helpers/rendering_helper.rb +0 -90
  169. data/lib/action_view/helpers/sanitize_helper.rb +0 -256
  170. data/lib/action_view/helpers/tag_helper.rb +0 -173
  171. data/lib/action_view/helpers/tags/base.rb +0 -148
  172. data/lib/action_view/helpers/tags/check_box.rb +0 -64
  173. data/lib/action_view/helpers/tags/checkable.rb +0 -16
  174. data/lib/action_view/helpers/tags/collection_check_boxes.rb +0 -44
  175. data/lib/action_view/helpers/tags/collection_helpers.rb +0 -84
  176. data/lib/action_view/helpers/tags/collection_radio_buttons.rb +0 -36
  177. data/lib/action_view/helpers/tags/collection_select.rb +0 -28
  178. data/lib/action_view/helpers/tags/color_field.rb +0 -25
  179. data/lib/action_view/helpers/tags/date_field.rb +0 -13
  180. data/lib/action_view/helpers/tags/date_select.rb +0 -72
  181. data/lib/action_view/helpers/tags/datetime_field.rb +0 -22
  182. data/lib/action_view/helpers/tags/datetime_local_field.rb +0 -19
  183. data/lib/action_view/helpers/tags/datetime_select.rb +0 -8
  184. data/lib/action_view/helpers/tags/email_field.rb +0 -8
  185. data/lib/action_view/helpers/tags/file_field.rb +0 -8
  186. data/lib/action_view/helpers/tags/grouped_collection_select.rb +0 -29
  187. data/lib/action_view/helpers/tags/hidden_field.rb +0 -8
  188. data/lib/action_view/helpers/tags/label.rb +0 -66
  189. data/lib/action_view/helpers/tags/month_field.rb +0 -13
  190. data/lib/action_view/helpers/tags/number_field.rb +0 -18
  191. data/lib/action_view/helpers/tags/password_field.rb +0 -12
  192. data/lib/action_view/helpers/tags/radio_button.rb +0 -31
  193. data/lib/action_view/helpers/tags/range_field.rb +0 -8
  194. data/lib/action_view/helpers/tags/search_field.rb +0 -24
  195. data/lib/action_view/helpers/tags/select.rb +0 -40
  196. data/lib/action_view/helpers/tags/tel_field.rb +0 -8
  197. data/lib/action_view/helpers/tags/text_area.rb +0 -18
  198. data/lib/action_view/helpers/tags/text_field.rb +0 -29
  199. data/lib/action_view/helpers/tags/time_field.rb +0 -13
  200. data/lib/action_view/helpers/tags/time_select.rb +0 -8
  201. data/lib/action_view/helpers/tags/time_zone_select.rb +0 -20
  202. data/lib/action_view/helpers/tags/url_field.rb +0 -8
  203. data/lib/action_view/helpers/tags/week_field.rb +0 -13
  204. data/lib/action_view/helpers/tags.rb +0 -39
  205. data/lib/action_view/helpers/text_helper.rb +0 -443
  206. data/lib/action_view/helpers/translation_helper.rb +0 -107
  207. data/lib/action_view/helpers/url_helper.rb +0 -635
  208. data/lib/action_view/helpers.rb +0 -58
  209. data/lib/action_view/locale/en.yml +0 -56
  210. data/lib/action_view/log_subscriber.rb +0 -30
  211. data/lib/action_view/lookup_context.rb +0 -241
  212. data/lib/action_view/model_naming.rb +0 -12
  213. data/lib/action_view/path_set.rb +0 -77
  214. data/lib/action_view/railtie.rb +0 -43
  215. data/lib/action_view/record_identifier.rb +0 -84
  216. data/lib/action_view/renderer/abstract_renderer.rb +0 -47
  217. data/lib/action_view/renderer/partial_renderer.rb +0 -492
  218. data/lib/action_view/renderer/renderer.rb +0 -50
  219. data/lib/action_view/renderer/streaming_template_renderer.rb +0 -103
  220. data/lib/action_view/renderer/template_renderer.rb +0 -96
  221. data/lib/action_view/routing_url_for.rb +0 -107
  222. data/lib/action_view/tasks/dependencies.rake +0 -17
  223. data/lib/action_view/template/error.rb +0 -138
  224. data/lib/action_view/template/handlers/builder.rb +0 -26
  225. data/lib/action_view/template/handlers/erb.rb +0 -146
  226. data/lib/action_view/template/handlers/raw.rb +0 -11
  227. data/lib/action_view/template/handlers.rb +0 -53
  228. data/lib/action_view/template/resolver.rb +0 -326
  229. data/lib/action_view/template/text.rb +0 -34
  230. data/lib/action_view/template/types.rb +0 -57
  231. data/lib/action_view/template.rb +0 -339
  232. data/lib/action_view/test_case.rb +0 -270
  233. data/lib/action_view/testing/resolvers.rb +0 -50
  234. data/lib/action_view/vendor/html-scanner/html/document.rb +0 -68
  235. data/lib/action_view/vendor/html-scanner/html/node.rb +0 -532
  236. data/lib/action_view/vendor/html-scanner/html/sanitizer.rb +0 -188
  237. data/lib/action_view/vendor/html-scanner/html/selector.rb +0 -830
  238. data/lib/action_view/vendor/html-scanner/html/tokenizer.rb +0 -107
  239. data/lib/action_view/vendor/html-scanner/html/version.rb +0 -11
  240. data/lib/action_view/vendor/html-scanner.rb +0 -20
  241. data/lib/action_view.rb +0 -93
@@ -0,0 +1,23 @@
1
+ <%
2
+ clean_params = @request.filtered_parameters.clone
3
+ clean_params.delete("action")
4
+ clean_params.delete("controller")
5
+
6
+ request_dump = clean_params.empty? ? 'None' : clean_params.inspect.gsub(',', ",\n")
7
+
8
+ def debug_hash(object)
9
+ object.to_hash.sort_by { |k, _| k.to_s }.map { |k, v| "#{k}: #{v.inspect rescue $!.message}" }.join("\n")
10
+ end unless self.class.method_defined?(:debug_hash)
11
+ %>
12
+
13
+ Request parameters
14
+ <%= request_dump %>
15
+
16
+ Session dump
17
+ <%= debug_hash @request.session %>
18
+
19
+ Env dump
20
+ <%= debug_hash @request.env.slice(*@request.class::ENV_METHODS) %>
21
+
22
+ Response headers
23
+ <%= defined?(@response) ? @response.headers.inspect.gsub(',', ",\n") : 'None' %>
@@ -1,25 +1,27 @@
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| %>
1
+ <% @source_extracts.each_with_index do |source_extract, index| %>
2
+ <% if source_extract[:code] %>
3
+ <div class="source <%="hidden" if @show_source_idx != index%>" id="frame-source-<%=index%>">
4
+ <div class="info">
5
+ Extracted source (around line <strong>#<%= source_extract[:line_number] %></strong>):
6
+ </div>
7
+ <div class="data">
8
+ <table cellpadding="0" cellspacing="0" class="lines">
9
+ <tr>
10
+ <td>
11
+ <pre class="line_numbers">
12
+ <% source_extract[:code].each_key do |line_number| %>
12
13
  <span><%= line_number -%></span>
13
- <% end %>
14
- </pre>
15
- </td>
14
+ <% end %>
15
+ </pre>
16
+ </td>
16
17
  <td width="100%">
17
18
  <pre>
18
- <% @source_extract.each do |line, source| -%><div class="line<%= " active" if line == @line_number -%>"><%= source -%></div><% end -%>
19
+ <% source_extract[:code].each do |line, source| -%><div class="line<%= " active" if line == source_extract[:line_number] -%>"><%= source -%></div><% end -%>
19
20
  </pre>
20
21
  </td>
21
- </tr>
22
- </table>
23
- </div>
24
- </div>
22
+ </tr>
23
+ </table>
24
+ </div>
25
+ </div>
26
+ <% end %>
25
27
  <% end %>
@@ -0,0 +1,52 @@
1
+ <% names = @traces.keys %>
2
+
3
+ <p><code>Rails.root: <%= defined?(Rails) && Rails.respond_to?(:root) ? Rails.root : "unset" %></code></p>
4
+
5
+ <div id="traces">
6
+ <% names.each do |name| %>
7
+ <%
8
+ show = "show('#{name.gsub(/\s/, '-')}');"
9
+ hide = (names - [name]).collect {|hide_name| "hide('#{hide_name.gsub(/\s/, '-')}');"}
10
+ %>
11
+ <a href="#" onclick="<%= hide.join %><%= show %>; return false;"><%= name %></a> <%= '|' unless names.last == name %>
12
+ <% end %>
13
+
14
+ <% @traces.each do |name, trace| %>
15
+ <div id="<%= name.gsub(/\s/, '-') %>" style="display: <%= (name == @trace_to_show) ? 'block' : 'none' %>;">
16
+ <pre><code><% trace.each do |frame| %><a class="trace-frames" data-frame-id="<%= frame[:id] %>" href="#"><%= frame[:trace] %></a><br><% end %></code></pre>
17
+ </div>
18
+ <% end %>
19
+
20
+ <script type="text/javascript">
21
+ var traceFrames = document.getElementsByClassName('trace-frames');
22
+ var selectedFrame, currentSource = document.getElementById('frame-source-0');
23
+
24
+ // Add click listeners for all stack frames
25
+ for (var i = 0; i < traceFrames.length; i++) {
26
+ traceFrames[i].addEventListener('click', function(e) {
27
+ e.preventDefault();
28
+ var target = e.target;
29
+ var frame_id = target.dataset.frameId;
30
+
31
+ if (selectedFrame) {
32
+ selectedFrame.className = selectedFrame.className.replace("selected", "");
33
+ }
34
+
35
+ target.className += " selected";
36
+ selectedFrame = target;
37
+
38
+ // Change the extracted source code
39
+ changeSourceExtract(frame_id);
40
+ });
41
+
42
+ function changeSourceExtract(frame_id) {
43
+ var el = document.getElementById('frame-source-' + frame_id);
44
+ if (currentSource && el) {
45
+ currentSource.className += " hidden";
46
+ el.className = el.className.replace(" hidden", "");
47
+ currentSource = el;
48
+ }
49
+ }
50
+ }
51
+ </script>
52
+ </div>
@@ -0,0 +1,9 @@
1
+ Rails.root: <%= defined?(Rails) && Rails.respond_to?(:root) ? Rails.root : "unset" %>
2
+
3
+ <% @traces.each do |name, trace| %>
4
+ <% if trace.any? %>
5
+ <%= name %>
6
+ <%= trace.map { |t| t[:trace] }.join("\n") %>
7
+
8
+ <% end %>
9
+ <% end %>
@@ -8,7 +8,7 @@
8
8
  </header>
9
9
 
10
10
  <div id="container">
11
- <h2><%= @exception.message %></h2>
11
+ <h2><%= h @exception.message %></h2>
12
12
 
13
13
  <%= render template: "rescues/_source" %>
14
14
  <%= render template: "rescues/_trace" %>
@@ -0,0 +1,9 @@
1
+ <%= @exception.class.to_s %><%
2
+ if @request.parameters['controller']
3
+ %> in <%= @request.parameters['controller'].camelize %>Controller<% if @request.parameters['action'] %>#<%= @request.parameters['action'] %><% end %>
4
+ <% end %>
5
+
6
+ <%= @exception.message %>
7
+ <%= render template: "rescues/_source" %>
8
+ <%= render template: "rescues/_trace" %>
9
+ <%= render template: "rescues/_request_and_response" %>
@@ -116,9 +116,15 @@
116
116
  background-color: #FFCCCC;
117
117
  }
118
118
 
119
+ .hidden {
120
+ display: none;
121
+ }
122
+
119
123
  a { color: #980905; }
120
124
  a:visited { color: #666; }
125
+ a.trace-frames { color: #666; }
121
126
  a:hover { color: #C52F24; }
127
+ a.trace-frames.selected { color: #C52F24 }
122
128
 
123
129
  <%= yield :style %>
124
130
  </style>
@@ -0,0 +1,11 @@
1
+ <header>
2
+ <h1>Template is missing</h1>
3
+ </header>
4
+
5
+ <div id="container">
6
+ <h2><%= h @exception.message %></h2>
7
+
8
+ <%= render template: "rescues/_source" %>
9
+ <%= render template: "rescues/_trace" %>
10
+ <%= render template: "rescues/_request_and_response" %>
11
+ </div>
@@ -0,0 +1,3 @@
1
+ Template is missing
2
+
3
+ <%= @exception.message %>
@@ -2,7 +2,7 @@
2
2
  <h1>Routing Error</h1>
3
3
  </header>
4
4
  <div id="container">
5
- <h2><%= @exception.message %></h2>
5
+ <h2><%= h @exception.message %></h2>
6
6
  <% unless @exception.failures.empty? %>
7
7
  <p>
8
8
  <h2>Failure reasons:</h2>
@@ -27,4 +27,6 @@
27
27
 
28
28
  <%= @routes_inspector.format(ActionDispatch::Routing::HtmlTableFormatter.new(self)) %>
29
29
  <% end %>
30
+
31
+ <%= render template: "rescues/_request_and_response" %>
30
32
  </div>
@@ -0,0 +1,11 @@
1
+ Routing Error
2
+
3
+ <%= @exception.message %>
4
+ <% unless @exception.failures.empty? %>
5
+ Failure reasons:
6
+ <% @exception.failures.each do |route, reason| %>
7
+ - <%= route.inspect.delete('\\') %></code> failed because <%= reason.downcase %>
8
+ <% end %>
9
+ <% end %>
10
+
11
+ <%= render template: "rescues/_trace", format: :text %>
@@ -0,0 +1,20 @@
1
+ <header>
2
+ <h1>
3
+ <%= @exception.original_exception.class.to_s %> in
4
+ <%= @request.parameters["controller"].camelize if @request.parameters["controller"] %>#<%= @request.parameters["action"] %>
5
+ </h1>
6
+ </header>
7
+
8
+ <div id="container">
9
+ <p>
10
+ Showing <i><%= @exception.file_name %></i> where line <b>#<%= @exception.line_number %></b> raised:
11
+ </p>
12
+ <pre><code><%= h @exception.message %></code></pre>
13
+
14
+ <%= render template: "rescues/_source" %>
15
+
16
+ <p><%= @exception.sub_template_message %></p>
17
+
18
+ <%= render template: "rescues/_trace" %>
19
+ <%= render template: "rescues/_request_and_response" %>
20
+ </div>
@@ -0,0 +1,7 @@
1
+ <%= @exception.original_exception.class.to_s %> in <%= @request.parameters["controller"].camelize if @request.parameters["controller"] %>#<%= @request.parameters["action"] %>
2
+
3
+ Showing <%= @exception.file_name %> where line #<%= @exception.line_number %> raised:
4
+ <%= @exception.message %>
5
+ <%= @exception.sub_template_message %>
6
+ <%= render template: "rescues/_trace", format: :text %>
7
+ <%= render template: "rescues/_request_and_response", format: :text %>
@@ -2,5 +2,5 @@
2
2
  <h1>Unknown action</h1>
3
3
  </header>
4
4
  <div id="container">
5
- <h2><%= @exception.message %></h2>
5
+ <h2><%= h @exception.message %></h2>
6
6
  </div>
@@ -0,0 +1,3 @@
1
+ Unknown action
2
+
3
+ <%= @exception.message %>
@@ -1,24 +1,44 @@
1
1
  <% content_for :style do %>
2
2
  #route_table {
3
- margin: 0 auto 0;
3
+ margin: 0;
4
4
  border-collapse: collapse;
5
5
  }
6
6
 
7
- #route_table td {
8
- padding: 0 30px;
7
+ #route_table thead tr {
8
+ border-bottom: 2px solid #ddd;
9
+ }
10
+
11
+ #route_table thead tr.bottom {
12
+ border-bottom: none;
9
13
  }
10
14
 
11
- #route_table tr.bottom th {
12
- padding-bottom: 10px;
15
+ #route_table thead tr.bottom th {
16
+ padding: 10px 0;
13
17
  line-height: 15px;
14
18
  }
15
19
 
16
- #route_table .matched_paths {
20
+ #route_table tbody tr {
21
+ border-bottom: 1px solid #ddd;
22
+ }
23
+
24
+ #route_table tbody tr:nth-child(odd) {
25
+ background: #f2f2f2;
26
+ }
27
+
28
+ #route_table tbody.exact_matches,
29
+ #route_table tbody.fuzzy_matches {
17
30
  background-color: LightGoldenRodYellow;
31
+ border-bottom: solid 2px SlateGrey;
18
32
  }
19
33
 
20
- #route_table .matched_paths {
21
- border-bottom: solid 3px SlateGrey;
34
+ #route_table tbody.exact_matches tr,
35
+ #route_table tbody.fuzzy_matches tr {
36
+ background: none;
37
+ border-bottom: none;
38
+ }
39
+
40
+ #route_table td {
41
+ padding: 4px 30px;
22
42
  }
23
43
 
24
44
  #path_search {
@@ -45,13 +65,15 @@
45
65
  <th><%# HTTP Verb %>
46
66
  </th>
47
67
  <th><%# Path %>
48
- <%= search_field(:path, nil, id: 'path_search', placeholder: "Path Match") %>
68
+ <%= search_field(:path, nil, id: 'search', placeholder: "Path Match") %>
49
69
  </th>
50
70
  <th><%# Controller#action %>
51
71
  </th>
52
72
  </tr>
53
73
  </thead>
54
- <tbody class='matched_paths' id='matched_paths'>
74
+ <tbody class='exact_matches' id='exact_matches'>
75
+ </tbody>
76
+ <tbody class='fuzzy_matches' id='fuzzy_matches'>
55
77
  </tbody>
56
78
  <tbody>
57
79
  <%= yield %>
@@ -59,6 +81,7 @@
59
81
  </table>
60
82
 
61
83
  <script type='text/javascript'>
84
+ // Iterates each element through a function
62
85
  function each(elems, func) {
63
86
  if (!elems instanceof Array) { elems = [elems]; }
64
87
  for (var i = 0, len = elems.length; i < len; i++) {
@@ -66,77 +89,110 @@
66
89
  }
67
90
  }
68
91
 
69
- function setValOn(elems, val) {
70
- each(elems, function(elem) {
71
- elem.innerHTML = val;
72
- });
92
+ // Sets innerHTML for an element
93
+ function setContent(elem, text) {
94
+ elem.innerHTML = text;
73
95
  }
74
96
 
75
- function onClick(elems, func) {
76
- each(elems, function(elem) {
77
- elem.onclick = func;
78
- });
79
- }
97
+ // Enables path search functionality
98
+ function setupMatchPaths() {
99
+ // Check if the user input (sanitized as a path) matches the regexp data attribute
100
+ function checkExactMatch(section, elem, value) {
101
+ var string = sanitizePath(value),
102
+ regexp = elem.getAttribute("data-regexp");
80
103
 
81
- // Enables functionality to toggle between `_path` and `_url` helper suffixes
82
- function setupRouteToggleHelperLinks() {
83
- var toggleLinks = document.querySelectorAll('#route_table [data-route-helper]');
84
- onClick(toggleLinks, function(){
85
- var helperTxt = this.getAttribute("data-route-helper"),
86
- helperElems = document.querySelectorAll('[data-route-name] span.helper');
87
- setValOn(helperElems, helperTxt);
88
- });
89
- }
104
+ showMatch(string, regexp, section, elem);
105
+ }
90
106
 
91
- // takes an array of elements with a data-regexp attribute and
92
- // passes their their parent <tr> into the callback function
93
- // if the regexp matchs a given path
94
- function eachElemsForPath(elems, path, func) {
95
- each(elems, function(e){
96
- var reg = e.getAttribute("data-regexp");
97
- if (path.match(RegExp(reg))) {
98
- func(e.parentNode.cloneNode(true));
99
- }
100
- })
101
- }
107
+ // Check if the route path data attribute contains the user input
108
+ function checkFuzzyMatch(section, elem, value) {
109
+ var string = elem.getAttribute("data-route-path"),
110
+ regexp = value;
102
111
 
103
- // Ensure path always starts with a slash "/" and remove params or fragments
104
- function sanitizePath(path) {
105
- var path = path.charAt(0) == '/' ? path : "/" + path;
106
- return path.replace(/\#.*|\?.*/, '');
107
- }
112
+ showMatch(string, regexp, section, elem);
113
+ }
108
114
 
109
- // Enables path search functionality
110
- function setupMatchPaths() {
111
- var regexpElems = document.querySelectorAll('#route_table [data-regexp]'),
112
- pathElem = document.querySelector('#path_search'),
113
- selectedSection = document.querySelector('#matched_paths'),
114
- noMatchText = '<tr><th colspan="4">None</th></tr>';
115
+ // Display the parent <tr> element in the appropriate section when there's a match
116
+ function showMatch(string, regexp, section, elem) {
117
+ if(string.match(RegExp(regexp))) {
118
+ section.appendChild(elem.parentNode.cloneNode(true));
119
+ }
120
+ }
121
+
122
+ // Check if there are any matched results in a section
123
+ function checkNoMatch(section, defaultText, noMatchText) {
124
+ if (section.innerHTML === defaultText) {
125
+ setContent(section, defaultText + noMatchText);
126
+ }
127
+ }
115
128
 
129
+ // Ensure path always starts with a slash "/" and remove params or fragments
130
+ function sanitizePath(path) {
131
+ var path = path.charAt(0) == '/' ? path : "/" + path;
132
+ return path.replace(/\#.*|\?.*/, '');
133
+ }
116
134
 
117
- // Remove matches if no path is present
118
- pathElem.onblur = function(e) {
119
- if (pathElem.value === "") selectedSection.innerHTML = "";
135
+ var regexpElems = document.querySelectorAll('#route_table [data-regexp]'),
136
+ searchElem = document.querySelector('#search'),
137
+ exactMatches = document.querySelector('#exact_matches'),
138
+ fuzzyMatches = document.querySelector('#fuzzy_matches');
139
+
140
+ // Remove matches when no search value is present
141
+ searchElem.onblur = function(e) {
142
+ if (searchElem.value === "") {
143
+ setContent(exactMatches, "");
144
+ setContent(fuzzyMatches, "");
145
+ }
120
146
  }
121
147
 
122
148
  // On key press perform a search for matching paths
123
- pathElem.onkeyup = function(e){
124
- var path = sanitizePath(pathElem.value),
125
- defaultText = '<tr><th colspan="4">Paths Matching (' + path + '):</th></tr>';
149
+ searchElem.onkeyup = function(e){
150
+ var userInput = searchElem.value,
151
+ defaultExactMatch = '<tr><th colspan="4">Paths Matching (' + escape(sanitizePath(userInput)) +'):</th></tr>',
152
+ defaultFuzzyMatch = '<tr><th colspan="4">Paths Containing (' + escape(userInput) +'):</th></tr>',
153
+ noExactMatch = '<tr><th colspan="4">No Exact Matches Found</th></tr>',
154
+ noFuzzyMatch = '<tr><th colspan="4">No Fuzzy Matches Found</th></tr>';
126
155
 
127
156
  // Clear out results section
128
- selectedSection.innerHTML= defaultText;
157
+ setContent(exactMatches, defaultExactMatch);
158
+ setContent(fuzzyMatches, defaultFuzzyMatch);
159
+
160
+ // Display exact matches and fuzzy matches
161
+ each(regexpElems, function(elem) {
162
+ checkExactMatch(exactMatches, elem, userInput);
163
+ checkFuzzyMatch(fuzzyMatches, elem, userInput);
164
+ })
165
+
166
+ // Display 'No Matches' message when no matches are found
167
+ checkNoMatch(exactMatches, defaultExactMatch, noExactMatch);
168
+ checkNoMatch(fuzzyMatches, defaultFuzzyMatch, noFuzzyMatch);
169
+ }
170
+ }
129
171
 
130
- // Display matches if they exist
131
- eachElemsForPath(regexpElems, path, function(e){
132
- selectedSection.appendChild(e);
172
+ // Enables functionality to toggle between `_path` and `_url` helper suffixes
173
+ function setupRouteToggleHelperLinks() {
174
+
175
+ // Sets content for each element
176
+ function setValOn(elems, val) {
177
+ each(elems, function(elem) {
178
+ setContent(elem, val);
133
179
  });
180
+ }
134
181
 
135
- // If no match present, tell the user
136
- if (selectedSection.innerHTML === defaultText) {
137
- selectedSection.innerHTML = selectedSection.innerHTML + noMatchText;
138
- }
182
+ // Sets onClick event for each element
183
+ function onClick(elems, func) {
184
+ each(elems, function(elem) {
185
+ elem.onclick = func;
186
+ });
139
187
  }
188
+
189
+ var toggleLinks = document.querySelectorAll('#route_table [data-route-helper]');
190
+ onClick(toggleLinks, function(){
191
+ var helperTxt = this.getAttribute("data-route-helper"),
192
+ helperElems = document.querySelectorAll('[data-route-name] span.helper');
193
+
194
+ setValOn(helperElems, helperTxt);
195
+ });
140
196
  }
141
197
 
142
198
  setupMatchPaths();
@@ -16,12 +16,12 @@ module ActionDispatch
16
16
  config.action_dispatch.signed_cookie_salt = 'signed cookie'
17
17
  config.action_dispatch.encrypted_cookie_salt = 'encrypted cookie'
18
18
  config.action_dispatch.encrypted_signed_cookie_salt = 'signed encrypted cookie'
19
+ config.action_dispatch.perform_deep_munge = true
19
20
 
20
21
  config.action_dispatch.default_headers = {
21
22
  'X-Frame-Options' => 'SAMEORIGIN',
22
23
  'X-XSS-Protection' => '1; mode=block',
23
- 'X-Content-Type-Options' => 'nosniff',
24
- 'X-UA-Compatible' => 'chrome=1'
24
+ 'X-Content-Type-Options' => 'nosniff'
25
25
  }
26
26
 
27
27
  config.eager_load_namespaces << ActionDispatch
@@ -29,6 +29,7 @@ module ActionDispatch
29
29
  initializer "action_dispatch.configure" do |app|
30
30
  ActionDispatch::Http::URL.tld_length = app.config.action_dispatch.tld_length
31
31
  ActionDispatch::Request.ignore_accept_header = app.config.action_dispatch.ignore_accept_header
32
+ ActionDispatch::Request::Utils.perform_deep_munge = app.config.action_dispatch.perform_deep_munge
32
33
  ActionDispatch::Response.default_charset = app.config.action_dispatch.default_charset || app.config.encoding
33
34
  ActionDispatch::Response.default_headers = app.config.action_dispatch.default_headers
34
35
 
@@ -39,6 +40,8 @@ module ActionDispatch
39
40
  ActionDispatch::Cookies::CookieJar.always_write_cookie = config.action_dispatch.always_write_cookie
40
41
 
41
42
  ActionDispatch.test_app = app
43
+
44
+ ActionDispatch::Routing::RouteSet.relative_url_root = app.config.relative_url_root
42
45
  end
43
46
  end
44
47
  end
@@ -7,6 +7,9 @@ module ActionDispatch
7
7
  ENV_SESSION_KEY = Rack::Session::Abstract::ENV_SESSION_KEY # :nodoc:
8
8
  ENV_SESSION_OPTIONS_KEY = Rack::Session::Abstract::ENV_SESSION_OPTIONS_KEY # :nodoc:
9
9
 
10
+ # Singleton object used to determine if an optional param wasn't specified
11
+ Unspecified = Object.new
12
+
10
13
  def self.create(store, env, default_options)
11
14
  session_was = find env
12
15
  session = Request::Session.new(store, env)
@@ -127,6 +130,15 @@ module ActionDispatch
127
130
  @delegate.delete key.to_s
128
131
  end
129
132
 
133
+ def fetch(key, default=Unspecified, &block)
134
+ load_for_read!
135
+ if default == Unspecified
136
+ @delegate.fetch(key.to_s, &block)
137
+ else
138
+ @delegate.fetch(key.to_s, default, &block)
139
+ end
140
+ end
141
+
130
142
  def inspect
131
143
  if loaded?
132
144
  super
@@ -0,0 +1,35 @@
1
+ module ActionDispatch
2
+ class Request < Rack::Request
3
+ class Utils # :nodoc:
4
+
5
+ mattr_accessor :perform_deep_munge
6
+ self.perform_deep_munge = true
7
+
8
+ class << self
9
+ # Remove nils from the params hash
10
+ def deep_munge(hash, keys = [])
11
+ return hash unless perform_deep_munge
12
+
13
+ hash.each do |k, v|
14
+ keys << k
15
+ case v
16
+ when Array
17
+ v.grep(Hash) { |x| deep_munge(x, keys) }
18
+ v.compact!
19
+ if v.empty?
20
+ hash[k] = nil
21
+ ActiveSupport::Notifications.instrument("deep_munge.action_controller", keys: keys)
22
+ end
23
+ when Hash
24
+ deep_munge(v, keys)
25
+ end
26
+ keys.pop
27
+ end
28
+
29
+ hash
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+
@@ -0,0 +1,10 @@
1
+ module ActionDispatch
2
+ module Routing
3
+ class Endpoint # :nodoc:
4
+ def dispatcher?; false; end
5
+ def redirect?; false; end
6
+ def matches?(req); true; end
7
+ def app; self; end
8
+ end
9
+ end
10
+ end