roda 3.93.0 → 3.95.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d1e04d3df576ad873687f27895cf5100f34a6142ee2204d4e74372d8da03ffe0
4
- data.tar.gz: 6b4f577746d682fc763c765d6d9f787a251db3c392072d1fa123fe5bddab7e20
3
+ metadata.gz: f24c09b316cf269199b54b3de06e3d5f27529c46b8ab34f015a8bb1ce42799f0
4
+ data.tar.gz: e59f9b4e7e880f6313c5af6f33c59d9b87cd2a2b37cb247ea551a1a3556acaad
5
5
  SHA512:
6
- metadata.gz: 845525a607910671a61b61645ecfa7243ab8565963169aff78e7908cd5a982c8cbd5f8420e9e53e6689488be5fa57bfba9fc7da714d5e892f79f205c0a895ccf
7
- data.tar.gz: 37fe2d01f609363e382b0fffe45b2dc13c5c04d0467890db334417a44d42b8a906a3d95f0ec68e465b17b0c8c54667cd7ef93fe866e0ef48d0afdbf5916c5aaa
6
+ metadata.gz: 6a27c05cabeb588bbccd1e4d0341106575c1f702d970906ee800bc8747cbbad41d53d456cfe53c2725d86d9d6181c17cde734565a0a127bf71918c6a5b4d6e0b
7
+ data.tar.gz: fede1fe07b011d998c2962bc77c5c27cd28b3235d144f440dfb518f8c00184138fe6fcf355160ae98eb79ddce81e29f72c900543d128cc85d13c7f394501cd82
@@ -70,6 +70,35 @@ class Roda
70
70
 
71
71
  ALLOWED_KEYS = [:locals, :local].freeze
72
72
 
73
+ if Render::COMPILED_METHOD_SUPPORT
74
+ module ClassMethods
75
+ # If using compiled methods and assuming fixed locals, optimize
76
+ # _cached_render_each_template_method.
77
+ def freeze
78
+ if render_opts[:assume_fixed_locals] && !render_opts[:check_template_mtime]
79
+ include AssumeFixedLocalsInstanceMethods
80
+ end
81
+
82
+ super
83
+ end
84
+ end
85
+
86
+ module AssumeFixedLocalsInstanceMethods
87
+ private
88
+
89
+ # Optimize method since this module is only loaded when using fixed locals
90
+ # and when caching templates.
91
+ def _cached_render_each_template_method(template)
92
+ case template
93
+ when String, Symbol
94
+ _cached_template_method_lookup(render_opts[:template_method_cache], template)
95
+ else
96
+ false
97
+ end
98
+ end
99
+ end
100
+ end
101
+
73
102
  module InstanceMethods
74
103
  # For each value in enum, render the given template using the
75
104
  # given opts. The template and options hash are passed to +render+.
@@ -123,10 +152,31 @@ class Roda
123
152
 
124
153
  private
125
154
 
126
- # The default local variable name to use for the template, if the :local option
127
- # is not used when calling render_each.
128
- def render_each_default_local(template)
129
- File.basename(template.to_s).sub(/\..+\z/, '').to_sym
155
+ if File.basename("a/b") == "b" && File.basename("a\\b") == "a\\b" && RUBY_VERSION >= '3'
156
+ # The default local variable name to use for the template, if the :local option
157
+ # is not used when calling render_each.
158
+ def render_each_default_local(template)
159
+ # Optimize to avoid allocations when possible
160
+ template = case template
161
+ when Symbol
162
+ s = template.name
163
+ return template unless s.include?("/") || s.include?(".")
164
+ s
165
+ when String
166
+ return template.to_sym unless template.include?("/") || template.include?(".")
167
+ template
168
+ else
169
+ template.to_s
170
+ end
171
+
172
+ File.basename(template).sub(/\..+\z/, '').to_sym
173
+ end
174
+ # :nocov:
175
+ else
176
+ def render_each_default_local(template)
177
+ File.basename(template.to_s).sub(/\..+\z/, '').to_sym
178
+ end
179
+ # :nocov:
130
180
  end
131
181
 
132
182
  if Render::COMPILED_METHOD_SUPPORT
