roda 2.29.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (170) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +52 -0
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +51 -109
  5. data/Rakefile +7 -14
  6. data/doc/conventions.rdoc +4 -4
  7. data/doc/release_notes/1.2.0.txt +1 -1
  8. data/doc/release_notes/3.0.0.txt +84 -0
  9. data/lib/roda.rb +25 -79
  10. data/lib/roda/plugins/assets.rb +25 -58
  11. data/lib/roda/plugins/assets_preloading.rb +0 -5
  12. data/lib/roda/plugins/backtracking_array.rb +0 -5
  13. data/lib/roda/plugins/branch_locals.rb +3 -3
  14. data/lib/roda/plugins/caching.rb +5 -38
  15. data/lib/roda/plugins/chunked.rb +7 -25
  16. data/lib/roda/plugins/class_level_routing.rb +2 -2
  17. data/lib/roda/plugins/content_for.rb +7 -10
  18. data/lib/roda/plugins/cookies.rb +3 -3
  19. data/lib/roda/plugins/csrf.rb +2 -2
  20. data/lib/roda/plugins/delegate.rb +3 -3
  21. data/lib/roda/plugins/drop_body.rb +0 -7
  22. data/lib/roda/plugins/empty_root.rb +0 -3
  23. data/lib/roda/plugins/error_email.rb +4 -6
  24. data/lib/roda/plugins/error_handler.rb +1 -2
  25. data/lib/roda/plugins/error_mail.rb +3 -6
  26. data/lib/roda/plugins/flash.rb +0 -4
  27. data/lib/roda/plugins/h.rb +5 -0
  28. data/lib/roda/plugins/hash_matcher.rb +4 -2
  29. data/lib/roda/plugins/head.rb +5 -7
  30. data/lib/roda/plugins/header_matchers.rb +12 -33
  31. data/lib/roda/plugins/heartbeat.rb +2 -7
  32. data/lib/roda/plugins/indifferent_params.rb +2 -2
  33. data/lib/roda/plugins/json.rb +6 -14
  34. data/lib/roda/plugins/json_parser.rb +2 -13
  35. data/lib/roda/plugins/mailer.rb +29 -39
  36. data/lib/roda/plugins/match_affix.rb +0 -5
  37. data/lib/roda/plugins/middleware.rb +10 -15
  38. data/lib/roda/plugins/multi_route.rb +8 -5
  39. data/lib/roda/plugins/multi_run.rb +1 -0
  40. data/lib/roda/plugins/named_templates.rb +2 -2
  41. data/lib/roda/plugins/optimized_string_matchers.rb +0 -3
  42. data/lib/roda/plugins/padrino_render.rb +6 -9
  43. data/lib/roda/plugins/param_matchers.rb +6 -6
  44. data/lib/roda/plugins/params_capturing.rb +15 -35
  45. data/lib/roda/plugins/partials.rb +3 -8
  46. data/lib/roda/plugins/path.rb +5 -5
  47. data/lib/roda/plugins/path_matchers.rb +3 -3
  48. data/lib/roda/plugins/path_rewriter.rb +4 -9
  49. data/lib/roda/plugins/placeholder_string_matchers.rb +1 -1
  50. data/lib/roda/plugins/precompile_templates.rb +10 -20
  51. data/lib/roda/plugins/public.rb +6 -9
  52. data/lib/roda/plugins/render.rb +50 -171
  53. data/lib/roda/plugins/render_each.rb +4 -7
  54. data/lib/roda/plugins/render_locals.rb +6 -20
  55. data/lib/roda/plugins/request_headers.rb +2 -4
  56. data/lib/roda/plugins/run_append_slash.rb +1 -4
  57. data/lib/roda/plugins/run_handler.rb +4 -7
  58. data/lib/roda/plugins/shared_vars.rb +3 -6
  59. data/lib/roda/plugins/sinatra_helpers.rb +11 -40
  60. data/lib/roda/plugins/slash_path_empty.rb +0 -3
  61. data/lib/roda/plugins/static.rb +2 -2
  62. data/lib/roda/plugins/static_routing.rb +2 -3
  63. data/lib/roda/plugins/streaming.rb +15 -108
  64. data/lib/roda/plugins/strip_path_prefix.rb +1 -1
  65. data/lib/roda/plugins/symbol_matchers.rb +7 -23
  66. data/lib/roda/plugins/type_routing.rb +4 -9
  67. data/lib/roda/plugins/view_options.rb +10 -66
  68. data/lib/roda/version.rb +2 -2
  69. data/spec/all.rb +0 -2
  70. data/spec/composition_spec.rb +1 -1
  71. data/spec/env_spec.rb +1 -1
  72. data/spec/freeze_spec.rb +1 -1
  73. data/spec/integration_spec.rb +1 -1
  74. data/spec/matchers_spec.rb +26 -70
  75. data/spec/opts_spec.rb +1 -1
  76. data/spec/plugin/all_verbs_spec.rb +1 -1
  77. data/spec/plugin/assets_preloading_spec.rb +1 -1
  78. data/spec/plugin/assets_spec.rb +43 -27
  79. data/spec/plugin/backtracking_array_spec.rb +1 -1
  80. data/spec/plugin/branch_locals_spec.rb +1 -1
  81. data/spec/plugin/caching_spec.rb +1 -1
  82. data/spec/plugin/chunked_spec.rb +1 -1
  83. data/spec/plugin/class_level_routing_spec.rb +1 -1
  84. data/spec/plugin/class_matchers_spec.rb +1 -1
  85. data/spec/plugin/content_for_spec.rb +2 -7
  86. data/spec/plugin/cookies_spec.rb +1 -1
  87. data/spec/plugin/csrf_spec.rb +1 -1
  88. data/spec/plugin/default_headers_spec.rb +1 -1
  89. data/spec/plugin/default_status_spec.rb +1 -1
  90. data/spec/plugin/delay_build_spec.rb +1 -1
  91. data/spec/plugin/delegate_spec.rb +1 -1
  92. data/spec/plugin/delete_empty_headers_spec.rb +1 -1
  93. data/spec/plugin/disallow_file_uploads_spec.rb +2 -2
  94. data/spec/plugin/drop_body_spec.rb +1 -1
  95. data/spec/plugin/empty_root_spec.rb +1 -1
  96. data/spec/plugin/environments_spec.rb +1 -1
  97. data/spec/plugin/error_email_spec.rb +1 -1
  98. data/spec/plugin/error_handler_spec.rb +1 -1
  99. data/spec/plugin/error_mail_spec.rb +2 -2
  100. data/spec/plugin/flash_spec.rb +1 -1
  101. data/spec/plugin/h_spec.rb +1 -1
  102. data/spec/plugin/halt_spec.rb +2 -2
  103. data/spec/plugin/hash_matcher_spec.rb +1 -1
  104. data/spec/plugin/head_spec.rb +1 -1
  105. data/spec/plugin/header_matchers_spec.rb +4 -47
  106. data/spec/plugin/heartbeat_spec.rb +1 -1
  107. data/spec/plugin/hooks_spec.rb +1 -1
  108. data/spec/plugin/indifferent_params_spec.rb +1 -1
  109. data/spec/plugin/json_parser_spec.rb +12 -1
  110. data/spec/plugin/json_spec.rb +8 -1
  111. data/spec/plugin/mailer_spec.rb +1 -1
  112. data/spec/plugin/match_affix_spec.rb +1 -1
  113. data/spec/plugin/middleware_spec.rb +15 -1
  114. data/spec/plugin/module_include_spec.rb +1 -1
  115. data/spec/plugin/multi_route_spec.rb +5 -3
  116. data/spec/plugin/multi_run_spec.rb +1 -1
  117. data/spec/plugin/multi_view_spec.rb +1 -1
  118. data/spec/plugin/named_templates_spec.rb +1 -1
  119. data/spec/plugin/not_allowed_spec.rb +1 -1
  120. data/spec/plugin/not_found_spec.rb +1 -1
  121. data/spec/plugin/optimized_string_matchers_spec.rb +1 -1
  122. data/spec/plugin/padrino_render_spec.rb +1 -1
  123. data/spec/plugin/param_matchers_spec.rb +1 -1
  124. data/spec/plugin/params_capturing_spec.rb +6 -22
  125. data/spec/plugin/partials_spec.rb +1 -1
  126. data/spec/plugin/pass_spec.rb +1 -1
  127. data/spec/plugin/path_matchers_spec.rb +1 -1
  128. data/spec/plugin/path_rewriter_spec.rb +1 -1
  129. data/spec/plugin/path_spec.rb +1 -1
  130. data/spec/plugin/placeholder_string_matchers_spec.rb +3 -36
  131. data/spec/plugin/precompile_templates_spec.rb +1 -17
  132. data/spec/plugin/public_spec.rb +3 -4
  133. data/spec/plugin/render_each_spec.rb +1 -1
  134. data/spec/plugin/render_locals_spec.rb +1 -1
  135. data/spec/plugin/render_spec.rb +28 -114
  136. data/spec/plugin/request_headers_spec.rb +1 -1
  137. data/spec/plugin/response_request_spec.rb +1 -1
  138. data/spec/plugin/run_append_slash_spec.rb +1 -1
  139. data/spec/plugin/run_handler_spec.rb +1 -1
  140. data/spec/plugin/shared_vars_spec.rb +1 -1
  141. data/spec/plugin/sinatra_helpers_spec.rb +1 -1
  142. data/spec/plugin/slash_path_empty_spec.rb +1 -1
  143. data/spec/plugin/static_routing_spec.rb +1 -1
  144. data/spec/plugin/static_spec.rb +1 -1
  145. data/spec/plugin/status_303_spec.rb +1 -1
  146. data/spec/plugin/status_handler_spec.rb +1 -1
  147. data/spec/plugin/streaming_spec.rb +1 -106
  148. data/spec/plugin/strip_path_prefix_spec.rb +1 -1
  149. data/spec/plugin/symbol_matchers_spec.rb +1 -77
  150. data/spec/plugin/symbol_status_spec.rb +1 -1
  151. data/spec/plugin/symbol_views_spec.rb +1 -1
  152. data/spec/plugin/type_routing_spec.rb +1 -1
  153. data/spec/plugin/unescape_path_spec.rb +1 -1
  154. data/spec/plugin/view_options_spec.rb +16 -110
  155. data/spec/plugin_spec.rb +1 -1
  156. data/spec/redirect_spec.rb +1 -1
  157. data/spec/request_spec.rb +1 -1
  158. data/spec/response_spec.rb +1 -1
  159. data/spec/session_spec.rb +1 -1
  160. data/spec/spec_helper.rb +1 -3
  161. data/spec/version_spec.rb +1 -1
  162. metadata +6 -26
  163. data/lib/roda/plugins/_erubis_escaping.rb +0 -59
  164. data/lib/roda/plugins/per_thread_caching.rb +0 -71
  165. data/lib/roda/plugins/static_path_info.rb +0 -12
  166. data/lib/roda/plugins/view_subdirs.rb +0 -7
  167. data/lib/roda/plugins/websockets.rb +0 -107
  168. data/spec/plugin/_erubis_escaping_spec.rb +0 -97
  169. data/spec/plugin/per_thread_caching_spec.rb +0 -28
  170. data/spec/plugin/websockets_spec.rb +0 -84
