roda 3.109.0 → 3.110.0

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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/lib/roda/cache.rb +0 -2
  3. data/lib/roda/opts.rb +1 -1
  4. data/lib/roda/plugins/_symbol_class_matchers.rb +2 -4
  5. data/lib/roda/plugins/additional_view_directories.rb +2 -2
  6. data/lib/roda/plugins/assets.rb +173 -142
  7. data/lib/roda/plugins/assets_preloading.rb +26 -10
  8. data/lib/roda/plugins/backtracking_array.rb +2 -2
  9. data/lib/roda/plugins/branch_locals.rb +4 -4
  10. data/lib/roda/plugins/break.rb +2 -2
  11. data/lib/roda/plugins/caching.rb +27 -17
  12. data/lib/roda/plugins/capture_erb.rb +15 -12
  13. data/lib/roda/plugins/chunked.rb +32 -30
  14. data/lib/roda/plugins/class_level_routing.rb +5 -2
  15. data/lib/roda/plugins/class_matchers.rb +11 -6
  16. data/lib/roda/plugins/common_logger.rb +21 -3
  17. data/lib/roda/plugins/conditional_sessions.rb +3 -3
  18. data/lib/roda/plugins/content_for.rb +7 -6
  19. data/lib/roda/plugins/content_security_policy.rb +11 -12
  20. data/lib/roda/plugins/cookie_flags.rb +12 -6
  21. data/lib/roda/plugins/cookies.rb +7 -5
  22. data/lib/roda/plugins/csrf.rb +2 -1
  23. data/lib/roda/plugins/custom_block_results.rb +6 -7
  24. data/lib/roda/plugins/default_headers.rb +2 -2
  25. data/lib/roda/plugins/delay_build.rb +1 -1
  26. data/lib/roda/plugins/delegate.rb +7 -6
  27. data/lib/roda/plugins/direct_call.rb +5 -1
  28. data/lib/roda/plugins/disallow_file_uploads.rb +2 -3
  29. data/lib/roda/plugins/drop_body.rb +3 -6
  30. data/lib/roda/plugins/each_part.rb +4 -6
  31. data/lib/roda/plugins/early_hints.rb +4 -4
  32. data/lib/roda/plugins/empty_root.rb +5 -5
  33. data/lib/roda/plugins/environments.rb +8 -8
  34. data/lib/roda/plugins/erb_h.rb +4 -4
  35. data/lib/roda/plugins/error_email.rb +16 -17
  36. data/lib/roda/plugins/error_handler.rb +24 -32
  37. data/lib/roda/plugins/error_mail.rb +26 -15
  38. data/lib/roda/plugins/exception_page.rb +41 -35
  39. data/lib/roda/plugins/filter_common_logger.rb +6 -4
  40. data/lib/roda/plugins/flash.rb +16 -13
  41. data/lib/roda/plugins/freeze_request_response.rb +24 -0
  42. data/lib/roda/plugins/hash_routes.rb +1 -1
  43. data/lib/roda/plugins/permissions_policy.rb +14 -16
  44. data/lib/roda/plugins/public.rb +11 -0
  45. data/lib/roda/plugins/recheck_precompiled_assets.rb +30 -8
  46. data/lib/roda/plugins/render.rb +3 -0
  47. data/lib/roda/plugins/render_locals.rb +1 -1
  48. data/lib/roda/plugins/sessions.rb +158 -137
  49. data/lib/roda/plugins/symbol_matchers.rb +8 -5
  50. data/lib/roda/plugins/unescape_path.rb +22 -4
  51. data/lib/roda/plugins.rb +24 -0
  52. data/lib/roda/request.rb +8 -7
  53. data/lib/roda/response.rb +9 -7
  54. data/lib/roda/version.rb +1 -1
  55. data/lib/roda.rb +12 -9
  56. metadata +2 -1