@@ -0,0 +1,79 @@
1
+ # frozen-string-literal: true
2
+
3
+ #
4
+ class Roda
5
+ module RodaPlugins
6
+ # The response_content_type extension adds response.content_type
7
+ # and response.content_type= methods for getting and setting the
8
+ # response content-type.
9
+ #
10
+ # When setting the content-type, you can pass either a string, which
11
+ # is used directly:
12
+ #
13
+ # response.content_type = "text/html"
14
+ #
15
+ # Or, if you have registered mime types when loading the plugin:
16
+ #
17
+ # plugin :response_content_type, mime_types: {
18
+ # plain: "text/plain",
19
+ # html: "text/html",
20
+ # pdf: "application/pdf"
21
+ # }
22
+ #
23
+ # You can use a symbol:
24
+ #
25
+ # response.content_type = :html
26
+ #
27
+ # If you would like to load all mime types supported by rack/mime,
28
+ # you can use the <tt>mime_types: :from_rack_mime</tt> option:
29
+ #
30
+ # plugin :response_content_type, mime_types: :from_rack_mime
31
+ #
32
+ # Note that you are unlikely to be using all of these mime types,
33
+ # so doing this will likely result in unnecessary memory usage. It
34
+ # is recommended to use a hash with only the mime types your
35
+ # application actually uses.
36
+ #
37
+ # To prevent silent failures, if you attempt to set the response
38
+ # type with a symbol, and the symbol is not recognized, a KeyError
39
+ # is raised.
40
+ module ResponseContentType
41
+ def self.configure(app, opts=OPTS)
42
+ if mime_types = opts[:mime_types]
43
+ mime_types = if mime_types == :from_rack_mime
44
+ require "rack/mime"
45
+ h = {}
46
+ Rack::Mime::MIME_TYPES.each do |k, v|
47
+ h[k.slice(1,100).to_sym] = v
48
+ end
49
+ h
50
+ else
51
+ mime_types.dup
52
+ end
53
+ app.opts[:repsonse_content_types] = mime_types.freeze
54
+ else
55
+ app.opts[:repsonse_content_types] ||= {}
56
+ end
57
+ end
58
+
59
+ module ResponseMethods
60
+ # Return the content-type of the response. Will be nil if it has
61
+ # not yet been explicitly set.
62
+ def content_type
63
+ @headers[RodaResponseHeaders::CONTENT_TYPE]
64
+ end
65
+
66
+ # Set the content-type of the response. If given a string,
67
+ # it is used directly. If given a symbol, looks up the mime
68
+ # type with the given file extension. If the symbol is not
69
+ # a recognized mime type, raises KeyError.
70
+ def content_type=(mime_type)
71
+ mime_type = roda_class.opts[:repsonse_content_types].fetch(mime_type) if mime_type.is_a?(Symbol)
72
+ @headers[RodaResponseHeaders::CONTENT_TYPE] = mime_type
73
+ end
74
+ end
75
+ end
76
+
77
+ register_plugin(:response_content_type, ResponseContentType)
78
+ end
79
+ end
@@ -273,7 +273,29 @@ class Roda
273
273
  cookie = Hash[opts[:cookie_options]]
274
274
  cookie[:value] = cookie_value
275
275
  cookie[:secure] = true if !cookie.has_key?(:secure) && ssl?
276
+
277
+ before_size = if (set_cookie_before = headers[RodaResponseHeaders::SET_COOKIE]).is_a?(String)
278
+ set_cookie_before.bytesize
279
+ else
280
+ 0
281
+ end
282
+
276
283
  Rack::Utils.set_cookie_header!(headers, opts[:key], cookie)
284
+
285
+ cookie_size = case set_cookie_after = headers[RodaResponseHeaders::SET_COOKIE]
286
+ when String
287
+ # Rack < 3 always takes this branch, combines cookies into string, subtract previous size
288
+ # Rack 3+ takes this branch if this is the first cookie set, in which case before size is 0
289
+ set_cookie_after.bytesize - before_size
290
+ else # when Array
291
+ # Rack 3+ takes branch if this is not the first cookie set, and last element of the array
292
+ # is most recently added cookie
293
+ set_cookie_after.last.bytesize
294
+ end
295
+
296
+ if cookie_size >= 4096
297
+ raise CookieTooLarge, "attempted to create cookie larger than 4096 bytes (bytes: #{cookie_size})"
298
+ end
277
299
  end
278
300
 
279
301
  if env[SESSION_DELETE_RACK_COOKIE]
@@ -500,7 +522,7 @@ class Roda
500
522
  data = Base64_.urlsafe_encode64(data)
501
523
 
502
524
  if data.bytesize >= 4096
503
- raise CookieTooLarge, "attempted to create cookie larger than 4096 bytes"
525
+ raise CookieTooLarge, "attempted to create cookie larger than 4096 bytes (bytes: #{data.bytesize})"
504
526
  end
505
527
 
506
528
  data
@@ -1155,11 +1155,26 @@ class Roda
1155
1155
  end
1156
1156
 
1157
1157
  module InstanceMethods
1158
- # Return and cache the instance of the Params class for the current request.
1158
+ # Return and cache the instance of the TypecastParams class wrapping access
1159
+ # to the request's params (merging query string params and body params).
1159
1160
  # Type conversion methods will be called on the result of this method.