@@ -15,20 +15,17 @@ class Roda
15
15
  #
16
16
  # You can pass additional render options via an options hash:
17
17
  #
18
- # render_each([1,2,3], :foo, :views=>'partials')
18
+ # render_each([1,2,3], :foo, views: 'partials')
19
19
  #
20
20
  # One additional option supported by is +:local+, which sets the
21
21
  # local variable containing the current value to use. So:
22
22
  #
23
- # render_each([1,2,3], :foo, :local=>:bar)
23
+ # render_each([1,2,3], :foo, local: :bar)
24
24
  #
25
25
  # Will render the +foo+ template, but the local variable used inside
26
- # the template will be +bar+. You can use <tt>:local=>nil</tt> to
26
+ # the template will be +bar+. You can use <tt>local: nil</tt> to
27
27
  # not set a local variable inside the template.
28
28
  module RenderEach
29
- OPTS = {}.freeze
30
- RodaPlugins.deprecate_constant(self, :OPTS)
31
-
32
29
  # Load the render plugin before this plugin, since this plugin
33
30
  # calls the render method.
34
31
  def self.load_dependencies(app)
@@ -42,7 +39,7 @@ class Roda
42
39
  # :local :: The local variable to use for the current enum value
43
40
  # inside the template. An explicit +nil+ value does not