data/lib/roda/request.rb CHANGED
@@ -109,10 +109,10 @@ class Roda
109
109
  # rack response array of status, headers, and body. If no argument
110
110
  # is given, uses the current response.
111
111
  #
112
- # r.halt [200, {'Content-Type'=>'text/html'}, ['Hello World!']]
112
+ # r.halt [200, {'content-type'=>'text/html'}, ['Hello World!']]
113
113
  #
114
114
  # response.status = 200
115
- # response['Content-Type'] = 'text/html'
115
+ # response['content-type'] = 'text/html'
116
116
  # response.write 'Hello World!'
117
117
  # r.halt
118
118
  def halt(res=response.finish)
@@ -328,7 +328,7 @@ class Roda
328
328
  # # matches
329
329
  # end
330
330
  #
331
- # This is usuable inside other match blocks:
331
+ # This is usable inside other match blocks:
332
332
  #
333
333
  # [r.request_method, r.remaining_path]
334
334
  # # => ['GET', '/foo/']
@@ -512,7 +512,7 @@ class Roda
512
512
  end
513
513
  end
514
514
 
515
- # Match the given symbol if any segment matches.
515
+ # Match for any nonempty segment.
516
516
  def _match_symbol(sym=nil)
517
517
  rp = @remaining_path
518
518
  if rp.getbyte(0) == 47
@@ -635,7 +635,7 @@ class Roda
635
635
  # For non-GET requests, redirects to the current path, which will
636
636
  # trigger a GET request. This is to make the common case where
637
637
  # a POST request will redirect to a GET request at the same location
638
- # will work fine.
638
+ # work fine.
639
639
  #
640
640
  # If the current request is a GET request, raise an error, as otherwise
641
641
  # it is easy to create an infinite redirect.
@@ -654,7 +654,7 @@ class Roda
654
654
  302
655
655
  end
656
656
 
657
- # Whether the current path is considered empty.
657
+ # Whether the remaining path is considered empty.
658
658
  def empty_path?
659
659
  @remaining_path.empty?
660
660
  end
@@ -723,13 +723,14 @@ class Roda
723
723
  end
724
724
  end
725
725
 
726
- # How to handle block results that are not nil, false, or a String.
726
+ # Handle block results that are not nil, false, or a String.
727
727
  # By default raises an exception.
728
728
  def unsupported_block_result(result)
729
729
  raise RodaError, "unsupported block result: #{result.inspect}"
730
730
  end
731
731
 
732
732
  # Handle an unsupported matcher.
733
+ # By default raises an exception.
733
734
  def unsupported_matcher(matcher)
734
735
  raise RodaError, "unsupported matcher: #{matcher.inspect}"
735
736
  end
data/lib/roda/response.rb CHANGED
@@ -10,6 +10,7 @@ class Roda
10
10
  # headers used internally by Roda can be lower case on Rack 3, so that it is
11
11
  # possible to use a plain hash of response headers instead of using Rack::Headers.
12
12
  module RodaResponseHeaders
13
+ # RODA4: switch all constant access to downcased strings
13
14
  downcase = defined?(Rack::Headers) && Rack::Headers.is_a?(Class)
14
15
 
15
16
  %w'Allow Cache-Control Content-Disposition Content-Encoding Content-Length
@@ -65,14 +66,14 @@ class Roda
65
66
 
66
67
  # Return the response header with the given key. Example:
67
68
  #
68
- # response['Content-Type'] # => 'text/html'
69
+ # response['content-type'] # => 'text/html'
69
70
  def [](key)
70
71
  @headers[key]
71
72
  end
72
73
 
73
74
  # Set the response header with the given key to the given value.
74
75
  #
75
- # response['Content-Type'] = 'application/json'
76
+ # response['content-type'] = 'application/json'
76
77
  def []=(key, value)
77
78
  @headers[key] = value
78
79
  end
@@ -97,13 +98,13 @@ class Roda
97
98
  # for the current response. If the status has not been set,
