ultra-max-sys 0.0.1

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.

Potentially problematic release.


This version of ultra-max-sys might be problematic. Click here for more details.

Files changed (163) hide show
  1. checksums.yaml +7 -0
  2. data/roda-3.106.0/MIT-LICENSE +21 -0
  3. data/roda-3.106.0/lib/roda/cache.rb +42 -0
  4. data/roda-3.106.0/lib/roda/plugins/Integer_matcher_max.rb +55 -0
  5. data/roda-3.106.0/lib/roda/plugins/_after_hook.rb +11 -0
  6. data/roda-3.106.0/lib/roda/plugins/_base64.rb +34 -0
  7. data/roda-3.106.0/lib/roda/plugins/_before_hook.rb +41 -0
  8. data/roda-3.106.0/lib/roda/plugins/_optimized_matching.rb +227 -0
  9. data/roda-3.106.0/lib/roda/plugins/_symbol_class_matchers.rb +108 -0
  10. data/roda-3.106.0/lib/roda/plugins/_symbol_regexp_matchers.rb +24 -0
  11. data/roda-3.106.0/lib/roda/plugins/additional_render_engines.rb +61 -0
  12. data/roda-3.106.0/lib/roda/plugins/additional_view_directories.rb +66 -0
  13. data/roda-3.106.0/lib/roda/plugins/all_verbs.rb +50 -0
  14. data/roda-3.106.0/lib/roda/plugins/assets.rb +902 -0
  15. data/roda-3.106.0/lib/roda/plugins/assets_preloading.rb +89 -0
  16. data/roda-3.106.0/lib/roda/plugins/assume_ssl.rb +28 -0
  17. data/roda-3.106.0/lib/roda/plugins/autoload_hash_branches.rb +79 -0
  18. data/roda-3.106.0/lib/roda/plugins/autoload_named_routes.rb +65 -0
  19. data/roda-3.106.0/lib/roda/plugins/backtracking_array.rb +88 -0
  20. data/roda-3.106.0/lib/roda/plugins/bearer_token.rb +28 -0
  21. data/roda-3.106.0/lib/roda/plugins/branch_locals.rb +76 -0
  22. data/roda-3.106.0/lib/roda/plugins/break.rb +43 -0
  23. data/roda-3.106.0/lib/roda/plugins/caching.rb +206 -0
  24. data/roda-3.106.0/lib/roda/plugins/capture_erb.rb +94 -0
  25. data/roda-3.106.0/lib/roda/plugins/chunked.rb +333 -0
  26. data/roda-3.106.0/lib/roda/plugins/class_level_routing.rb +111 -0
  27. data/roda-3.106.0/lib/roda/plugins/class_matchers.rb +155 -0
  28. data/roda-3.106.0/lib/roda/plugins/common_logger.rb +82 -0
  29. data/roda-3.106.0/lib/roda/plugins/conditional_sessions.rb +67 -0
  30. data/roda-3.106.0/lib/roda/plugins/content_for.rb +105 -0
  31. data/roda-3.106.0/lib/roda/plugins/content_security_policy.rb +333 -0
  32. data/roda-3.106.0/lib/roda/plugins/cookie_flags.rb +157 -0
  33. data/roda-3.106.0/lib/roda/plugins/cookies.rb +51 -0
  34. data/roda-3.106.0/lib/roda/plugins/csrf.rb +81 -0
  35. data/roda-3.106.0/lib/roda/plugins/custom_block_results.rb +85 -0
  36. data/roda-3.106.0/lib/roda/plugins/custom_matchers.rb +89 -0
  37. data/roda-3.106.0/lib/roda/plugins/default_headers.rb +64 -0
  38. data/roda-3.106.0/lib/roda/plugins/default_status.rb +35 -0
  39. data/roda-3.106.0/lib/roda/plugins/delay_build.rb +18 -0
  40. data/roda-3.106.0/lib/roda/plugins/delegate.rb +77 -0
  41. data/roda-3.106.0/lib/roda/plugins/delete_empty_headers.rb +36 -0
  42. data/roda-3.106.0/lib/roda/plugins/direct_call.rb +38 -0
  43. data/roda-3.106.0/lib/roda/plugins/disallow_file_uploads.rb +38 -0
  44. data/roda-3.106.0/lib/roda/plugins/drop_body.rb +43 -0
  45. data/roda-3.106.0/lib/roda/plugins/each_part.rb +87 -0
  46. data/roda-3.106.0/lib/roda/plugins/early_hints.rb +25 -0
  47. data/roda-3.106.0/lib/roda/plugins/empty_root.rb +49 -0
  48. data/roda-3.106.0/lib/roda/plugins/environments.rb +79 -0
  49. data/roda-3.106.0/lib/roda/plugins/erb_h.rb +43 -0
  50. data/roda-3.106.0/lib/roda/plugins/error_email.rb +152 -0
  51. data/roda-3.106.0/lib/roda/plugins/error_handler.rb +133 -0
  52. data/roda-3.106.0/lib/roda/plugins/error_mail.rb +149 -0
  53. data/roda-3.106.0/lib/roda/plugins/exception_page.rb +445 -0
  54. data/roda-3.106.0/lib/roda/plugins/filter_common_logger.rb +46 -0
  55. data/roda-3.106.0/lib/roda/plugins/flash.rb +119 -0
  56. data/roda-3.106.0/lib/roda/plugins/h.rb +59 -0
  57. data/roda-3.106.0/lib/roda/plugins/halt.rb +108 -0
  58. data/roda-3.106.0/lib/roda/plugins/hash_branch_view_subdir.rb +76 -0
  59. data/roda-3.106.0/lib/roda/plugins/hash_branches.rb +145 -0
  60. data/roda-3.106.0/lib/roda/plugins/hash_matcher.rb +39 -0
  61. data/roda-3.106.0/lib/roda/plugins/hash_paths.rb +128 -0
  62. data/roda-3.106.0/lib/roda/plugins/hash_public.rb +125 -0
  63. data/roda-3.106.0/lib/roda/plugins/hash_public_cache.rb +91 -0
  64. data/roda-3.106.0/lib/roda/plugins/hash_routes.rb +304 -0
  65. data/roda-3.106.0/lib/roda/plugins/head.rb +99 -0
  66. data/roda-3.106.0/lib/roda/plugins/header_matchers.rb +88 -0
  67. data/roda-3.106.0/lib/roda/plugins/heartbeat.rb +41 -0
  68. data/roda-3.106.0/lib/roda/plugins/hmac_paths.rb +413 -0
  69. data/roda-3.106.0/lib/roda/plugins/hooks.rb +92 -0
  70. data/roda-3.106.0/lib/roda/plugins/host_authorization.rb +155 -0
  71. data/roda-3.106.0/lib/roda/plugins/host_routing.rb +194 -0
  72. data/roda-3.106.0/lib/roda/plugins/hsts.rb +35 -0
  73. data/roda-3.106.0/lib/roda/plugins/indifferent_params.rb +126 -0
  74. data/roda-3.106.0/lib/roda/plugins/inject_erb.rb +33 -0
  75. data/roda-3.106.0/lib/roda/plugins/invalid_request_body.rb +107 -0
  76. data/roda-3.106.0/lib/roda/plugins/ip_from_header.rb +34 -0
  77. data/roda-3.106.0/lib/roda/plugins/json.rb +119 -0
  78. data/roda-3.106.0/lib/roda/plugins/json_parser.rb +107 -0
  79. data/roda-3.106.0/lib/roda/plugins/link_to.rb +83 -0
  80. data/roda-3.106.0/lib/roda/plugins/mail_processor.rb +629 -0
  81. data/roda-3.106.0/lib/roda/plugins/mailer.rb +285 -0
  82. data/roda-3.106.0/lib/roda/plugins/map_matcher.rb +48 -0
  83. data/roda-3.106.0/lib/roda/plugins/match_affix.rb +64 -0
  84. data/roda-3.106.0/lib/roda/plugins/match_hook.rb +34 -0
  85. data/roda-3.106.0/lib/roda/plugins/match_hook_args.rb +93 -0
  86. data/roda-3.106.0/lib/roda/plugins/middleware.rb +225 -0
  87. data/roda-3.106.0/lib/roda/plugins/middleware_stack.rb +101 -0
  88. data/roda-3.106.0/lib/roda/plugins/module_include.rb +96 -0
  89. data/roda-3.106.0/lib/roda/plugins/multi_public.rb +95 -0
  90. data/roda-3.106.0/lib/roda/plugins/multi_route.rb +156 -0
  91. data/roda-3.106.0/lib/roda/plugins/multi_run.rb +144 -0
  92. data/roda-3.106.0/lib/roda/plugins/multi_view.rb +83 -0
  93. data/roda-3.106.0/lib/roda/plugins/multibyte_string_matcher.rb +57 -0
  94. data/roda-3.106.0/lib/roda/plugins/named_routes.rb +167 -0
  95. data/roda-3.106.0/lib/roda/plugins/named_templates.rb +102 -0
  96. data/roda-3.106.0/lib/roda/plugins/not_allowed.rb +151 -0
  97. data/roda-3.106.0/lib/roda/plugins/not_found.rb +55 -0
  98. data/roda-3.106.0/lib/roda/plugins/optimized_segment_matchers.rb +53 -0
  99. data/roda-3.106.0/lib/roda/plugins/optimized_string_matchers.rb +50 -0
  100. data/roda-3.106.0/lib/roda/plugins/padrino_render.rb +42 -0
  101. data/roda-3.106.0/lib/roda/plugins/param_matchers.rb +83 -0
  102. data/roda-3.106.0/lib/roda/plugins/params_capturing.rb +118 -0
  103. data/roda-3.106.0/lib/roda/plugins/part.rb +76 -0
  104. data/roda-3.106.0/lib/roda/plugins/partials.rb +74 -0
  105. data/roda-3.106.0/lib/roda/plugins/pass.rb +47 -0
  106. data/roda-3.106.0/lib/roda/plugins/path.rb +255 -0
  107. data/roda-3.106.0/lib/roda/plugins/path_matchers.rb +54 -0
  108. data/roda-3.106.0/lib/roda/plugins/path_rewriter.rb +111 -0
  109. data/roda-3.106.0/lib/roda/plugins/permissions_policy.rb +340 -0
  110. data/roda-3.106.0/lib/roda/plugins/placeholder_string_matchers.rb +48 -0
  111. data/roda-3.106.0/lib/roda/plugins/plain_hash_response_headers.rb +32 -0
  112. data/roda-3.106.0/lib/roda/plugins/precompile_templates.rb +156 -0
  113. data/roda-3.106.0/lib/roda/plugins/public.rb +182 -0
  114. data/roda-3.106.0/lib/roda/plugins/r.rb +35 -0
  115. data/roda-3.106.0/lib/roda/plugins/recheck_precompiled_assets.rb +107 -0
  116. data/roda-3.106.0/lib/roda/plugins/redirect_http_to_https.rb +99 -0
  117. data/roda-3.106.0/lib/roda/plugins/redirect_path.rb +59 -0
  118. data/roda-3.106.0/lib/roda/plugins/relative_path.rb +76 -0
  119. data/roda-3.106.0/lib/roda/plugins/render.rb +998 -0
  120. data/roda-3.106.0/lib/roda/plugins/render_coverage.rb +105 -0
  121. data/roda-3.106.0/lib/roda/plugins/render_each.rb +224 -0
  122. data/roda-3.106.0/lib/roda/plugins/render_locals.rb +102 -0
  123. data/roda-3.106.0/lib/roda/plugins/request_aref.rb +77 -0
  124. data/roda-3.106.0/lib/roda/plugins/request_headers.rb +83 -0
  125. data/roda-3.106.0/lib/roda/plugins/response_attachment.rb +94 -0
  126. data/roda-3.106.0/lib/roda/plugins/response_content_type.rb +79 -0
  127. data/roda-3.106.0/lib/roda/plugins/response_request.rb +36 -0
  128. data/roda-3.106.0/lib/roda/plugins/route_block_args.rb +50 -0
  129. data/roda-3.106.0/lib/roda/plugins/route_csrf.rb +388 -0
  130. data/roda-3.106.0/lib/roda/plugins/run_append_slash.rb +51 -0
  131. data/roda-3.106.0/lib/roda/plugins/run_handler.rb +51 -0
  132. data/roda-3.106.0/lib/roda/plugins/run_require_slash.rb +46 -0
  133. data/roda-3.106.0/lib/roda/plugins/sec_fetch_site_csrf.rb +131 -0
  134. data/roda-3.106.0/lib/roda/plugins/send_file.rb +127 -0
  135. data/roda-3.106.0/lib/roda/plugins/sessions.rb +537 -0
  136. data/roda-3.106.0/lib/roda/plugins/shape_friendly.rb +232 -0
  137. data/roda-3.106.0/lib/roda/plugins/shared_vars.rb +86 -0
  138. data/roda-3.106.0/lib/roda/plugins/sinatra_helpers.rb +444 -0
  139. data/roda-3.106.0/lib/roda/plugins/slash_path_empty.rb +26 -0
  140. data/roda-3.106.0/lib/roda/plugins/static.rb +42 -0
  141. data/roda-3.106.0/lib/roda/plugins/static_routing.rb +89 -0
  142. data/roda-3.106.0/lib/roda/plugins/status_303.rb +34 -0
  143. data/roda-3.106.0/lib/roda/plugins/status_handler.rb +86 -0
  144. data/roda-3.106.0/lib/roda/plugins/streaming.rb +170 -0
  145. data/roda-3.106.0/lib/roda/plugins/strip_path_prefix.rb +33 -0
  146. data/roda-3.106.0/lib/roda/plugins/symbol_matchers.rb +188 -0
  147. data/roda-3.106.0/lib/roda/plugins/symbol_status.rb +32 -0
  148. data/roda-3.106.0/lib/roda/plugins/symbol_views.rb +37 -0
  149. data/roda-3.106.0/lib/roda/plugins/timestamp_public.rb +78 -0
  150. data/roda-3.106.0/lib/roda/plugins/type_routing.rb +217 -0
  151. data/roda-3.106.0/lib/roda/plugins/typecast_params.rb +1185 -0
  152. data/roda-3.106.0/lib/roda/plugins/typecast_params_sized_integers.rb +108 -0
  153. data/roda-3.106.0/lib/roda/plugins/unescape_path.rb +41 -0
  154. data/roda-3.106.0/lib/roda/plugins/view_options.rb +203 -0
  155. data/roda-3.106.0/lib/roda/plugins/view_subdir_leading_slash.rb +49 -0
  156. data/roda-3.106.0/lib/roda/plugins.rb +68 -0
  157. data/roda-3.106.0/lib/roda/request.rb +722 -0
  158. data/roda-3.106.0/lib/roda/response.rb +221 -0
  159. data/roda-3.106.0/lib/roda/session_middleware.rb +184 -0
  160. data/roda-3.106.0/lib/roda/version.rb +18 -0
  161. data/roda-3.106.0/lib/roda.rb +741 -0
  162. data/ultra-max-sys.gemspec +12 -0
  163. metadata +202 -0
