actionpack 4.2.11.1 → 6.1.3.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionpack might be problematic. Click here for more details.

Files changed (187) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +291 -489
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +9 -9
  5. data/lib/abstract_controller/asset_paths.rb +2 -0
  6. data/lib/abstract_controller/base.rb +81 -51
  7. data/lib/{action_controller → abstract_controller}/caching/fragments.rb +64 -17
  8. data/lib/abstract_controller/caching.rb +66 -0
  9. data/lib/abstract_controller/callbacks.rb +61 -33
  10. data/lib/abstract_controller/collector.rb +9 -13
  11. data/lib/abstract_controller/error.rb +6 -0
  12. data/lib/abstract_controller/helpers.rb +115 -99
  13. data/lib/abstract_controller/logger.rb +2 -0
  14. data/lib/abstract_controller/railties/routes_helpers.rb +21 -3
  15. data/lib/abstract_controller/rendering.rb +48 -47
  16. data/lib/abstract_controller/translation.rb +17 -8
  17. data/lib/abstract_controller/url_for.rb +2 -0
  18. data/lib/abstract_controller.rb +13 -5
  19. data/lib/action_controller/api/api_rendering.rb +16 -0
  20. data/lib/action_controller/api.rb +150 -0
  21. data/lib/action_controller/base.rb +29 -24
  22. data/lib/action_controller/caching.rb +12 -57
  23. data/lib/action_controller/form_builder.rb +50 -0
  24. data/lib/action_controller/log_subscriber.rb +17 -19
  25. data/lib/action_controller/metal/basic_implicit_render.rb +13 -0
  26. data/lib/action_controller/metal/conditional_get.rb +134 -46
  27. data/lib/action_controller/metal/content_security_policy.rb +51 -0
  28. data/lib/action_controller/metal/cookies.rb +6 -4
  29. data/lib/action_controller/metal/data_streaming.rb +30 -50
  30. data/lib/action_controller/metal/default_headers.rb +17 -0
  31. data/lib/action_controller/metal/etag_with_flash.rb +18 -0
  32. data/lib/action_controller/metal/etag_with_template_digest.rb +21 -16
  33. data/lib/action_controller/metal/exceptions.rb +63 -15
  34. data/lib/action_controller/metal/flash.rb +9 -8
  35. data/lib/action_controller/metal/head.rb +26 -21
  36. data/lib/action_controller/metal/helpers.rb +37 -18
  37. data/lib/action_controller/metal/http_authentication.rb +81 -73
  38. data/lib/action_controller/metal/implicit_render.rb +53 -9
  39. data/lib/action_controller/metal/instrumentation.rb +32 -35
  40. data/lib/action_controller/metal/live.rb +102 -120
  41. data/lib/action_controller/metal/logging.rb +20 -0
  42. data/lib/action_controller/metal/mime_responds.rb +49 -47
  43. data/lib/action_controller/metal/parameter_encoding.rb +82 -0
  44. data/lib/action_controller/metal/params_wrapper.rb +83 -66
  45. data/lib/action_controller/metal/permissions_policy.rb +46 -0
  46. data/lib/action_controller/metal/redirecting.rb +53 -32
  47. data/lib/action_controller/metal/renderers.rb +87 -44
  48. data/lib/action_controller/metal/rendering.rb +77 -50
  49. data/lib/action_controller/metal/request_forgery_protection.rb +267 -103
  50. data/lib/action_controller/metal/rescue.rb +10 -17
  51. data/lib/action_controller/metal/streaming.rb +12 -11
  52. data/lib/action_controller/metal/strong_parameters.rb +714 -186
  53. data/lib/action_controller/metal/testing.rb +2 -17
  54. data/lib/action_controller/metal/url_for.rb +19 -10
  55. data/lib/action_controller/metal.rb +104 -87
  56. data/lib/action_controller/railtie.rb +28 -10
  57. data/lib/action_controller/railties/helpers.rb +3 -1
  58. data/lib/action_controller/renderer.rb +141 -0
  59. data/lib/action_controller/template_assertions.rb +11 -0
  60. data/lib/action_controller/test_case.rb +296 -422
  61. data/lib/action_controller.rb +34 -23
  62. data/lib/action_dispatch/http/cache.rb +107 -56
  63. data/lib/action_dispatch/http/content_disposition.rb +45 -0
  64. data/lib/action_dispatch/http/content_security_policy.rb +286 -0
  65. data/lib/action_dispatch/http/filter_parameters.rb +32 -25
  66. data/lib/action_dispatch/http/filter_redirect.rb +10 -12
  67. data/lib/action_dispatch/http/headers.rb +55 -22
  68. data/lib/action_dispatch/http/mime_negotiation.rb +79 -51
  69. data/lib/action_dispatch/http/mime_type.rb +153 -121
  70. data/lib/action_dispatch/http/mime_types.rb +20 -6
  71. data/lib/action_dispatch/http/parameters.rb +90 -40
  72. data/lib/action_dispatch/http/permissions_policy.rb +173 -0
  73. data/lib/action_dispatch/http/rack_cache.rb +2 -0
  74. data/lib/action_dispatch/http/request.rb +226 -121
  75. data/lib/action_dispatch/http/response.rb +248 -113
  76. data/lib/action_dispatch/http/upload.rb +21 -7
  77. data/lib/action_dispatch/http/url.rb +182 -100
  78. data/lib/action_dispatch/journey/formatter.rb +90 -43
  79. data/lib/action_dispatch/journey/gtg/builder.rb +28 -41
  80. data/lib/action_dispatch/journey/gtg/simulator.rb +11 -16
  81. data/lib/action_dispatch/journey/gtg/transition_table.rb +23 -21
  82. data/lib/action_dispatch/journey/nfa/dot.rb +3 -14
  83. data/lib/action_dispatch/journey/nodes/node.rb +29 -15
  84. data/lib/action_dispatch/journey/parser.rb +17 -16
  85. data/lib/action_dispatch/journey/parser.y +4 -3
  86. data/lib/action_dispatch/journey/parser_extras.rb +12 -4
  87. data/lib/action_dispatch/journey/path/pattern.rb +58 -54
  88. data/lib/action_dispatch/journey/route.rb +100 -32
  89. data/lib/action_dispatch/journey/router/utils.rb +29 -18
  90. data/lib/action_dispatch/journey/router.rb +55 -51
  91. data/lib/action_dispatch/journey/routes.rb +17 -17
  92. data/lib/action_dispatch/journey/scanner.rb +26 -17
  93. data/lib/action_dispatch/journey/visitors.rb +98 -54
  94. data/lib/action_dispatch/journey.rb +5 -5
  95. data/lib/action_dispatch/middleware/actionable_exceptions.rb +46 -0
  96. data/lib/action_dispatch/middleware/callbacks.rb +3 -6
  97. data/lib/action_dispatch/middleware/cookies.rb +347 -217
  98. data/lib/action_dispatch/middleware/debug_exceptions.rb +135 -63
  99. data/lib/action_dispatch/middleware/debug_locks.rb +124 -0
  100. data/lib/action_dispatch/middleware/debug_view.rb +66 -0
  101. data/lib/action_dispatch/middleware/exception_wrapper.rb +115 -71
  102. data/lib/action_dispatch/middleware/executor.rb +21 -0
  103. data/lib/action_dispatch/middleware/flash.rb +78 -54
  104. data/lib/action_dispatch/middleware/host_authorization.rb +130 -0
  105. data/lib/action_dispatch/middleware/public_exceptions.rb +32 -27
  106. data/lib/action_dispatch/middleware/reloader.rb +5 -91
  107. data/lib/action_dispatch/middleware/remote_ip.rb +53 -45
  108. data/lib/action_dispatch/middleware/request_id.rb +17 -10
  109. data/lib/action_dispatch/middleware/session/abstract_store.rb +41 -26
  110. data/lib/action_dispatch/middleware/session/cache_store.rb +24 -14
  111. data/lib/action_dispatch/middleware/session/cookie_store.rb +74 -75
  112. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -2
  113. data/lib/action_dispatch/middleware/show_exceptions.rb +28 -23
  114. data/lib/action_dispatch/middleware/ssl.rb +118 -35
  115. data/lib/action_dispatch/middleware/stack.rb +82 -41
  116. data/lib/action_dispatch/middleware/static.rb +156 -89
  117. data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +13 -0
  118. data/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb +0 -0
  119. data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +22 -0
  120. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +4 -14
  121. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +1 -1
  122. data/lib/action_dispatch/middleware/templates/rescues/{_source.erb → _source.html.erb} +4 -2
  123. data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
  124. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +45 -35
  125. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +7 -0
  126. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +5 -0
  127. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +23 -4
  128. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +1 -1
  129. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +24 -0
  130. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +15 -0
  131. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +105 -8
  132. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +19 -0
  133. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.text.erb +3 -0
  134. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +2 -2
  135. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +1 -1
  136. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +3 -3
  137. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +1 -1
  138. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -1
  139. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +4 -4
  140. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +87 -64
  141. data/lib/action_dispatch/railtie.rb +27 -13
  142. data/lib/action_dispatch/request/session.rb +109 -61
  143. data/lib/action_dispatch/request/utils.rb +90 -23
  144. data/lib/action_dispatch/routing/endpoint.rb +9 -2
  145. data/lib/action_dispatch/routing/inspector.rb +141 -102
  146. data/lib/action_dispatch/routing/mapper.rb +811 -473
  147. data/lib/action_dispatch/routing/polymorphic_routes.rb +167 -143
  148. data/lib/action_dispatch/routing/redirection.rb +37 -27
  149. data/lib/action_dispatch/routing/route_set.rb +363 -331
  150. data/lib/action_dispatch/routing/routes_proxy.rb +32 -5
  151. data/lib/action_dispatch/routing/url_for.rb +66 -26
  152. data/lib/action_dispatch/routing.rb +36 -36
  153. data/lib/action_dispatch/system_test_case.rb +190 -0
  154. data/lib/action_dispatch/system_testing/browser.rb +86 -0
  155. data/lib/action_dispatch/system_testing/driver.rb +67 -0
  156. data/lib/action_dispatch/system_testing/server.rb +31 -0
  157. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +138 -0
  158. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +29 -0
  159. data/lib/action_dispatch/testing/assertion_response.rb +46 -0
  160. data/lib/action_dispatch/testing/assertions/response.rb +44 -22
  161. data/lib/action_dispatch/testing/assertions/routing.rb +47 -31
  162. data/lib/action_dispatch/testing/assertions.rb +6 -4
  163. data/lib/action_dispatch/testing/integration.rb +391 -220
  164. data/lib/action_dispatch/testing/request_encoder.rb +55 -0
  165. data/lib/action_dispatch/testing/test_process.rb +53 -22
  166. data/lib/action_dispatch/testing/test_request.rb +27 -34
  167. data/lib/action_dispatch/testing/test_response.rb +11 -11
  168. data/lib/action_dispatch.rb +35 -21
  169. data/lib/action_pack/gem_version.rb +6 -4
  170. data/lib/action_pack/version.rb +3 -1
  171. data/lib/action_pack.rb +4 -2
  172. metadata +78 -48
  173. data/lib/action_controller/metal/force_ssl.rb +0 -97
  174. data/lib/action_controller/metal/hide_actions.rb +0 -40
  175. data/lib/action_controller/metal/rack_delegation.rb +0 -32
  176. data/lib/action_controller/middleware.rb +0 -39
  177. data/lib/action_controller/model_naming.rb +0 -12
  178. data/lib/action_dispatch/http/parameter_filter.rb +0 -72
  179. data/lib/action_dispatch/journey/backwards.rb +0 -5
  180. data/lib/action_dispatch/journey/nfa/builder.rb +0 -76
  181. data/lib/action_dispatch/journey/nfa/simulator.rb +0 -47
  182. data/lib/action_dispatch/journey/nfa/transition_table.rb +0 -163
  183. data/lib/action_dispatch/journey/router/strexp.rb +0 -27
  184. data/lib/action_dispatch/middleware/params_parser.rb +0 -60
  185. data/lib/action_dispatch/testing/assertions/dom.rb +0 -3
  186. data/lib/action_dispatch/testing/assertions/selector.rb +0 -3
  187. data/lib/action_dispatch/testing/assertions/tag.rb +0 -3
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionDispatch
2
4
  module Journey # :nodoc:
3
5
  # The Routing table. Contains all routes for a system. Routes can be
@@ -5,13 +7,13 @@ module ActionDispatch
5
7
  class Routes # :nodoc:
6
8
  include Enumerable
7
9
 
8
- attr_reader :routes, :named_routes
10
+ attr_reader :routes, :custom_routes, :anchored_routes
9
11
 
10
12
  def initialize
11
13
  @routes = []
12
- @named_routes = {}
13
14
  @ast = nil
14
- @partitioned_routes = nil
15
+ @anchored_routes = []
16
+ @custom_routes = []
15
17
  @simulator = nil
16
18
  end
17
19
 
@@ -34,19 +36,22 @@ module ActionDispatch
34
36
 
35
37
  def clear
36
38
  routes.clear
37
- named_routes.clear
39
+ anchored_routes.clear
40
+ custom_routes.clear
38
41
  end
39
42
 
40
- def partitioned_routes
41
- @partitioned_routes ||= routes.partition do |r|
42
- r.path.anchored && r.ast.grep(Nodes::Symbol).all?(&:default_regexp?)
43
+ def partition_route(route)
44
+ if route.path.anchored && route.ast.grep(Nodes::Symbol).all?(&:default_regexp?)
45
+ anchored_routes << route
46
+ else
47
+ custom_routes << route
43
48
  end