44
41
  # set a local variable. If not set, uses the template name.
45
- def render_each(enum, template, opts=RodaPlugins::OPTS)
42
+ def render_each(enum, template, opts=OPTS)
46
43
  if as = opts.has_key?(:local)
47
44
  as = opts[:local]
48
45
  else
@@ -5,15 +5,15 @@ class Roda
5
5
  module RodaPlugins
6
6
  # The render_locals plugin allows setting default locals for rendering templates.
7
7
  #
8
- # plugin :render_locals, :render=>{:heading=>'Hello'}
8
+ # plugin :render_locals, render: {heading: 'Hello'}
9
9
  #
10
10
  # route do |r|
11
11
  # r.get "foo" do
12
- # view 'foo', :locals=>{:name=>'Foo'} # locals: {:heading=>'Hello', :name=>'Foo'}
12
+ # view 'foo', locals: {name: 'Foo'} # locals: {:heading=>'Hello', :name=>'Foo'}
13
13
  # end
14
14
  #
15
15
  # r.get "bar" do
16
- # view 'foo', :locals=>{:heading=>'Bar'} # locals: {:heading=>'Bar'}
16
+ # view 'foo', locals: {heading: 'Bar'} # locals: {:heading=>'Bar'}
17
17
  # end
18
18
  #
