roda 2.29.0 → 3.0.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 +4 -4
- data/CHANGELOG +52 -0
- data/MIT-LICENSE +1 -1
- data/README.rdoc +51 -109
- data/Rakefile +7 -14
- data/doc/conventions.rdoc +4 -4
- data/doc/release_notes/1.2.0.txt +1 -1
- data/doc/release_notes/3.0.0.txt +84 -0
- data/lib/roda.rb +25 -79
- data/lib/roda/plugins/assets.rb +25 -58
- data/lib/roda/plugins/assets_preloading.rb +0 -5
- data/lib/roda/plugins/backtracking_array.rb +0 -5
- data/lib/roda/plugins/branch_locals.rb +3 -3
- data/lib/roda/plugins/caching.rb +5 -38
- data/lib/roda/plugins/chunked.rb +7 -25
- data/lib/roda/plugins/class_level_routing.rb +2 -2
- data/lib/roda/plugins/content_for.rb +7 -10
- data/lib/roda/plugins/cookies.rb +3 -3
- data/lib/roda/plugins/csrf.rb +2 -2
- data/lib/roda/plugins/delegate.rb +3 -3
- data/lib/roda/plugins/drop_body.rb +0 -7
- data/lib/roda/plugins/empty_root.rb +0 -3
- data/lib/roda/plugins/error_email.rb +4 -6
- data/lib/roda/plugins/error_handler.rb +1 -2
- data/lib/roda/plugins/error_mail.rb +3 -6
- data/lib/roda/plugins/flash.rb +0 -4
- data/lib/roda/plugins/h.rb +5 -0
- data/lib/roda/plugins/hash_matcher.rb +4 -2
- data/lib/roda/plugins/head.rb +5 -7
- data/lib/roda/plugins/header_matchers.rb +12 -33
- data/lib/roda/plugins/heartbeat.rb +2 -7
- data/lib/roda/plugins/indifferent_params.rb +2 -2
- data/lib/roda/plugins/json.rb +6 -14
- data/lib/roda/plugins/json_parser.rb +2 -13
- data/lib/roda/plugins/mailer.rb +29 -39
- data/lib/roda/plugins/match_affix.rb +0 -5
- data/lib/roda/plugins/middleware.rb +10 -15
- data/lib/roda/plugins/multi_route.rb +8 -5
- data/lib/roda/plugins/multi_run.rb +1 -0
- data/lib/roda/plugins/named_templates.rb +2 -2
- data/lib/roda/plugins/optimized_string_matchers.rb +0 -3
- data/lib/roda/plugins/padrino_render.rb +6 -9
- data/lib/roda/plugins/param_matchers.rb +6 -6
- data/lib/roda/plugins/params_capturing.rb +15 -35
- data/lib/roda/plugins/partials.rb +3 -8
- data/lib/roda/plugins/path.rb +5 -5
- data/lib/roda/plugins/path_matchers.rb +3 -3
- data/lib/roda/plugins/path_rewriter.rb +4 -9
- data/lib/roda/plugins/placeholder_string_matchers.rb +1 -1
- data/lib/roda/plugins/precompile_templates.rb +10 -20
- data/lib/roda/plugins/public.rb +6 -9
- data/lib/roda/plugins/render.rb +50 -171
- data/lib/roda/plugins/render_each.rb +4 -7
- data/lib/roda/plugins/render_locals.rb +6 -20
- data/lib/roda/plugins/request_headers.rb +2 -4
- data/lib/roda/plugins/run_append_slash.rb +1 -4
- data/lib/roda/plugins/run_handler.rb +4 -7
- data/lib/roda/plugins/shared_vars.rb +3 -6
- data/lib/roda/plugins/sinatra_helpers.rb +11 -40
- data/lib/roda/plugins/slash_path_empty.rb +0 -3
- data/lib/roda/plugins/static.rb +2 -2
- data/lib/roda/plugins/static_routing.rb +2 -3
- data/lib/roda/plugins/streaming.rb +15 -108
- data/lib/roda/plugins/strip_path_prefix.rb +1 -1
- data/lib/roda/plugins/symbol_matchers.rb +7 -23
- data/lib/roda/plugins/type_routing.rb +4 -9
- data/lib/roda/plugins/view_options.rb +10 -66
- data/lib/roda/version.rb +2 -2
- data/spec/all.rb +0 -2
- data/spec/composition_spec.rb +1 -1
- data/spec/env_spec.rb +1 -1
- data/spec/freeze_spec.rb +1 -1
- data/spec/integration_spec.rb +1 -1
- data/spec/matchers_spec.rb +26 -70
- data/spec/opts_spec.rb +1 -1
- data/spec/plugin/all_verbs_spec.rb +1 -1
- data/spec/plugin/assets_preloading_spec.rb +1 -1
- data/spec/plugin/assets_spec.rb +43 -27
- data/spec/plugin/backtracking_array_spec.rb +1 -1
- data/spec/plugin/branch_locals_spec.rb +1 -1
- data/spec/plugin/caching_spec.rb +1 -1
- data/spec/plugin/chunked_spec.rb +1 -1
- data/spec/plugin/class_level_routing_spec.rb +1 -1
- data/spec/plugin/class_matchers_spec.rb +1 -1
- data/spec/plugin/content_for_spec.rb +2 -7
- data/spec/plugin/cookies_spec.rb +1 -1
- data/spec/plugin/csrf_spec.rb +1 -1
- data/spec/plugin/default_headers_spec.rb +1 -1
- data/spec/plugin/default_status_spec.rb +1 -1
- data/spec/plugin/delay_build_spec.rb +1 -1
- data/spec/plugin/delegate_spec.rb +1 -1
- data/spec/plugin/delete_empty_headers_spec.rb +1 -1
- data/spec/plugin/disallow_file_uploads_spec.rb +2 -2
- data/spec/plugin/drop_body_spec.rb +1 -1
- data/spec/plugin/empty_root_spec.rb +1 -1
- data/spec/plugin/environments_spec.rb +1 -1
- data/spec/plugin/error_email_spec.rb +1 -1
- data/spec/plugin/error_handler_spec.rb +1 -1
- data/spec/plugin/error_mail_spec.rb +2 -2
- data/spec/plugin/flash_spec.rb +1 -1
- data/spec/plugin/h_spec.rb +1 -1
- data/spec/plugin/halt_spec.rb +2 -2
- data/spec/plugin/hash_matcher_spec.rb +1 -1
- data/spec/plugin/head_spec.rb +1 -1
- data/spec/plugin/header_matchers_spec.rb +4 -47
- data/spec/plugin/heartbeat_spec.rb +1 -1
- data/spec/plugin/hooks_spec.rb +1 -1
- data/spec/plugin/indifferent_params_spec.rb +1 -1
- data/spec/plugin/json_parser_spec.rb +12 -1
- data/spec/plugin/json_spec.rb +8 -1
- data/spec/plugin/mailer_spec.rb +1 -1
- data/spec/plugin/match_affix_spec.rb +1 -1
- data/spec/plugin/middleware_spec.rb +15 -1
- data/spec/plugin/module_include_spec.rb +1 -1
- data/spec/plugin/multi_route_spec.rb +5 -3
- data/spec/plugin/multi_run_spec.rb +1 -1
- data/spec/plugin/multi_view_spec.rb +1 -1
- data/spec/plugin/named_templates_spec.rb +1 -1
- data/spec/plugin/not_allowed_spec.rb +1 -1
- data/spec/plugin/not_found_spec.rb +1 -1
- data/spec/plugin/optimized_string_matchers_spec.rb +1 -1
- data/spec/plugin/padrino_render_spec.rb +1 -1
- data/spec/plugin/param_matchers_spec.rb +1 -1
- data/spec/plugin/params_capturing_spec.rb +6 -22
- data/spec/plugin/partials_spec.rb +1 -1
- data/spec/plugin/pass_spec.rb +1 -1
- data/spec/plugin/path_matchers_spec.rb +1 -1
- data/spec/plugin/path_rewriter_spec.rb +1 -1
- data/spec/plugin/path_spec.rb +1 -1
- data/spec/plugin/placeholder_string_matchers_spec.rb +3 -36
- data/spec/plugin/precompile_templates_spec.rb +1 -17
- data/spec/plugin/public_spec.rb +3 -4
- data/spec/plugin/render_each_spec.rb +1 -1
- data/spec/plugin/render_locals_spec.rb +1 -1
- data/spec/plugin/render_spec.rb +28 -114
- data/spec/plugin/request_headers_spec.rb +1 -1
- data/spec/plugin/response_request_spec.rb +1 -1
- data/spec/plugin/run_append_slash_spec.rb +1 -1
- data/spec/plugin/run_handler_spec.rb +1 -1
- data/spec/plugin/shared_vars_spec.rb +1 -1
- data/spec/plugin/sinatra_helpers_spec.rb +1 -1
- data/spec/plugin/slash_path_empty_spec.rb +1 -1
- data/spec/plugin/static_routing_spec.rb +1 -1
- data/spec/plugin/static_spec.rb +1 -1
- data/spec/plugin/status_303_spec.rb +1 -1
- data/spec/plugin/status_handler_spec.rb +1 -1
- data/spec/plugin/streaming_spec.rb +1 -106
- data/spec/plugin/strip_path_prefix_spec.rb +1 -1
- data/spec/plugin/symbol_matchers_spec.rb +1 -77
- data/spec/plugin/symbol_status_spec.rb +1 -1
- data/spec/plugin/symbol_views_spec.rb +1 -1
- data/spec/plugin/type_routing_spec.rb +1 -1
- data/spec/plugin/unescape_path_spec.rb +1 -1
- data/spec/plugin/view_options_spec.rb +16 -110
- data/spec/plugin_spec.rb +1 -1
- data/spec/redirect_spec.rb +1 -1
- data/spec/request_spec.rb +1 -1
- data/spec/response_spec.rb +1 -1
- data/spec/session_spec.rb +1 -1
- data/spec/spec_helper.rb +1 -3
- data/spec/version_spec.rb +1 -1
- metadata +6 -26
- data/lib/roda/plugins/_erubis_escaping.rb +0 -59
- data/lib/roda/plugins/per_thread_caching.rb +0 -71
- data/lib/roda/plugins/static_path_info.rb +0 -12
- data/lib/roda/plugins/view_subdirs.rb +0 -7
- data/lib/roda/plugins/websockets.rb +0 -107
- data/spec/plugin/_erubis_escaping_spec.rb +0 -97
- data/spec/plugin/per_thread_caching_spec.rb +0 -28
- 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, :
|
|
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, :
|
|
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
|
|
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=
|
|
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, :
|
|
8
|
+
# plugin :render_locals, render: {heading: 'Hello'}
|
|
9
9
|
#
|
|
10
10
|
# route do |r|
|
|
11
11
|
# r.get "foo" do
|
|
12
|
-
# view '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', :
|
|
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
|
-
|
|
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=
|
|
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
|
-
|
|
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
|
|
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=
|
|
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
|
|
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, :
|
|
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
|
|
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=
|
|
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(:
|
|
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(:
|
|
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
|
-
# :
|
|
18
|
+
# <tt>delegate: false</tt> option:
|
|
19
19
|
#
|
|
20
|
-
# plugin :sinatra_helpers, :
|
|
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=
|
|
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 =
|
|
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 =
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
data/lib/roda/plugins/static.rb
CHANGED
|
@@ -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'], :
|
|
26
|
-
# plugin :static, ['/media'], :
|
|
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
|
-
#
|
|
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=
|
|
114
|
-
@
|
|
115
|
-
@
|
|
116
|
-
@
|
|
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
|
-
@
|
|
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
|
-
@
|
|
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(&
|
|
161
|
-
@
|
|
162
|
-
@
|
|
163
|
-
|
|
164
|
-
|
|
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=
|
|
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?
|