44
49
  end
45
50
 
46
51
  def ast
47
52
  @ast ||= begin
48
- asts = partitioned_routes.first.map(&:ast)
49
- Nodes::Or.new(asts) unless asts.empty?
53
+ asts = anchored_routes.map(&:ast)
54
+ Nodes::Or.new(asts)
50
55
  end
51
56
  end
52
57
 
@@ -57,22 +62,17 @@ module ActionDispatch
57
62
  end
58
63
  end
59
64
 
60
- # Add a route to the routing table.
61
- def add_route(app, path, conditions, defaults, name = nil)
62
- route = Route.new(name, app, path, conditions, defaults)
63
-
64
- route.precedence = routes.length
65
+ def add_route(name, mapping)
66
+ route = mapping.make_route name, routes.length
65
67
  routes << route
66
- named_routes[name] = route if name && !named_routes[name]
68
+ partition_route(route)
67
69
  clear_cache!
68
70
  route
69
71
  end
70
72
 
71
73
  private
72
-
73
74
  def clear_cache!
74
75
  @ast = nil
75
- @partitioned_routes = nil
76
76
  @simulator = nil
77
77
  end
78
78
  end
@@ -1,4 +1,6 @@
1
- require 'strscan'
1
+ # frozen_string_literal: true
2
+
3
+ require "strscan"
2
4
 