19
19
  # view "default" # locals: {:heading=>'Hello'}
@@ -25,14 +25,11 @@ class Roda
25
25
  # layout :: The default locals to use for layout rendering
26
26
  # merge :: Whether to merge template locals into layout locals
27
27
  module RenderLocals
28
- OPTS = {}.freeze
29
- RodaPlugins.deprecate_constant(self, :OPTS)
30
-
31
- def self.load_dependencies(app, opts=RodaPlugins::OPTS)
28
+ def self.load_dependencies(app, opts=OPTS)
32
29
  app.plugin :render
33
30
  end
34
31
 
35
- def self.configure(app, opts=RodaPlugins::OPTS)
32
+ def self.configure(app, opts=OPTS)
36
33
  app.opts[:render_locals] = (app.opts[:render_locals] || {}).merge(opts[:render]||{}).freeze
37
34
  app.opts[:layout_locals] = (app.opts[:layout_locals] || {}).merge(opts[:layout]||{}).freeze
38
35
  if opts.has_key?(:merge)
@@ -52,11 +49,6 @@ class Roda
52
49
  opts[:layout_locals]
53
50
  end
54
51
 
55
- # RODA3: Remove
56
- def render_plugin_handle_locals?
57
- false
58
- end
59
-
60
52
  # If this isn't the layout template, then use the plugin's render locals as the default locals.
61
53
  def render_template_opts(template, opts)
62
54
  opts = super
@@ -76,12 +68,7 @@ class Roda
76
68
  merge_locals = layout_opts.has_key?(:merge_locals) ? layout_opts[:merge_locals] : self.opts[:merge_locals]
77
69
 
78
70
  locals = {}
79
- if merge_locals && (plugin_locals = render_locals)
80
- locals.merge!(plugin_locals)
81
- end
82
- if layout_locals = layout_locals()
83
- locals.merge!(layout_locals)
84
- end
71
+ locals.merge!(layout_locals)
85
72
  if merge_locals && (method_locals = opts[:locals])
86
73
  locals.merge!(method_locals)
87
74
  end
@@ -90,7 +77,6 @@ class Roda
90
77
  end
91
78
 
92
79
  layout_opts[:locals] = locals
93
- layout_opts[:_is_layout] = true
94
80
  layout_opts
95
81
  end
96
82
  end
@@ -19,16 +19,14 @@ class Roda
19
19
  #
20
20
  # r.headers['X-My-Header']
21
21
  #
22
- # The name is actually case-insensitive so x-my-header will work as well.
23
- #
22
+ # The name is actually case-insensitive so <tt>x-my-header</tt> will work as well.
24
23
  #
25
24
  # Example:
26
25
  #
27
26
  # plugin :request_headers
28
- #
29
27
  module RequestHeaders
30
28
  module RequestMethods
31
- # Provide access to the request headers while normalising indexes.
29
+ # Provide access to the request headers while normalizing indexes.
32
30
  def headers
33
31
  @request_headers ||= Headers.new(@env)
34
32
  end
@@ -21,13 +21,10 @@ class Roda
21
21
  # # GET /a => App gets "/" as PATH_INFO
22
22
  # # GET /a/ => App gets "/" as PATH_INFO
23
23
  module RunAppendSlash
24
- OPTS = {}.freeze
25
- RodaPlugins.deprecate_constant(self, :OPTS)
26
-
27
24
  # Set plugin specific options. Options:
28
25
  # :use_redirects :: Whether to issue 302 redirects when appending the
29
26
  # trailing slash.
30
- def self.configure(app, opts=RodaPlugins::OPTS)
27
+ def self.configure(app, opts=OPTS)
31
28
  app.opts[:run_append_slash_redirect] = !!opts[:use_redirects]
32
29
  end
33
30
 
@@ -7,7 +7,7 @@ class Roda
7
7
  # the rack response array, before it returns it as a response.
8
8
  #
9
9
  # Additionally, r.run also takes a options hash, and you can provide a
10
- # <tt>:not_found=>:pass</tt> option to keep routing normally if the rack
10
+ # <tt>not_found: :pass</tt> option to keep routing normally if the rack
11
11
  # app returns a 404 response.
12
12
  #
13
13
  #
@@ -16,7 +16,7 @@ class Roda
16
16
  # route do |r|
17
17
  # r.on 'a' do
18
18
  # # Keep running code if RackAppFoo doesn't return a result
19
- # r.run RackAppFoo, :not_found=>:pass
19
+ # r.run RackAppFoo, not_found: :pass
20
20
  #
21
21
  # # Change response status codes before returning.
22
22
  # r.run(RackAppBar) do |response|
@@ -25,17 +25,14 @@ class Roda
25
25
  # end
26
26
  # end
27
27
  module RunHandler
28
- OPTS = {}.freeze
29
- RodaPlugins.deprecate_constant(self, :OPTS)
30
-
31
28
  module RequestMethods
32
29
  # If a block is given, yield the rack response array to it. The response can
33
30
  # be modified before it is returned by the current app.
34
31
  #
35
- # If the <tt>:not_found=>:pass</tt> option is given, and the rack response
32
+ # If the <tt>not_found: :pass</tt> option is given, and the rack response
36
33
  # returned by the app is a 404 response, do not return the response, continue
37
34
  # routing normally.
38
- def run(app, opts=RodaPlugins::OPTS)
35
+ def run(app, opts=OPTS)
39
36
  res = catch(:halt){super(app)}
40
37
  yield res if block_given?
41
38
  throw(:halt, res) unless opts[:not_found] == :pass && res[0] == 404
@@ -3,7 +3,7 @@
3
3
  #
4
4
  class Roda
5
5
  module RodaPlugins
6
- # The shared_vars plugin adds a shared method for storing
6
+ # The shared_vars plugin adds a +shared+ method for storing
7
7
  # shared variables across nested Roda apps.
8
8
  #
9
9
  # class API < Roda
@@ -30,7 +30,7 @@ class Roda
30
30
  #
31
31
  # route do |r|
32
32
  # r.on Integer do |user_id|
33
- # shared(:user => User[user_id])
33
+ # shared(user: User[user_id])
34
34
  # r.run API
35
35
  # end
36
36
  # end
@@ -41,15 +41,12 @@ class Roda
41
41
  #
42
42
  # route do |r|
43
43
  # r.on Integer do |user_id|
44
- # shared(:user => User[user_id]) do
44
+ # shared(user: User[user_id]) do
45
45
  # r.run API
46
46
  # end
47
47
  # end
48
48
  # end
49
49
  module SharedVars
50
- KEY = 'roda.shared'.freeze
51
- RodaPlugins.deprecate_constant(self, :KEY)
52
-
53
50
  module InstanceMethods
54
51
  # Returns the current shared vars for the request. These are
55
52
  # stored in the request's environment, so they will be implicitly
@@ -15,9 +15,9 @@ class Roda
15
15
  # of the route block that call the methods on the request
16
16
  # or response. If you do not want to pollute the namespace
17
17
  # of the route block, you should load the plugin with the
18
- # :delegate => false option:
18
+ # <tt>delegate: false</tt> option:
19
19
  #
20
- # plugin :sinatra_helpers, :delegate=>false
20
+ # plugin :sinatra_helpers, delegate: false
21
21
  #
22
22
  # == Class Methods Added
23
23
  #
@@ -211,35 +211,6 @@ class Roda
211
211
  # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
212
212
  # OTHER DEALINGS IN THE SOFTWARE.
213
213
  module SinatraHelpers
