actionpack 3.2.22.5 → 5.2.4

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 (271) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +279 -603
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +13 -297
  5. data/lib/abstract_controller/asset_paths.rb +4 -2
  6. data/lib/abstract_controller/base.rb +82 -52
  7. data/lib/abstract_controller/caching/fragments.rb +166 -0
  8. data/lib/abstract_controller/caching.rb +66 -0
  9. data/lib/abstract_controller/callbacks.rb +117 -103
  10. data/lib/abstract_controller/collector.rb +18 -7
  11. data/lib/abstract_controller/error.rb +6 -0
  12. data/lib/abstract_controller/helpers.rb +65 -38
  13. data/lib/abstract_controller/logger.rb +3 -2
  14. data/lib/abstract_controller/railties/routes_helpers.rb +5 -3
  15. data/lib/abstract_controller/rendering.rb +77 -129
  16. data/lib/abstract_controller/translation.rb +21 -3
  17. data/lib/abstract_controller/url_for.rb +9 -7
  18. data/lib/abstract_controller.rb +12 -13
  19. data/lib/action_controller/api/api_rendering.rb +16 -0
  20. data/lib/action_controller/api.rb +149 -0
  21. data/lib/action_controller/base.rb +81 -40
  22. data/lib/action_controller/caching.rb +22 -62
  23. data/lib/action_controller/form_builder.rb +50 -0
  24. data/lib/action_controller/log_subscriber.rb +30 -18
  25. data/lib/action_controller/metal/basic_implicit_render.rb +13 -0
  26. data/lib/action_controller/metal/conditional_get.rb +190 -47
  27. data/lib/action_controller/metal/content_security_policy.rb +52 -0
  28. data/lib/action_controller/metal/cookies.rb +3 -3
  29. data/lib/action_controller/metal/data_streaming.rb +40 -65
  30. data/lib/action_controller/metal/etag_with_flash.rb +18 -0
  31. data/lib/action_controller/metal/etag_with_template_digest.rb +57 -0
  32. data/lib/action_controller/metal/exceptions.rb +19 -12
  33. data/lib/action_controller/metal/flash.rb +42 -9
  34. data/lib/action_controller/metal/force_ssl.rb +79 -19
  35. data/lib/action_controller/metal/head.rb +35 -10
  36. data/lib/action_controller/metal/helpers.rb +31 -21
  37. data/lib/action_controller/metal/http_authentication.rb +182 -134
  38. data/lib/action_controller/metal/implicit_render.rb +62 -8
  39. data/lib/action_controller/metal/instrumentation.rb +28 -26
  40. data/lib/action_controller/metal/live.rb +312 -0
  41. data/lib/action_controller/metal/mime_responds.rb +159 -163
  42. data/lib/action_controller/metal/parameter_encoding.rb +51 -0
  43. data/lib/action_controller/metal/params_wrapper.rb +146 -93
  44. data/lib/action_controller/metal/redirecting.rb +80 -56
  45. data/lib/action_controller/metal/renderers.rb +119 -47
  46. data/lib/action_controller/metal/rendering.rb +89 -32
  47. data/lib/action_controller/metal/request_forgery_protection.rb +373 -41
  48. data/lib/action_controller/metal/rescue.rb +9 -16
  49. data/lib/action_controller/metal/streaming.rb +39 -45
  50. data/lib/action_controller/metal/strong_parameters.rb +1086 -0
  51. data/lib/action_controller/metal/testing.rb +8 -29
  52. data/lib/action_controller/metal/url_for.rb +43 -32
  53. data/lib/action_controller/metal.rb +112 -106
  54. data/lib/action_controller/railtie.rb +56 -18
  55. data/lib/action_controller/railties/helpers.rb +24 -0
  56. data/lib/action_controller/renderer.rb +117 -0
  57. data/lib/action_controller/template_assertions.rb +11 -0
  58. data/lib/action_controller/test_case.rb +402 -347
  59. data/lib/action_controller.rb +31 -30
  60. data/lib/action_dispatch/http/cache.rb +133 -34
  61. data/lib/action_dispatch/http/content_security_policy.rb +272 -0
  62. data/lib/action_dispatch/http/filter_parameters.rb +40 -24
  63. data/lib/action_dispatch/http/filter_redirect.rb +37 -0
  64. data/lib/action_dispatch/http/headers.rb +117 -16
  65. data/lib/action_dispatch/http/mime_negotiation.rb +98 -33
  66. data/lib/action_dispatch/http/mime_type.rb +198 -146
  67. data/lib/action_dispatch/http/mime_types.rb +22 -7
  68. data/lib/action_dispatch/http/parameter_filter.rb +61 -49
  69. data/lib/action_dispatch/http/parameters.rb +94 -51
  70. data/lib/action_dispatch/http/rack_cache.rb +4 -3
  71. data/lib/action_dispatch/http/request.rb +262 -117
  72. data/lib/action_dispatch/http/response.rb +400 -86
  73. data/lib/action_dispatch/http/upload.rb +66 -29
  74. data/lib/action_dispatch/http/url.rb +232 -60
  75. data/lib/action_dispatch/journey/formatter.rb +189 -0
  76. data/lib/action_dispatch/journey/gtg/builder.rb +164 -0
  77. data/lib/action_dispatch/journey/gtg/simulator.rb +41 -0
  78. data/lib/action_dispatch/journey/gtg/transition_table.rb +158 -0
  79. data/lib/action_dispatch/journey/nfa/builder.rb +78 -0
  80. data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
  81. data/lib/action_dispatch/journey/nfa/simulator.rb +49 -0
  82. data/lib/action_dispatch/journey/nfa/transition_table.rb +120 -0
  83. data/lib/action_dispatch/journey/nodes/node.rb +140 -0
  84. data/lib/action_dispatch/journey/parser.rb +199 -0
  85. data/lib/action_dispatch/journey/parser.y +50 -0
  86. data/lib/action_dispatch/journey/parser_extras.rb +31 -0
  87. data/lib/action_dispatch/journey/path/pattern.rb +199 -0
  88. data/lib/action_dispatch/journey/route.rb +203 -0
  89. data/lib/action_dispatch/journey/router/utils.rb +102 -0
  90. data/lib/action_dispatch/journey/router.rb +156 -0
  91. data/lib/action_dispatch/journey/routes.rb +82 -0
  92. data/lib/action_dispatch/journey/scanner.rb +64 -0
  93. data/lib/action_dispatch/journey/visitors.rb +268 -0
  94. data/lib/action_dispatch/journey/visualizer/fsm.css +30 -0
  95. data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
  96. data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
  97. data/lib/action_dispatch/journey.rb +7 -0
  98. data/lib/action_dispatch/middleware/callbacks.rb +17 -13
  99. data/lib/action_dispatch/middleware/cookies.rb +494 -162
  100. data/lib/action_dispatch/middleware/debug_exceptions.rb +176 -53
  101. data/lib/action_dispatch/middleware/debug_locks.rb +124 -0
  102. data/lib/action_dispatch/middleware/exception_wrapper.rb +103 -38
  103. data/lib/action_dispatch/middleware/executor.rb +21 -0
  104. data/lib/action_dispatch/middleware/flash.rb +128 -91
  105. data/lib/action_dispatch/middleware/public_exceptions.rb +43 -16
  106. data/lib/action_dispatch/middleware/reloader.rb +6 -83
  107. data/lib/action_dispatch/middleware/remote_ip.rb +151 -49
  108. data/lib/action_dispatch/middleware/request_id.rb +19 -15
  109. data/lib/action_dispatch/middleware/session/abstract_store.rb +38 -34
  110. data/lib/action_dispatch/middleware/session/cache_store.rb +14 -9
  111. data/lib/action_dispatch/middleware/session/cookie_store.rb +94 -44
  112. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +15 -4
  113. data/lib/action_dispatch/middleware/show_exceptions.rb +36 -61
  114. data/lib/action_dispatch/middleware/ssl.rb +150 -0
  115. data/lib/action_dispatch/middleware/stack.rb +33 -41
  116. data/lib/action_dispatch/middleware/static.rb +92 -48
  117. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +22 -0
  118. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +23 -0
  119. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +27 -0
  120. data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
  121. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +52 -0
  122. data/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb +9 -0
  123. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +16 -0
  124. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +9 -0
  125. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +21 -0
  126. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +13 -0
  127. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +134 -5
  128. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +11 -0
  129. data/lib/action_dispatch/middleware/templates/rescues/missing_template.text.erb +3 -0
  130. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +32 -0
  131. data/lib/action_dispatch/middleware/templates/rescues/routing_error.text.erb +11 -0
  132. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +20 -0
  133. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +7 -0
  134. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +6 -0
  135. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +3 -0
  136. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +16 -0
  137. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +200 -0
  138. data/lib/action_dispatch/railtie.rb +29 -8
  139. data/lib/action_dispatch/request/session.rb +234 -0
  140. data/lib/action_dispatch/request/utils.rb +78 -0
  141. data/lib/action_dispatch/routing/endpoint.rb +17 -0
  142. data/lib/action_dispatch/routing/inspector.rb +225 -0
  143. data/lib/action_dispatch/routing/mapper.rb +1329 -582
  144. data/lib/action_dispatch/routing/polymorphic_routes.rb +237 -94
  145. data/lib/action_dispatch/routing/redirection.rb +120 -50
  146. data/lib/action_dispatch/routing/route_set.rb +545 -322
  147. data/lib/action_dispatch/routing/routes_proxy.rb +37 -7
  148. data/lib/action_dispatch/routing/url_for.rb +103 -34
  149. data/lib/action_dispatch/routing.rb +66 -99
  150. data/lib/action_dispatch/system_test_case.rb +147 -0
  151. data/lib/action_dispatch/system_testing/browser.rb +49 -0
  152. data/lib/action_dispatch/system_testing/driver.rb +59 -0
  153. data/lib/action_dispatch/system_testing/server.rb +31 -0
  154. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +96 -0
  155. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +31 -0
  156. data/lib/action_dispatch/system_testing/test_helpers/undef_methods.rb +26 -0
  157. data/lib/action_dispatch/testing/assertion_response.rb +47 -0
  158. data/lib/action_dispatch/testing/assertions/response.rb +53 -42
  159. data/lib/action_dispatch/testing/assertions/routing.rb +79 -74
  160. data/lib/action_dispatch/testing/assertions.rb +15 -9
  161. data/lib/action_dispatch/testing/integration.rb +361 -207
  162. data/lib/action_dispatch/testing/request_encoder.rb +55 -0
  163. data/lib/action_dispatch/testing/test_process.rb +28 -19
  164. data/lib/action_dispatch/testing/test_request.rb +30 -33
  165. data/lib/action_dispatch/testing/test_response.rb +35 -11
  166. data/lib/action_dispatch.rb +42 -32
  167. data/lib/action_pack/gem_version.rb +17 -0
  168. data/lib/action_pack/version.rb +7 -7
  169. data/lib/action_pack.rb +4 -2
  170. metadata +116 -175
  171. data/lib/abstract_controller/layouts.rb +0 -423
  172. data/lib/abstract_controller/view_paths.rb +0 -96
  173. data/lib/action_controller/caching/actions.rb +0 -185
  174. data/lib/action_controller/caching/fragments.rb +0 -127
  175. data/lib/action_controller/caching/pages.rb +0 -187
  176. data/lib/action_controller/caching/sweeping.rb +0 -97
  177. data/lib/action_controller/deprecated/integration_test.rb +0 -2
  178. data/lib/action_controller/deprecated/performance_test.rb +0 -1
  179. data/lib/action_controller/deprecated.rb +0 -3
  180. data/lib/action_controller/metal/compatibility.rb +0 -65
  181. data/lib/action_controller/metal/hide_actions.rb +0 -41
  182. data/lib/action_controller/metal/rack_delegation.rb +0 -26
  183. data/lib/action_controller/metal/responder.rb +0 -286
  184. data/lib/action_controller/metal/session_management.rb +0 -14
  185. data/lib/action_controller/middleware.rb +0 -39
  186. data/lib/action_controller/railties/paths.rb +0 -25
  187. data/lib/action_controller/record_identifier.rb +0 -85
  188. data/lib/action_controller/vendor/html-scanner/html/document.rb +0 -68
  189. data/lib/action_controller/vendor/html-scanner/html/node.rb +0 -532
  190. data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +0 -177
  191. data/lib/action_controller/vendor/html-scanner/html/selector.rb +0 -830
  192. data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +0 -107
  193. data/lib/action_controller/vendor/html-scanner/html/version.rb +0 -11
  194. data/lib/action_controller/vendor/html-scanner.rb +0 -20
  195. data/lib/action_dispatch/middleware/best_standards_support.rb +0 -30
  196. data/lib/action_dispatch/middleware/body_proxy.rb +0 -30
  197. data/lib/action_dispatch/middleware/head.rb +0 -18
  198. data/lib/action_dispatch/middleware/params_parser.rb +0 -75
  199. data/lib/action_dispatch/middleware/rescue.rb +0 -26
  200. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +0 -31
  201. data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +0 -26
  202. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +0 -10
  203. data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +0 -2
  204. data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +0 -15
  205. data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +0 -17
  206. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +0 -2
  207. data/lib/action_dispatch/testing/assertions/dom.rb +0 -37
  208. data/lib/action_dispatch/testing/assertions/selector.rb +0 -435
  209. data/lib/action_dispatch/testing/assertions/tag.rb +0 -138
  210. data/lib/action_dispatch/testing/performance_test.rb +0 -10
  211. data/lib/action_view/asset_paths.rb +0 -142
  212. data/lib/action_view/base.rb +0 -220
  213. data/lib/action_view/buffers.rb +0 -43
  214. data/lib/action_view/context.rb +0 -36
  215. data/lib/action_view/flows.rb +0 -79
  216. data/lib/action_view/helpers/active_model_helper.rb +0 -50
  217. data/lib/action_view/helpers/asset_paths.rb +0 -7
  218. data/lib/action_view/helpers/asset_tag_helper.rb +0 -457
  219. data/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb +0 -146
  220. data/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb +0 -93
  221. data/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +0 -193
  222. data/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +0 -148
  223. data/lib/action_view/helpers/atom_feed_helper.rb +0 -200
  224. data/lib/action_view/helpers/cache_helper.rb +0 -64
  225. data/lib/action_view/helpers/capture_helper.rb +0 -203
  226. data/lib/action_view/helpers/controller_helper.rb +0 -25
  227. data/lib/action_view/helpers/csrf_helper.rb +0 -32
  228. data/lib/action_view/helpers/date_helper.rb +0 -1062
  229. data/lib/action_view/helpers/debug_helper.rb +0 -40
  230. data/lib/action_view/helpers/form_helper.rb +0 -1486
  231. data/lib/action_view/helpers/form_options_helper.rb +0 -658
  232. data/lib/action_view/helpers/form_tag_helper.rb +0 -685
  233. data/lib/action_view/helpers/javascript_helper.rb +0 -110
  234. data/lib/action_view/helpers/number_helper.rb +0 -622
  235. data/lib/action_view/helpers/output_safety_helper.rb +0 -38
  236. data/lib/action_view/helpers/record_tag_helper.rb +0 -111
  237. data/lib/action_view/helpers/rendering_helper.rb +0 -92
  238. data/lib/action_view/helpers/sanitize_helper.rb +0 -259
  239. data/lib/action_view/helpers/tag_helper.rb +0 -167
  240. data/lib/action_view/helpers/text_helper.rb +0 -426
  241. data/lib/action_view/helpers/translation_helper.rb +0 -91
  242. data/lib/action_view/helpers/url_helper.rb +0 -693
  243. data/lib/action_view/helpers.rb +0 -60
  244. data/lib/action_view/locale/en.yml +0 -160
  245. data/lib/action_view/log_subscriber.rb +0 -28
  246. data/lib/action_view/lookup_context.rb +0 -258
  247. data/lib/action_view/path_set.rb +0 -101
  248. data/lib/action_view/railtie.rb +0 -55
  249. data/lib/action_view/renderer/abstract_renderer.rb +0 -41
  250. data/lib/action_view/renderer/partial_renderer.rb +0 -415
  251. data/lib/action_view/renderer/renderer.rb +0 -61
  252. data/lib/action_view/renderer/streaming_template_renderer.rb +0 -106
  253. data/lib/action_view/renderer/template_renderer.rb +0 -95
  254. data/lib/action_view/template/error.rb +0 -128
  255. data/lib/action_view/template/handlers/builder.rb +0 -26
  256. data/lib/action_view/template/handlers/erb.rb +0 -125
  257. data/lib/action_view/template/handlers.rb +0 -50
  258. data/lib/action_view/template/resolver.rb +0 -298
  259. data/lib/action_view/template/text.rb +0 -30
  260. data/lib/action_view/template.rb +0 -337
  261. data/lib/action_view/test_case.rb +0 -246
  262. data/lib/action_view/testing/resolvers.rb +0 -49
  263. data/lib/action_view.rb +0 -84
  264. data/lib/sprockets/assets.rake +0 -99
  265. data/lib/sprockets/bootstrap.rb +0 -37
  266. data/lib/sprockets/compressors.rb +0 -83
  267. data/lib/sprockets/helpers/isolated_helper.rb +0 -13
  268. data/lib/sprockets/helpers/rails_helper.rb +0 -182
  269. data/lib/sprockets/helpers.rb +0 -6
  270. data/lib/sprockets/railtie.rb +0 -62
  271. data/lib/sprockets/static_compiler.rb +0 -56
