sinatra-contrib 2.2.4 → 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/README.md +5 -3
- data/Rakefile +24 -22
- data/ideas.md +2 -2
- data/lib/sinatra/capture.rb +4 -2
- data/lib/sinatra/config_file.rb +4 -9
- data/lib/sinatra/content_for.rb +5 -4
- data/lib/sinatra/contrib/all.rb +2 -0
- data/lib/sinatra/contrib/setup.rb +3 -1
- data/lib/sinatra/contrib/version.rb +3 -2
- data/lib/sinatra/contrib.rb +2 -1
- data/lib/sinatra/cookies.rb +47 -34
- data/lib/sinatra/custom_logger.rb +2 -1
- data/lib/sinatra/engine_tracking.rb +6 -47
- data/lib/sinatra/extension.rb +4 -2
- data/lib/sinatra/json.rb +9 -10
- data/lib/sinatra/link_header.rb +7 -7
- data/lib/sinatra/multi_route.rb +2 -0
- data/lib/sinatra/namespace.rb +29 -20
- data/lib/sinatra/quiet_logger.rb +8 -3
- data/lib/sinatra/reloader.rb +33 -18
- data/lib/sinatra/required_params.rb +3 -1
- data/lib/sinatra/respond_with.rb +40 -30
- data/lib/sinatra/runner.rb +25 -16
- data/lib/sinatra/streaming.rb +11 -11
- data/lib/sinatra/test_helpers.rb +6 -20
- data/lib/sinatra/webdav.rb +7 -6
- data/sinatra-contrib.gemspec +42 -49
- metadata +43 -156
- data/lib/sinatra/decompile.rb +0 -5
data/lib/sinatra/link_header.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'sinatra/base'
|
2
2
|
|
3
3
|
module Sinatra
|
4
|
-
|
5
4
|
# = Sinatra::LinkHeader
|
6
5
|
#
|
7
6
|
# <tt>Sinatra::LinkHeader</tt> adds a set of helper methods to generate link
|
@@ -86,8 +85,8 @@ module Sinatra
|
|
86
85
|
opts[:rel] = urls.shift unless urls.first.respond_to? :to_str
|
87
86
|
options = opts.map { |k, v| " #{k}=#{v.to_s.inspect}" }
|
88
87
|
html_pattern = "<link href=\"%s\"#{options.join} />"
|
89
|
-
http_pattern = [
|
90
|
-
link = (response[
|
88
|
+
http_pattern = ['<%s>', *options].join ';'
|
89
|
+
link = (response['Link'] ||= '')
|
91
90
|
|
92
91
|
urls.map do |url|
|
93
92
|
link << ",\n" unless link.empty?
|
@@ -116,14 +115,15 @@ module Sinatra
|
|
116
115
|
# %body= yield
|
117
116
|
def link_headers
|
118
117
|
yield if block_given?
|
119
|
-
return
|
120
|
-
|
118
|
+
return '' unless response.include? 'Link'
|
119
|
+
|
120
|
+
response['Link'].split(",\n").map do |line|
|
121
121
|
url, *opts = line.split(';').map(&:strip)
|
122
|
-
"<link href=\"#{url[1..-2]}\" #{opts.join
|
122
|
+
"<link href=\"#{url[1..-2]}\" #{opts.join ' '} />"
|
123
123
|
end.join "\n"
|
124
124
|
end
|
125
125
|
|
126
|
-
def self.registered(
|
126
|
+
def self.registered(_base)
|
127
127
|
puts "WARNING: #{self} is a helpers module, not an extension."
|
128
128
|
end
|
129
129
|
end
|
data/lib/sinatra/multi_route.rb
CHANGED
data/lib/sinatra/namespace.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'sinatra/base'
|
2
4
|
require 'mustermann'
|
3
5
|
|
4
6
|
module Sinatra
|
5
|
-
|
6
7
|
# = Sinatra::Namespace
|
7
8
|
#
|
8
9
|
# <tt>Sinatra::Namespace</tt> is an extension that adds namespaces to an
|
@@ -187,13 +188,16 @@ module Sinatra
|
|
187
188
|
module Namespace
|
188
189
|
def self.new(base, pattern, conditions = {}, &block)
|
189
190
|
Module.new do
|
190
|
-
#quelch uninitialized variable warnings, since these get used by compile method.
|
191
|
-
@pattern
|
191
|
+
# quelch uninitialized variable warnings, since these get used by compile method.
|
192
|
+
@pattern = nil
|
193
|
+
@conditions = nil
|
192
194
|
extend NamespacedMethods
|
193
195
|
include InstanceMethods
|
194
|
-
@base
|
196
|
+
@base = base
|
197
|
+
@extensions = []
|
198
|
+
@errors = {}
|
195
199
|
@pattern, @conditions = compile(pattern, conditions)
|
196
|
-
@templates = Hash.new { |
|
200
|
+
@templates = Hash.new { |_h, k| @base.templates[k] }
|
197
201
|
namespace = self
|
198
202
|
before { extend(@namespace = namespace) }
|
199
203
|
class_eval(&block)
|
@@ -224,14 +228,14 @@ module Sinatra
|
|
224
228
|
include SharedMethods
|
225
229
|
attr_reader :base, :templates
|
226
230
|
|
227
|
-
ALLOWED_ENGINES = [
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
+
ALLOWED_ENGINES = %i[
|
232
|
+
erb erubi haml hamlit builder nokogiri
|
233
|
+
liquid markdown rdoc asciidoc markaby
|
234
|
+
rabl slim yajl
|
231
235
|
]
|
232
236
|
|
233
237
|
def self.prefixed(*names)
|
234
|
-
names.each { |n| define_method(n) { |*a, &b| prefixed(n, *a, &b) }}
|
238
|
+
names.each { |n| define_method(n) { |*a, &b| prefixed(n, *a, &b) } }
|
235
239
|
end
|
236
240
|
|
237
241
|
prefixed :before, :after, :delete, :get, :head, :options, :patch, :post, :put
|
@@ -267,7 +271,7 @@ module Sinatra
|
|
267
271
|
end
|
268
272
|
|
269
273
|
def error(*codes, &block)
|
270
|
-
args = Sinatra::Base.send(:compile!,
|
274
|
+
args = Sinatra::Base.send(:compile!, 'ERROR', /.*/, block)
|
271
275
|
codes = codes.map { |c| Array(c) }.flatten
|
272
276
|
codes << Exception if codes.empty?
|
273
277
|
codes << Sinatra::NotFound if codes.include?(404)
|
@@ -280,12 +284,14 @@ module Sinatra
|
|
280
284
|
|
281
285
|
def respond_to(*args)
|
282
286
|
return @conditions[:provides] || base.respond_to if args.empty?
|
287
|
+
|
283
288
|
@conditions[:provides] = args
|
284
289
|
end
|
285
290
|
|
286
291
|
def set(key, value = self, &block)
|
287
|
-
return key.each { |k,v| set(k, v) } if key.respond_to?(:each)
|
292
|
+
return key.each { |k, v| set(k, v) } if key.respond_to?(:each) && block.nil? && (value == self)
|
288
293
|
raise ArgumentError, "may not set #{key}" unless ([:views] + ALLOWED_ENGINES).include?(key)
|
294
|
+
|
289
295
|
block ||= proc { value }
|
290
296
|
singleton_class.send(:define_method, key, &block)
|
291
297
|
end
|
@@ -299,11 +305,13 @@ module Sinatra
|
|
299
305
|
end
|
300
306
|
|
301
307
|
def template(name, &block)
|
302
|
-
|
303
|
-
|
308
|
+
first_location = caller_locations.first
|
309
|
+
filename = first_location.path
|
310
|
+
line = first_location.lineno
|
311
|
+
templates[name] = [block, filename, line]
|
304
312
|
end
|
305
313
|
|
306
|
-
def layout(name
|
314
|
+
def layout(name = :layout, &block)
|
307
315
|
template name, &block
|
308
316
|
end
|
309
317
|
|
@@ -322,21 +330,22 @@ module Sinatra
|
|
322
330
|
conditions = conditions.merge pattern.to_hash
|
323
331
|
pattern = nil
|
324
332
|
end
|
325
|
-
base_pattern
|
333
|
+
base_pattern = @pattern
|
334
|
+
base_conditions = @conditions
|
326
335
|
pattern ||= default_pattern
|
327
|
-
[
|
328
|
-
|
336
|
+
[prefixed_path(base_pattern, pattern),
|
337
|
+
(base_conditions || {}).merge(conditions)]
|
329
338
|
end
|
330
339
|
|
331
340
|
def prefixed_path(a, b)
|
332
|
-
return a || b || /.*/ unless a
|
341
|
+
return a || b || /.*/ unless a && b
|
333
342
|
return Mustermann.new(b) if a == /.*/
|
334
343
|
|
335
344
|
Mustermann.new(a) + Mustermann.new(b)
|
336
345
|
end
|
337
346
|
|
338
347
|
def prefixed(method, pattern = nil, conditions = {}, &block)
|
339
|
-
default = %r{(?:/.*)?} if method == :before
|
348
|
+
default = %r{(?:/.*)?} if (method == :before) || (method == :after)
|
340
349
|
pattern, conditions = compile pattern, conditions, default
|
341
350
|
result = base.send(method, pattern, **conditions, &block)
|
342
351
|
invoke_hook :route_added, method.to_s.upcase, pattern, block
|
data/lib/sinatra/quiet_logger.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Sinatra
|
2
4
|
# = Sinatra::QuietLogger
|
3
5
|
#
|
@@ -32,10 +34,14 @@ module Sinatra
|
|
32
34
|
# end
|
33
35
|
#
|
34
36
|
module QuietLogger
|
35
|
-
|
36
37
|
def self.registered(app)
|
37
|
-
quiet_logger_prefixes =
|
38
|
+
quiet_logger_prefixes = begin
|
39
|
+
app.settings.quiet_logger_prefixes.join('|')
|
40
|
+
rescue StandardError
|
41
|
+
''
|
42
|
+
end
|
38
43
|
return warn('You need to specify the paths you wish to exclude from logging via `set :quiet_logger_prefixes, %w(images css fonts)`') if quiet_logger_prefixes.empty?
|
44
|
+
|
39
45
|
const_set('QUIET_LOGGER_REGEX', %r(\A/{0,2}(?:#{quiet_logger_prefixes})))
|
40
46
|
::Rack::CommonLogger.prepend(
|
41
47
|
::Module.new do
|
@@ -45,6 +51,5 @@ module Sinatra
|
|
45
51
|
end
|
46
52
|
)
|
47
53
|
end
|
48
|
-
|
49
54
|
end
|
50
55
|
end
|
data/lib/sinatra/reloader.rb
CHANGED
@@ -1,9 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'sinatra/base'
|
2
4
|
|
3
5
|
module Sinatra
|
4
|
-
|
5
6
|
# = Sinatra::Reloader
|
6
7
|
#
|
8
|
+
# <b>DEPRECATED:<b> Please consider using an alternative like
|
9
|
+
# <tt>rerun</tt> or <tt>rack-unreloader</tt> instead.
|
10
|
+
#
|
7
11
|
# Extension to reload modified files. Useful during development,
|
8
12
|
# since it will automatically require files defining routes, filters,
|
9
13
|
# error handlers and inline templates, with every incoming request,
|
@@ -94,11 +98,9 @@ module Sinatra
|
|
94
98
|
# end
|
95
99
|
#
|
96
100
|
module Reloader
|
97
|
-
|
98
101
|
# Watches a file so it can tell when it has been updated, and what
|
99
102
|
# elements does it contain.
|
100
103
|
class Watcher
|
101
|
-
|
102
104
|
# Represents an element of a Sinatra application that may need to
|
103
105
|
# be reloaded. An element could be:
|
104
106
|
# * a route
|
@@ -172,7 +174,8 @@ module Sinatra
|
|
172
174
|
# Creates a new +Watcher+ instance for the file located at +path+.
|
173
175
|
def initialize(path)
|
174
176
|
@ignore = nil
|
175
|
-
@path
|
177
|
+
@path = path
|
178
|
+
@elements = []
|
176
179
|
update
|
177
180
|
end
|
178
181
|
|
@@ -215,7 +218,7 @@ module Sinatra
|
|
215
218
|
# Allow a block to be executed after any file being reloaded
|
216
219
|
@@after_reload = []
|
217
220
|
def after_reload(&block)
|
218
|
-
@@after_reload
|
221
|
+
@@after_reload << block
|
219
222
|
end
|
220
223
|
|
221
224
|
# When the extension is registered it extends the Sinatra application
|
@@ -242,14 +245,27 @@ module Sinatra
|
|
242
245
|
# Reloads the modified files, adding, updating and removing the
|
243
246
|
# needed elements.
|
244
247
|
def self.perform(klass)
|
248
|
+
reloaded_paths = []
|
245
249
|
Watcher::List.for(klass).updated.each do |watcher|
|
246
250
|
klass.set(:inline_templates, watcher.path) if watcher.inline_templates?
|
247
251
|
watcher.elements.each { |element| klass.deactivate(element) }
|
252
|
+
# Deletes all old elements.
|
253
|
+
watcher.elements.delete_if { true }
|
248
254
|
$LOADED_FEATURES.delete(watcher.path)
|
249
255
|
require watcher.path
|
250
256
|
watcher.update
|
257
|
+
reloaded_paths << watcher.path
|
258
|
+
end
|
259
|
+
return if reloaded_paths.empty?
|
260
|
+
|
261
|
+
@@after_reload.each do |block|
|
262
|
+
block.arity.zero? ? block.call : block.call(reloaded_paths)
|
263
|
+
end
|
264
|
+
# Prevents after_reload from increasing each time it's reloaded.
|
265
|
+
@@after_reload.delete_if do |blk|
|
266
|
+
path, = blk.source_location
|
267
|
+
path && reloaded_paths.include?(path)
|
251
268
|
end
|
252
|
-
@@after_reload.each(&:call)
|
253
269
|
end
|
254
270
|
|
255
271
|
# Contains the methods defined in Sinatra::Base that are overridden.
|
@@ -274,7 +290,7 @@ module Sinatra
|
|
274
290
|
block.source_location.first : caller_files[1]
|
275
291
|
signature = super
|
276
292
|
watch_element(
|
277
|
-
source_location, :route, { :
|
293
|
+
source_location, :route, { verb: verb, signature: signature }
|
278
294
|
)
|
279
295
|
signature
|
280
296
|
end
|
@@ -283,9 +299,8 @@ module Sinatra
|
|
283
299
|
# tells the +Watcher::List+ for the Sinatra application to watch the
|
284
300
|
# inline templates in +file+ or the file who made the call to this
|
285
301
|
# method.
|
286
|
-
def inline_templates=(file=nil)
|
287
|
-
file = (file.nil? || file == true
|
288
|
-
(caller_files[1] || File.expand_path($0)) : file
|
302
|
+
def inline_templates=(file = nil)
|
303
|
+
file = (caller_files[1] || File.expand_path($0)) if file.nil? || file == true
|
289
304
|
watch_element(file, :inline_templates)
|
290
305
|
super
|
291
306
|
end
|
@@ -317,7 +332,7 @@ module Sinatra
|
|
317
332
|
path = caller_files[1] || File.expand_path($0)
|
318
333
|
result = super
|
319
334
|
codes.each do |c|
|
320
|
-
watch_element(path, :error, :
|
335
|
+
watch_element(path, :error, code: c, handler: @errors[c])
|
321
336
|
end
|
322
337
|
result
|
323
338
|
end
|
@@ -346,17 +361,17 @@ module Sinatra
|
|
346
361
|
# Removes the +element+ from the Sinatra application.
|
347
362
|
def deactivate(element)
|
348
363
|
case element.type
|
349
|
-
when :route
|
364
|
+
when :route
|
350
365
|
verb = element.representation[:verb]
|
351
366
|
signature = element.representation[:signature]
|
352
367
|
(routes[verb] ||= []).delete(signature)
|
353
|
-
when :middleware
|
368
|
+
when :middleware
|
354
369
|
@middleware.delete(element.representation)
|
355
|
-
when :before_filter
|
370
|
+
when :before_filter
|
356
371
|
filters[:before].delete(element.representation)
|
357
|
-
when :after_filter
|
372
|
+
when :after_filter
|
358
373
|
filters[:after].delete(element.representation)
|
359
|
-
when :error
|
374
|
+
when :error
|
360
375
|
code = element.representation[:code]
|
361
376
|
handler = element.representation[:handler]
|
362
377
|
@errors.delete(code) if @errors[code] == handler
|
@@ -375,7 +390,7 @@ module Sinatra
|
|
375
390
|
Dir[*glob].each { |path| Watcher::List.for(self).ignore(path) }
|
376
391
|
end
|
377
392
|
|
378
|
-
|
393
|
+
private
|
379
394
|
|
380
395
|
# attr_reader :register_path warn on -w (private attribute)
|
381
396
|
def register_path; @register_path ||= nil; end
|
@@ -403,7 +418,7 @@ module Sinatra
|
|
403
418
|
# watch it in the file where the extension has been registered.
|
404
419
|
# This prevents the duplication of the elements added by the
|
405
420
|
# extension in its +registered+ method with every reload.
|
406
|
-
def watch_element(path, type, representation=nil)
|
421
|
+
def watch_element(path, type, representation = nil)
|
407
422
|
list = Watcher::List.for(self)
|
408
423
|
element = Watcher::Element.new(type, representation)
|
409
424
|
list.watch(path, element)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'sinatra/base'
|
2
4
|
|
3
5
|
module Sinatra
|
@@ -60,7 +62,7 @@ module Sinatra
|
|
60
62
|
elsif key.is_a?(Array)
|
61
63
|
_required_params(p, *key)
|
62
64
|
else
|
63
|
-
halt 400 unless p
|
65
|
+
halt 400 unless p.respond_to?(:key?) && p&.key?(key.to_s)
|
64
66
|
end
|
65
67
|
end
|
66
68
|
true
|
data/lib/sinatra/respond_with.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'sinatra/json'
|
2
4
|
require 'sinatra/base'
|
3
5
|
|
@@ -88,14 +90,17 @@ module Sinatra
|
|
88
90
|
module RespondWith
|
89
91
|
class Format
|
90
92
|
def initialize(app)
|
91
|
-
@app
|
93
|
+
@app = app
|
94
|
+
@map = {}
|
95
|
+
@generic = {}
|
96
|
+
@default = nil
|
92
97
|
end
|
93
98
|
|
94
99
|
def on(type, &block)
|
95
100
|
@app.settings.mime_types(type).each do |mime|
|
96
101
|
case mime
|
97
102
|
when '*/*' then @default = block
|
98
|
-
when
|
103
|
+
when %r{^([^/]+)/\*$} then @generic[$1] = block
|
99
104
|
else @map[mime] = block
|
100
105
|
end
|
101
106
|
end
|
@@ -103,23 +108,24 @@ module Sinatra
|
|
103
108
|
|
104
109
|
def finish
|
105
110
|
yield self if block_given?
|
106
|
-
mime_type = @app.content_type
|
107
|
-
|
108
|
-
|
109
|
-
|
111
|
+
mime_type = @app.content_type ||
|
112
|
+
@app.request.preferred_type(@map.keys) ||
|
113
|
+
@app.request.preferred_type ||
|
114
|
+
'text/html'
|
110
115
|
type = mime_type.split(/\s*;\s*/, 2).first
|
111
|
-
handlers = [@map[type], @generic[type[
|
116
|
+
handlers = [@map[type], @generic[type[%r{^[^/]+}]], @default].compact
|
112
117
|
handlers.each do |block|
|
113
|
-
if result = block.call(type)
|
118
|
+
if (result = block.call(type))
|
114
119
|
@app.content_type mime_type
|
115
120
|
@app.halt result
|
116
121
|
end
|
117
122
|
end
|
118
|
-
@app.halt 500,
|
123
|
+
@app.halt 500, 'Unknown template engine'
|
119
124
|
end
|
120
125
|
|
121
126
|
def method_missing(method, *args, &block)
|
122
|
-
return super if args.any?
|
127
|
+
return super if args.any? || block.nil? || !@app.mime_type(method)
|
128
|
+
|
123
129
|
on(method, &block)
|
124
130
|
end
|
125
131
|
end
|
@@ -128,19 +134,22 @@ module Sinatra
|
|
128
134
|
include Sinatra::JSON
|
129
135
|
|
130
136
|
def respond_with(template, object = nil, &block)
|
131
|
-
|
137
|
+
unless Symbol === template
|
138
|
+
object = template
|
139
|
+
template = nil
|
140
|
+
end
|
132
141
|
format = Format.new(self)
|
133
|
-
format.on
|
142
|
+
format.on '*/*' do |type|
|
134
143
|
exts = settings.ext_map[type]
|
135
144
|
exts << :xml if type.end_with? '+xml'
|
136
145
|
if template
|
137
146
|
args = template_cache.fetch(type, template) { template_for(template, exts) }
|
138
147
|
if args.any?
|
139
|
-
locals = { :
|
148
|
+
locals = { object: object }
|
140
149
|
locals.merge! object.to_hash if object.respond_to? :to_hash
|
141
150
|
|
142
151
|
renderer = args.first
|
143
|
-
options = args[1
|
152
|
+
options = args[1..] + [{ locals: locals }]
|
144
153
|
|
145
154
|
halt send(renderer, *options)
|
146
155
|
end
|
@@ -149,6 +158,7 @@ module Sinatra
|
|
149
158
|
exts.each do |ext|
|
150
159
|
halt json(object) if ext == :json
|
151
160
|
next unless object.respond_to? method = "to_#{ext}"
|
161
|
+
|
152
162
|
halt(*object.send(method))
|
153
163
|
end
|
154
164
|
end
|
@@ -176,10 +186,11 @@ module Sinatra
|
|
176
186
|
|
177
187
|
possible.each do |engine, template|
|
178
188
|
klass = Tilt.default_mapping.template_map[engine.to_s] ||
|
179
|
-
|
189
|
+
Tilt.lazy_map[engine.to_s].fetch(0, [])[0]
|
180
190
|
|
181
191
|
find_template(settings.views, template, klass) do |file|
|
182
192
|
next unless File.exist? file
|
193
|
+
|
183
194
|
return settings.rendering_method(engine) << template.to_sym
|
184
195
|
end
|
185
196
|
end
|
@@ -189,7 +200,7 @@ module Sinatra
|
|
189
200
|
|
190
201
|
def remap_extensions
|
191
202
|
ext_map.clear
|
192
|
-
Rack::Mime::MIME_TYPES.each { |e,t| ext_map[t] << e[1
|
203
|
+
Rack::Mime::MIME_TYPES.each { |e, t| ext_map[t] << e[1..].to_sym }
|
193
204
|
ext_map['text/javascript'] << 'js'
|
194
205
|
ext_map['text/xml'] << 'xml'
|
195
206
|
end
|
@@ -206,7 +217,7 @@ module Sinatra
|
|
206
217
|
if formats.any?
|
207
218
|
@respond_to ||= []
|
208
219
|
@respond_to.concat formats
|
209
|
-
elsif @respond_to.nil?
|
220
|
+
elsif @respond_to.nil? && superclass.respond_to?(:respond_to)
|
210
221
|
superclass.respond_to
|
211
222
|
else
|
212
223
|
@respond_to
|
@@ -216,7 +227,8 @@ module Sinatra
|
|
216
227
|
def rendering_method(engine)
|
217
228
|
return [engine] if Sinatra::Templates.method_defined? engine
|
218
229
|
return [:mab] if engine.to_sym == :markaby
|
219
|
-
|
230
|
+
|
231
|
+
%i[render engine]
|
220
232
|
end
|
221
233
|
|
222
234
|
private
|
@@ -228,8 +240,8 @@ module Sinatra
|
|
228
240
|
|
229
241
|
def self.jrubyify(engs)
|
230
242
|
not_supported = [:markdown]
|
231
|
-
engs.
|
232
|
-
engs[key].collect! { |eng|
|
243
|
+
engs.each_key do |key|
|
244
|
+
engs[key].collect! { |eng| eng == :yajl ? :json_pure : eng }
|
233
245
|
engs[key].delete_if { |eng| not_supported.include?(eng) }
|
234
246
|
end
|
235
247
|
engs
|
@@ -237,21 +249,19 @@ module Sinatra
|
|
237
249
|
|
238
250
|
def self.engines
|
239
251
|
engines = {
|
240
|
-
:
|
241
|
-
:
|
242
|
-
|
243
|
-
:
|
244
|
-
:mab
|
245
|
-
:
|
246
|
-
[:mab] - [:find_template, :markaby]),
|
247
|
-
:json => [:yajl],
|
252
|
+
xml: %i[builder nokogiri],
|
253
|
+
html: %i[erb erubi haml hamlit slim liquid
|
254
|
+
mab markdown rdoc],
|
255
|
+
all: (Sinatra::Templates.instance_methods.map(&:to_sym) +
|
256
|
+
[:mab] - %i[find_template markaby]),
|
257
|
+
json: [:yajl]
|
248
258
|
}
|
249
259
|
engines.default = []
|
250
|
-
|
260
|
+
defined?(JRUBY_VERSION) ? jrubyify(engines) : engines
|
251
261
|
end
|
252
262
|
|
253
263
|
def self.registered(base)
|
254
|
-
base.set :ext_map, Hash.new { |h,k| h[k] = [] }
|
264
|
+
base.set :ext_map, Hash.new { |h, k| h[k] = [] }
|
255
265
|
base.set :template_engines, engines
|
256
266
|
base.remap_extensions
|
257
267
|
base.helpers Helpers
|
data/lib/sinatra/runner.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'open-uri'
|
2
4
|
require 'net/http'
|
3
5
|
require 'timeout'
|
@@ -28,7 +30,7 @@ module Sinatra
|
|
28
30
|
#
|
29
31
|
# class Runner < Sinatra::Runner
|
30
32
|
# def app_file
|
31
|
-
# File.expand_path("
|
33
|
+
# File.expand_path("server.rb", __dir__)
|
32
34
|
# end
|
33
35
|
# end
|
34
36
|
#
|
@@ -49,7 +51,7 @@ module Sinatra
|
|
49
51
|
# For an example, check https://github.com/apotonick/roar/blob/master/test/integration/runner.rb
|
50
52
|
class Runner
|
51
53
|
def app_file
|
52
|
-
File.expand_path(
|
54
|
+
File.expand_path('server.rb', __dir__)
|
53
55
|
end
|
54
56
|
|
55
57
|
def run
|
@@ -60,7 +62,8 @@ module Sinatra
|
|
60
62
|
|
61
63
|
def kill
|
62
64
|
return unless pipe
|
63
|
-
|
65
|
+
|
66
|
+
Process.kill('KILL', pipe.pid)
|
64
67
|
rescue NotImplementedError
|
65
68
|
system "kill -9 #{pipe.pid}"
|
66
69
|
rescue Errno::ESRCH
|
@@ -70,7 +73,7 @@ module Sinatra
|
|
70
73
|
Timeout.timeout(1) { get_url("#{protocol}://127.0.0.1:#{port}#{url}") }
|
71
74
|
end
|
72
75
|
|
73
|
-
def get_stream(url =
|
76
|
+
def get_stream(url = '/stream', &block)
|
74
77
|
Net::HTTP.start '127.0.0.1', port do |http|
|
75
78
|
request = Net::HTTP::Get.new url
|
76
79
|
http.request request do |response|
|
@@ -89,29 +92,32 @@ module Sinatra
|
|
89
92
|
end
|
90
93
|
|
91
94
|
def log
|
92
|
-
@log ||=
|
93
|
-
loop { @log <<
|
95
|
+
@log ||= ''
|
96
|
+
loop { @log << pipe.read_nonblock(1) }
|
94
97
|
rescue Exception
|
95
98
|
@log
|
96
99
|
end
|
97
100
|
|
98
|
-
|
101
|
+
private
|
102
|
+
|
99
103
|
attr_accessor :pipe
|
100
104
|
|
101
105
|
def start
|
102
106
|
IO.popen(command)
|
103
107
|
end
|
104
108
|
|
105
|
-
|
109
|
+
# to be overwritten
|
110
|
+
def command
|
106
111
|
"bundle exec ruby #{app_file} -p #{port} -e production"
|
107
112
|
end
|
108
113
|
|
109
|
-
def ping(timeout=30)
|
114
|
+
def ping(timeout = 30)
|
110
115
|
loop do
|
111
116
|
return if alive?
|
117
|
+
|
112
118
|
if Time.now - @started > timeout
|
113
|
-
|
114
|
-
|
119
|
+
warn command, log
|
120
|
+
raise 'timeout'
|
115
121
|
else
|
116
122
|
sleep 0.1
|
117
123
|
end
|
@@ -121,26 +127,29 @@ module Sinatra
|
|
121
127
|
def alive?
|
122
128
|
3.times { get(ping_path) }
|
123
129
|
true
|
124
|
-
rescue
|
130
|
+
rescue EOFError, SystemCallError, OpenURI::HTTPError, Timeout::Error
|
125
131
|
false
|
126
132
|
end
|
127
133
|
|
128
|
-
|
134
|
+
# to be overwritten
|
135
|
+
def ping_path
|
129
136
|
'/ping'
|
130
137
|
end
|
131
138
|
|
132
|
-
|
139
|
+
# to be overwritten
|
140
|
+
def port
|
133
141
|
4567
|
134
142
|
end
|
135
143
|
|
136
144
|
def protocol
|
137
|
-
|
145
|
+
'http'
|
138
146
|
end
|
139
147
|
|
140
148
|
def get_url(url)
|
141
149
|
uri = URI.parse(url)
|
142
150
|
|
143
|
-
return uri.read unless protocol ==
|
151
|
+
return uri.read unless protocol == 'https'
|
152
|
+
|
144
153
|
get_https_url(uri)
|
145
154
|
end
|
146
155
|
|