214
- OPTS = {}.freeze
215
- RodaPlugins.deprecate_constant(self, :OPTS)
216
- CONTENT_TYPE = "Content-Type".freeze
217
- RodaPlugins.deprecate_constant(self, :CONTENT_TYPE)
218
- CONTENT_DISPOSITION = "Content-Disposition".freeze
219
- RodaPlugins.deprecate_constant(self, :CONTENT_DISPOSITION)
220
- CONTENT_LENGTH = "Content-Length".freeze
221
- RodaPlugins.deprecate_constant(self, :CONTENT_LENGTH)
222
- OCTET_STREAM = 'application/octet-stream'.freeze
223
- RodaPlugins.deprecate_constant(self, :OCTET_STREAM)
224
- ATTACHMENT = 'attachment'.freeze
225
- RodaPlugins.deprecate_constant(self, :ATTACHMENT)
226
- HTTP_VERSION = 'HTTP_VERSION'.freeze
227
- RodaPlugins.deprecate_constant(self, :HTTP_VERSION)
228
- HTTP11 = "HTTP/1.1".freeze
229
- RodaPlugins.deprecate_constant(self, :HTTP11)
230
- HTTP_X_FORWARDED_HOST = "HTTP_X_FORWARDED_HOST".freeze
231
- RodaPlugins.deprecate_constant(self, :HTTP_X_FORWARDED_HOST)
232
- EMPTY_STRING = ''.freeze
233
- RodaPlugins.deprecate_constant(self, :EMPTY_STRING)
234
- SLASH = '/'.freeze
235
- RodaPlugins.deprecate_constant(self, :SLASH)
236
- SEMICOLON = ';'.freeze
237
- RodaPlugins.deprecate_constant(self, :SEMICOLON)
238
- COMMA = ', '.freeze
239
- RodaPlugins.deprecate_constant(self, :COMMA)
240
- CHARSET = 'charset'.freeze
241
- RodaPlugins.deprecate_constant(self, :CHARSET)
242
-
243
214
  # Depend on the status_303 plugin.
244
215
  def self.load_dependencies(app, _opts = nil)
245
216
  app.plugin :status_303
@@ -248,7 +219,7 @@ class Roda
248
219
  # Add delegate methods to the route block scope
249
220
  # calling request or response methods, unless the
250
221
  # :delegate option is false.
251
- def self.configure(app, opts=RodaPlugins::OPTS)
222
+ def self.configure(app, opts=OPTS)
252
223
  app.send(:include, DelegateMethods) unless opts[:delegate] == false
253
224
  end
254
225
 
@@ -339,7 +310,7 @@ class Roda
339
310
  end
340
311
 
341
312
  # Use the contents of the file at +path+ as the response body. See plugin documentation for options.
342
- def send_file(path, opts = RodaPlugins::OPTS)
313
+ def send_file(path, opts = OPTS)
343
314
  res = response
344
315
  headers = res.headers
345
316
  if opts[:type] || !headers["Content-Type"]
@@ -360,12 +331,12 @@ class Roda
360
331
 
361
332
  file = ::Rack::File.new nil
362
333
  s, h, b = if Rack.release > '2'
363
- # :nocov:
364
334
  file.serving(self, path)
365
- # :nocov:
366
335
  else
336
+ # :nocov:
367
337
  file.path = path
368
338
  file.serving(@env)
339
+ # :nocov:
369
340
  end
370
341
 
371
342
  res.status = opts[:status] || s
@@ -441,7 +412,7 @@ class Roda
441
412
 
442
413
  # Set the Content-Type of the response body given a media type or file
443
414
  # extension. See plugin documentation for options.
444
- def content_type(type = (return @headers["Content-Type"]; nil), opts = RodaPlugins::OPTS)
415
+ def content_type(type = (return @headers["Content-Type"]; nil), opts = OPTS)
445
416
  unless (mime_type = mime_type(type) || opts[:default])
446
417
  raise RodaError, "Unknown media type: #{type}"
447
418
  end
@@ -520,17 +491,17 @@ class Roda
520
491
 
521
492
  module DelegateMethods
522
493
  [:logger, :back].each do |meth|
523
- define_method(meth){@_request.send(meth)}
494
+ define_method(meth){@_request.public_send(meth)}
524
495
  end
525
496
  [:redirect, :uri, :url, :to, :send_file, :error, :not_found].each do |meth|