98
99
  # uses the return value of default_status if the body has
99
100
  # been written to, otherwise uses a 404 status.
100
- # Adds the Content-Length header to the size of the response body.
101
+ # Adds the content-length header to the size of the response body.
101
102
  #
102
103
  # Example:
103
104
  #
104
105
  # response.finish
105
106
  # # => [200,
106
- # # {'Content-Type'=>'text/html', 'Content-Length'=>'0'},
107
+ # # {'content-type'=>'text/html', 'content-length'=>'0'},
107
108
  # # []]
108
109
  def finish
109
110
  b = @body
@@ -129,7 +130,7 @@ class Roda
129
130
 
130
131
  # Return the rack response array using a given body. Assumes a
131
132
  # 200 response status unless status has been explicitly set,
132
- # and doesn't add the Content-Length header or use the existing
133
+ # and doesn't add the content-length header or use the existing
133
134
  # body.
134
135
  def finish_with_body(body)
135
136
  set_default_headers
@@ -151,8 +152,8 @@ class Roda
151
152
  # Set the Location header to the given path, and the status
152
153
  # to the given status. Example:
153
154
  #
154
- # response.redirect('foo', 301)
155
- # response.redirect('bar')
155
+ # response.redirect('/foo', 301)
156
+ # response.redirect('/bar')
156
157
  def redirect(path, status = 302)
157
158
  @headers[RodaResponseHeaders::LOCATION] = path
158
159
  @status = status
@@ -181,6 +182,7 @@ class Roda
181
182
 
182
183
  # Use Rack::Headers for headers by default on Rack 3
183
184
  def _initialize_headers
185
+ # RODA4: Use {} always, add plugin for using Rack::Headers
184
186
  Rack::Headers.new
185
187
  end
186
188
  else
data/lib/roda/version.rb CHANGED
@@ -4,7 +4,7 @@ class Roda
4
4
  RodaMajorVersion = 3
5
5
 
6
6
  # The minor version of Roda, updated for new feature releases of Roda.
7
- RodaMinorVersion = 109
7
+ RodaMinorVersion = 110
8
8
 
9
9
  # The patch version of Roda, updated only for bug fixes from the last
10
10
  # feature release.
data/lib/roda.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  # frozen-string-literal: true
2
2
 
3
- require "thread"
4
3
  require_relative "roda/request"
5
4
  require_relative "roda/response"
6
5
  require_relative "roda/plugins"
@@ -96,6 +95,7 @@ class Roda
96
95
  # Support for the :check_arity and :check_dynamic_arity options will be
97
96
  # removed in Roda 4.
98
97
  def define_roda_method(meth, expected_arity, &block)
98
+ # RODA4: Make expected_arity optional, remove from callers
99
99
  if meth.is_a?(String)
100
100
  meth = roda_method_name(meth)
101
101
  end
@@ -301,15 +301,14 @@ class Roda
301
301
  # class has been subclassed, as doing so can break the subclasses.
302
302
  #
303
303
  # Roda.plugin PluginModule
304
- # Roda.plugin :csrf
304
+ # Roda.plugin :route_csrf
305
305
  def plugin(plugin, *args, &block)
306
306
  raise RodaError, "Cannot add a plugin to a frozen Roda class" if frozen?
307
307
  plugin = RodaPlugins.load_plugin(plugin) if plugin.is_a?(Symbol)
308
308
  raise RodaError, "Invalid plugin type: #{plugin.class.inspect}" unless plugin.is_a?(Module)
309
309
 
310
310
  if !plugin.respond_to?(:load_dependencies) && !plugin.respond_to?(:configure) && (!args.empty? || block)
311
- # RODA4: switch from warning to error
312
- RodaPlugins.warn("Plugin #{plugin} does not accept arguments or a block, but arguments or a block was passed when loading this. This will raise an error in Roda 4.")
311
+ RodaPlugins.warn("Plugin #{plugin} does not accept arguments or a block, but arguments or a block was passed when loading this. This will raise an error in Roda 4.", uplevel: 1)
313
312
  end