3
5
  module ActionDispatch
4
6
  module Journey # :nodoc:
@@ -31,28 +33,35 @@ module ActionDispatch
31
33
  end
32
34
 
33
35
  private
36
+ # takes advantage of String @- deduping capabilities in Ruby 2.5 upwards
37
+ # see: https://bugs.ruby-lang.org/issues/13077
38
+ def dedup_scan(regex)
39
+ r = @ss.scan(regex)
40
+ r ? -r : nil
41
+ end
34
42
 
35
43
  def scan
36
44
  case
37
45
  # /
38
- when text = @ss.scan(/\//)
39
- [:SLASH, text]
40
- when text = @ss.scan(/\*\w+/)
41
- [:STAR, text]
42
- when text = @ss.scan(/(?<!\\)\(/)
43
- [:LPAREN, text]
44
- when text = @ss.scan(/(?<!\\)\)/)
45
- [:RPAREN, text]
46
- when text = @ss.scan(/\|/)
47
- [:OR, text]
48
- when text = @ss.scan(/\./)
49
- [:DOT, text]
50
- when text = @ss.scan(/(?<!\\):\w+/)
46
+ when @ss.skip(/\//)
47
+ [:SLASH, "/"]
48
+ when @ss.skip(/\(/)
49
+ [:LPAREN, "("]
50
+ when @ss.skip(/\)/)
51
+ [:RPAREN, ")"]
52
+ when @ss.skip(/\|/)
53
+ [:OR, "|"]
54
+ when @ss.skip(/\./)
55
+ [:DOT, "."]
56
+ when text = dedup_scan(/:\w+/)
51
57
  [:SYMBOL, text]
52
- when text = @ss.scan(/(?:[\w%\-~!$&'*+,;=@]|\\:|\\\(|\\\))+/)
53
- [:LITERAL, text.tr('\\', '')]
58
+ when text = dedup_scan(/\*\w+/)
59
+ [:STAR, text]
60
+ when text = @ss.scan(/(?:[\w%\-~!$&'*+,;=@]|\\[:()])+/)
61
+ text.tr! "\\", ""
62
+ [:LITERAL, -text]
54
63
  # any char
55
- when text = @ss.scan(/./)
64
+ when text = dedup_scan(/./)
56
65
  [:LITERAL, text]
57
66
  end
58
67
  end
@@ -1,12 +1,13 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module ActionDispatch
4
- module Journey # :nodoc:
4
+ # :stopdoc:
5
+ module Journey
5
6
  class Format
6
7
  ESCAPE_PATH = ->(value) { Router::Utils.escape_path(value) }
7
8
  ESCAPE_SEGMENT = ->(value) { Router::Utils.escape_segment(value) }
8
9
 
9
- class Parameter < Struct.new(:name, :escaper)
10
+ Parameter = Struct.new(:name, :escaper) do
10
11
  def escape(value); escaper.call value; end
11
12
  end
12
13
 
@@ -23,7 +24,7 @@ module ActionDispatch
23
24
  @children = []
24
25
  @parameters = []
25
26
 
26
- parts.each_with_index do |object,i|
27
+ parts.each_with_index do |object, i|
27
28
  case object
28
29
  when Journey::Format
29
30
  @children << i
@@ -39,7 +40,7 @@ module ActionDispatch
39
40
  @parameters.each do |index|
40
41
  param = parts[index]
41
42
  value = hash[param.name]
42
- return ''.freeze unless value
43
+ return "" unless value
43
44
  parts[index] = param.escape value
44
45
  end
45
46
 
@@ -58,8 +59,7 @@ module ActionDispatch
58
59
  end
59
60
 
60
61
  private
61
-
62
- def visit node
62
+ def visit(node)
63
63
  send(DISPATCH_CACHE[node.type], node)
64
64
  end
65
65
 
@@ -92,6 +92,45 @@ module ActionDispatch
92
92
  end
93
93
  end
94
94
 
95
+ class FunctionalVisitor # :nodoc:
96
+ DISPATCH_CACHE = {}
97
+
98
+ def accept(node, seed)
99
+ visit(node, seed)
100
+ end
101
+
102
+ def visit(node, seed)
103
+ send(DISPATCH_CACHE[node.type], node, seed)
104
+ end
105
+
106
+ def binary(node, seed)
107
+ visit(node.right, visit(node.left, seed))
108
+ end
109
+ def visit_CAT(n, seed); binary(n, seed); end
110
+
111
+ def nary(node, seed)
112
+ node.children.inject(seed) { |s, c| visit(c, s) }
113
+ end
114
+ def visit_OR(n, seed); nary(n, seed); end
115
+
116
+ def unary(node, seed)
117
+ visit(node.left, seed)
118
+ end
119
+ def visit_GROUP(n, seed); unary(n, seed); end
120
+ def visit_STAR(n, seed); unary(n, seed); end
121
+
122
+ def terminal(node, seed); seed; end
123
+ def visit_LITERAL(n, seed); terminal(n, seed); end
124
+ def visit_SYMBOL(n, seed); terminal(n, seed); end
125
+ def visit_SLASH(n, seed); terminal(n, seed); end
126
+ def visit_DOT(n, seed); terminal(n, seed); end
127
+
128
+ instance_methods(false).each do |pim|
129
+ next unless pim =~ /^visit_(.*)$/
130
+ DISPATCH_CACHE[$1.to_sym] = pim
131
+ end
132
+ end
133
+
95
134
  class FormatBuilder < Visitor # :nodoc:
96
135
  def accept(node); Journey::Format.new(super); end
97
136
  def terminal(node); [node.left]; end
@@ -116,106 +155,111 @@ module ActionDispatch
116
155
  end
117
156
  end
118
157
 
119
- # Loop through the requirements AST
120
- class Each < Visitor # :nodoc:
121
- attr_reader :block
122
-
123
- def initialize(block)
124
- @block = block
125
- end
126
-
127
- def visit(node)
158
+ # Loop through the requirements AST.
159
+ class Each < FunctionalVisitor # :nodoc:
160
+ def visit(node, block)
128
161
  block.call(node)
129
162
  super
130
163
  end
164
+
165
+ INSTANCE = new
131
166
  end
132
167
 
133
- class String < Visitor # :nodoc:
168
+ class String < FunctionalVisitor # :nodoc:
134
169
  private
170
+ def binary(node, seed)
171
+ visit(node.right, visit(node.left, seed))
172
+ end
135
173
 
136
- def binary(node)
137
- [visit(node.left), visit(node.right)].join
138
- end
174
+ def nary(node, seed)
175
+ last_child = node.children.last
176
+ node.children.inject(seed) { |s, c|
177
+ string = visit(c, s)
178
+ string << "|" unless last_child == c
179
+ string
180
+ }
181
+ end
139
182
 
140
- def nary(node)
141
- node.children.map { |c| visit(c) }.join '|'
142
- end
183
+ def terminal(node, seed)
184
+ seed + node.left
185
+ end
143
186
 
144
- def terminal(node)
145
- node.left
146
- end
187
+ def visit_GROUP(node, seed)
188
+ visit(node.left, seed.dup << "(") << ")"
189
+ end
147
190
 
148
- def visit_GROUP(node)
149
- "(#{visit(node.left)})"
150
- end
191
+ INSTANCE = new
151
192
  end
152
193
 
153
- class Dot < Visitor # :nodoc:
194
+ class Dot < FunctionalVisitor # :nodoc:
154
195
  def initialize
155
196
  @nodes = []
156
197
  @edges = []
157
198
  end
158
199
 
159
- def accept(node)
200
+ def accept(node, seed = [[], []])
160
201
  super
202
+ nodes, edges = seed
161
203
  <<-eodot
162
204
  digraph parse_tree {
163
205
  size="8,5"
164
206
  node [shape = none];
165
207
  edge [dir = none];
166
- #{@nodes.join "\n"}
167
- #{@edges.join("\n")}
208
+ #{nodes.join "\n"}
209
+ #{edges.join("\n")}
168
210
  }
169
211
  eodot
170
212
  end
171
213
 
172
214
  private
173
-
174
- def binary(node)
175
- node.children.each do |c|
176
- @edges << "#{node.object_id} -> #{c.object_id};"
177
- end
215
+ def binary(node, seed)
216
+ seed.last.concat node.children.map { |c|
217
+ "#{node.object_id} -> #{c.object_id};"
218
+ }
178
219
  super
179
220
  end
180
221
 
181
- def nary(node)
182
- node.children.each do |c|
183
- @edges << "#{node.object_id} -> #{c.object_id};"
184
- end
222
+ def nary(node, seed)
223
+ seed.last.concat node.children.map { |c|
224
+ "#{node.object_id} -> #{c.object_id};"
225
+ }
185
226
  super
186
227
  end
187
228
 
188
- def unary(node)
189
- @edges << "#{node.object_id} -> #{node.left.object_id};"
229
+ def unary(node, seed)
230
+ seed.last << "#{node.object_id} -> #{node.left.object_id};"
190
231
  super
191
232
  end
192
233
 
193
- def visit_GROUP(node)
194
- @nodes << "#{node.object_id} [label=\"()\"];"
234
+ def visit_GROUP(node, seed)
235
+ seed.first << "#{node.object_id} [label=\"()\"];"
195
236
  super
196
237
  end
197
238
 
198
- def visit_CAT(node)
199
- @nodes << "#{node.object_id} [label=\"○\"];"
239
+ def visit_CAT(node, seed)
240
+ seed.first << "#{node.object_id} [label=\"○\"];"
200
241
  super
201
242
  end
202
243
 
203
- def visit_STAR(node)
204
- @nodes << "#{node.object_id} [label=\"*\"];"
244
+ def visit_STAR(node, seed)
245
+ seed.first << "#{node.object_id} [label=\"*\"];"
205
246
  super
206
247
  end
207
248
 
208
- def visit_OR(node)
209
- @nodes << "#{node.object_id} [label=\"|\"];"
249
+ def visit_OR(node, seed)
250
+ seed.first << "#{node.object_id} [label=\"|\"];"
210
251
  super
211
252
  end
212
253
 
213
- def terminal(node)
254
+ def terminal(node, seed)
214
255
  value = node.left
215
256
 
216
- @nodes << "#{node.object_id} [label=\"#{value}\"];"
257
+ seed.first << "#{node.object_id} [label=\"#{value}\"];"
258
+ seed
217
259
  end
260
+ INSTANCE = new
218
261
  end
219
262
  end
220
263
  end
264
+ # :startdoc:
221
265
  end
@@ -1,5 +1,5 @@
1
- require 'action_dispatch/journey/router'
2
- require 'action_dispatch/journey/gtg/builder'
3
- require 'action_dispatch/journey/gtg/simulator'
4
- require 'action_dispatch/journey/nfa/builder'
5
- require 'action_dispatch/journey/nfa/simulator'
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"
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "erb"
4
+ require "uri"
5
+ require "action_dispatch/http/request"
6
+ require "active_support/actionable_error"
7
+
8
+ module ActionDispatch
9
+ class ActionableExceptions # :nodoc:
10
+ cattr_accessor :endpoint, default: "/rails/actions"
11
+
12
+ def initialize(app)
13
+ @app = app
14
+ end
15
+
16
+ def call(env)
17
+ request = ActionDispatch::Request.new(env)
18
+ return @app.call(env) unless actionable_request?(request)
19
+
20
+ ActiveSupport::ActionableError.dispatch(request.params[:error].to_s.safe_constantize, request.params[:action])
21
+
22
+ redirect_to request.params[:location]
23
+ end
24
+
25
+ private
26
+ def actionable_request?(request)
27
+ request.get_header("action_dispatch.show_detailed_exceptions") && request.post? && request.path == endpoint
28
+ end
29
+
30
+ def redirect_to(location)
31
+ uri = URI.parse location
32
+
33
+ if uri.relative? || uri.scheme == "http" || uri.scheme == "https"
34
+ body = "<html><body>You are being <a href=\"#{ERB::Util.unwrapped_html_escape(location)}\">redirected</a>.</body></html>"
35
+ else
36
+ return [400, { "Content-Type" => "text/plain" }, ["Invalid redirection URI"]]
37
+ end
38
+
39
+ [302, {
40
+ "Content-Type" => "text/html; charset=#{Response.default_charset}",
41
+ "Content-Length" => body.bytesize.to_s,
42
+ "Location" => location,
43
+ }, [body]]
44
+ end
45
+ end
46
+ end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  module ActionDispatch
3
4
  # Provides callbacks to be executed before and after dispatching the request.
@@ -7,8 +8,6 @@ module ActionDispatch
7
8
  define_callbacks :call
8
9
 
9
10
  class << self
10
- delegate :to_prepare, :to_cleanup, :to => "ActionDispatch::Reloader"
11
-
12
11
  def before(*args, &block)
13
12
  set_callback(:call, :before, *args, &block)
14
13
  end
@@ -25,10 +24,8 @@ module ActionDispatch
25
24
  def call(env)
26
25
  error = nil
27
26
  result = run_callbacks :call do
28
- begin
29
- @app.call(env)
30
- rescue => error
31
- end
27
+ @app.call(env)
28
+ rescue => error
32
29
  end
33
30
  raise error if error
34
31
  result