ultra-lite-hub 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.
Files changed (162) hide show
  1. checksums.yaml +7 -0
  2. data/roda-3.105.0/MIT-LICENSE +21 -0
  3. data/roda-3.105.0/lib/roda/cache.rb +42 -0
  4. data/roda-3.105.0/lib/roda/plugins/Integer_matcher_max.rb +55 -0
  5. data/roda-3.105.0/lib/roda/plugins/_after_hook.rb +11 -0
  6. data/roda-3.105.0/lib/roda/plugins/_base64.rb +34 -0
  7. data/roda-3.105.0/lib/roda/plugins/_before_hook.rb +41 -0
  8. data/roda-3.105.0/lib/roda/plugins/_optimized_matching.rb +227 -0
  9. data/roda-3.105.0/lib/roda/plugins/_symbol_class_matchers.rb +108 -0
  10. data/roda-3.105.0/lib/roda/plugins/_symbol_regexp_matchers.rb +24 -0
  11. data/roda-3.105.0/lib/roda/plugins/additional_render_engines.rb +61 -0
  12. data/roda-3.105.0/lib/roda/plugins/additional_view_directories.rb +66 -0
  13. data/roda-3.105.0/lib/roda/plugins/all_verbs.rb +50 -0
  14. data/roda-3.105.0/lib/roda/plugins/assets.rb +902 -0
  15. data/roda-3.105.0/lib/roda/plugins/assets_preloading.rb +89 -0
  16. data/roda-3.105.0/lib/roda/plugins/assume_ssl.rb +28 -0
  17. data/roda-3.105.0/lib/roda/plugins/autoload_hash_branches.rb +79 -0
  18. data/roda-3.105.0/lib/roda/plugins/autoload_named_routes.rb +65 -0
  19. data/roda-3.105.0/lib/roda/plugins/backtracking_array.rb +88 -0
  20. data/roda-3.105.0/lib/roda/plugins/bearer_token.rb +28 -0
  21. data/roda-3.105.0/lib/roda/plugins/branch_locals.rb +74 -0
  22. data/roda-3.105.0/lib/roda/plugins/break.rb +43 -0
  23. data/roda-3.105.0/lib/roda/plugins/caching.rb +206 -0
  24. data/roda-3.105.0/lib/roda/plugins/capture_erb.rb +94 -0
  25. data/roda-3.105.0/lib/roda/plugins/chunked.rb +331 -0
  26. data/roda-3.105.0/lib/roda/plugins/class_level_routing.rb +111 -0
  27. data/roda-3.105.0/lib/roda/plugins/class_matchers.rb +155 -0
  28. data/roda-3.105.0/lib/roda/plugins/common_logger.rb +80 -0
  29. data/roda-3.105.0/lib/roda/plugins/conditional_sessions.rb +67 -0
  30. data/roda-3.105.0/lib/roda/plugins/content_for.rb +103 -0
  31. data/roda-3.105.0/lib/roda/plugins/content_security_policy.rb +329 -0
  32. data/roda-3.105.0/lib/roda/plugins/cookie_flags.rb +157 -0
  33. data/roda-3.105.0/lib/roda/plugins/cookies.rb +51 -0
  34. data/roda-3.105.0/lib/roda/plugins/csrf.rb +81 -0
  35. data/roda-3.105.0/lib/roda/plugins/custom_block_results.rb +85 -0
  36. data/roda-3.105.0/lib/roda/plugins/custom_matchers.rb +89 -0
  37. data/roda-3.105.0/lib/roda/plugins/default_headers.rb +64 -0
  38. data/roda-3.105.0/lib/roda/plugins/default_status.rb +35 -0
  39. data/roda-3.105.0/lib/roda/plugins/delay_build.rb +18 -0
  40. data/roda-3.105.0/lib/roda/plugins/delegate.rb +77 -0
  41. data/roda-3.105.0/lib/roda/plugins/delete_empty_headers.rb +36 -0
  42. data/roda-3.105.0/lib/roda/plugins/direct_call.rb +38 -0
  43. data/roda-3.105.0/lib/roda/plugins/disallow_file_uploads.rb +38 -0
  44. data/roda-3.105.0/lib/roda/plugins/drop_body.rb +43 -0
  45. data/roda-3.105.0/lib/roda/plugins/each_part.rb +87 -0
  46. data/roda-3.105.0/lib/roda/plugins/early_hints.rb +25 -0
  47. data/roda-3.105.0/lib/roda/plugins/empty_root.rb +49 -0
  48. data/roda-3.105.0/lib/roda/plugins/environments.rb +79 -0
  49. data/roda-3.105.0/lib/roda/plugins/erb_h.rb +43 -0
  50. data/roda-3.105.0/lib/roda/plugins/error_email.rb +152 -0
  51. data/roda-3.105.0/lib/roda/plugins/error_handler.rb +133 -0
  52. data/roda-3.105.0/lib/roda/plugins/error_mail.rb +149 -0
  53. data/roda-3.105.0/lib/roda/plugins/exception_page.rb +445 -0
  54. data/roda-3.105.0/lib/roda/plugins/filter_common_logger.rb +46 -0
  55. data/roda-3.105.0/lib/roda/plugins/flash.rb +117 -0
  56. data/roda-3.105.0/lib/roda/plugins/h.rb +59 -0
  57. data/roda-3.105.0/lib/roda/plugins/halt.rb +108 -0
  58. data/roda-3.105.0/lib/roda/plugins/hash_branch_view_subdir.rb +76 -0
  59. data/roda-3.105.0/lib/roda/plugins/hash_branches.rb +145 -0
  60. data/roda-3.105.0/lib/roda/plugins/hash_matcher.rb +39 -0
  61. data/roda-3.105.0/lib/roda/plugins/hash_paths.rb +128 -0
  62. data/roda-3.105.0/lib/roda/plugins/hash_public.rb +125 -0
  63. data/roda-3.105.0/lib/roda/plugins/hash_public_cache.rb +91 -0
  64. data/roda-3.105.0/lib/roda/plugins/hash_routes.rb +304 -0
  65. data/roda-3.105.0/lib/roda/plugins/head.rb +99 -0
  66. data/roda-3.105.0/lib/roda/plugins/header_matchers.rb +88 -0
  67. data/roda-3.105.0/lib/roda/plugins/heartbeat.rb +41 -0
  68. data/roda-3.105.0/lib/roda/plugins/hmac_paths.rb +413 -0
  69. data/roda-3.105.0/lib/roda/plugins/hooks.rb +92 -0
  70. data/roda-3.105.0/lib/roda/plugins/host_authorization.rb +155 -0
  71. data/roda-3.105.0/lib/roda/plugins/host_routing.rb +190 -0
  72. data/roda-3.105.0/lib/roda/plugins/hsts.rb +35 -0
  73. data/roda-3.105.0/lib/roda/plugins/indifferent_params.rb +124 -0
  74. data/roda-3.105.0/lib/roda/plugins/inject_erb.rb +33 -0
  75. data/roda-3.105.0/lib/roda/plugins/invalid_request_body.rb +107 -0
  76. data/roda-3.105.0/lib/roda/plugins/ip_from_header.rb +34 -0
  77. data/roda-3.105.0/lib/roda/plugins/json.rb +119 -0
  78. data/roda-3.105.0/lib/roda/plugins/json_parser.rb +107 -0
  79. data/roda-3.105.0/lib/roda/plugins/link_to.rb +83 -0
  80. data/roda-3.105.0/lib/roda/plugins/mail_processor.rb +629 -0
  81. data/roda-3.105.0/lib/roda/plugins/mailer.rb +283 -0
  82. data/roda-3.105.0/lib/roda/plugins/map_matcher.rb +48 -0
  83. data/roda-3.105.0/lib/roda/plugins/match_affix.rb +64 -0
  84. data/roda-3.105.0/lib/roda/plugins/match_hook.rb +34 -0
  85. data/roda-3.105.0/lib/roda/plugins/match_hook_args.rb +93 -0
  86. data/roda-3.105.0/lib/roda/plugins/middleware.rb +225 -0
  87. data/roda-3.105.0/lib/roda/plugins/middleware_stack.rb +101 -0
  88. data/roda-3.105.0/lib/roda/plugins/module_include.rb +96 -0
  89. data/roda-3.105.0/lib/roda/plugins/multi_public.rb +95 -0
  90. data/roda-3.105.0/lib/roda/plugins/multi_route.rb +156 -0
  91. data/roda-3.105.0/lib/roda/plugins/multi_run.rb +144 -0
  92. data/roda-3.105.0/lib/roda/plugins/multi_view.rb +83 -0
  93. data/roda-3.105.0/lib/roda/plugins/multibyte_string_matcher.rb +57 -0
  94. data/roda-3.105.0/lib/roda/plugins/named_routes.rb +167 -0
  95. data/roda-3.105.0/lib/roda/plugins/named_templates.rb +102 -0
  96. data/roda-3.105.0/lib/roda/plugins/not_allowed.rb +149 -0
  97. data/roda-3.105.0/lib/roda/plugins/not_found.rb +55 -0
  98. data/roda-3.105.0/lib/roda/plugins/optimized_segment_matchers.rb +53 -0
  99. data/roda-3.105.0/lib/roda/plugins/optimized_string_matchers.rb +50 -0
  100. data/roda-3.105.0/lib/roda/plugins/padrino_render.rb +42 -0
  101. data/roda-3.105.0/lib/roda/plugins/param_matchers.rb +83 -0
  102. data/roda-3.105.0/lib/roda/plugins/params_capturing.rb +116 -0
  103. data/roda-3.105.0/lib/roda/plugins/part.rb +76 -0
  104. data/roda-3.105.0/lib/roda/plugins/partials.rb +74 -0
  105. data/roda-3.105.0/lib/roda/plugins/pass.rb +47 -0
  106. data/roda-3.105.0/lib/roda/plugins/path.rb +255 -0
  107. data/roda-3.105.0/lib/roda/plugins/path_matchers.rb +54 -0
  108. data/roda-3.105.0/lib/roda/plugins/path_rewriter.rb +111 -0
  109. data/roda-3.105.0/lib/roda/plugins/permissions_policy.rb +336 -0
  110. data/roda-3.105.0/lib/roda/plugins/placeholder_string_matchers.rb +48 -0
  111. data/roda-3.105.0/lib/roda/plugins/plain_hash_response_headers.rb +32 -0
  112. data/roda-3.105.0/lib/roda/plugins/precompile_templates.rb +156 -0
  113. data/roda-3.105.0/lib/roda/plugins/public.rb +182 -0
  114. data/roda-3.105.0/lib/roda/plugins/r.rb +35 -0
  115. data/roda-3.105.0/lib/roda/plugins/recheck_precompiled_assets.rb +107 -0
  116. data/roda-3.105.0/lib/roda/plugins/redirect_http_to_https.rb +99 -0
  117. data/roda-3.105.0/lib/roda/plugins/redirect_path.rb +59 -0
  118. data/roda-3.105.0/lib/roda/plugins/relative_path.rb +74 -0
  119. data/roda-3.105.0/lib/roda/plugins/render.rb +998 -0
  120. data/roda-3.105.0/lib/roda/plugins/render_coverage.rb +105 -0
  121. data/roda-3.105.0/lib/roda/plugins/render_each.rb +224 -0
  122. data/roda-3.105.0/lib/roda/plugins/render_locals.rb +102 -0
  123. data/roda-3.105.0/lib/roda/plugins/request_aref.rb +77 -0
  124. data/roda-3.105.0/lib/roda/plugins/request_headers.rb +81 -0
  125. data/roda-3.105.0/lib/roda/plugins/response_attachment.rb +94 -0
  126. data/roda-3.105.0/lib/roda/plugins/response_content_type.rb +79 -0
  127. data/roda-3.105.0/lib/roda/plugins/response_request.rb +29 -0
  128. data/roda-3.105.0/lib/roda/plugins/route_block_args.rb +50 -0
  129. data/roda-3.105.0/lib/roda/plugins/route_csrf.rb +388 -0
  130. data/roda-3.105.0/lib/roda/plugins/run_append_slash.rb +51 -0
  131. data/roda-3.105.0/lib/roda/plugins/run_handler.rb +51 -0
  132. data/roda-3.105.0/lib/roda/plugins/run_require_slash.rb +46 -0
  133. data/roda-3.105.0/lib/roda/plugins/sec_fetch_site_csrf.rb +131 -0
  134. data/roda-3.105.0/lib/roda/plugins/send_file.rb +127 -0
  135. data/roda-3.105.0/lib/roda/plugins/sessions.rb +537 -0
  136. data/roda-3.105.0/lib/roda/plugins/shared_vars.rb +86 -0
  137. data/roda-3.105.0/lib/roda/plugins/sinatra_helpers.rb +443 -0
  138. data/roda-3.105.0/lib/roda/plugins/slash_path_empty.rb +26 -0
  139. data/roda-3.105.0/lib/roda/plugins/static.rb +42 -0
  140. data/roda-3.105.0/lib/roda/plugins/static_routing.rb +89 -0
  141. data/roda-3.105.0/lib/roda/plugins/status_303.rb +34 -0
  142. data/roda-3.105.0/lib/roda/plugins/status_handler.rb +86 -0
  143. data/roda-3.105.0/lib/roda/plugins/streaming.rb +170 -0
  144. data/roda-3.105.0/lib/roda/plugins/strip_path_prefix.rb +33 -0
  145. data/roda-3.105.0/lib/roda/plugins/symbol_matchers.rb +188 -0
  146. data/roda-3.105.0/lib/roda/plugins/symbol_status.rb +32 -0
  147. data/roda-3.105.0/lib/roda/plugins/symbol_views.rb +37 -0
  148. data/roda-3.105.0/lib/roda/plugins/timestamp_public.rb +78 -0
  149. data/roda-3.105.0/lib/roda/plugins/type_routing.rb +215 -0
  150. data/roda-3.105.0/lib/roda/plugins/typecast_params.rb +1183 -0
  151. data/roda-3.105.0/lib/roda/plugins/typecast_params_sized_integers.rb +108 -0
  152. data/roda-3.105.0/lib/roda/plugins/unescape_path.rb +41 -0
  153. data/roda-3.105.0/lib/roda/plugins/view_options.rb +201 -0
  154. data/roda-3.105.0/lib/roda/plugins/view_subdir_leading_slash.rb +49 -0
  155. data/roda-3.105.0/lib/roda/plugins.rb +68 -0
  156. data/roda-3.105.0/lib/roda/request.rb +722 -0
  157. data/roda-3.105.0/lib/roda/response.rb +221 -0
  158. data/roda-3.105.0/lib/roda/session_middleware.rb +183 -0
  159. data/roda-3.105.0/lib/roda/version.rb +18 -0
  160. data/roda-3.105.0/lib/roda.rb +586 -0
  161. data/ultra-lite-hub.gemspec +12 -0
  162. metadata +201 -0