@@ -0,0 +1,268 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionDispatch
4
+ # :stopdoc:
5
+ module Journey
6
+ class Format
7
+ ESCAPE_PATH = ->(value) { Router::Utils.escape_path(value) }
8
+ ESCAPE_SEGMENT = ->(value) { Router::Utils.escape_segment(value) }
9
+
10
+ Parameter = Struct.new(:name, :escaper) do
11
+ def escape(value); escaper.call value; end
12
+ end
13
+
14
+ def self.required_path(symbol)
15
+ Parameter.new symbol, ESCAPE_PATH
16
+ end
17
+
18
+ def self.required_segment(symbol)
19
+ Parameter.new symbol, ESCAPE_SEGMENT
20
+ end
21
+
22
+ def initialize(parts)
23
+ @parts = parts
24
+ @children = []
25
+ @parameters = []
26
+
27
+ parts.each_with_index do |object, i|
28
+ case object
29
+ when Journey::Format
30
+ @children << i
31
+ when Parameter
32
+ @parameters << i
33
+ end
34
+ end
35
+ end
36
+
37
+ def evaluate(hash)
38
+ parts = @parts.dup
39
+
40
+ @parameters.each do |index|
41
+ param = parts[index]
42
+ value = hash[param.name]
43
+ return "".freeze unless value
44
+ parts[index] = param.escape value
45
+ end
46
+
47
+ @children.each { |index| parts[index] = parts[index].evaluate(hash) }
48
+
49
+ parts.join
50
+ end
51
+ end
52
+
53
+ module Visitors # :nodoc:
54
+ class Visitor # :nodoc:
55
+ DISPATCH_CACHE = {}
56
+
57
+ def accept(node)
58
+ visit(node)
59
+ end
60
+
61
+ private
62
+
63
+ def visit(node)
64
+ send(DISPATCH_CACHE[node.type], node)
65
+ end
66
+
67
+ def binary(node)
68
+ visit(node.left)
69
+ visit(node.right)
70
+ end
71
+ def visit_CAT(n); binary(n); end
72
+
73
+ def nary(node)
74
+ node.children.each { |c| visit(c) }
75
+ end
76
+ def visit_OR(n); nary(n); end
77
+
78
+ def unary(node)
79
+ visit(node.left)
80
+ end
81
+ def visit_GROUP(n); unary(n); end
82
+ def visit_STAR(n); unary(n); end
83
+
84
+ def terminal(node); end
85
+ def visit_LITERAL(n); terminal(n); end
86
+ def visit_SYMBOL(n); terminal(n); end
87
+ def visit_SLASH(n); terminal(n); end
88
+ def visit_DOT(n); terminal(n); end
89
+
90
+ private_instance_methods(false).each do |pim|
91
+ next unless pim =~ /^visit_(.*)$/
92
+ DISPATCH_CACHE[$1.to_sym] = pim
93
+ end
94
+ end
95
+
96
+ class FunctionalVisitor # :nodoc:
97
+ DISPATCH_CACHE = {}
98
+
99
+ def accept(node, seed)
100
+ visit(node, seed)
101
+ end
102
+
103
+ def visit(node, seed)
104
+ send(DISPATCH_CACHE[node.type], node, seed)
105
+ end
106
+
107
+ def binary(node, seed)
108
+ visit(node.right, visit(node.left, seed))
109
+ end
110
+ def visit_CAT(n, seed); binary(n, seed); end
111
+
112
+ def nary(node, seed)
113
+ node.children.inject(seed) { |s, c| visit(c, s) }
114
+ end
115
+ def visit_OR(n, seed); nary(n, seed); end
116
+
117
+ def unary(node, seed)
118
+ visit(node.left, seed)
119
+ end
120
+ def visit_GROUP(n, seed); unary(n, seed); end
121
+ def visit_STAR(n, seed); unary(n, seed); end
122
+
123
+ def terminal(node, seed); seed; end
124
+ def visit_LITERAL(n, seed); terminal(n, seed); end
125
+ def visit_SYMBOL(n, seed); terminal(n, seed); end
126
+ def visit_SLASH(n, seed); terminal(n, seed); end
127
+ def visit_DOT(n, seed); terminal(n, seed); end
128
+
129
+ instance_methods(false).each do |pim|
130
+ next unless pim =~ /^visit_(.*)$/
131
+ DISPATCH_CACHE[$1.to_sym] = pim
132
+ end
133
+ end
134
+
135
+ class FormatBuilder < Visitor # :nodoc:
136
+ def accept(node); Journey::Format.new(super); end
137
+ def terminal(node); [node.left]; end
138
+
139
+ def binary(node)
140
+ visit(node.left) + visit(node.right)
141
+ end
142
+
143
+ def visit_GROUP(n); [Journey::Format.new(unary(n))]; end
144
+
145
+ def visit_STAR(n)
146
+ [Journey::Format.required_path(n.left.to_sym)]
147
+ end
148
+
149
+ def visit_SYMBOL(n)
150
+ symbol = n.to_sym
151
+ if symbol == :controller
152
+ [Journey::Format.required_path(symbol)]
153
+ else
154
+ [Journey::Format.required_segment(symbol)]
155
+ end
156
+ end
157
+ end
158
+
159
+ # Loop through the requirements AST.
160
+ class Each < FunctionalVisitor # :nodoc:
161
+ def visit(node, block)
162
+ block.call(node)
163
+ super
164
+ end
165
+
166
+ INSTANCE = new
167
+ end
168
+
169
+ class String < FunctionalVisitor # :nodoc:
170
+ private
171
+
172
+ def binary(node, seed)
173
+ visit(node.right, visit(node.left, seed))
174
+ end
175
+
176
+ def nary(node, seed)
177
+ last_child = node.children.last
178
+ node.children.inject(seed) { |s, c|
179
+ string = visit(c, s)
180
+ string << "|" unless last_child == c
181
+ string
182
+ }
183
+ end
184
+
185
+ def terminal(node, seed)
186
+ seed + node.left
187
+ end
188
+
189
+ def visit_GROUP(node, seed)
190
+ visit(node.left, seed.dup << "(") << ")"
191
+ end
192
+
193
+ INSTANCE = new
194
+ end
195
+
196
+ class Dot < FunctionalVisitor # :nodoc:
197
+ def initialize
198
+ @nodes = []
199
+ @edges = []
200
+ end
201
+
202
+ def accept(node, seed = [[], []])
203
+ super
204
+ nodes, edges = seed
205
+ <<-eodot
206
+ digraph parse_tree {
207
+ size="8,5"
208
+ node [shape = none];
209
+ edge [dir = none];
210
+ #{nodes.join "\n"}
211
+ #{edges.join("\n")}
212
+ }
213
+ eodot
214
+ end
215
+
216
+ private
217
+
218
+ def binary(node, seed)
219
+ seed.last.concat node.children.map { |c|
220
+ "#{node.object_id} -> #{c.object_id};"
221
+ }
222
+ super
223
+ end
224
+
225
+ def nary(node, seed)
226
+ seed.last.concat node.children.map { |c|
227
+ "#{node.object_id} -> #{c.object_id};"
228
+ }
229
+ super
230
+ end
231
+
232
+ def unary(node, seed)
233
+ seed.last << "#{node.object_id} -> #{node.left.object_id};"
234
+ super
235
+ end
236
+
237
+ def visit_GROUP(node, seed)
238
+ seed.first << "#{node.object_id} [label=\"()\"];"
239
+ super
240
+ end
241
+
242
+ def visit_CAT(node, seed)
243
+ seed.first << "#{node.object_id} [label=\"○\"];"
244
+ super
245
+ end
246
+
247
+ def visit_STAR(node, seed)
248
+ seed.first << "#{node.object_id} [label=\"*\"];"
249
+ super
250
+ end
251
+
252
+ def visit_OR(node, seed)
253
+ seed.first << "#{node.object_id} [label=\"|\"];"
254
+ super
255
+ end
256
+
257
+ def terminal(node, seed)
258
+ value = node.left
259
+
260
+ seed.first << "#{node.object_id} [label=\"#{value}\"];"
261
+ seed
262
+ end
263
+ INSTANCE = new
264
+ end
265
+ end
266
+ end
267
+ # :startdoc:
268
+ end
@@ -0,0 +1,30 @@
1
+ body {
2
+ font-family: "Helvetica Neue", Helvetica, Arial, Sans-Serif;
3
+ margin: 0;
4
+ }
5
+
6
+ h1 {
7
+ font-size: 2.0em; font-weight: bold; text-align: center;
8
+ color: white; background-color: black;
9
+ padding: 5px 0;
10
+ margin: 0 0 20px;
11
+ }
12
+
13
+ h2 {
14
+ text-align: center;
15
+ display: none;
16
+ font-size: 0.5em;
17
+ }
18
+
19
+ .clearfix {display: inline-block; }
20
+ .input { overflow: show;}
21
+ .instruction { color: #666; padding: 0 30px 20px; font-size: 0.9em}
22
+ .instruction p { padding: 0 0 5px; }
23
+ .instruction li { padding: 0 10px 5px; }
24
+
25
+ .form { background: #EEE; padding: 20px 30px; border-radius: 5px; margin-left: auto; margin-right: auto; width: 500px; margin-bottom: 20px}
26
+ .form p, .form form { text-align: center }
27
+ .form form {padding: 0 10px 5px; }
28
+ .form .fun_routes { font-size: 0.9em;}
29
+ .form .fun_routes a { margin: 0 5px 0 0; }
30
+
@@ -0,0 +1,134 @@
1
+ function tokenize(input, callback) {
2
+ while(input.length > 0) {
3
+ callback(input.match(/^[\/\.\?]|[^\/\.\?]+/)[0]);
4
+ input = input.replace(/^[\/\.\?]|[^\/\.\?]+/, '');
5
+ }
6
+ }
7
+
8
+ var graph = d3.select("#chart-2 svg");
9
+ var svg_edges = {};
10
+ var svg_nodes = {};
11
+
12
+ graph.selectAll("g.edge").each(function() {
13
+ var node = d3.select(this);
14
+ var index = node.select("title").text().split("->");
15
+ var left = parseInt(index[0]);
16
+ var right = parseInt(index[1]);
17
+
18
+ if(!svg_edges[left]) { svg_edges[left] = {} }
19
+ svg_edges[left][right] = node;
20
+ });
21
+
22
+ graph.selectAll("g.node").each(function() {
23
+ var node = d3.select(this);
24
+ var index = parseInt(node.select("title").text());
25
+ svg_nodes[index] = node;
26
+ });
27
+
28
+ function reset_graph() {
29
+ for(var key in svg_edges) {
30
+ for(var mkey in svg_edges[key]) {
31
+ var node = svg_edges[key][mkey];
32
+ var path = node.select("path");
33
+ var arrow = node.select("polygon");
34
+ path.style("stroke", "black");
35
+ arrow.style("stroke", "black").style("fill", "black");
36
+ }
37
+ }
38
+
39
+ for(var key in svg_nodes) {
40
+ var node = svg_nodes[key];
41
+ node.select('ellipse').style("fill", "white");
42
+ node.select('polygon').style("fill", "white");
43
+ }
44
+ return false;
45
+ }
46
+
47
+ function highlight_edge(from, to) {
48
+ var node = svg_edges[from][to];
49
+ var path = node.select("path");
50
+ var arrow = node.select("polygon");
51
+
52
+ path
53
+ .transition().duration(500)
54
+ .style("stroke", "green");
55
+
56
+ arrow
57
+ .transition().duration(500)
58
+ .style("stroke", "green").style("fill", "green");
59
+ }
60
+
61
+ function highlight_state(index, color) {
62
+ if(!color) { color = "green"; }
63
+
64
+ svg_nodes[index].select('ellipse')
65
+ .style("fill", "white")
66
+ .transition().duration(500)
67
+ .style("fill", color);
68
+ }
69
+
70
+ function highlight_finish(index) {
71
+ svg_nodes[index].select('polygon')
72
+ .style("fill", "while")
73
+ .transition().duration(500)
74
+ .style("fill", "blue");
75
+ }
76
+
77
+ function match(input) {
78
+ reset_graph();
79
+ var table = tt();
80
+ var states = [0];
81
+ var regexp_states = table['regexp_states'];
82
+ var string_states = table['string_states'];
83
+ var accepting = table['accepting'];
84
+
85
+ highlight_state(0);
86
+
87
+ tokenize(input, function(token) {
88
+ var new_states = [];
89
+ for(var key in states) {
90
+ var state = states[key];
91
+
92
+ if(string_states[state] && string_states[state][token]) {
93
+ var new_state = string_states[state][token];
94
+ highlight_edge(state, new_state);
95
+ highlight_state(new_state);
96
+ new_states.push(new_state);
97
+ }
98
+
99
+ if(regexp_states[state]) {
100
+ for(var key in regexp_states[state]) {
101
+ var re = new RegExp("^" + key + "$");
102
+ if(re.test(token)) {
103
+ var new_state = regexp_states[state][key];
104
+ highlight_edge(state, new_state);
105
+ highlight_state(new_state);
106
+ new_states.push(new_state);
107
+ }
108
+ }
109
+ }
110
+ }
111
+
112
+ if(new_states.length == 0) {
113
+ return;
114
+ }
115
+ states = new_states;
116
+ });
117
+
118
+ for(var key in states) {
119
+ var state = states[key];
120
+ if(accepting[state]) {
121
+ for(var mkey in svg_edges[state]) {
122
+ if(!regexp_states[mkey] && !string_states[mkey]) {
123
+ highlight_edge(state, mkey);
124
+ highlight_finish(mkey);
125
+ }
126
+ }
127
+ } else {
128
+ highlight_state(state, "red");
129
+ }
130
+ }
131
+
132
+ return false;
133
+ }
134
+
@@ -0,0 +1,52 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title><%= title %></title>
5
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.css" type="text/css">
6
+ <style>
7
+ <% stylesheets.each do |style| %>
8
+ <%= style %>
9
+ <% end %>
10
+ </style>
11
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.8/d3.min.js" type="text/javascript"></script>
12
+ </head>
13
+ <body>
14
+ <div id="wrapper">
15
+ <h1>Routes FSM with NFA simulation</h1>
16
+ <div class="instruction form">
17
+ <p>
18
+ Type a route in to the box and click "simulate".
19
+ </p>
20
+ <form onsubmit="return match(this.route.value);">
21
+ <input type="text" size="30" name="route" value="/articles/new" />
22
+ <button>simulate</button>
23
+ <input type="reset" value="reset" onclick="return reset_graph();"/>
24
+ </form>
25
+ <p class="fun_routes">
26
+ Some fun routes to try:
27
+ <% fun_routes.each do |path| %>
28
+ <a href="#" onclick="document.forms[0].elements[0].value=this.text.replace(/^\s+|\s+$/g,''); return match(this.text.replace(/^\s+|\s+$/g,''));">
29
+ <%= path %>
30
+ </a>
31
+ <% end %>
32
+ </p>
33
+ </div>
34
+ <div class='chart' id='chart-2'>
35
+ <%= svg %>
36
+ </div>
37
+ <div class="instruction">
38
+ <p>
39
+ This is a FSM for a system that has the following routes:
40
+ </p>
41
+ <ul>
42
+ <% paths.each do |route| %>
43
+ <li><%= route %></li>
44
+ <% end %>
45
+ </ul>
46
+ </div>
47
+ </div>
48
+ <% javascripts.each do |js| %>
49
+ <script><%= js %></script>
50
+ <% end %>
51
+ </body>
52
+ </html>
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "action_dispatch/journey/router"
4
+ require "action_dispatch/journey/gtg/builder"
5
+ require "action_dispatch/journey/gtg/simulator"
6
+ require "action_dispatch/journey/nfa/builder"
7
+ require "action_dispatch/journey/nfa/simulator"
@@ -1,22 +1,20 @@
1
- require 'active_support/core_ext/module/delegation'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module ActionDispatch
4
- # Provide callbacks to be executed before and after the request dispatch.
4
+ # Provides callbacks to be executed before and after dispatching the request.
5
5
  class Callbacks
6
6
  include ActiveSupport::Callbacks
7
7
 
8
- define_callbacks :call, :rescuable => true
8
+ define_callbacks :call
9
9
 
10
10
  class << self
11
- delegate :to_prepare, :to_cleanup, :to => "ActionDispatch::Reloader"
12
- end
13
-
14
- def self.before(*args, &block)
15
- set_callback(:call, :before, *args, &block)
16
- end
11
+ def before(*args, &block)
12
+ set_callback(:call, :before, *args, &block)
13
+ end
17
14
 
18
- def self.after(*args, &block)
19
- set_callback(:call, :after, *args, &block)
15
+ def after(*args, &block)
16
+ set_callback(:call, :after, *args, &block)
17
+ end
20
18
  end
21
19
 
22
20
  def initialize(app)
@@ -24,9 +22,15 @@ module ActionDispatch
24
22
  end
25
23
 
26
24
  def call(env)
27
- run_callbacks :call do
28
- @app.call(env)
25
+ error = nil
26
+ result = run_callbacks :call do
27
+ begin
28
+ @app.call(env)
29
+ rescue => error
30
+ end
29
31
  end
32
+ raise error if error
33
+ result
30
34
  end
31
35
  end
32
36
  end