526
- define_method(meth){|*v, &block| @_request.send(meth, *v, &block)}
497
+ define_method(meth){|*v, &block| @_request.public_send(meth, *v, &block)}
527
498
  end
528
499
 
529
500
  [:informational?, :success?, :redirect?, :client_error?, :server_error?, :not_found?].each do |meth|
530
- define_method(meth){@_response.send(meth)}
501
+ define_method(meth){@_response.public_send(meth)}
531
502
  end
532
503
  [:status, :body, :headers, :mime_type, :content_type, :attachment].each do |meth|
533
- define_method(meth){|*v, &block| @_response.send(meth, *v, &block)}
504
+ define_method(meth){|*v, &block| @_response.public_send(meth, *v, &block)}
534
505
  end
535
506
  end
536
507
  end
@@ -11,9 +11,6 @@ class Roda
11
11
  # are processed. This can make it easier to handle applications
12
12
  # where a trailing "/" in the path should be ignored.
13
13
  module SlashPathEmpty
14
- SLASH = "/".freeze
15
- RodaPlugins.deprecate_constant(self, :SLASH)
16
-
17
14
  module RequestMethods
18
15
  private
19
16
 
@@ -22,8 +22,8 @@ class Roda
22
22
  #
23
23
  # opts[:root] = '/path/to/app'
24
24
  # plugin :static, ['/js', '/css'] # path: /path/to/app/public
25
- # plugin :static, ['/images'], :root=>'pub' # path: /path/to/app/pub
26
- # plugin :static, ['/media'], :root=>'/path/to/public' # path: /path/to/public
25
+ # plugin :static, ['/images'], root: 'pub' # path: /path/to/app/pub
26
+ # plugin :static, ['/media'], root: '/path/to/public' # path: /path/to/public
27
27
  module Static
28
28
  # Load the Rack::Static middleware. Use the paths given as the :urls option,
29
29
  # and set the :root option to be relative to the application's :root option.
@@ -4,7 +4,7 @@
4
4
  class Roda
5
5
  module RodaPlugins
6
6
  # The static_routing plugin adds static_* routing class methods for handling
7
- # static routes (i.e. routes with static paths, no placeholders). These
7
+ # static routes (i.e. routes with static paths, no nesting or placeholders). These
8
8
  # routes are processed before the normal routing tree and designed for
9
9
  # maximum performance. This can be substantially faster than Roda's normal
10
10
  # tree based routing if you have large numbers of static routes, about 3-4x
@@ -59,8 +59,7 @@ class Roda
59
59
  module ClassMethods
60
60
  # Freeze the static route metadata when freezing the app.
61
61
  def freeze
62
- opts[:static_routes].freeze
63
- opts[:static_routes].each_value(&:freeze)
62
+ opts[:static_routes].freeze.each_value(&:freeze)
64
63
  super
65
64
  end
66
65
 
@@ -19,12 +19,8 @@ class Roda
19
19
  #
20
20
  # The stream method takes the following options:
21
21
  #
22
- # :callback :: A callback proc to call when the connection is
23
- # closed.
24
- # :keep_open :: Whether to keep the connection open after the
25
- # stream block returns, default is false.
26
- # :loop :: Whether to call the stream block continuously until
27
- # the connection is closed.
22
+ # :callback :: A callback proc to call when the connection is closed.
23
+ # :loop :: Whether to call the stream block continuously until the connection is closed.
28
24
  #
29
25
  # If the :loop option is used, you can override the
30
26
  # handle_stream_error method to change how exceptions
@@ -44,111 +40,32 @@ class Roda
44
40
  # end
45
41
  #
46
42
  # or handle the errors in some other way.
47
- #
48
- # The implementation was originally taken from Sinatra,
49
- # which is also released under the MIT License:
50
- #
51
- # Copyright (c) 2007, 2008, 2009 Blake Mizerany
52
- # Copyright (c) 2010, 2011, 2012, 2013, 2014 Konstantin Haase
53
- #
54
- # Permission is hereby granted, free of charge, to any person
55
- # obtaining a copy of this software and associated documentation
56
- # files (the "Software"), to deal in the Software without
57
- # restriction, including without limitation the rights to use,
58
- # copy, modify, merge, publish, distribute, sublicense, and/or sell
59
- # copies of the Software, and to permit persons to whom the
60
- # Software is furnished to do so, subject to the following
61
- # conditions:
62
- #
63
- # The above copyright notice and this permission notice shall be
64
- # included in all copies or substantial portions of the Software.
65
- #
66
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
67
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
68
- # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
69
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
70
- # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
71
- # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
72
- # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
73
- # OTHER DEALINGS IN THE SOFTWARE.
74
43
  module Streaming