@@ -0,0 +1,336 @@
1
+ # frozen-string-literal: true
2
+
3
+ #
4
+ class Roda
5
+ module RodaPlugins
6
+ # A permissions_policy plugin has been added that allows you to easily set a
7
+ # Permissions-Policy header for the application, which browsers can use to
8
+ # determine whether to allow specific functionality on the returned page
9
+ # (mainly related to which JavaScript APIs the page is allowed to use).
10
+ #
11
+ # You would generally call the plugin with a block to set the default policy:
12
+ #
13
+ # plugin :permissions_policy do |pp|
14
+ # pp.camera :none
15
+ # pp.fullscreen :self
16
+ # pp.clipboard_read :self, 'https://example.com'
17
+ # end
18
+ #
19
+ # Then, anywhere in the routing tree, you can customize the policy for just that
20
+ # branch or action using the same block syntax:
21
+ #
22
+ # r.get 'foo' do
23
+ # permissions_policy do |pp|
24
+ # pp.camera :self
25
+ # end
26
+ # # ...
27
+ # end
28
+ #
29
+ # In addition to using a block, you can also call methods on the object returned
30
+ # by the method:
31
+ #
32
+ # r.get 'foo' do
33
+ # permissions_policy.camera :self
34
+ # # ...
35
+ # end
36
+ #
37
+ # You can use the :default plugin option to set the default for all settings.
38
+ # For example, to disallow all access for each setting by default:
39
+ #
40
+ # plugin :permissions_policy, default: :none
41
+ #
42
+ # The following methods are available for configuring the permissions policy,
43
+ # which specify the setting (substituting _ with -):
44
+ #
45
+ # * accelerometer
46
+ # * ambient_light_sensor
47
+ # * autoplay
48
+ # * bluetooth
49
+ # * camera
50
+ # * clipboard_read
51
+ # * clipboard_write
52
+ # * display_capture
53
+ # * encrypted_media
54
+ # * fullscreen
55
+ # * geolocation
56
+ # * gyroscope
57
+ # * hid
58
+ # * idle_detection
59
+ # * keyboard_map
60
+ # * magnetometer
61
+ # * microphone
62
+ # * midi
63
+ # * payment
64
+ # * picture_in_picture
65
+ # * publickey_credentials_get
66
+ # * screen_wake_lock
67
+ # * serial
68
+ # * sync_xhr
69
+ # * usb
70
+ # * web_share
71
+ # * window_management
72
+ #
73
+ # All of these methods support any number of arguments, and each argument should
74
+ # be one of the following values:
75
+ #
76
+ # :all :: Grants permission to all domains (must be only argument)
77
+ # :none :: Does not allow permission at all (must be only argument)
78
+ # :self :: Allows feature in current document and any nested browsing contexts
79
+ # that use the same domain as the current document.
80
+ # :src :: Allows feature in current document and any nested browsing contexts
81
+ # that use the same domain as the src of the iframe.
82
+ # String :: Specifies origin domain where access is allowed
83
+ #
84
+ # When calling a method with no arguments, the setting is removed from the policy instead
85
+ # of being left empty, since all of these setting require at least one value. Likewise,
86
+ # if the policy does not have any settings, the header will not be added.
87
+ #
88
+ # Calling the method overrides any previous setting. Each of the methods has +add_*+ and
89
+ # +get_*+ methods defined. The +add_*+ method appends to any existing setting, and the +get_*+ method
90
+ # returns the current value for the setting (this will be +:all+ if all domains are allowed, or
91
+ # any array of strings/:self/:src).
92
+ #
93
+ # permissions_policy.fullscreen :self, 'https://example.com'
94
+ # # fullscreen (self "https://example.com")
95
+ #
96
+ # permissions_policy.add_fullscreen 'https://*.example.com'
97
+ # # fullscreen (self "https://example.com" "https://*.example.com")
98
+ #
99
+ # permissions_policy.get_fullscreen
100
+ # # => [:self, "https://example.com", "https://*.example.com"]
101
+ #
102
+ # The clear method can be used to remove all settings from the policy. Empty policies
103
+ # do not set any headers. You can use +response.skip_permissions_policy!+ to skip
104
+ # setting a policy. This is faster than calling +permissions_policy.clear+, since
105
+ # it does not duplicate the default policy.
106
+ module PermissionsPolicy
107
+ SUPPORTED_SETTINGS = %w'
108
+ accelerometer
109
+ ambient-light-sensor
110
+ autoplay
111
+ bluetooth
112
+ camera
113
+ clipboard-read
114
+ clipboard-write
115
+ display-capture
116
+ encrypted-media
117
+ fullscreen
118
+ geolocation
119
+ gyroscope
120
+ hid
121
+ idle-detection
122
+ keyboard-map
123
+ magnetometer
124
+ microphone
125
+ midi
126
+ payment
127
+ picture-in-picture
128
+ publickey-credentials-get
129
+ screen-wake-lock
130
+ serial
131
+ sync-xhr
132
+ usb
133
+ web-share
134
+ window-management
135
+ '.each(&:freeze).freeze
136
+ private_constant :SUPPORTED_SETTINGS
137
+
138
+ # Represents a permissions policy.
139
+ class Policy
140
+ SUPPORTED_SETTINGS.each do |setting|
141
+ meth = setting.tr('-', '_').freeze
142
+
143
+ # Setting method name sets the setting value, or removes it if no args are given.
144
+ define_method(meth) do |*args|
145
+ if args.empty?
146
+ @opts.delete(setting)
147
+ else
148
+ @opts[setting] = option_value(args)
149
+ end
150
+ nil
151
+ end
152
+
153
+ # add_* method name adds to the setting value, or clears setting if no values
154
+ # are given.
155
+ define_method(:"add_#{meth}") do |*args|
156
+ unless args.empty?
157
+ case v = @opts[setting]
158
+ when :all
159
+ # If all domains are already allowed, there is no reason to add more.
160
+ return
161
+ when Array
162
+ @opts[setting] = option_value(v + args)
163
+ else
164
+ @opts[setting] = option_value(args)
165
+ end
166
+ end
167
+ nil
168
+ end
169
+
170
+ # get_* method always returns current setting value.
171
+ define_method(:"get_#{meth}") do
172
+ @opts[setting]
173
+ end
174
+ end
175
+
176
+ def initialize
177
+ clear
178
+ end
179
+
180
+ # Clear all settings, useful to remove any inherited settings.
181
+ def clear
182
+ @opts = {}
183
+ end
184
+
185
+ # Do not allow future modifications to any settings.
186
+ def freeze
187
+ @opts.freeze
188
+ header_value.freeze
189
+ super
190
+ end
191
+
192
+ # The header name to use, depends on whether report only mode has been enabled.
193
+ def header_key
194
+ @report_only ? RodaResponseHeaders::PERMISSIONS_POLICY_REPORT_ONLY : RodaResponseHeaders::PERMISSIONS_POLICY
195
+ end
196
+
197
+ # The header value to use.
198
+ def header_value
199
+ return @header_value if @header_value
200
+
201
+ s = String.new
202
+ @opts.each do |k, vs|
203
+ s << k << "="
204
+
205
+ if vs == :all
206
+ s << '*, '
207
+ else
208
+ s << '('
209
+ vs.each{|v| append_formatted_value(s, v)}
210
+ s.chop! unless vs.empty?
211
+ s << '), '
212
+ end
213
+ end
214
+ s.chop!
215
+ s.chop!
216
+ @header_value = s
217
+ end
218
+
219
+ # Set whether the Permissions-Policy-Report-Only header instead of the
220
+ # default Permissions-Policy header.
221
+ def report_only(report=true)
222
+ @report_only = report
223
+ end
224
+
225
+ # Whether this policy uses report only mode.
226
+ def report_only?
227
+ !!@report_only
228
+ end
229
+
230
+ # Set the current policy in the headers hash. If no settings have been made
231
+ # in the policy, does not set a header.
232
+ def set_header(headers)
233
+ return if @opts.empty?
234
+ headers[header_key] ||= header_value
235
+ end
236
+
237
+ private
238
+
239
+ # Formats nested values, quoting strings and using :self and :src verbatim.
240
+ def append_formatted_value(s, v)
241
+ case v
242
+ when String
243
+ s << v.inspect << ' '
244
+ when :self
245
+ s << 'self '
246
+ when :src
247
+ s << 'src '
248
+ else
249
+ raise RodaError, "unsupported Permissions-Policy item value used: #{v.inspect}"
250
+ end
251
+ end
252
+
253
+ # Make object copy use copy of settings, and remove cached header value.
254
+ def initialize_copy(_)
255
+ super
256
+ @opts = @opts.dup
257
+ @header_value = nil
258
+ end
259
+
260
+ # The option value to store for the given args.
261
+ def option_value(args)
262
+ if args.length == 1
263
+ case args[0]
264
+ when :all
265
+ :all
266
+ when :none
267
+ EMPTY_ARRAY
268
+ else
269
+ args.freeze
270
+ end
271
+ else
272
+ args.freeze
273
+ end
274
+ end
275
+ end
276
+
277
+ # Yield the current Permissions Policy to the block.
278
+ def self.configure(app, opts=OPTS)
279
+ policy = app.opts[:permissions_policy] = if policy = app.opts[:permissions_policy]
280
+ policy.dup
281
+ else
282
+ Policy.new
283
+ end
284
+
285
+ if default = opts[:default]
286
+ SUPPORTED_SETTINGS.each do |setting|
287
+ policy.send(setting.tr('-', '_'), *default)
288
+ end
289
+ end
290
+
291
+ yield policy if defined?(yield)
292
+ policy.freeze
293
+ end
294
+
295
+ module InstanceMethods
296
+ # If a block is given, yield the current permission policy. Returns the
297
+ # current permissions policy.
298
+ def permissions_policy
299
+ policy = @_response.permissions_policy
300
+ yield policy if defined?(yield)
301
+ policy
302
+ end
303
+ end
304
+
305
+ module ResponseMethods
306
+ # Unset any permissions policy when reinitializing
307
+ def initialize
308
+ super
309
+ @permissions_policy &&= nil
310
+ end
311
+
312
+ # The current permissions policy to be used for this response.
313
+ def permissions_policy
314
+ @permissions_policy ||= roda_class.opts[:permissions_policy].dup
315
+ end
316
+
317
+ # Do not set a permissions policy header for this response.
318
+ def skip_permissions_policy!
319
+ @skip_permissions_policy = true
320
+ end
321
+
322
+ private
323
+
324
+ # Set the appropriate permissions policy header.
325
+ def set_default_headers
326
+ super
327
+ unless @skip_permissions_policy
328
+ (@permissions_policy || roda_class.opts[:permissions_policy]).set_header(headers)
329
+ end
330
+ end
331
+ end
332
+ end
333
+
334
+ register_plugin(:permissions_policy, PermissionsPolicy)
335
+ end
336
+ end
@@ -0,0 +1,48 @@
1
+ # frozen-string-literal: true
2
+
3
+ #
4
+ class Roda
5
+ module RodaPlugins
6
+ # The placeholder_string_matcher plugin exists for backwards compatibility
7
+ # with previous versions of Roda that allowed placeholders inside strings
8
+ # if they were prefixed by colons:
9
+ #
10
+ # plugin :placeholder_string_matchers
11
+ #
12
+ # route do |r|
13
+ # r.is("foo/:bar") |v|
14
+ # # matches foo/baz, yielding "baz"
15
+ # # does not match foo, foo/, or foo/baz/
16
+ # end
17
+ # end
18
+ #
19
+ # It is not recommended to use this in new applications, and it is encouraged
20
+ # to use separate string class or symbol matchers instead:
21
+ #
22
+ # r.is "foo", String
23
+ # r.is "foo", :bar
24
+ #
25
+ # If used with the symbol_matchers plugin, this plugin respects the regexps
26
+ # for the registered symbols, but it does not perform the conversions, the
27
+ # captures for the regexp are used directly as the captures for the match method.
28
+ module PlaceholderStringMatchers
29
+ def self.load_dependencies(app)
30
+ app.plugin :_symbol_regexp_matchers
31
+ end
32
+
33
+ module RequestMethods
34
+ private
35
+
36
+ def _match_string(str)
37
+ if str.index(":")
38
+ consume(self.class.cached_matcher(str){Regexp.escape(str).gsub(/:(\w+)/){|m| _match_symbol_regexp($1)}})
39
+ else
40
+ super
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ register_plugin(:placeholder_string_matchers, PlaceholderStringMatchers)
47
+ end
48
+ end
@@ -0,0 +1,32 @@
1
+ # frozen-string-literal: true
2
+
3
+ #
4
+ class Roda
5
+ module RodaPlugins
6
+ # The plain_hash_response_headers plugin will change Roda to
7
+ # use a plain hash for response headers. This is Roda's
8
+ # default behavior on Rack 2, but on Rack 3+, Roda defaults
9
+ # to using Rack::Headers for response headers for backwards
10
+ # compatibility (Rack::Headers automatically lower cases header
11
+ # keys).
12
+ #
13
+ # On Rack 3+, you should use this plugin for better performance
14
+ # if you are sure all headers in your application and middleware
15
+ # are already lower case (lower case response header keys are
16
+ # required by the Rack 3 spec).
17
+ module PlainHashResponseHeaders
18
+ if defined?(Rack::Headers) && Rack::Headers.is_a?(Class)
19
+ module ResponseMethods
20
+ private
21
+
22
+ # Use plain hash for headers
23
+ def _initialize_headers
24
+ {}
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ register_plugin(:plain_hash_response_headers, PlainHashResponseHeaders)
31
+ end
32
+ end
@@ -0,0 +1,156 @@
1
+ # frozen-string-literal: true
2
+
3
+ #
4
+ class Roda
5
+ module RodaPlugins
6
+ # The precompile_templates plugin adds support for precompiling template code.
7
+ # This can result in a large memory savings for applications that have large
8
+ # templates or a large number of small templates if the application uses a
9
+ # forking webserver. By default, template compilation is lazy, so all the
10
+ # child processes in a forking webserver will have their own copy of the
11
+ # compiled template. By using the precompile_templates plugin, you can
12
+ # precompile the templates in the parent process before forking, and then
13
+ # all of the child processes can use the same precompiled templates, which
14
+ # saves memory.
15
+ #
16
+ # Another advantage of the precompile_templates plugin is that after
17
+ # template precompilation, access to the template file in the file system is
18
+ # no longer needed, so this can be used with security features that do not
19
+ # allow access to the template files at runtime.
20
+ #
21
+ # After loading the plugin, you should call precompile_views with an array
22
+ # of views to compile, using the same argument you are passing to view or
23
+ # render:
24
+ #
25
+ # plugin :precompile_templates
26
+ # precompile_views %w'view1 view2'
27
+ #
28
+ # If the view requires local variables, you should call precompile_views with a second
29
+ # argument for the local variables:
30
+ #
31
+ # plugin :precompile_templates
32
+ # precompile_views :view3, [:local_var1, :local_var2]
33
+ #
34
+ # After all templates are precompiled, you can optionally use freeze_template_caches!,
35
+ # which will freeze the template caches so that any template compilation at runtime
36
+ # will result in an error. This also speeds up template cache access, since the
37
+ # template caches no longer need a mutex.
38
+ #
39
+ # freeze_template_caches!
40
+ #
41
+ # Note that you should use Tilt 2.0.1+ if you are using this plugin, so
42
+ # that locals are handled in the same order.
43
+ module PrecompileTemplates
44
+ # Load the render plugin as precompile_templates depends on it.
45
+ def self.load_dependencies(app, opts=OPTS)
46
+ app.plugin :render
47
+ end
48
+
49
+ module ClassMethods
50
+ # Freeze the template caches. Should be called after precompiling all templates during
51
+ # application startup, if you don't want to allow templates to be cached at runtime.
52
+ # In addition to ensuring that no templates are compiled at runtime, this also speeds
53
+ # up rendering by freezing the template caches, so that a mutex is not needed to access
54
+ # them.
55
+ def freeze_template_caches!
56
+ _freeze_layout_method
57
+
58
+ opts[:render] = render_opts.merge(
59
+ :cache=>render_opts[:cache].freeze,
60
+ :template_method_cache=>render_opts[:template_method_cache].freeze,
61
+ ).freeze
62
+ self::RodaCompiledTemplates.freeze
63
+
64
+ nil
65
+ end
66
+
67
+ # Precompile the templates using the given options. Note that this doesn't
68
+ # handle optimized template methods supported in newer versions of Roda, but
69
+ # there are still cases where makes sense to use it.
70
+ #
71
+ # You can call +precompile_templates+ with the pattern of templates you would
72
+ # like to precompile:
73
+ #
74
+ # precompile_templates "views/**/*.erb"
75
+ #
76
+ # That will precompile all erb template files in the views directory or
77
+ # any subdirectory.
78
+ #
79
+ # If the templates use local variables, you need to specify which local
80
+ # variables to precompile, which should be an array of symbols:
81
+ #
82
+ # precompile_templates 'views/users/_*.erb', locals: [:user]
83
+ #
84
+ # You can specify other render options when calling +precompile_templates+,
85
+ # including +:cache_key+, +:template_class+, and +:template_opts+. If you
86
+ # are passing any of those options to render/view for the template, you
87
+ # should pass the same options when precompiling the template.
88
+ #
89
+ # To compile inline templates, just pass a single hash containing an :inline
90
+ # to +precompile_templates+:
91
+ #
92
+ # precompile_templates inline: some_template_string
93
+ def precompile_templates(pattern, opts=OPTS)
94
+ if pattern.is_a?(Hash)
95
+ opts = pattern.merge(opts)
96
+ end
97
+
98
+ if locals = opts[:locals]
99
+ locals.sort!
100
+ else
101
+ locals = EMPTY_ARRAY
102
+ end
103
+
104
+ compile_opts = if pattern.is_a?(Hash)
105
+ [opts]
106
+ else
107
+ Dir[pattern].map{|file| opts.merge(:path=>File.expand_path(file, nil))}
108
+ end
109
+
110
+ instance = allocate
111
+ compile_opts.each do |compile_opt|
112
+ template = instance.send(:retrieve_template, compile_opt)
113
+ begin
114
+ Render.tilt_template_compiled_method(template, locals, self)
115
+ rescue NotImplementedError
116
+ # When freezing template caches, you may want to precompile a template for a
117
+ # template type that doesn't support template precompilation, just to populate
118
+ # the cache. Tilt rescues NotImplementedError in this case, which we can ignore.
119
+ nil
120
+ end
121
+ end
122
+
123
+ nil
124
+ end
125
+
126
+ # Precompile the given views with the given locals, handling optimized template methods.
127
+ def precompile_views(views, locals=EMPTY_ARRAY)
128
+ instance = allocate
129
+ views = Array(views)
130
+
131
+ if locals.empty?
132
+ opts = OPTS
133
+ else
134
+ locals_hash = {}
135
+ locals.each{|k| locals_hash[k] = nil}
136
+ opts = {:locals=>locals_hash}
137
+ end
138
+
139
+ views.each do |view|
140
+ instance.send(:retrieve_template, instance.send(:render_template_opts, view, opts))
141
+ end
142
+
143
+ if locals_hash
144
+ views.each do |view|
145
+ instance.send(:_optimized_render_method_for_locals, view, locals_hash)
146
+ end
147
+ end
148
+
149
+ nil
150
+ end
151
+ end
152
+ end
153
+
154
+ register_plugin(:precompile_templates, PrecompileTemplates)
155
+ end
156
+ end