omg-actionpack 8.0.0.alpha1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +129 -0
  3. data/MIT-LICENSE +21 -0
  4. data/README.rdoc +57 -0
  5. data/lib/abstract_controller/asset_paths.rb +14 -0
  6. data/lib/abstract_controller/base.rb +299 -0
  7. data/lib/abstract_controller/caching/fragments.rb +149 -0
  8. data/lib/abstract_controller/caching.rb +68 -0
  9. data/lib/abstract_controller/callbacks.rb +265 -0
  10. data/lib/abstract_controller/collector.rb +44 -0
  11. data/lib/abstract_controller/deprecator.rb +9 -0
  12. data/lib/abstract_controller/error.rb +8 -0
  13. data/lib/abstract_controller/helpers.rb +243 -0
  14. data/lib/abstract_controller/logger.rb +16 -0
  15. data/lib/abstract_controller/railties/routes_helpers.rb +25 -0
  16. data/lib/abstract_controller/rendering.rb +126 -0
  17. data/lib/abstract_controller/translation.rb +42 -0
  18. data/lib/abstract_controller/url_for.rb +37 -0
  19. data/lib/abstract_controller.rb +36 -0
  20. data/lib/action_controller/api/api_rendering.rb +18 -0
  21. data/lib/action_controller/api.rb +155 -0
  22. data/lib/action_controller/base.rb +332 -0
  23. data/lib/action_controller/caching.rb +49 -0
  24. data/lib/action_controller/deprecator.rb +9 -0
  25. data/lib/action_controller/form_builder.rb +55 -0
  26. data/lib/action_controller/log_subscriber.rb +96 -0
  27. data/lib/action_controller/metal/allow_browser.rb +123 -0
  28. data/lib/action_controller/metal/basic_implicit_render.rb +17 -0
  29. data/lib/action_controller/metal/conditional_get.rb +341 -0
  30. data/lib/action_controller/metal/content_security_policy.rb +86 -0
  31. data/lib/action_controller/metal/cookies.rb +20 -0
  32. data/lib/action_controller/metal/data_streaming.rb +154 -0
  33. data/lib/action_controller/metal/default_headers.rb +21 -0
  34. data/lib/action_controller/metal/etag_with_flash.rb +22 -0
  35. data/lib/action_controller/metal/etag_with_template_digest.rb +59 -0
  36. data/lib/action_controller/metal/exceptions.rb +106 -0
  37. data/lib/action_controller/metal/flash.rb +67 -0
  38. data/lib/action_controller/metal/head.rb +67 -0
  39. data/lib/action_controller/metal/helpers.rb +129 -0
  40. data/lib/action_controller/metal/http_authentication.rb +565 -0
  41. data/lib/action_controller/metal/implicit_render.rb +67 -0
  42. data/lib/action_controller/metal/instrumentation.rb +120 -0
  43. data/lib/action_controller/metal/live.rb +398 -0
  44. data/lib/action_controller/metal/logging.rb +22 -0
  45. data/lib/action_controller/metal/mime_responds.rb +337 -0
  46. data/lib/action_controller/metal/parameter_encoding.rb +84 -0
  47. data/lib/action_controller/metal/params_wrapper.rb +312 -0
  48. data/lib/action_controller/metal/permissions_policy.rb +38 -0
  49. data/lib/action_controller/metal/rate_limiting.rb +62 -0
  50. data/lib/action_controller/metal/redirecting.rb +251 -0
  51. data/lib/action_controller/metal/renderers.rb +181 -0
  52. data/lib/action_controller/metal/rendering.rb +260 -0
  53. data/lib/action_controller/metal/request_forgery_protection.rb +667 -0
  54. data/lib/action_controller/metal/rescue.rb +33 -0
  55. data/lib/action_controller/metal/streaming.rb +183 -0
  56. data/lib/action_controller/metal/strong_parameters.rb +1546 -0
  57. data/lib/action_controller/metal/testing.rb +25 -0
  58. data/lib/action_controller/metal/url_for.rb +65 -0
  59. data/lib/action_controller/metal.rb +339 -0
  60. data/lib/action_controller/railtie.rb +149 -0
  61. data/lib/action_controller/railties/helpers.rb +26 -0
  62. data/lib/action_controller/renderer.rb +161 -0
  63. data/lib/action_controller/template_assertions.rb +13 -0
  64. data/lib/action_controller/test_case.rb +691 -0
  65. data/lib/action_controller.rb +80 -0
  66. data/lib/action_dispatch/constants.rb +34 -0
  67. data/lib/action_dispatch/deprecator.rb +9 -0
  68. data/lib/action_dispatch/http/cache.rb +249 -0
  69. data/lib/action_dispatch/http/content_disposition.rb +47 -0
  70. data/lib/action_dispatch/http/content_security_policy.rb +365 -0
  71. data/lib/action_dispatch/http/filter_parameters.rb +80 -0
  72. data/lib/action_dispatch/http/filter_redirect.rb +50 -0
  73. data/lib/action_dispatch/http/headers.rb +134 -0
  74. data/lib/action_dispatch/http/mime_negotiation.rb +187 -0
  75. data/lib/action_dispatch/http/mime_type.rb +389 -0
  76. data/lib/action_dispatch/http/mime_types.rb +54 -0
  77. data/lib/action_dispatch/http/parameters.rb +119 -0
  78. data/lib/action_dispatch/http/permissions_policy.rb +189 -0
  79. data/lib/action_dispatch/http/rack_cache.rb +67 -0
  80. data/lib/action_dispatch/http/request.rb +498 -0
  81. data/lib/action_dispatch/http/response.rb +556 -0
  82. data/lib/action_dispatch/http/upload.rb +107 -0
  83. data/lib/action_dispatch/http/url.rb +344 -0
  84. data/lib/action_dispatch/journey/formatter.rb +226 -0
  85. data/lib/action_dispatch/journey/gtg/builder.rb +149 -0
  86. data/lib/action_dispatch/journey/gtg/simulator.rb +50 -0
  87. data/lib/action_dispatch/journey/gtg/transition_table.rb +217 -0
  88. data/lib/action_dispatch/journey/nfa/dot.rb +27 -0
  89. data/lib/action_dispatch/journey/nodes/node.rb +208 -0
  90. data/lib/action_dispatch/journey/parser.rb +103 -0
  91. data/lib/action_dispatch/journey/path/pattern.rb +209 -0
  92. data/lib/action_dispatch/journey/route.rb +189 -0
  93. data/lib/action_dispatch/journey/router/utils.rb +105 -0
  94. data/lib/action_dispatch/journey/router.rb +151 -0
  95. data/lib/action_dispatch/journey/routes.rb +82 -0
  96. data/lib/action_dispatch/journey/scanner.rb +70 -0
  97. data/lib/action_dispatch/journey/visitors.rb +267 -0
  98. data/lib/action_dispatch/journey/visualizer/fsm.css +30 -0
  99. data/lib/action_dispatch/journey/visualizer/fsm.js +159 -0
  100. data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
  101. data/lib/action_dispatch/journey.rb +7 -0
  102. data/lib/action_dispatch/log_subscriber.rb +25 -0
  103. data/lib/action_dispatch/middleware/actionable_exceptions.rb +46 -0
  104. data/lib/action_dispatch/middleware/assume_ssl.rb +27 -0
  105. data/lib/action_dispatch/middleware/callbacks.rb +38 -0
  106. data/lib/action_dispatch/middleware/cookies.rb +719 -0
  107. data/lib/action_dispatch/middleware/debug_exceptions.rb +206 -0
  108. data/lib/action_dispatch/middleware/debug_locks.rb +129 -0
  109. data/lib/action_dispatch/middleware/debug_view.rb +73 -0
  110. data/lib/action_dispatch/middleware/exception_wrapper.rb +350 -0
  111. data/lib/action_dispatch/middleware/executor.rb +32 -0
  112. data/lib/action_dispatch/middleware/flash.rb +318 -0
  113. data/lib/action_dispatch/middleware/host_authorization.rb +171 -0
  114. data/lib/action_dispatch/middleware/public_exceptions.rb +64 -0
  115. data/lib/action_dispatch/middleware/reloader.rb +16 -0
  116. data/lib/action_dispatch/middleware/remote_ip.rb +199 -0
  117. data/lib/action_dispatch/middleware/request_id.rb +50 -0
  118. data/lib/action_dispatch/middleware/server_timing.rb +78 -0
  119. data/lib/action_dispatch/middleware/session/abstract_store.rb +112 -0
  120. data/lib/action_dispatch/middleware/session/cache_store.rb +66 -0
  121. data/lib/action_dispatch/middleware/session/cookie_store.rb +129 -0
  122. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +34 -0
  123. data/lib/action_dispatch/middleware/show_exceptions.rb +88 -0
  124. data/lib/action_dispatch/middleware/ssl.rb +180 -0
  125. data/lib/action_dispatch/middleware/stack.rb +194 -0
  126. data/lib/action_dispatch/middleware/static.rb +192 -0
  127. data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +13 -0
  128. data/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb +0 -0
  129. data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +22 -0
  130. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +17 -0
  131. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +23 -0
  132. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +36 -0
  133. data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
  134. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +62 -0
  135. data/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb +9 -0
  136. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +12 -0
  137. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +9 -0
  138. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +35 -0
  139. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +9 -0
  140. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +24 -0
  141. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +16 -0
  142. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +284 -0
  143. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +23 -0
  144. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.text.erb +3 -0
  145. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +11 -0
  146. data/lib/action_dispatch/middleware/templates/rescues/missing_template.text.erb +3 -0
  147. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +32 -0
  148. data/lib/action_dispatch/middleware/templates/rescues/routing_error.text.erb +11 -0
  149. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +20 -0
  150. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +7 -0
  151. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +6 -0
  152. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +3 -0
  153. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +19 -0
  154. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +232 -0
  155. data/lib/action_dispatch/railtie.rb +77 -0
  156. data/lib/action_dispatch/request/session.rb +283 -0
  157. data/lib/action_dispatch/request/utils.rb +109 -0
  158. data/lib/action_dispatch/routing/endpoint.rb +19 -0
  159. data/lib/action_dispatch/routing/inspector.rb +323 -0
  160. data/lib/action_dispatch/routing/mapper.rb +2372 -0
  161. data/lib/action_dispatch/routing/polymorphic_routes.rb +363 -0
  162. data/lib/action_dispatch/routing/redirection.rb +218 -0
  163. data/lib/action_dispatch/routing/route_set.rb +958 -0
  164. data/lib/action_dispatch/routing/routes_proxy.rb +66 -0
  165. data/lib/action_dispatch/routing/url_for.rb +244 -0
  166. data/lib/action_dispatch/routing.rb +262 -0
  167. data/lib/action_dispatch/system_test_case.rb +206 -0
  168. data/lib/action_dispatch/system_testing/browser.rb +75 -0
  169. data/lib/action_dispatch/system_testing/driver.rb +85 -0
  170. data/lib/action_dispatch/system_testing/server.rb +33 -0
  171. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +164 -0
  172. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +23 -0
  173. data/lib/action_dispatch/testing/assertion_response.rb +48 -0
  174. data/lib/action_dispatch/testing/assertions/response.rb +114 -0
  175. data/lib/action_dispatch/testing/assertions/routing.rb +343 -0
  176. data/lib/action_dispatch/testing/assertions.rb +25 -0
  177. data/lib/action_dispatch/testing/integration.rb +694 -0
  178. data/lib/action_dispatch/testing/request_encoder.rb +60 -0
  179. data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
  180. data/lib/action_dispatch/testing/test_process.rb +57 -0
  181. data/lib/action_dispatch/testing/test_request.rb +73 -0
  182. data/lib/action_dispatch/testing/test_response.rb +58 -0
  183. data/lib/action_dispatch.rb +147 -0
  184. data/lib/action_pack/gem_version.rb +19 -0
  185. data/lib/action_pack/version.rb +12 -0
  186. data/lib/action_pack.rb +27 -0
  187. metadata +375 -0
