sinatra 1.4.3 → 1.4.4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sinatra might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.yardopts +3 -2
- data/CHANGES +36 -1
- data/Gemfile +7 -4
- data/README.de.md +25 -25
- data/README.es.md +2 -2
- data/README.fr.md +682 -387
- data/README.hu.md +14 -14
- data/README.jp.md +82 -38
- data/README.ko.md +60 -60
- data/README.md +24 -13
- data/README.pt-br.md +18 -7
- data/README.ru.md +7 -0
- data/Rakefile +2 -0
- data/lib/sinatra/base.rb +104 -49
- data/lib/sinatra/images/404.png +0 -0
- data/lib/sinatra/images/500.png +0 -0
- data/lib/sinatra/{showexceptions.rb → show_exceptions.rb} +0 -0
- data/lib/sinatra/version.rb +1 -1
- data/test/base_test.rb +0 -1
- data/test/compile_test.rb +28 -28
- data/test/filter_test.rb +1 -1
- data/test/helpers_test.rb +11 -0
- data/test/integration/app.rb +17 -0
- data/test/integration_helper.rb +10 -1
- data/test/integration_test.rb +11 -1
- data/test/rdoc_test.rb +2 -2
- data/test/request_test.rb +19 -0
- data/test/response_test.rb +1 -1
- data/test/routing_test.rb +18 -0
- data/test/slim_test.rb +4 -4
- data/test/templates_test.rb +15 -0
- metadata +4 -4
data/README.md
CHANGED
@@ -493,12 +493,16 @@ Available Options:
|
|
493
493
|
<tt>set :rdoc, :layout_options => { :views => 'views/layouts' }</tt>
|
494
494
|
</dd>
|
495
495
|
</dl>
|
496
|
-
|
497
|
-
Templates are assumed to be located directly under the `./views` directory. To
|
498
|
-
use a different views directory:
|
499
|
-
`set :views, settings.root + '/templates'`
|
500
496
|
|
501
|
-
|
497
|
+
Templates are assumed to be located directly under the `./views` directory. To
|
498
|
+
use a different views directory:
|
499
|
+
|
500
|
+
``` ruby
|
501
|
+
set :views, settings.root + '/templates'
|
502
|
+
```
|
503
|
+
|
504
|
+
|
505
|
+
One important thing to remember is that you always have to reference templates
|
502
506
|
with symbols, even if they're in a subdirectory (in this case, use:
|
503
507
|
`:'subdir/template'` or `'subdir/template'.to_sym`). You must use a symbol
|
504
508
|
because otherwise rendering methods will render any strings passed to them
|
@@ -1299,6 +1303,13 @@ the `sessions` setting:
|
|
1299
1303
|
set :sessions, :domain => 'foo.com'
|
1300
1304
|
```
|
1301
1305
|
|
1306
|
+
To share your session across other apps on subdomains of foo.com, prefix the
|
1307
|
+
domain with a *.* like this instead:
|
1308
|
+
|
1309
|
+
``` ruby
|
1310
|
+
set :sessions, :domain => '.foo.com'
|
1311
|
+
```
|
1312
|
+
|
1302
1313
|
### Halting
|
1303
1314
|
|
1304
1315
|
To immediately stop a request within a filter or route use:
|
@@ -1540,7 +1551,7 @@ end
|
|
1540
1551
|
For generating URLs you should use the `url` helper method, for instance, in
|
1541
1552
|
Haml:
|
1542
1553
|
|
1543
|
-
```
|
1554
|
+
``` ruby
|
1544
1555
|
%a{:href => url('/foo')} foo
|
1545
1556
|
```
|
1546
1557
|
|
@@ -1933,8 +1944,7 @@ configure :production do
|
|
1933
1944
|
end
|
1934
1945
|
```
|
1935
1946
|
|
1936
|
-
Run when the environment is set to either `:production` or
|
1937
|
-
`:test`:
|
1947
|
+
Run when the environment is set to either `:production` or `:test`:
|
1938
1948
|
|
1939
1949
|
```ruby
|
1940
1950
|
configure :production, :test do
|
@@ -1981,7 +1991,8 @@ set :protection, :except => [:path_traversal, :session_hijacking]
|
|
1981
1991
|
|
1982
1992
|
By default, Sinatra will only set up session based protection if `:sessions`
|
1983
1993
|
has been enabled. Sometimes you want to set up sessions on your own, though. In
|
1984
|
-
that case you can get it to set up session based protections by passing the
|
1994
|
+
that case you can get it to set up session based protections by passing the
|
1995
|
+
`:session` option:
|
1985
1996
|
|
1986
1997
|
``` ruby
|
1987
1998
|
use Rack::Session::Pool
|
@@ -2459,7 +2470,7 @@ end
|
|
2459
2470
|
|
2460
2471
|
Start with:
|
2461
2472
|
|
2462
|
-
```
|
2473
|
+
``` shell
|
2463
2474
|
ruby my_app.rb
|
2464
2475
|
```
|
2465
2476
|
|
@@ -2473,7 +2484,7 @@ run MyApp
|
|
2473
2484
|
|
2474
2485
|
Run:
|
2475
2486
|
|
2476
|
-
```
|
2487
|
+
``` shell
|
2477
2488
|
rackup -p 4567
|
2478
2489
|
```
|
2479
2490
|
|
@@ -2689,7 +2700,7 @@ being [extending the main object](https://github.com/sinatra/sinatra/blob/ca0636
|
|
2689
2700
|
|
2690
2701
|
Sinatra applications can be run directly:
|
2691
2702
|
|
2692
|
-
```
|
2703
|
+
``` shell
|
2693
2704
|
ruby myapp.rb [-h] [-x] [-e ENVIRONMENT] [-p PORT] [-o HOST] [-s HANDLER]
|
2694
2705
|
```
|
2695
2706
|
|
@@ -2737,7 +2748,7 @@ The following Ruby versions are officially supported:
|
|
2737
2748
|
|
2738
2749
|
<dt>Rubinius</dt>
|
2739
2750
|
<dd>
|
2740
|
-
Rubinius is officially supported (Rubinius >= 2.x). It is
|
2751
|
+
Rubinius is officially supported (Rubinius >= 2.x). It is recommended to
|
2741
2752
|
<tt>gem install puma</tt>.
|
2742
2753
|
</dd>
|
2743
2754
|
|
data/README.pt-br.md
CHANGED
@@ -3,12 +3,17 @@
|
|
3
3
|
*Atenção: Este documento é apenas uma tradução da versão em inglês e
|
4
4
|
pode estar desatualizado.*
|
5
5
|
|
6
|
-
|
7
|
-
|
6
|
+
Alguns dos trechos de códigos a seguir utilizam caracteres UTF-8, então caso esteja utilizando uma versão de ruby inferior a `2.0.0` adicione o enconding no início de seus arquivos:
|
7
|
+
|
8
|
+
```ruby
|
9
|
+
# encoding: utf-8
|
10
|
+
```
|
11
|
+
|
12
|
+
Sinatra é uma [DSL](http://pt.wikipedia.org/wiki/Linguagem_de_domínio_específico) para
|
8
13
|
criar aplicações web em Ruby com o mínimo de esforço e rapidez:
|
9
14
|
|
10
15
|
``` ruby
|
11
|
-
#
|
16
|
+
# minha_app.rb
|
12
17
|
require 'sinatra'
|
13
18
|
|
14
19
|
get '/' do
|
@@ -16,18 +21,24 @@ get '/' do
|
|
16
21
|
end
|
17
22
|
```
|
18
23
|
|
19
|
-
Instale a gem
|
24
|
+
Instale a gem:
|
20
25
|
|
21
26
|
``` shell
|
22
27
|
gem install sinatra
|
23
|
-
ruby minhaapp.rb
|
24
28
|
```
|
25
29
|
|
26
|
-
|
30
|
+
Em seguida execute:
|
31
|
+
|
32
|
+
``` shell
|
33
|
+
ruby minha_app.rb
|
34
|
+
```
|
35
|
+
|
36
|
+
Acesse: [localhost:4567](http://localhost:4567)
|
27
37
|
|
28
|
-
|
38
|
+
É recomendado também executar `gem install thin`. Caso esta gem esteja disponível, o
|
29
39
|
Sinatra irá utilizá-la.
|
30
40
|
|
41
|
+
|
31
42
|
## Rotas
|
32
43
|
|
33
44
|
No Sinatra, uma rota é um método HTTP emparelhado com um padrão de URL.
|
data/README.ru.md
CHANGED
@@ -1187,6 +1187,13 @@ set :session_secret, 'super secret'
|
|
1187
1187
|
set :sessions, :domain => 'foo.com'
|
1188
1188
|
```
|
1189
1189
|
|
1190
|
+
Чтобы сделать сессию доступной другим приложениям, размещенным на поддоменах
|
1191
|
+
foo.com, добавьте *.* перед доменом:
|
1192
|
+
|
1193
|
+
``` ruby
|
1194
|
+
set :sessions, :domain => '.foo.com'
|
1195
|
+
```
|
1196
|
+
|
1190
1197
|
### Прерывание
|
1191
1198
|
|
1192
1199
|
Чтобы незамедлительно прервать обработку запроса внутри фильтра или маршрута,
|
data/Rakefile
CHANGED
@@ -41,6 +41,7 @@ Rake::TestTask.new(:test) do |t|
|
|
41
41
|
t.test_files = FileList['test/*_test.rb']
|
42
42
|
t.ruby_opts = ['-rubygems'] if defined? Gem
|
43
43
|
t.ruby_opts << '-I.'
|
44
|
+
t.warning = true
|
44
45
|
end
|
45
46
|
|
46
47
|
Rake::TestTask.new(:"test:core") do |t|
|
@@ -51,6 +52,7 @@ Rake::TestTask.new(:"test:core") do |t|
|
|
51
52
|
t.test_files = core_tests.map {|n| "test/#{n}_test.rb"}
|
52
53
|
t.ruby_opts = ["-rubygems"] if defined? Gem
|
53
54
|
t.ruby_opts << "-I."
|
55
|
+
t.warning = true
|
54
56
|
end
|
55
57
|
|
56
58
|
# Rcov ================================================================
|
data/lib/sinatra/base.rb
CHANGED
@@ -9,7 +9,7 @@ require 'time'
|
|
9
9
|
require 'uri'
|
10
10
|
|
11
11
|
# other files we need
|
12
|
-
require 'sinatra/
|
12
|
+
require 'sinatra/show_exceptions'
|
13
13
|
require 'sinatra/version'
|
14
14
|
|
15
15
|
module Sinatra
|
@@ -22,13 +22,17 @@ module Sinatra
|
|
22
22
|
# Returns an array of acceptable media types for the response
|
23
23
|
def accept
|
24
24
|
@env['sinatra.accept'] ||= begin
|
25
|
-
|
26
|
-
|
25
|
+
if @env.include? 'HTTP_ACCEPT' and @env['HTTP_ACCEPT'].to_s != ''
|
26
|
+
@env['HTTP_ACCEPT'].to_s.scan(HEADER_VALUE_WITH_PARAMS).
|
27
|
+
map! { |e| AcceptEntry.new(e) }.sort
|
28
|
+
else
|
29
|
+
[AcceptEntry.new('*/*')]
|
30
|
+
end
|
27
31
|
end
|
28
32
|
end
|
29
33
|
|
30
34
|
def accept?(type)
|
31
|
-
preferred_type.include?(type)
|
35
|
+
preferred_type(type).include?(type)
|
32
36
|
end
|
33
37
|
|
34
38
|
def preferred_type(*types)
|
@@ -70,7 +74,7 @@ module Sinatra
|
|
70
74
|
attr_accessor :params
|
71
75
|
|
72
76
|
def initialize(entry)
|
73
|
-
params = entry.scan(HEADER_PARAM).map do |s|
|
77
|
+
params = entry.scan(HEADER_PARAM).map! do |s|
|
74
78
|
key, value = s.strip.split('=', 2)
|
75
79
|
value = value[1..-2].gsub(/\\(.)/, '\1') if value.start_with?('"')
|
76
80
|
[key, value]
|
@@ -79,7 +83,7 @@ module Sinatra
|
|
79
83
|
@entry = entry
|
80
84
|
@type = entry[/[^;]+/].delete(' ')
|
81
85
|
@params = Hash[params]
|
82
|
-
@q = @params.delete('q') {
|
86
|
+
@q = @params.delete('q') { 1.0 }.to_f
|
83
87
|
end
|
84
88
|
|
85
89
|
def <=>(other)
|
@@ -114,6 +118,7 @@ module Sinatra
|
|
114
118
|
# http://rack.rubyforge.org/doc/classes/Rack/Response.html
|
115
119
|
# http://rack.rubyforge.org/doc/classes/Rack/Response/Helpers.html
|
116
120
|
class Response < Rack::Response
|
121
|
+
DROP_BODY_RESPONSES = [204, 205, 304]
|
117
122
|
def initialize(*)
|
118
123
|
super
|
119
124
|
headers['Content-Type'] ||= 'text/html'
|
@@ -161,7 +166,7 @@ module Sinatra
|
|
161
166
|
end
|
162
167
|
|
163
168
|
def drop_body?
|
164
|
-
|
169
|
+
DROP_BODY_RESPONSES.include?(status.to_i)
|
165
170
|
end
|
166
171
|
end
|
167
172
|
|
@@ -233,7 +238,7 @@ module Sinatra
|
|
233
238
|
def block.each; yield(call) end
|
234
239
|
response.body = block
|
235
240
|
elsif value
|
236
|
-
headers.delete 'Content-Length' unless request.head?
|
241
|
+
headers.delete 'Content-Length' unless request.head? || value.is_a?(Rack::File) || value.is_a?(Stream)
|
237
242
|
response.body = value
|
238
243
|
else
|
239
244
|
response.body
|
@@ -361,6 +366,7 @@ module Sinatra
|
|
361
366
|
result = file.serving env
|
362
367
|
result[1].each { |k,v| headers[k] ||= v }
|
363
368
|
headers['Content-Length'] = result[1]['Content-Length']
|
369
|
+
opts[:status] &&= Integer(opts[:status])
|
364
370
|
halt opts[:status] || result[0], result[2]
|
365
371
|
rescue Errno::ENOENT
|
366
372
|
not_found
|
@@ -453,7 +459,7 @@ module Sinatra
|
|
453
459
|
hash.each do |key, value|
|
454
460
|
key = key.to_s.tr('_', '-')
|
455
461
|
value = value.to_i if key == "max-age"
|
456
|
-
values <<
|
462
|
+
values << "#{key}=#{value}"
|
457
463
|
end
|
458
464
|
|
459
465
|
response['Cache-Control'] = values.join(', ') if values.any?
|
@@ -512,6 +518,7 @@ module Sinatra
|
|
512
518
|
rescue ArgumentError
|
513
519
|
end
|
514
520
|
|
521
|
+
ETAG_KINDS = [:strong, :weak]
|
515
522
|
# Set the response entity tag (HTTP 'ETag' header) and halt if conditional
|
516
523
|
# GET matches. The +value+ argument is an identifier that uniquely
|
517
524
|
# identifies the current version of the resource. The +kind+ argument
|
@@ -527,12 +534,12 @@ module Sinatra
|
|
527
534
|
kind = options[:kind] || :strong
|
528
535
|
new_resource = options.fetch(:new_resource) { request.post? }
|
529
536
|
|
530
|
-
unless
|
537
|
+
unless ETAG_KINDS.include?(kind)
|
531
538
|
raise ArgumentError, ":strong or :weak expected"
|
532
539
|
end
|
533
540
|
|
534
541
|
value = '"%s"' % value
|
535
|
-
value =
|
542
|
+
value = "W/#{value}" if kind == :weak
|
536
543
|
response['ETag'] = value
|
537
544
|
|
538
545
|
if success? or status == 304
|
@@ -770,7 +777,7 @@ module Sinatra
|
|
770
777
|
def render(engine, data, options = {}, locals = {}, &block)
|
771
778
|
# merge app-level options
|
772
779
|
engine_options = settings.respond_to?(engine) ? settings.send(engine) : {}
|
773
|
-
options
|
780
|
+
options.merge!(engine_options) { |key, v1, v2| v1 }
|
774
781
|
|
775
782
|
# extract generic options
|
776
783
|
locals = options.delete(:locals) || locals || {}
|
@@ -778,7 +785,7 @@ module Sinatra
|
|
778
785
|
layout = options[:layout]
|
779
786
|
layout = false if layout.nil? && options.include?(:layout)
|
780
787
|
eat_errors = layout.nil?
|
781
|
-
layout = engine_options[:layout] if layout.nil? or layout == true
|
788
|
+
layout = engine_options[:layout] if layout.nil? or (layout == true && engine_options[:layout] != false)
|
782
789
|
layout = @default_layout if layout.nil? or layout == true
|
783
790
|
layout_options = options.delete(:layout_options) || {}
|
784
791
|
content_type = options.delete(:content_type) || options.delete(:default_content_type)
|
@@ -802,8 +809,8 @@ module Sinatra
|
|
802
809
|
|
803
810
|
# render layout
|
804
811
|
if layout
|
805
|
-
options
|
806
|
-
|
812
|
+
options.merge!(:views => views, :layout => false, :eat_errors => eat_errors, :scope => scope).
|
813
|
+
merge!(layout_options)
|
807
814
|
catch(:layout_missing) { return render(layout_engine, layout, options, locals) { output } }
|
808
815
|
end
|
809
816
|
|
@@ -853,7 +860,7 @@ module Sinatra
|
|
853
860
|
include Helpers
|
854
861
|
include Templates
|
855
862
|
|
856
|
-
|
863
|
+
URI_INSTANCE = URI.const_defined?(:Parser) ? URI::Parser.new : URI
|
857
864
|
|
858
865
|
attr_accessor :app, :env, :request, :response, :params
|
859
866
|
attr_reader :template_cache
|
@@ -945,10 +952,13 @@ module Sinatra
|
|
945
952
|
def route!(base = settings, pass_block = nil)
|
946
953
|
if routes = base.routes[@request.request_method]
|
947
954
|
routes.each do |pattern, keys, conditions, block|
|
948
|
-
|
955
|
+
returned_pass_block = process_route(pattern, keys, conditions) do |*args|
|
949
956
|
env['sinatra.route'] = block.instance_variable_get(:@route_name)
|
950
957
|
route_eval { block[*args] }
|
951
958
|
end
|
959
|
+
|
960
|
+
# don't wipe out pass_block in superclass
|
961
|
+
pass_block = returned_pass_block if returned_pass_block
|
952
962
|
end
|
953
963
|
end
|
954
964
|
|
@@ -975,7 +985,7 @@ module Sinatra
|
|
975
985
|
route = @request.path_info
|
976
986
|
route = '/' if route.empty? and not settings.empty_path_info?
|
977
987
|
return unless match = pattern.match(route)
|
978
|
-
values += match.captures.
|
988
|
+
values += match.captures.map! { |v| force_encoding URI_INSTANCE.unescape(v) if v }
|
979
989
|
|
980
990
|
if values.any?
|
981
991
|
original, @params = params, params.merge('splat' => [], 'captures' => values)
|
@@ -1007,10 +1017,8 @@ module Sinatra
|
|
1007
1017
|
# a matching file is found, returns nil otherwise.
|
1008
1018
|
def static!
|
1009
1019
|
return if (public_dir = settings.public_folder).nil?
|
1010
|
-
|
1011
|
-
|
1012
|
-
path = File.expand_path(public_dir + unescape(request.path_info))
|
1013
|
-
return unless path.start_with?(public_dir) and File.file?(path)
|
1020
|
+
path = File.expand_path("#{public_dir}#{unescape(request.path_info)}" )
|
1021
|
+
return unless File.file?(path)
|
1014
1022
|
|
1015
1023
|
env['sinatra.static_file'] = path
|
1016
1024
|
cache_control(*settings.static_cache_control) if settings.static_cache_control?
|
@@ -1326,7 +1334,7 @@ module Sinatra
|
|
1326
1334
|
end
|
1327
1335
|
|
1328
1336
|
def public=(value)
|
1329
|
-
warn ":public is no longer used to avoid overloading Module#public, use :public_dir instead"
|
1337
|
+
warn ":public is no longer used to avoid overloading Module#public, use :public_folder or :public_dir instead"
|
1330
1338
|
set(:public_folder, value)
|
1331
1339
|
end
|
1332
1340
|
|
@@ -1381,7 +1389,7 @@ module Sinatra
|
|
1381
1389
|
|
1382
1390
|
# Set configuration options for Sinatra and/or the app.
|
1383
1391
|
# Allows scoping of settings for certain environments.
|
1384
|
-
def configure(*envs
|
1392
|
+
def configure(*envs)
|
1385
1393
|
yield self if envs.empty? || envs.include?(environment.to_sym)
|
1386
1394
|
end
|
1387
1395
|
|
@@ -1391,32 +1399,44 @@ module Sinatra
|
|
1391
1399
|
@middleware << [middleware, args, block]
|
1392
1400
|
end
|
1393
1401
|
|
1394
|
-
|
1402
|
+
# Stop the self-hosted server if running.
|
1403
|
+
def quit!
|
1404
|
+
return unless running?
|
1395
1405
|
# Use Thin's hard #stop! if available, otherwise just #stop.
|
1396
|
-
|
1397
|
-
$stderr.puts "
|
1406
|
+
running_server.respond_to?(:stop!) ? running_server.stop! : running_server.stop
|
1407
|
+
$stderr.puts "== Sinatra has ended his set (crowd applauds)" unless handler_name =~/cgi/i
|
1408
|
+
set :running_server, nil
|
1409
|
+
set :handler_name, nil
|
1398
1410
|
end
|
1399
1411
|
|
1412
|
+
alias_method :stop!, :quit!
|
1413
|
+
|
1400
1414
|
# Run the Sinatra app as a self-hosted server using
|
1401
1415
|
# Thin, Puma, Mongrel, or WEBrick (in that order). If given a block, will call
|
1402
1416
|
# with the constructed handler once we have taken the stage.
|
1403
|
-
def run!(options = {})
|
1417
|
+
def run!(options = {}, &block)
|
1418
|
+
return if running?
|
1404
1419
|
set options
|
1405
1420
|
handler = detect_rack_handler
|
1406
1421
|
handler_name = handler.name.gsub(/.*::/, '')
|
1407
1422
|
server_settings = settings.respond_to?(:server_settings) ? settings.server_settings : {}
|
1408
|
-
|
1409
|
-
|
1410
|
-
|
1411
|
-
|
1412
|
-
|
1413
|
-
|
1414
|
-
|
1415
|
-
|
1416
|
-
|
1423
|
+
server_settings.merge!(:Port => port, :Host => bind)
|
1424
|
+
|
1425
|
+
begin
|
1426
|
+
start_server(handler, server_settings, handler_name, &block)
|
1427
|
+
rescue Errno::EADDRINUSE
|
1428
|
+
$stderr.puts "== Someone is already performing on port #{port}!"
|
1429
|
+
raise
|
1430
|
+
ensure
|
1431
|
+
quit!
|
1417
1432
|
end
|
1418
|
-
|
1419
|
-
|
1433
|
+
end
|
1434
|
+
|
1435
|
+
alias_method :start!, :run!
|
1436
|
+
|
1437
|
+
# Check whether the self-hosted server is running or not.
|
1438
|
+
def running?
|
1439
|
+
running_server?
|
1420
1440
|
end
|
1421
1441
|
|
1422
1442
|
# The prototype instance used to process requests.
|
@@ -1463,6 +1483,38 @@ module Sinatra
|
|
1463
1483
|
|
1464
1484
|
private
|
1465
1485
|
|
1486
|
+
# Starts the server by running the Rack Handler.
|
1487
|
+
def start_server(handler, server_settings, handler_name)
|
1488
|
+
handler.run(self, server_settings) do |server|
|
1489
|
+
unless handler_name =~ /cgi/i
|
1490
|
+
$stderr.puts "== Sinatra/#{Sinatra::VERSION} has taken the stage " +
|
1491
|
+
"on #{port} for #{environment} with backup from #{handler_name}"
|
1492
|
+
end
|
1493
|
+
|
1494
|
+
setup_traps
|
1495
|
+
set :running_server, server
|
1496
|
+
set :handler_name, handler_name
|
1497
|
+
server.threaded = settings.threaded if server.respond_to? :threaded=
|
1498
|
+
|
1499
|
+
yield server if block_given?
|
1500
|
+
end
|
1501
|
+
end
|
1502
|
+
|
1503
|
+
def setup_traps
|
1504
|
+
if traps?
|
1505
|
+
at_exit { quit! }
|
1506
|
+
|
1507
|
+
[:INT, :TERM].each do |signal|
|
1508
|
+
old_handler = trap(signal) do
|
1509
|
+
quit!
|
1510
|
+
old_handler.call if old_handler.respond_to?(:call)
|
1511
|
+
end
|
1512
|
+
end
|
1513
|
+
|
1514
|
+
set :traps, false
|
1515
|
+
end
|
1516
|
+
end
|
1517
|
+
|
1466
1518
|
# Dynamically defines a method on settings.
|
1467
1519
|
def define_singleton(name, content = Proc.new)
|
1468
1520
|
# replace with call to singleton_class once we're 1.9 only
|
@@ -1566,7 +1618,7 @@ module Sinatra
|
|
1566
1618
|
ignore << escaped(c).join if c.match(/[\.@]/)
|
1567
1619
|
patt = encoded(c)
|
1568
1620
|
patt.gsub(/%[\da-fA-F]{2}/) do |match|
|
1569
|
-
match.split(//).map {|char| char =~ /[A-Z]/ ? "[#{char}#{char.tr('A-Z', 'a-z')}]" : char}.join
|
1621
|
+
match.split(//).map! {|char| char =~ /[A-Z]/ ? "[#{char}#{char.tr('A-Z', 'a-z')}]" : char}.join
|
1570
1622
|
end
|
1571
1623
|
end
|
1572
1624
|
|
@@ -1611,14 +1663,14 @@ module Sinatra
|
|
1611
1663
|
end
|
1612
1664
|
|
1613
1665
|
def encoded(char)
|
1614
|
-
enc =
|
1666
|
+
enc = URI_INSTANCE.escape(char)
|
1615
1667
|
enc = "(?:#{escaped(char, enc).join('|')})" if enc == char
|
1616
1668
|
enc = "(?:#{enc}|#{encoded('+')})" if char == " "
|
1617
1669
|
enc
|
1618
1670
|
end
|
1619
1671
|
|
1620
|
-
def escaped(char, enc =
|
1621
|
-
[Regexp.escape(enc),
|
1672
|
+
def escaped(char, enc = URI_INSTANCE.escape(char))
|
1673
|
+
[Regexp.escape(enc), URI_INSTANCE.escape(char, /./)]
|
1622
1674
|
end
|
1623
1675
|
|
1624
1676
|
def safe_ignore(ignore)
|
@@ -1627,8 +1679,8 @@ module Sinatra
|
|
1627
1679
|
unsafe_ignore << hex[1..2]
|
1628
1680
|
''
|
1629
1681
|
end
|
1630
|
-
unsafe_patterns = unsafe_ignore.map do |unsafe|
|
1631
|
-
chars = unsafe.split(//).map do |char|
|
1682
|
+
unsafe_patterns = unsafe_ignore.map! do |unsafe|
|
1683
|
+
chars = unsafe.split(//).map! do |char|
|
1632
1684
|
if char =~ /[A-Z]/
|
1633
1685
|
char <<= char.tr('A-Z', 'a-z')
|
1634
1686
|
end
|
@@ -1735,7 +1787,7 @@ module Sinatra
|
|
1735
1787
|
# Like Kernel#caller but excluding certain magic entries
|
1736
1788
|
def cleaned_caller(keep = 3)
|
1737
1789
|
caller(1).
|
1738
|
-
map { |line| line.split(/:(?=\d|in )/, 3)[0,keep] }.
|
1790
|
+
map! { |line| line.split(/:(?=\d|in )/, 3)[0,keep] }.
|
1739
1791
|
reject { |file, *_| CALLERS_TO_IGNORE.any? { |pattern| file =~ pattern } }
|
1740
1792
|
end
|
1741
1793
|
end
|
@@ -1794,7 +1846,9 @@ module Sinatra
|
|
1794
1846
|
end
|
1795
1847
|
|
1796
1848
|
set :run, false # start server via at-exit hook?
|
1797
|
-
set :
|
1849
|
+
set :running_server, nil
|
1850
|
+
set :handler_name, nil
|
1851
|
+
set :traps, true
|
1798
1852
|
set :server, %w[HTTP webrick]
|
1799
1853
|
set :bind, Proc.new { development? ? 'localhost' : '0.0.0.0' }
|
1800
1854
|
set :port, Integer(ENV['PORT'] && !ENV['PORT'].empty? ? ENV['PORT'] : 4567)
|
@@ -1804,11 +1858,12 @@ module Sinatra
|
|
1804
1858
|
if ruby_engine == 'macruby'
|
1805
1859
|
server.unshift 'control_tower'
|
1806
1860
|
else
|
1861
|
+
server.unshift 'reel'
|
1807
1862
|
server.unshift 'mongrel' if ruby_engine.nil?
|
1808
1863
|
server.unshift 'puma' if ruby_engine != 'rbx'
|
1809
1864
|
server.unshift 'thin' if ruby_engine != 'jruby'
|
1810
1865
|
server.unshift 'puma' if ruby_engine == 'rbx'
|
1811
|
-
server.unshift 'trinidad' if ruby_engine =='jruby'
|
1866
|
+
server.unshift 'trinidad' if ruby_engine == 'jruby'
|
1812
1867
|
end
|
1813
1868
|
|
1814
1869
|
set :absolute_redirects, true
|
@@ -1956,7 +2011,7 @@ module Sinatra
|
|
1956
2011
|
|
1957
2012
|
# Create a new Sinatra application. The block is evaluated in the new app's
|
1958
2013
|
# class scope.
|
1959
|
-
def self.new(base = Base,
|
2014
|
+
def self.new(base = Base, &block)
|
1960
2015
|
base = Class.new(base)
|
1961
2016
|
base.class_eval(&block) if block_given?
|
1962
2017
|
base
|