75
- OPTS = {}.freeze
76
- RodaPlugins.deprecate_constant(self, :OPTS)
77
-
78
44
  # Class of the response body in case you use #stream.
79
- #
80
- # Three things really matter: The front and back block (back being the
81
- # block generating content, front the one sending it to the client) and
82
- # the scheduler, integrating with whatever concurrency feature the Rack
83
- # handler is using.
84
- #
85
- # Scheduler has to respond to defer and schedule.
86
45
  class Stream
87
46
  include Enumerable
88
47
 
89
- # The default scheduler to used when streaming, useful for code
90
- # using ruby's default threading support.
91
- class Scheduler
92
- # Store the stream to schedule.
93
- def initialize(stream)
94
- @stream = stream
95
- end
96
-
97
- # Immediately yield.
98
- def defer(*)
99
- yield
100
- end
101
-
102
- # Close the stream if there is an exception when scheduling,
103
- # and reraise the exception if so.
104
- def schedule(*)
105
- yield
106
- rescue Exception
107
- @stream.close
108
- raise
109
- end
110
- end
111
-
112
48
  # Handle streaming options, see Streaming for details.
113
- def initialize(opts=RodaPlugins::OPTS, &back)
114
- @scheduler = opts[:scheduler] || Scheduler.new(self)
115
- @back = back.to_proc
116
- @keep_open = opts[:keep_open]
117
- @callbacks = []
49
+ def initialize(opts=OPTS, &block)
50
+ @block = block
51
+ @out = nil
52
+ @callback = opts[:callback]
118
53
  @closed = false
119
-
120
- if opts[:callback]
121
- @callbacks << opts[:callback]
122
- end
123
54
  end
124
55
 
125
56
  # Add output to the streaming response body.
126
57
  def write(data)
127
- @scheduler.schedule{@front.call(data.to_s)}
58
+ @out.call(data.to_s)
128
59
  self
129
60
  end
130
-
131
- # Alias for +write+.
132
- def <<(data)
133
- write(data)
134
- end
135
-
136
- # Add the given block as a callback to call when the block closes.
137
- def callback(&block)
138
- RodaPlugins.warn 'Stream#callback in the streaming plugin is deprecated and will be removed in Roda 3. Specify callback at initialization using the stream method :callback option.'
139
- return yield if closed?
140
- @callbacks << block
141
- end
142
-
143
- # Alias to callback for EventMachine compatibility.
144
- alias errback callback
61
+ alias << write
145
62
 
146
63
  # If not already closed, close the connection, and call
147
64
  # any callbacks.
148
65
  def close
149
66
  return if closed?
150
67
  @closed = true
151
- @scheduler.schedule{@callbacks.each(&:call)}
68
+ @callback.call if @callback
152
69
  end
153
70
 
154
71
  # Whether the connection has already been closed.
@@ -157,16 +74,11 @@ class Roda
157
74
  end
158
75
 
159
76
  # Yield values to the block as they are passed in via #<<.
160
- def each(&front)
161
- @front = front
162
- @scheduler.defer do
163
- begin
164
- @back.call(self)
165
- rescue Exception => e
166
- @scheduler.schedule{raise e}
167
- end
168
- close unless @keep_open
169
- end
77
+ def each(&out)
78
+ @out = out
79
+ @block.call(self)
80
+ ensure
81
+ close
170
82
  end
171
83
  end
172
84
 
@@ -174,12 +86,7 @@ class Roda
174
86
  # Immediately return a streaming response using the current response
175
87
  # status and headers, calling the block to get the streaming response.
176
88
  # See Streaming for details.
177
- def stream(opts=RodaPlugins::OPTS, &block)
178
- if !opts.has_key?(:scheduler) && env['async.callback']
179
- RodaPlugins.warn 'The automatic support for EventMachine in the streaming plugin is deprecated and will be removed in Roda 3.'
180
- opts = opts.merge(:scheduler=>EventMachine)
181
- end
182
-
89
+ def stream(opts=OPTS, &block)
183
90
  if opts[:loop]
184
91
  block = proc do |out|
185
92
  until out.closed?