@@ -0,0 +1,192 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :markup: markdown
4
+
5
+ require "rack/utils"
6
+
7
+ module ActionDispatch
8
+ # # Action Dispatch Static
9
+ #
10
+ # This middleware serves static files from disk, if available. If no file is
11
+ # found, it hands off to the main app.
12
+ #
13
+ # In Rails apps, this middleware is configured to serve assets from the
14
+ # `public/` directory.
15
+ #
16
+ # Only GET and HEAD requests are served. POST and other HTTP methods are handed
17
+ # off to the main app.
18
+ #
19
+ # Only files in the root directory are served; path traversal is denied.
20
+ class Static
21
+ def initialize(app, path, index: "index", headers: {})
22
+ @app = app
23
+ @file_handler = FileHandler.new(path, index: index, headers: headers)
24
+ end
25
+
26
+ def call(env)
27
+ @file_handler.attempt(env) || @app.call(env)
28
+ end
29
+ end
30
+
31
+ # # Action Dispatch FileHandler
32
+ #
33
+ # This endpoint serves static files from disk using `Rack::Files`.
34
+ #
35
+ # URL paths are matched with static files according to expected conventions:
36
+ # `path`, `path`.html, `path`/index.html.
37
+ #
38
+ # Precompressed versions of these files are checked first. Brotli (.br) and gzip
39
+ # (.gz) files are supported. If `path`.br exists, this endpoint returns that
40
+ # file with a `content-encoding: br` header.
41
+ #
42
+ # If no matching file is found, this endpoint responds `404 Not Found`.
43
+ #
44
+ # Pass the `root` directory to search for matching files, an optional `index:
45
+ # "index"` to change the default `path`/index.html, and optional additional
46
+ # response headers.
47
+ class FileHandler
48
+ # `Accept-Encoding` value -> file extension
49
+ PRECOMPRESSED = {
50
+ "br" => ".br",
51
+ "gzip" => ".gz",
52
+ "identity" => nil
53
+ }
54
+
55
+ def initialize(root, index: "index", headers: {}, precompressed: %i[ br gzip ], compressible_content_types: /\A(?:text\/|application\/javascript|image\/svg\+xml)/)
56
+ @root = root.chomp("/").b
57
+ @index = index
58
+
59
+ @precompressed = Array(precompressed).map(&:to_s) | %w[ identity ]
60
+ @compressible_content_types = compressible_content_types
61
+
62
+ @file_server = ::Rack::Files.new(@root, headers)
63
+ end
64
+
65
+ def call(env)
66
+ attempt(env) || @file_server.call(env)
67
+ end
68
+
69
+ def attempt(env)
70
+ request = Rack::Request.new env
71
+
72
+ if request.get? || request.head?
73
+ if found = find_file(request.path_info, accept_encoding: request.accept_encoding)
74
+ serve request, *found
75
+ end
76
+ end
77
+ end
78
+
79
+ private
80
+ def serve(request, filepath, content_headers)
81
+ original, request.path_info =
82
+ request.path_info, ::Rack::Utils.escape_path(filepath).b
83
+
84
+ @file_server.call(request.env).tap do |status, headers, body|
85
+ # Omit content-encoding/type/etc headers for 304 Not Modified
86
+ if status != 304
87
+ headers.update(content_headers)
88
+ end
89
+ end
90
+ ensure
91
+ request.path_info = original
92
+ end
93
+
94
+ # Match a URI path to a static file to be served.
95
+ #
96
+ # Used by the `Static` class to negotiate a servable file in the `public/`
97
+ # directory (see Static#call).
98
+ #
99
+ # Checks for `path`, `path`.html, and `path`/index.html files, in that order,
100
+ # including .br and .gzip compressed extensions.
101
+ #
102
+ # If a matching file is found, the path and necessary response headers
103
+ # (Content-Type, Content-Encoding) are returned.
104
+ def find_file(path_info, accept_encoding:)
105
+ each_candidate_filepath(path_info) do |filepath, content_type|
106
+ if response = try_files(filepath, content_type, accept_encoding: accept_encoding)
107
+ return response
108
+ end
109
+ end
110
+ end
111
+
112
+ def try_files(filepath, content_type, accept_encoding:)
113
+ headers = { Rack::CONTENT_TYPE => content_type }
114
+
115
+ if compressible? content_type
116
+ try_precompressed_files filepath, headers, accept_encoding: accept_encoding
117
+ elsif file_readable? filepath
118
+ [ filepath, headers ]
119
+ end
120
+ end
121
+
122
+ def try_precompressed_files(filepath, headers, accept_encoding:)
123
+ each_precompressed_filepath(filepath) do |content_encoding, precompressed_filepath|
124
+ if file_readable? precompressed_filepath
125
+ # Identity encoding is default, so we skip Accept-Encoding negotiation and
126
+ # needn't set Content-Encoding.
127
+ #
128
+ # Vary header is expected when we've found other available encodings that
129
+ # Accept-Encoding ruled out.
130
+ if content_encoding == "identity"
131
+ return precompressed_filepath, headers
132
+ else
133
+ headers[ActionDispatch::Constants::VARY] = "accept-encoding"
134
+
135
+ if accept_encoding.any? { |enc, _| /\b#{content_encoding}\b/i.match?(enc) }
136
+ headers[ActionDispatch::Constants::CONTENT_ENCODING] = content_encoding
137
+ return precompressed_filepath, headers
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
143
+
144
+ def file_readable?(path)
145
+ file_path = File.join(@root, path.b)
146
+ File.file?(file_path) && File.readable?(file_path)
147
+ end
148
+
149
+ def compressible?(content_type)
150
+ @compressible_content_types.match?(content_type)
151
+ end
152
+
153
+ def each_precompressed_filepath(filepath)
154
+ @precompressed.each do |content_encoding|
155
+ precompressed_ext = PRECOMPRESSED.fetch(content_encoding)
156
+ yield content_encoding, "#{filepath}#{precompressed_ext}"
157
+ end
158
+
159
+ nil
160
+ end
161
+
162
+ def each_candidate_filepath(path_info)
163
+ return unless path = clean_path(path_info)
164
+
165
+ ext = ::File.extname(path)
166
+ content_type = ::Rack::Mime.mime_type(ext, nil)
167
+ yield path, content_type || "text/plain"
168
+
169
+ # Tack on .html and /index.html only for paths that don't have an explicit,
170
+ # resolvable file extension. No need to check for foo.js.html and
171
+ # foo.js/index.html.
172
+ unless content_type
173
+ default_ext = ::ActionController::Base.default_static_extension
174
+ if ext != default_ext
175
+ default_content_type = ::Rack::Mime.mime_type(default_ext, "text/plain")
176
+
177
+ yield "#{path}#{default_ext}", default_content_type
178
+ yield "#{path}/#{@index}#{default_ext}", default_content_type
179
+ end
180
+ end
181
+
182
+ nil
183
+ end
184
+
185
+ def clean_path(path_info)
186
+ path = ::Rack::Utils.unescape_path path_info.chomp("/")
187
+ if ::Rack::Utils.valid_path? path
188
+ ::Rack::Utils.clean_path_info path
189
+ end
190
+ end
191
+ end
192
+ end
@@ -0,0 +1,13 @@
1
+ <% actions = exception_wrapper.actions %>
2
+
3
+ <% if actions.any? %>
4
+ <div class="actions">
5
+ <% actions.each do |action, _| %>
6
+ <%= button_to action, ActionDispatch::ActionableExceptions.endpoint, params: {
7
+ error: exception_wrapper.exception_class_name,
8
+ action: action,
9
+ location: request.path
10
+ } %>
11
+ <% end %>
12
+ </div>
13
+ <% end %>
@@ -0,0 +1,22 @@
1
+ <% if exception_wrapper.has_corrections? %>
2
+ <div class="exception-message">
3
+ <%= simple_format h(exception_wrapper.original_message), { class: "message" }, wrapper_tag: "div" %>
4
+ </div>
5
+ <%
6
+ # The 'did_you_mean' gem can raise exceptions when calling #corrections on
7
+ # the exception. If it does there are no corrections to show.
8
+ corrections = exception_wrapper.corrections rescue []
9
+ %>
10
+ <% if corrections.any? %>
11
+ <b>Did you mean?</b>
12
+ <ul>
13
+ <% corrections.each do |correction| %>
14
+ <li class="correction"><%= h correction %></li>
15
+ <% end %>
16
+ </ul>
17
+ <% end %>
18
+ <% else %>
19
+ <div class="exception-message">
20
+ <%= simple_format h(exception_wrapper.message), { class: "message" }, wrapper_tag: "div" %>
21
+ </div>
22
+ <% end %>
@@ -0,0 +1,17 @@
1
+ <h2 class="request-heading">Request</h2>
2
+ <% if params_valid? %>
3
+ <p><b>Parameters</b>:</p> <pre><%= debug_params(@request.filtered_parameters) %></pre>
4
+ <% end %>
5
+
6
+ <div class="details">
7
+ <div class="summary"><a href="#" onclick="return toggleSessionDump()">Toggle session dump</a></div>
8
+ <div id="session_dump" class="hidden"><pre><%= debug_hash @request.session %></pre></div>
9
+ </div>
10
+
11
+ <div class="details">
12
+ <div class="summary"><a href="#" onclick="return toggleEnvDump()">Toggle env dump</a></div>
13
+ <div id="env_dump" class="hidden"><pre><%= debug_hash @request.env.slice(*@request.class::ENV_METHODS) %></pre></div>
14
+ </div>
15
+
16
+ <h2 class="response-heading">Response</h2>
17
+ <p><b>Headers</b>:</p> <pre><%= debug_headers(defined?(@response) ? @response.headers : {}) %></pre>
@@ -0,0 +1,23 @@
1
+ <%
2
+ clean_params = params_valid? ? @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' %>
@@ -0,0 +1,36 @@
1
+ <% error_index = local_assigns[:error_index] || 0 %>
2
+
3
+ <% source_extracts.each_with_index do |source_extract, index| %>
4
+ <% if source_extract[:code] %>
5
+ <div class="source <%= "hidden" if show_source_idx != index %>" id="frame-source-<%= error_index %>-<%= index %>">
6
+ <div class="info">
7
+ Extracted source (around line <strong>#<%= source_extract[:line_number] %></strong>):
8
+ </div>
9
+ <div class="data">
10
+ <table cellpadding="0" cellspacing="0" class="lines">
11
+ <tr>
12
+ <td>
13
+ <pre class="line_numbers">
14
+ <% source_extract[:code].each_key do |line_number| %>
15
+ <span><%= line_number -%></span>
16
+ <% end %>
17
+ </pre>
18
+ </td>
19
+ <td width="100%">
20
+ <pre>
21
+ <% source_extract[:code].each do |line, source| -%>
22
+ <div class="line<%= " active" if line == source_extract[:line_number] -%>"><% if source.is_a?(Array) -%><%= source[0] -%><span class="error_highlight"><%= source[1] -%></span><%= source[2] -%>
23
+ <% else -%>
24
+ <%= source -%>
25
+ <% end -%></div><% end -%>
26
+ </pre>
27
+ </td>
28
+ </tr>
29
+ </table>
30
+ </div>
31
+ <%- unless self.error_highlight_available? -%>
32
+ <p class="error_highlight_tip">Tip: You may want to add <code>gem "error_highlight", "&gt;= 0.4.0"</code> into your Gemfile, which will display the fine-grained error location.</p>
33
+ <%- end -%>
34
+ </div>
35
+ <% end %>
36
+ <% end %>
@@ -0,0 +1,8 @@
1
+ <% @source_extracts.first(3).each do |source_extract| %>
2
+ <% if source_extract[:code] %>
3
+ Extracted source (around line #<%= source_extract[:line_number] %>):
4
+
5
+ <% source_extract[:code].each do |line, source| -%>
6
+ <%= line == source_extract[:line_number] ? "*#{line}" : "##{line}" -%> <%= source -%><% end -%>
7
+ <% end %>
8
+ <% end %>
@@ -0,0 +1,62 @@
1
+ <% names = traces.keys %>
2
+ <% error_index = local_assigns[:error_index] || 0 %>
3
+
4
+ <p><code>Rails.root: <%= defined?(Rails) && Rails.respond_to?(:root) ? Rails.root : "unset" %></code></p>
5
+
6
+ <div id="traces-<%= error_index %>">
7
+ <% names.each do |name| %>
8
+ <%
9
+ show = "show('#{name.gsub(/\s/, '-')}-#{error_index}');"
10
+ hide = (names - [name]).collect {|hide_name| "hide('#{hide_name.gsub(/\s/, '-')}-#{error_index}');"}
11
+ %>
12
+ <a href="#" onclick="<%= hide.join %><%= show %>; return false;"><%= name %></a> <%= '|' unless names.last == name %>
13
+ <% end %>
14
+
15
+ <% traces.each do |name, trace| %>
16
+ <div id="<%= "#{name.gsub(/\s/, '-')}-#{error_index}" %>" style="display: <%= (name == trace_to_show) ? 'block' : 'none' %>;">
17
+ <code class="traces">
18
+ <% trace.each do |frame| %>
19
+ <a class="trace-frames trace-frames-<%= error_index %>" data-exception-object-id="<%= frame[:exception_object_id] %>" data-frame-id="<%= frame[:id] %>" href="#">
20
+ <%= frame[:trace] %>
21
+ </a>
22
+ <br>
23
+ <% end %>
24
+ </code>
25
+ </div>
26
+ <% end %>
27
+
28
+ <script>
29
+ (function() {
30
+ var traceFrames = document.getElementsByClassName('trace-frames-<%= error_index %>');
31
+ var selectedFrame, currentSource = document.getElementById('frame-source-<%= error_index %>-0');
32
+
33
+ // Add click listeners for all stack frames
34
+ for (var i = 0; i < traceFrames.length; i++) {
35
+ traceFrames[i].addEventListener('click', function(e) {
36
+ e.preventDefault();
37
+ var target = e.target;
38
+ var frame_id = target.dataset.frameId;
39
+
40
+ if (selectedFrame) {
41
+ selectedFrame.className = selectedFrame.className.replace("selected", "");
42
+ }
43
+
44
+ target.className += " selected";
45
+ selectedFrame = target;
46
+
47
+ // Change the extracted source code
48
+ changeSourceExtract(frame_id);
49
+ });
50
+
51
+ function changeSourceExtract(frame_id) {
52
+ var el = document.getElementById('frame-source-<%= error_index %>-' + frame_id);
53
+ if (currentSource && el) {
54
+ currentSource.className += " hidden";
55
+ el.className = el.className.replace(" hidden", "");
56
+ currentSource = el;
57
+ }
58
+ }
59
+ }
60
+ })();
61
+ </script>
62
+ </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 %>
@@ -0,0 +1,12 @@
1
+ <header>
2
+ <h1>Blocked hosts: <%= @hosts.join(", ") %></h1>
3
+ </header>
4
+ <main role="main" id="container">
5
+ <h2>To allow requests to these hosts, make sure they are valid hostnames (containing only numbers, letters, dashes and dots), then add the following to your environment configuration:</h2>
6
+ <pre>
7
+ <% @hosts.each do |host| %>
8
+ config.hosts &lt;&lt; "<%= host %>"
9
+ <% end %>
10
+ </pre>
11
+ <p>For more details view: <a href="https://guides.rubyonrails.org/configuring.html#actiondispatch-hostauthorization">the Host Authorization guide</a></p>
12
+ </main>
@@ -0,0 +1,9 @@
1
+ Blocked hosts: <%= @hosts.join(", ") %>
2
+
3
+ To allow requests to these hosts, make sure they are valid hostnames (containing only numbers, letters, dashes and dots), then add the following to your environment configuration:
4
+
5
+ <% @hosts.each do |host| %>
6
+ config.hosts << "<%= host %>"
7
+ <% end %>
8
+
9
+ For more details on host authorization view: https://guides.rubyonrails.org/configuring.html#actiondispatch-hostauthorization
@@ -0,0 +1,35 @@
1
+ <header>
2
+ <h1>
3
+ <%= @exception_wrapper.exception_class_name %>
4
+ <% if params_valid? && @request.parameters['controller'] %>
5
+ in <%= @request.parameters['controller'].camelize %>Controller<% if @request.parameters['action'] %>#<%= @request.parameters['action'] %><% end %>
6
+ <% end %>
7
+ </h1>
8
+ </header>
9
+
10
+ <main role="main" id="container">
11
+ <%= render "rescues/message_and_suggestions", exception: @exception, exception_wrapper: @exception_wrapper %>
12
+ <%= render "rescues/actions", exception: @exception, request: @request, exception_wrapper: @exception_wrapper %>
13
+
14
+ <%= render "rescues/source", source_extracts: @source_extracts, show_source_idx: @show_source_idx, error_index: 0 %>
15
+ <%= render "rescues/trace", traces: @traces, trace_to_show: @trace_to_show, error_index: 0 %>
16
+
17
+ <% if @exception_wrapper.has_cause? %>
18
+ <h2>Exception Causes</h2>
19
+ <% end %>
20
+
21
+ <% @exception_wrapper.wrapped_causes.each.with_index(1) do |wrapper, index| %>
22
+ <div class="details">
23
+ <a class="summary" href="#" onclick="return toggle(<%= wrapper.exception_id %>)">
24
+ <%= wrapper.exception_class_name %>: <%= h wrapper.message %>
25
+ </a>
26
+ </div>
27
+
28
+ <div id="<%= wrapper.exception_id %>" class="hidden">
29
+ <%= render "rescues/source", source_extracts: wrapper.source_extracts, show_source_idx: wrapper.source_to_show_id, error_index: index %>
30
+ <%= render "rescues/trace", traces: wrapper.traces, trace_to_show: wrapper.trace_to_show, error_index: index %>
31
+ </div>
32
+ <% end %>
33
+
34
+ <%= render template: "rescues/_request_and_response" %>
35
+ </main>
@@ -0,0 +1,9 @@
1
+ <%= @exception_wrapper.exception_class_name %><%
2
+ if params_valid? && @request.parameters['controller']
3
+ %> in <%= @request.parameters['controller'].camelize %>Controller<% if @request.parameters['action'] %>#<%= @request.parameters['action'] %><% end %>
4
+ <% end %>
5
+
6
+ <%= @exception_wrapper.message %>
7
+ <%= render template: "rescues/_source" %>
8
+ <%= render template: "rescues/_trace" %>
9
+ <%= render template: "rescues/_request_and_response" %>
@@ -0,0 +1,24 @@
1
+ <header role="banner">
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>
9
+
10
+ <main role="main" id="container">
11
+ <h2>
12
+ <%= h @exception.message %>
13
+ <% if defined?(ActiveStorage) && @exception.message.match?(%r{#{ActiveStorage::Blob.table_name}|#{ActiveStorage::Attachment.table_name}}) %>
14
+ <br />To resolve this issue run: bin/rails active_storage:install
15
+ <% end %>
16
+ <% if defined?(ActionMailbox) && @exception.message.match?(%r{#{ActionMailbox::InboundEmail.table_name}}) %>
17
+ <br />To resolve this issue run: bin/rails action_mailbox:install
18
+ <% end %>
19
+ </h2>
20
+
21
+ <%= render "rescues/source", source_extracts: @source_extracts, show_source_idx: @show_source_idx %>
22
+ <%= render "rescues/trace", traces: @traces, trace_to_show: @trace_to_show %>
23
+ <%= render template: "rescues/_request_and_response" %>
24
+ </main>
@@ -0,0 +1,16 @@
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
+ <% if defined?(ActiveStorage) && @exception.message.match?(%r{#{ActiveStorage::Blob.table_name}|#{ActiveStorage::Attachment.table_name}}) %>
8
+ To resolve this issue run: bin/rails active_storage:install
9
+ <% end %>
10
+ <% if defined?(ActionMailbox) && @exception.message.match?(%r{#{ActionMailbox::InboundEmail.table_name}}) %>
11
+ To resolve this issue run: bin/rails action_mailbox:install
12
+ <% end %>
13
+
14
+ <%= render template: "rescues/_source" %>
15
+ <%= render template: "rescues/_trace" %>
16
+ <%= render template: "rescues/_request_and_response" %>