roda 2.29.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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?
|