1160
1161
  def typecast_params
1161
1162
  @_typecast_params ||= self.class::TypecastParams.new(@_request.params)
1162
1163
  end
1164
+
1165
+ # Return and cache the instance of the TypecastParams class wrapping
1166
+ # access to parameters in the request's query string.
1167
+ # Type conversion methods will be called on the result of this method.
1168
+ def typecast_query_params
1169
+ @_typecast_query_params ||= self.class::TypecastParams.new(@_request.GET)
1170
+ end
1171
+
1172
+ # Return and cache the instance of the TypecastParams class wrapping
1173
+ # access to parameters in the request's body.
1174
+ # Type conversion methods will be called on the result of this method.
1175
+ def typecast_body_params
1176
+ @_typecast_body_params ||= self.class::TypecastParams.new(@_request.POST)
1177
+ end
1163
1178
  end
1164
1179
  end
1165
1180
 
@@ -182,12 +182,17 @@ class Roda
182
182
  # contain a slash.
183
183
  def template_name(opts)
184
184
  name = super
185
- if (v = @_view_subdir) && !name.include?('/')
185
+ if (v = @_view_subdir) && use_view_subdir_for_template_name?(name)
186
186
  "#{v}/#{name}"
187
187
  else
188
188
  name
189
189
  end
190
190
  end
191
+
192
+ # Whether to use a view subdir for the template name.
193
+ def use_view_subdir_for_template_name?(name)
194
+ !name.include?('/')
195
+ end
191
196
  end
192
197
  end
193
198
 
@@ -0,0 +1,49 @@
1
+ # frozen-string-literal: true
2
+
3
+ #
4
+ class Roda
5
+ module RodaPlugins
6
+ # The view_subdir_leading_slash plugin builds on the view_options
7
+ # plugin, and changes the behavior so that if a view subdir is set,
8
+ # it is used for all templates, unless the template starts with a
9
+ # leading slash:
10
+ #
11
+ # plugin :view_subdir_leading_slash
12
+ #
13
+ # route do |r|
14
+ # r.on "users" do
15
+ # set_view_subdir 'users'
16
+ #
17
+ # r.get 'list' do
18
+ # view 'lists/users' # uses ./views/users/lists/users.erb
19
+ # end
20
+ #
21
+ # r.get 'list' do
22
+ # view '/lists/users' # uses ./views//lists/users.erb
23
+ # end
24
+ # end
25
+ # end
26
+ #
27
+ # The default for the view_options plugin is to not use a
28
+ # view subdir if the template name contains a slash at all.
29
+ module ViewSubdirLeadingSlash
30
+ # Load the view_options plugin before this plugin, since this plugin
31
+ # works by overriding a method in the view_options plugin.
32
+ def self.load_dependencies(app)
33
+ app.plugin :view_options
34
+ end
35
+
36
+ module InstanceMethods
37
+ private
38
+
39
+ # Use a view subdir unless the template starts with a slash.
40
+ def use_view_subdir_for_template_name?(name)
41
+ !name.start_with?('/')
42
+ end
43
+ end
44
+ end
45
+
46
+ register_plugin(:view_subdir_leading_slash, ViewSubdirLeadingSlash)
47
+ end
48
+ end
49
+
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 = 93
7
+ RodaMinorVersion = 95
8
8
 
9
9
  # The patch version of Roda, updated only for bug fixes from the last
10
10
  # feature release.
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.93.0
4
+ version: 3.95.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
@@ -275,6 +275,7 @@ files:
275
275
  - lib/roda/plugins/render_locals.rb
276
276
  - lib/roda/plugins/request_aref.rb
277
277
  - lib/roda/plugins/request_headers.rb
278
+ - lib/roda/plugins/response_content_type.rb
278
279
  - lib/roda/plugins/response_request.rb
279
280
  - lib/roda/plugins/route_block_args.rb
280
281
  - lib/roda/plugins/route_csrf.rb
@@ -300,6 +301,7 @@ files:
300
301
  - lib/roda/plugins/typecast_params_sized_integers.rb
301
302
  - lib/roda/plugins/unescape_path.rb
302
303
  - lib/roda/plugins/view_options.rb
304
+ - lib/roda/plugins/view_subdir_leading_slash.rb
303
305
  - lib/roda/request.rb
304
306
  - lib/roda/response.rb
305
307
  - lib/roda/session_middleware.rb
@@ -327,7 +329,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
327
329
  - !ruby/object:Gem::Version
328
330
  version: '0'
329
331
  requirements: []
330
- rubygems_version: 3.6.7
332
+ rubygems_version: 3.6.9
331
333
  specification_version: 4
332
334
  summary: Routing tree web toolkit
333
335
  test_files: []