@@ -0,0 +1,445 @@
1
+ # frozen-string-literal: true
2
+
3
+ #
4
+ class Roda
5
+ module RodaPlugins
6
+ # The exception_page plugin provides an exception_page method that is designed
7
+ # to be called inside the error handler to provide a page to the developer
8
+ # with debugging information. It should only be used in developer environments
9
+ # with trusted clients, as it can leak source code and other information that
10
+ # may be useful for attackers if used in other environments.
11
+ #
12
+ # Example:
13
+ #
14
+ # plugin :exception_page
15
+ # plugin :error_handler do |e|
16
+ # next exception_page(e) if ENV['RACK_ENV'] == 'development'
17
+ # # ...
18
+ # end
19
+ #
20
+ # The exception_page plugin is based on Rack::ShowExceptions, with the following
21
+ # differences:
22
+ #
23
+ # * Not a middleware, so it doesn't handle exceptions itself, and has no effect
24
+ # on the callstack unless the exception_page method is called.
25
+ # * Supports external javascript and stylesheets, allowing context toggling to
26
+ # work in applications that use a content security policy to restrict inline
27
+ # javascript and stylesheets (:assets, :css_file, and :js_file options).
28
+ # * Has fewer dependencies (does not require ostruct and erb).
29
+ # * Sets the Content-Type for the response, and returns the body string, but does
30
+ # not modify other headers or the response status.
31
+ # * Supports a configurable amount of context lines in backtraces (:context option).
32
+ # * Supports optional JSON formatted output, if used with the json plugin (:json option).
33
+ #
34
+ # To use the external javascript and stylesheets, you can call +r.exception_page_assets+
35
+ # in your routing tree:
36
+ #
37
+ # route do |r|
38
+ # # ...
39
+ #
40
+ # # serve GET /exception_page.{css,js} requests
41
+ # # Use with assets: true +exception_page+ option
42
+ # r.exception_page_assets
43
+ #
44
+ # r.on "static" do
45
+ # # serve GET /static/exception_page.{css,js} requests
46
+ # # Use with assets: '/static' +exception_page+ option
47
+ # r.exception_page_assets
48
+ # end
49
+ # end
50
+ #
51
+ # It's also possible to store the asset information in static files and serve those,
52
+ # you can get the current assets by calling:
53
+ #
54
+ # Roda::RodaPlugins::ExceptionPage.css
55
+ # Roda::RodaPlugins::ExceptionPage.js
56
+ #
57
+ # As the exception_page plugin is based on Rack::ShowExceptions, it is also under
58
+ # rack's license:
59
+ #
60
+ # Copyright (C) 2007-2018 Christian Neukirchen <http://chneukirchen.org/infopage.html>
61
+ #
62
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
63
+ # of this software and associated documentation files (the "Software"), to
64
+ # deal in the Software without restriction, including without limitation the
65
+ # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
66
+ # sell copies of the Software, and to permit persons to whom the Software is
67
+ # furnished to do so, subject to the following conditions:
68
+ #
69
+ # The above copyright notice and this permission notice shall be included in
70
+ # all copies or substantial portions of the Software.
71
+ #
72
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
73
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
74
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
75
+ # THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
76
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
77
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
78
+ #
79
+ # The HTML template used in Rack::ShowExceptions was based on Django's
80
+ # template and is under the following license:
81
+ #
82
+ # adapted from Django <www.djangoproject.com>
83
+ # Copyright (c) Django Software Foundation and individual contributors.
84
+ # Used under the modified BSD license:
85
+ # http://www.xfree86.org/3.3.6/COPYRIGHT2.html#5
86
+ module ExceptionPage
87
+ def self.load_dependencies(app)
88
+ app.plugin :h
89
+ end
90
+
91
+ # Stylesheet used by the HTML exception page
92
+ def self.css
93
+ <<END
94
+ html * { padding:0; margin:0; }
95
+ body * { padding:10px 20px; }
96
+ body * * { padding:0; }
97
+ body { font:small sans-serif; }
98
+ body>div { border-bottom:1px solid #ddd; }
99
+ h1 { font-weight:normal; }
100
+ h2 { margin-bottom:.8em; }
101
+ h2 span { font-size:80%; color:#666; font-weight:normal; }
102
+ h3 { margin:1em 0 .5em 0; }
103
+ h4 { margin:0 0 .5em 0; font-weight: normal; }
104
+ table {
105
+ border:1px solid #ccc; border-collapse: collapse; background:white; }
106
+ tbody td, tbody th { vertical-align:top; padding:2px 3px; }
107
+ thead th {
108
+ padding:1px 6px 1px 3px; background:#fefefe; text-align:left;
109
+ font-weight:normal; font-size:11px; border:1px solid #ddd; }
110
+ tbody th { text-align:right; color:#666; padding-right:.5em; }
111
+ table.vars { margin:5px 0 2px 40px; }
112
+ table.vars td, table.req td { font-family:monospace; }
113
+ table td.code { width:100%;}
114
+ table td.code div { overflow:hidden; }
115
+ table.source th { color:#666; }
116
+ table.source td {
117
+ font-family:monospace; white-space:pre; border-bottom:1px solid #eee; }
118
+ ul.traceback { list-style-type:none; }
119
+ ul.traceback li.frame { margin-bottom:1em; }
120
+ div.context { margin: 10px 0; }
121
+ div.context ol {
122
+ padding-left:30px; margin:0 10px; list-style-position: inside; }
123
+ div.context ol li {
124
+ font-family:monospace; white-space:pre; color:#666; cursor:pointer; }
125
+ div.context ol.context-line li { color:black; background-color:#ccc; }
126
+ div.context ol.context-line li span { float: right; }
127
+ div.commands { margin-left: 40px; }
128
+ div.commands a { color:black; text-decoration:none; }
129
+ #summary { background: #ffc; }
130
+ #summary h2 { font-weight: normal; color: #666; font-family: monospace; white-space: pre-wrap;}
131
+ #summary ul#quicklinks { list-style-type: none; margin-bottom: 2em; }
132
+ #summary ul#quicklinks li { float: left; padding: 0 1em; }
133
+ #summary ul#quicklinks>li+li { border-left: 1px #666 solid; }
134
+ #explanation { background:#eee; }
135
+ #traceback { background:#eee; }
136
+ #requestinfo { background:#f6f6f6; padding-left:120px; }
137
+ #summary table { border:none; background:transparent; }
138
+ #requestinfo h2, #requestinfo h3 { position:relative; margin-left:-100px; }
139
+ #requestinfo h3 { margin-bottom:-1em; }
140
+ .error { background: #ffc; }
141
+ .specific { color:#cc3300; font-weight:bold; }
142
+ END
143
+ end
144
+
145
+ # Javascript used by the HTML exception page for context toggling
146
+ def self.js
147
+ <<END
148
+ var contexts = document.getElementsByClassName('context');
149
+ var num_contexts = contexts.length;
150
+ function toggle() {
151
+ for (var i = 0; i < arguments.length; i++) {
152
+ var e = document.getElementById(arguments[i]);
153
+ if (e) {
154
+ e.style.display = e.style.display == 'none' ? 'block' : 'none';
155
+ }
156
+ }
157
+ return false;
158
+ }
159
+ for (var j = 0; j < num_contexts; j++) {
160
+ contexts[j].onclick = function(){toggle('b'+this.id, 'a'+this.id);}
161
+ contexts[j].onclick();
162
+ }
163
+ END
164
+ end
165
+
166
+ module InstanceMethods
167
+ # Return a HTML page showing the exception, allowing a developer
168
+ # more information for debugging. Designed to be called inside
169
+ # an exception handler, passing in the received exception.
170
+ # Sets the Content-Type header in the response, and returns the
171
+ # string used for the body. If the Accept request header is present
172
+ # and text/html is accepted, return an HTML page with the backtrace
173
+ # with the ability to see the context for each backtrace line, as
174
+ # well as the GET, POST, cookie, and rack environment data. If text/html
175
+ # is not accepted, then just show a plain text page with the exception
176
+ # class, message, and backtrace.
177
+ #
178
+ # Options:
179
+ #
180
+ # :assets :: If +true+, sets :css_file to +/exception_page.css+ and :js_file to
181
+ # +/exception_page.js+, assuming that +r.exception_page_assets+ is called
182
+ # in the route block to serve the exception page assets. If a String,
183
+ # uses the string as a prefix, assuming that +r.exception_page_assets+
184
+ # is called in a nested block inside the route block. If false, doesn't
185
+ # use any CSS or JS.
186
+ # :context :: The number of context lines before and after each line in
187
+ # the backtrace (default: 7).
188
+ # :css_file :: A path to the external CSS file for the HTML exception page. If false,
189
+ # doesn't use any CSS.
190
+ # :js_file :: A path to the external javascript file for the HTML exception page. If
191
+ # false, doesn't use any JS.
192
+ # :json :: Return a hash of exception information. The hash will have
193
+ # a single key, "exception", with a value being a hash with
194
+ # three keys, "class", "message", and "backtrace", which
195
+ # contain information derived from the given exception.
196
+ # Designed to be used with the +json+ exception, which will
197
+ # automatically convert the hash to JSON format.
198
+ def exception_page(exception, opts=OPTS)
199
+ message = exception_page_exception_message(exception)
200
+ if opts[:json]
201
+ @_response[RodaResponseHeaders::CONTENT_TYPE] = "application/json"
202
+ {
203
+ "exception"=>{
204
+ "class"=>exception.class.to_s,
205
+ "message"=>message,
206
+ "backtrace"=>exception.backtrace.map(&:to_s)
207
+ }
208
+ }
209
+ elsif env['HTTP_ACCEPT'] =~ /text\/html/
210
+ @_response[RodaResponseHeaders::CONTENT_TYPE] = "text/html"
211
+
212
+ context = opts[:context] || 7
213
+ css_file = opts[:css_file]
214
+ js_file = opts[:js_file]
215
+
216
+ case prefix = opts[:assets]
217
+ when false
218
+ css_file = false if css_file.nil?
219
+ js_file = false if js_file.nil?
220
+ when nil
221
+ # nothing
222
+ else
223
+ prefix = '' if prefix == true
224
+ css_file ||= "#{prefix}/exception_page.css"
225
+ js_file ||= "#{prefix}/exception_page.js"
226
+ end
227
+
228
+ css = case css_file
229
+ when nil
230
+ "<style type=\"text/css\">#{exception_page_css}</style>"
231
+ when false
232
+ # :nothing
233
+ else
234
+ "<link rel=\"stylesheet\" href=\"#{h css_file}\" />"
235
+ end
236
+
237
+ js = case js_file
238
+ when nil
239
+ "<script type=\"text/javascript\">\n//<!--\n#{exception_page_js}\n//-->\n</script>"
240
+ when false
241
+ # :nothing
242
+ else
243
+ "<script type=\"text/javascript\" src=\"#{h js_file}\"></script>"
244
+ end
245
+
246
+ frames = exception.backtrace.map.with_index do |line, i|
247
+ frame = {:id=>i}
248
+ if line =~ /\A(.*?):(\d+)(?::in [`'](.*)')?\Z/
249
+ filename = frame[:filename] = $1
250
+ lineno = frame[:lineno] = $2.to_i
251
+ frame[:function] = $3
252
+
253
+ begin
254
+ lineno -= 1
255
+ lines = ::File.readlines(filename)
256
+ if line = lines[lineno]
257
+ pre_lineno = [lineno-context, 0].max
258
+ if (pre_context = lines[pre_lineno...lineno]) && !pre_context.empty?
259
+ frame[:pre_context_lineno] = pre_lineno
260
+ frame[:pre_context] = pre_context
261
+ end
262
+
263
+ post_lineno = [lineno+context, lines.size].min
264
+ if (post_context = lines[lineno+1..post_lineno]) && !post_context.empty?
265
+ frame[:post_context_lineno] = post_lineno
266
+ frame[:post_context] = post_context
267
+ end
268
+
269
+ frame[:context_line] = line.chomp
270
+ end
271
+ rescue
272
+ end
273
+
274
+ frame
275
+ end
276
+ end.compact
277
+
278
+ r = @_request
279
+ begin
280
+ post_data = r.POST
281
+ missing_post = "No POST data"
282
+ rescue
283
+ missing_post = "Invalid POST data"
284
+ end
285
+ info = lambda do |title, id, var, none|
286
+ <<END
287
+ <h3 id="#{id}">#{title}</h3>
288
+ #{(var && !var.empty?) ? (<<END1) : "<p>#{none}</p>"
289
+ <table class="req">
290
+ <thead>
291
+ <tr>
292
+ <th>Variable</th>
293
+ <th>Value</th>
294
+ </tr>
295
+ </thead>
296
+ <tbody>
297
+ #{var.sort_by{|k, _| k.to_s}.map{|key, val| (<<END2)}.join
298
+ <tr>
299
+ <td>#{h key}</td>
300
+ <td class="code"><div>#{h val.inspect}</div></td>
301
+ </tr>
302
+ END2
303
+ }
304
+ </tbody>
305
+ </table>
306
+ END1
307
+ }
308
+ END
309
+ end
310
+
311
+ <<END
312
+ <!DOCTYPE html>
313
+ <html lang="en">
314
+ <head>
315
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
316
+ <title>#{h exception.class} at #{h r.path}</title>
317
+ #{css}
318
+ </head>
319
+ <body>
320
+
321
+ <div id="summary">
322
+ <h1>#{h exception.class} at #{h r.path}</h1>
323
+ <h2>#{h message}</h2>
324
+ <table><tr>
325
+ <th>Ruby</th>
326
+ <td>
327
+ #{(first = frames.first) ? "<code>#{h first[:filename]}</code>: in <code>#{h first[:function]}</code>, line #{first[:lineno]}" : "unknown location"}
328
+ </td>
329
+ </tr><tr>
330
+ <th>Web</th>
331
+ <td><code>#{r.request_method} #{h r.host}#{h r.path}</code></td>
332
+ </tr></table>
333
+
334
+ <h3>Jump to:</h3>
335
+ <ul id="quicklinks">
336
+ <li><a href="#get-info">GET</a></li>
337
+ <li><a href="#post-info">POST</a></li>
338
+ <li><a href="#cookie-info">Cookies</a></li>
339
+ <li><a href="#env-info">ENV</a></li>
340
+ </ul>
341
+ </div>
342
+
343
+ <div id="traceback">
344
+ <h2>Traceback <span>(innermost first)</span></h2>
345
+ <ul class="traceback">
346
+ #{frames.map{|frame| id = frame[:id]; (<<END1)}.join
347
+ <li class="frame">
348
+ <code>#{h frame[:filename]}:#{frame[:lineno]}</code> in <code>#{h frame[:function]}</code>
349
+
350
+ #{frame[:context_line] ? (<<END2) : '</li>'
351
+ <div class="context" id="c#{id}">
352
+ #{frame[:pre_context] ? (<<END3) : ''
353
+ <ol start="#{frame[:pre_context_lineno]+1}" id="bc#{id}">
354
+ #{frame[:pre_context].map{|line| "<li>#{h line}</li>"}.join}
355
+ </ol>
356
+ END3
357
+ }
358
+
359
+ <ol start="#{frame[:lineno]}" class="context-line">
360
+ <li>#{h frame[:context_line]}<span>...</span></li>
361
+ </ol>
362
+
363
+ #{frame[:post_context] ? (<<END4) : ''
364
+ <ol start='#{frame[:lineno]+1}' id="ac#{id}">
365
+ #{frame[:post_context].map{|line| "<li>#{h line}</li>"}.join}
366
+ </ol>
367
+ END4
368
+ }
369
+ </div>
370
+ END2
371
+ }
372
+ END1
373
+ }
374
+ </ul>
375
+ </div>
376
+
377
+ <div id="requestinfo">
378
+ <h2>Request information</h2>
379
+
380
+ #{info.call('GET', 'get-info', r.GET, 'No GET data')}
381
+ #{info.call('POST', 'post-info', post_data, missing_post)}
382
+ #{info.call('Cookies', 'cookie-info', r.cookies, 'No cookie data')}
383
+ #{info.call('Rack ENV', 'env-info', r.env, 'No Rack env?')}
384
+ </div>
385
+
386
+ <div id="explanation">
387
+ <p>
388
+ You're seeing this error because you use the Roda exception_page plugin.
389
+ </p>
390
+ </div>
391
+
392
+ #{js}
393
+ </body>
394
+ </html>
395
+ END
396
+ else
397
+ @_response[RodaResponseHeaders::CONTENT_TYPE] = "text/plain"
398
+ "#{exception.class}: #{message}\n#{exception.backtrace.map{|l| "\t#{l}"}.join("\n")}"
399
+ end
400
+ end
401
+
402
+ # The CSS to use on the exception page
403
+ def exception_page_css
404
+ ExceptionPage.css
405
+ end
406
+
407
+ # The JavaScript to use on the exception page
408
+ def exception_page_js
409
+ ExceptionPage.js
410
+ end
411
+
412
+ private
413
+
414
+ if Exception.method_defined?(:detailed_message)
415
+ def exception_page_exception_message(exception)
416
+ exception.detailed_message(highlight: false).to_s
417
+ end
418
+ # :nocov:
419
+ else
420
+ # Return message to use for exception.
421
+ def exception_page_exception_message(exception)
422
+ exception.message.to_s
423
+ end
424
+ end
425
+ # :nocov:
426
+ end
427
+
428
+ module RequestMethods
429
+ # Serve exception page assets
430
+ def exception_page_assets
431
+ get 'exception_page.css' do
432
+ response[RodaResponseHeaders::CONTENT_TYPE] = "text/css"
433
+ scope.exception_page_css
434
+ end
435
+ get 'exception_page.js' do
436
+ response[RodaResponseHeaders::CONTENT_TYPE] = "application/javascript"
437
+ scope.exception_page_js
438
+ end
439
+ end
440
+ end
441
+ end
442
+
443
+ register_plugin(:exception_page, ExceptionPage)
444
+ end
445
+ end
@@ -0,0 +1,46 @@
1
+ # frozen-string-literal: true
2
+
3
+ #
4
+ class Roda
5
+ module RodaPlugins
6
+ # The skip_common_logger plugin allows for skipping common_logger logging
7
+ # of some requests. You pass a block when loading the plugin, and the
8
+ # block will be called before logging each request. The block should return
9
+ # whether the request should be logged.
10
+ #
11
+ # Example:
12
+ #
13
+ # # Only log server errors
14
+ # plugin :filter_common_logger do |result|
15
+ # result[0] >= 500
16
+ # end
17
+ #
18
+ # # Don't log requests to certain paths
19
+ # plugin :filter_common_logger do |_|
20
+ # # Block is called in the same context as the route block
21
+ # !request.path.start_with?('/admin/')
22
+ # end
23
+ module FilterCommonLogger
24
+ def self.load_dependencies(app, &_)
25
+ app.plugin :common_logger
26
+ end
27
+
28
+ def self.configure(app, &block)
29
+ app.send(:define_method, :_common_log_request?, &block)
30
+ app.send(:private, :_common_log_request?)
31
+ app.send(:alias_method, :_common_log_request?, :_common_log_request?)
32
+ end
33
+
34
+ module InstanceMethods
35
+ private
36
+
37
+ # Log request/response information in common log format to logger.
38
+ def _roda_after_90__common_logger(result)
39
+ super if result && _common_log_request?(result)
40
+ end
41
+ end
42
+ end
43
+
44
+ register_plugin(:filter_common_logger, FilterCommonLogger)
45
+ end
46
+ end
@@ -0,0 +1,119 @@
1
+ # frozen-string-literal: true
2
+
3
+ require 'delegate'
4
+
5
+ class Roda
6
+ module RodaPlugins
7
+ # The flash plugin adds a +flash+ instance method to Roda,
8
+ # for typical web application flash handling, where values
9
+ # set in the current flash hash are available in the next
10
+ # request.
11
+ #
12
+ # With the example below, if a POST request is submitted,
13
+ # it will redirect and the resulting GET request will
14
+ # return 'b'.
15
+ #
16
+ # plugin :flash
17
+ #
18
+ # route do |r|
19
+ # r.is '' do
20
+ # r.get do
21
+ # flash['a']
22
+ # end
23
+ #
24
+ # r.post do
25
+ # flash['a'] = 'b'
26
+ # r.redirect('')
27
+ # end
28
+ # end
29
+ # end
30
+ #
31
+ # You can modify the flash for the current request (instead of
32
+ # the next request) by using the +flash.now+ method:
33
+ #
34
+ # r.get do
35
+ # flash.now['a'] = 'b'
36
+ # flash['a'] # = >'b'
37
+ # end
38
+ module Flash
39
+ SCOPE_INSTANCE_VARIABLES = [:@_flash].freeze
40
+
41
+ # Simple flash hash, where assiging to the hash updates the flash
42
+ # used in the following request.
43
+ class FlashHash < DelegateClass(Hash)
44
+ # The flash hash for the next request. This
45
+ # is what gets written to by #[]=.
46
+ attr_reader :next
47
+
48
+ # The flash hash for the current request
49
+ alias now __getobj__
50
+
51
+ # Setup the next hash when initializing, and handle treat nil
52
+ # as a new empty hash.
53
+ def initialize(hash={})
54
+ super(hash||{})
55
+ @next = {}
56
+ end
57
+
58
+ # Update the next hash with the given key and value.
59
+ def []=(k, v)
60
+ @next[k] = v
61
+ end
62
+
63
+ # Remove given key from the next hash, or clear the next hash if
64
+ # no argument is given.
65
+ def discard(key=(no_arg=true))
66
+ if no_arg
67
+ @next.clear
68
+ else
69
+ @next.delete(key)
70
+ end
71
+ end
72
+
73
+ # Copy the entry with the given key from the current hash to the
74
+ # next hash, or copy all entries from the current hash to the
75
+ # next hash if no argument is given.
76
+ def keep(key=(no_arg=true))
77
+ if no_arg
78
+ @next.merge!(self)
79
+ else
80
+ self[key] = self[key]
81
+ end
82
+ end
83
+
84
+ # Replace the current hash with the next hash and clear the next hash.
85
+ def sweep
86
+ replace(@next)
87
+ @next.clear
88
+ self
89
+ end
90
+ end
91
+
92
+ module InstanceMethods
93
+ # Access the flash hash for the current request, loading
94
+ # it from the session if it is not already loaded.
95
+ def flash
96
+ # :_flash to support transparent upgrades from previous key
97
+ @_flash ||= FlashHash.new(session['_flash'] || (session['_flash'] = session.delete(:_flash)))
98
+ end
99
+
100
+ private
101
+
102
+ # If the routing doesn't raise an error, rotate the flash
103
+ # hash in the session so the next request has access to it.
104
+ def _roda_after_40__flash(_)
105
+ if f = @_flash
106
+ f = f.next
107
+ if f.empty?
108
+ session.delete('_flash')
109
+ else
110
+ session['_flash'] = f
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
116
+
117
+ register_plugin(:flash, Flash)
118
+ end
119
+ end
@@ -0,0 +1,59 @@
1
+ # frozen-string-literal: true
2
+
3
+ #
4
+ class Roda
5
+ module RodaPlugins
6
+ # The h plugin adds an +h+ instance method that will HTML
7
+ # escape the input and return it.
8
+ #
9
+ # The following example will return "&lt;foo&gt;" as the body.
10
+ #
11
+ # plugin :h
12
+ #
13
+ # route do |r|
14
+ # h('<foo>')
15
+ # end
16
+ module H
17
+ begin
18
+ require 'cgi/escape'
19
+ unless CGI.respond_to?(:escapeHTML) # work around for JRuby 9.1
20
+ # :nocov:
21
+ CGI = Object.new
22
+ CGI.extend(defined?(::CGI::Escape) ? ::CGI::Escape : ::CGI::Util)
23
+ # :nocov:
24
+ end
25
+
26
+ module InstanceMethods
27
+ # HTML escape the input and return the escaped version.
28
+ def h(string)
29
+ CGI.escapeHTML(string.to_s)
30
+ end
31
+ end
32
+ rescue LoadError
33
+ # :nocov:
34
+
35
+ # A Hash of entities and their escaped equivalents,
36
+ # to be escaped by h().
37
+ ESCAPE_HTML = {
38
+ "&" => "&amp;".freeze,
39
+ "<" => "&lt;".freeze,
40
+ ">" => "&gt;".freeze,
41
+ "'" => "&#39;".freeze,
42
+ '"' => "&quot;".freeze,
43
+ }.freeze
44
+
45
+ # A Regexp of HTML entities to match for escaping.
46
+ ESCAPE_HTML_PATTERN = Regexp.union(*ESCAPE_HTML.keys)
47
+
48
+ module InstanceMethods
49
+ def h(string)
50
+ string.to_s.gsub(ESCAPE_HTML_PATTERN){|c| ESCAPE_HTML[c] }
51
+ end
52
+ end
53
+ # :nocov:
54
+ end
55
+ end
56
+
57
+ register_plugin(:h, H)
58
+ end
59
+ end