314
313
 
315
314
  plugin.load_dependencies(self, *args, &block) if plugin.respond_to?(:load_dependencies)
@@ -342,7 +341,7 @@ class Roda
342
341
  # times will overwrite the previous routing.
343
342
  def route(&block)
344
343
  unless block
345
- RodaPlugins.warn "no block passed to Roda.route"
344
+ RodaPlugins.warn("no block passed to Roda.route", uplevel: 1)
346
345
  return
347
346
  end
348
347
 
@@ -353,8 +352,7 @@ class Roda
353
352
  @app = nil
354
353
  end
355
354
 
356
- # Add a middleware to use for the rack application. Must be
357
- # called before calling #route to have an effect. Example:
355
+ # Add a middleware to use for the rack application. Example:
358
356
  #
359
357
  # Roda.use Rack::ShowExceptions
360
358
  def use(*args, &block)
@@ -372,6 +370,7 @@ class Roda
372
370
  # and whether the callable accepts keyword arguments (true, false
373
371
  # or :required).
374
372
  def _define_roda_method_arg_numbers(callable)
373
+ # RODA4: Remove
375
374
  optional_args = 0
376
375
  rest = false
377
376
  keyword = false
@@ -403,7 +402,9 @@ class Roda
403
402
 
404
403
  # The base rack app to use, before middleware is added.
405
404
  def base_rack_app_callable(new_api=true)
405
+ # RODA4.1: Remove
406
406
  if new_api
407
+ # RODA4: Inline this behavior
407
408
  lambda{|env| new(env)._roda_handle_main_route}
408
409
  else
409
410
  block = @rack_app_route_block
@@ -428,6 +429,7 @@ class Roda
428
429
  # which can include route blocks that are delegated to by the main route block.
429
430
  # Can be modified by plugins.
430
431
  def convert_route_block(block)
432
+ # RODA4.1: Remove
431
433
  block
432
434
  end
433
435
 
@@ -471,6 +473,7 @@ class Roda
471
473
  # if any before hooks are defined.
472
474
  # Can be modified by plugins.
473
475
  def rack_app_route_block(block)
476
+ # RODA4.1: Remove
474
477
  block
475
478
  end
476
479
 
@@ -481,7 +484,7 @@ class Roda
481
484
  break if mod == InstanceMethods
482
485
  meths = mod.instance_methods(false)
483
486
  if meths.include?(:call) && !(meths.include?(:_roda_handle_main_route) || meths.include?(:_roda_run_main_route))
484
- RodaPlugins.warn <<WARNING
487
+ RodaPlugins.warn(<<WARNING, uplevel: 1)
485
488
  Falling back to using #call for dispatching for #{self}, due to #call override in #{mod}.
486
489
  #{mod} should be fixed to adjust to Roda's new dispatch API, and override _roda_handle_main_route or _roda_run_main_route
487
490
  WARNING
@@ -567,7 +570,7 @@ WARNING
567
570
  @_request.env
568
571
  end
569
572
 
570
- # The class-level options hash. This should probably not be
573
+ # The class-level options hash. This should not be
571
574
  # modified at the instance level. Example:
572
575
  #
573
576
  # Roda.plugin :render
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: roda
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.109.0
4
+ version: 3.110.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
@@ -215,6 +215,7 @@ files:
215
215
  - lib/roda/plugins/exception_page.rb
216
216
  - lib/roda/plugins/filter_common_logger.rb
217
217
  - lib/roda/plugins/flash.rb
218
+ - lib/roda/plugins/freeze_request_response.rb
218
219
  - lib/roda/plugins/h.rb
219
220
  - lib/roda/plugins/halt.rb
220
221
  - lib/roda/plugins/hash_branch_view_subdir.rb