sinatra 2.0.0.beta2 → 2.0.0.rc1
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/CHANGELOG.md +8 -0
- data/Gemfile +4 -1
- data/LICENSE +2 -1
- data/README.de.md +640 -432
- data/README.es.md +1 -1
- data/README.hu.md +34 -0
- data/README.ja.md +86 -39
- data/README.md +407 -328
- data/README.ru.md +0 -38
- data/Rakefile +3 -2
- data/lib/sinatra/base.rb +38 -31
- data/lib/sinatra/show_exceptions.rb +55 -47
- data/lib/sinatra/version.rb +1 -1
- data/sinatra.gemspec +2 -2
- metadata +6 -7
data/README.ru.md
CHANGED
@@ -83,8 +83,6 @@
|
|
83
83
|
* [Системные требования](#Системные-требования)
|
84
84
|
* [На острие](#На-острие)
|
85
85
|
* [С помощью Bundler](#С-помощью-bundler)
|
86
|
-
* [Вручную](#Вручную)
|
87
|
-
* [Установка глобально](#Установка-глобально)
|
88
86
|
* [Версии](#Версии)
|
89
87
|
* [Дальнейшее чтение](#Дальнейшее-чтение)
|
90
88
|
|
@@ -2913,42 +2911,6 @@ Bundler автоматически скачает и добавит.
|
|
2913
2911
|
bundle exec ruby myapp.rb
|
2914
2912
|
```
|
2915
2913
|
|
2916
|
-
### Вручную
|
2917
|
-
|
2918
|
-
Создайте локальный клон репозитория и запускайте свое приложение с
|
2919
|
-
`sinatra/lib` директорией в `$LOAD_PATH`:
|
2920
|
-
|
2921
|
-
```
|
2922
|
-
cd myapp
|
2923
|
-
git clone git://github.com/sinatra/sinatra.git
|
2924
|
-
ruby -Isinatra/lib myapp.rb
|
2925
|
-
```
|
2926
|
-
|
2927
|
-
Чтобы обновить исходники Sinatra:
|
2928
|
-
|
2929
|
-
```
|
2930
|
-
cd myapp/sinatra
|
2931
|
-
git pull
|
2932
|
-
```
|
2933
|
-
|
2934
|
-
### Установка глобально
|
2935
|
-
|
2936
|
-
Вы можете самостоятельно собрать gem:
|
2937
|
-
|
2938
|
-
```
|
2939
|
-
git clone git://github.com/sinatra/sinatra.git
|
2940
|
-
cd sinatra
|
2941
|
-
rake sinatra.gemspec
|
2942
|
-
rake install
|
2943
|
-
```
|
2944
|
-
|
2945
|
-
Если вы устанавливаете пакеты (gem) от пользователя root, то вашим последним
|
2946
|
-
шагом должна быть команда
|
2947
|
-
|
2948
|
-
```
|
2949
|
-
sudo rake install
|
2950
|
-
```
|
2951
|
-
|
2952
2914
|
## Версии
|
2953
2915
|
|
2954
2916
|
Sinatra использует [Semantic Versioning](http://semver.org/), SemVer и
|
data/Rakefile
CHANGED
@@ -55,7 +55,8 @@ namespace :test do
|
|
55
55
|
desc 'Measures test coverage'
|
56
56
|
task :coverage do
|
57
57
|
rm_f "coverage"
|
58
|
-
|
58
|
+
ENV['COVERAGE'] = '1'
|
59
|
+
Rake::Task['test'].invoke
|
59
60
|
end
|
60
61
|
end
|
61
62
|
|
@@ -89,7 +90,7 @@ end
|
|
89
90
|
|
90
91
|
# Thanks in announcement ===============================================
|
91
92
|
|
92
|
-
team = ["Ryan Tomayko", "Blake Mizerany", "Simon Rozet", "Konstantin Haase"]
|
93
|
+
team = ["Ryan Tomayko", "Blake Mizerany", "Simon Rozet", "Konstantin Haase", "Zachary Scott"]
|
93
94
|
desc "list of contributors"
|
94
95
|
task :thanks, [:release,:backports] do |t, a|
|
95
96
|
a.with_defaults :release => "#{prev_version}..HEAD",
|
data/lib/sinatra/base.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# coding: utf-8
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
3
4
|
# external dependencies
|
@@ -412,7 +413,7 @@ module Sinatra
|
|
412
413
|
def close
|
413
414
|
return if closed?
|
414
415
|
@closed = true
|
415
|
-
@scheduler.schedule { @callbacks.each { |c| c.call }}
|
416
|
+
@scheduler.schedule { @callbacks.each { |c| c.call } }
|
416
417
|
end
|
417
418
|
|
418
419
|
def each(&front)
|
@@ -469,8 +470,8 @@ module Sinatra
|
|
469
470
|
def cache_control(*values)
|
470
471
|
if values.last.kind_of?(Hash)
|
471
472
|
hash = values.pop
|
472
|
-
hash.reject! { |k,v| v == false }
|
473
|
-
hash.reject! { |k,v| values << k if v == true }
|
473
|
+
hash.reject! { |k, v| v == false }
|
474
|
+
hash.reject! { |k, v| values << k if v == true }
|
474
475
|
else
|
475
476
|
hash = {}
|
476
477
|
end
|
@@ -603,16 +604,16 @@ module Sinatra
|
|
603
604
|
status.between? 500, 599
|
604
605
|
end
|
605
606
|
|
606
|
-
# whether or not the status is set to 400
|
607
|
-
def bad_request?
|
608
|
-
status == 400
|
609
|
-
end
|
610
|
-
|
611
607
|
# whether or not the status is set to 404
|
612
608
|
def not_found?
|
613
609
|
status == 404
|
614
610
|
end
|
615
611
|
|
612
|
+
# whether or not the status is set to 400
|
613
|
+
def bad_request?
|
614
|
+
status == 400
|
615
|
+
end
|
616
|
+
|
616
617
|
# Generates a Time object from the given value.
|
617
618
|
# Used by #expires and #last_modified.
|
618
619
|
def time_for(value)
|
@@ -705,7 +706,7 @@ module Sinatra
|
|
705
706
|
render :less, template, options, locals
|
706
707
|
end
|
707
708
|
|
708
|
-
def stylus(template, options={}, locals={})
|
709
|
+
def stylus(template, options = {}, locals = {})
|
709
710
|
options.merge! :layout => false, :default_content_type => :css
|
710
711
|
render :styl, template, options, locals
|
711
712
|
end
|
@@ -807,7 +808,7 @@ module Sinatra
|
|
807
808
|
|
808
809
|
def render(engine, data, options = {}, locals = {}, &block)
|
809
810
|
# merge app-level options
|
810
|
-
engine_options
|
811
|
+
engine_options = settings.respond_to?(engine) ? settings.send(engine) : {}
|
811
812
|
options.merge!(engine_options) { |key, v1, v2| v1 }
|
812
813
|
|
813
814
|
# extract generic options
|
@@ -1081,15 +1082,15 @@ module Sinatra
|
|
1081
1082
|
|
1082
1083
|
# Creates a Hash with indifferent access.
|
1083
1084
|
def indifferent_hash
|
1084
|
-
Hash.new {|hash,key| hash[key.to_s] if Symbol === key }
|
1085
|
+
Hash.new { |hash, key| hash[key.to_s] if Symbol === key }
|
1085
1086
|
end
|
1086
1087
|
|
1087
1088
|
# Run the block with 'throw :halt' support and apply result to the response.
|
1088
1089
|
def invoke
|
1089
1090
|
res = catch(:halt) { yield }
|
1090
1091
|
|
1091
|
-
res = [res] if
|
1092
|
-
if Array === res and
|
1092
|
+
res = [res] if Integer === res or String === res
|
1093
|
+
if Array === res and Integer === res.first
|
1093
1094
|
res = res.dup
|
1094
1095
|
status(res.shift)
|
1095
1096
|
body(res.pop)
|
@@ -1137,15 +1138,15 @@ module Sinatra
|
|
1137
1138
|
|
1138
1139
|
status(500) unless status.between? 400, 599
|
1139
1140
|
|
1141
|
+
boom_message = boom.message if boom.message && boom.message != boom.class.name
|
1140
1142
|
if server_error?
|
1141
1143
|
dump_errors! boom if settings.dump_errors?
|
1142
1144
|
raise boom if settings.show_exceptions? and settings.show_exceptions != :after_handler
|
1143
1145
|
elsif not_found?
|
1144
1146
|
headers['X-Cascade'] = 'pass' if settings.x_cascade?
|
1145
|
-
body '<h1>Not Found</h1>'
|
1147
|
+
body boom_message || '<h1>Not Found</h1>'
|
1146
1148
|
elsif bad_request?
|
1147
|
-
|
1148
|
-
halt status
|
1149
|
+
body boom_message || '<h1>Bad Request</h1>'
|
1149
1150
|
end
|
1150
1151
|
|
1151
1152
|
res = error_block!(boom.class, boom) || error_block!(status, boom)
|
@@ -1207,7 +1208,7 @@ module Sinatra
|
|
1207
1208
|
@extensions = []
|
1208
1209
|
|
1209
1210
|
if superclass.respond_to?(:templates)
|
1210
|
-
@templates = Hash.new { |hash,key| superclass.templates[key] }
|
1211
|
+
@templates = Hash.new { |hash, key| superclass.templates[key] }
|
1211
1212
|
else
|
1212
1213
|
@templates = {}
|
1213
1214
|
end
|
@@ -1253,7 +1254,7 @@ module Sinatra
|
|
1253
1254
|
case value
|
1254
1255
|
when Proc
|
1255
1256
|
getter = value
|
1256
|
-
when Symbol,
|
1257
|
+
when Symbol, Integer, FalseClass, TrueClass, NilClass
|
1257
1258
|
getter = value.inspect
|
1258
1259
|
when Hash
|
1259
1260
|
setter = proc do |val|
|
@@ -1283,7 +1284,7 @@ module Sinatra
|
|
1283
1284
|
# handled.
|
1284
1285
|
def error(*codes, &block)
|
1285
1286
|
args = compile! "ERROR", /.*/, block
|
1286
|
-
codes = codes.
|
1287
|
+
codes = codes.flat_map(&method(:Array))
|
1287
1288
|
codes << Exception if codes.empty?
|
1288
1289
|
codes << Sinatra::NotFound if codes.include?(404)
|
1289
1290
|
codes.each { |c| (@errors[c] ||= []) << args }
|
@@ -1532,6 +1533,10 @@ module Sinatra
|
|
1532
1533
|
|
1533
1534
|
# Starts the server by running the Rack Handler.
|
1534
1535
|
def start_server(handler, server_settings, handler_name)
|
1536
|
+
# Ensure we initialize middleware before startup, to match standard Rack
|
1537
|
+
# behavior, by ensuring an instance exists:
|
1538
|
+
prototype
|
1539
|
+
# Run the instance we created:
|
1535
1540
|
handler.run(self, server_settings) do |server|
|
1536
1541
|
unless supress_messages?
|
1537
1542
|
$stderr.puts "== Sinatra (v#{Sinatra::VERSION}) has taken the stage on #{port} for #{environment} with backup from #{handler_name}"
|
@@ -1610,8 +1615,6 @@ module Sinatra
|
|
1610
1615
|
end
|
1611
1616
|
|
1612
1617
|
def route(verb, path, options = {}, &block)
|
1613
|
-
# Because of self.options.host
|
1614
|
-
host_name(options.delete(:host)) if options.key?(:host)
|
1615
1618
|
enable :empty_path_info if path == "" and empty_path_info.nil?
|
1616
1619
|
signature = compile!(verb, path, block, options)
|
1617
1620
|
(@routes[verb] ||= []) << signature
|
@@ -1624,7 +1627,6 @@ module Sinatra
|
|
1624
1627
|
end
|
1625
1628
|
|
1626
1629
|
def generate_method(method_name, &block)
|
1627
|
-
method_name = method_name.to_sym
|
1628
1630
|
define_method(method_name, &block)
|
1629
1631
|
method = instance_method method_name
|
1630
1632
|
remove_method method_name
|
@@ -1632,21 +1634,26 @@ module Sinatra
|
|
1632
1634
|
end
|
1633
1635
|
|
1634
1636
|
def compile!(verb, path, block, **options)
|
1637
|
+
# Because of self.options.host
|
1638
|
+
host_name(options.delete(:host)) if options.key?(:host)
|
1639
|
+
# Pass Mustermann opts to compile()
|
1640
|
+
route_mustermann_opts = options.key?(:mustermann_opts) ? options.delete(:mustermann_opts) : {}.freeze
|
1641
|
+
|
1635
1642
|
options.each_pair { |option, args| send(option, *args) }
|
1636
1643
|
|
1637
|
-
pattern = compile(path)
|
1644
|
+
pattern = compile(path, route_mustermann_opts)
|
1638
1645
|
method_name = "#{verb} #{path}"
|
1639
1646
|
unbound_method = generate_method(method_name, &block)
|
1640
1647
|
conditions, @conditions = @conditions, []
|
1641
1648
|
wrapper = block.arity != 0 ?
|
1642
|
-
proc { |a,p| unbound_method.bind(a).call(*p) } :
|
1643
|
-
proc { |a,p| unbound_method.bind(a).call }
|
1649
|
+
proc { |a, p| unbound_method.bind(a).call(*p) } :
|
1650
|
+
proc { |a, p| unbound_method.bind(a).call }
|
1644
1651
|
|
1645
1652
|
[ pattern, conditions, wrapper ]
|
1646
1653
|
end
|
1647
1654
|
|
1648
|
-
def compile(path)
|
1649
|
-
Mustermann.new(path)
|
1655
|
+
def compile(path, route_mustermann_opts = {})
|
1656
|
+
Mustermann.new(path, mustermann_opts.merge(route_mustermann_opts))
|
1650
1657
|
end
|
1651
1658
|
|
1652
1659
|
def setup_default_middleware(builder)
|
@@ -1790,6 +1797,7 @@ module Sinatra
|
|
1790
1797
|
set :x_cascade, true
|
1791
1798
|
set :add_charset, %w[javascript xml xhtml+xml].map { |t| "application/#{t}" }
|
1792
1799
|
settings.add_charset << /^text\//
|
1800
|
+
set :mustermann_opts, {}
|
1793
1801
|
|
1794
1802
|
# explicitly generating a session secret eagerly to play nice with preforking
|
1795
1803
|
begin
|
@@ -1909,14 +1917,13 @@ module Sinatra
|
|
1909
1917
|
# top-level. Subclassing Sinatra::Base is highly recommended for
|
1910
1918
|
# modular applications.
|
1911
1919
|
class Application < Base
|
1912
|
-
set :logging, Proc.new { !
|
1920
|
+
set :logging, Proc.new { !test? }
|
1913
1921
|
set :method_override, true
|
1914
|
-
set :run, Proc.new { !
|
1915
|
-
set :session_secret, Proc.new { super() unless development? }
|
1922
|
+
set :run, Proc.new { !test? }
|
1916
1923
|
set :app_file, nil
|
1917
1924
|
|
1918
1925
|
def self.register(*extensions, &block) #:nodoc:
|
1919
|
-
added_methods = extensions.
|
1926
|
+
added_methods = extensions.flat_map(&:public_instance_methods)
|
1920
1927
|
Delegator.delegate(*added_methods)
|
1921
1928
|
super(*extensions, &block)
|
1922
1929
|
end
|
@@ -15,7 +15,7 @@ module Sinatra
|
|
15
15
|
def @@eats_errors.puts(*) end
|
16
16
|
|
17
17
|
def initialize(app)
|
18
|
-
@app
|
18
|
+
@app = app
|
19
19
|
end
|
20
20
|
|
21
21
|
def call(env)
|
@@ -49,16 +49,20 @@ module Sinatra
|
|
49
49
|
|
50
50
|
private
|
51
51
|
|
52
|
+
def bad_request?(e)
|
53
|
+
Sinatra::BadRequest === e
|
54
|
+
end
|
55
|
+
|
52
56
|
def prefers_plain_text?(env)
|
53
57
|
!(Request.new(env).preferred_type("text/plain","text/html") == "text/html") &&
|
54
|
-
[/curl/].index{|item| item =~ env["HTTP_USER_AGENT"]}
|
58
|
+
[/curl/].index { |item| item =~ env["HTTP_USER_AGENT"] }
|
55
59
|
end
|
56
60
|
|
57
61
|
def frame_class(frame)
|
58
|
-
if frame.filename =~ /
|
62
|
+
if frame.filename =~ %r{lib/sinatra.*\.rb}
|
59
63
|
"framework"
|
60
64
|
elsif (defined?(Gem) && frame.filename.include?(Gem.dir)) ||
|
61
|
-
frame.filename =~
|
65
|
+
frame.filename =~ %r{/bin/(\w+)\z}
|
62
66
|
"system"
|
63
67
|
else
|
64
68
|
"app"
|
@@ -210,8 +214,10 @@ TEMPLATE = ERB.new <<-HTML # :nodoc:
|
|
210
214
|
<p><a href="#" id="expando"
|
211
215
|
onclick="toggleBacktrace(); return false">(expand)</a></p>
|
212
216
|
<p id="nav"><strong>JUMP TO:</strong>
|
213
|
-
|
214
|
-
|
217
|
+
<% unless bad_request?(exception) %>
|
218
|
+
<a href="#get-info">GET</a>
|
219
|
+
<a href="#post-info">POST</a>
|
220
|
+
<% end %>
|
215
221
|
<a href="#cookie-info">COOKIES</a>
|
216
222
|
<a href="#env-info">ENV</a>
|
217
223
|
</p>
|
@@ -264,47 +270,49 @@ TEMPLATE = ERB.new <<-HTML # :nodoc:
|
|
264
270
|
</ul>
|
265
271
|
</div> <!-- /BACKTRACE -->
|
266
272
|
|
267
|
-
|
268
|
-
<
|
269
|
-
|
270
|
-
|
271
|
-
<
|
272
|
-
<
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
<
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
<
|
290
|
-
|
291
|
-
|
292
|
-
<
|
293
|
-
<
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
<
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
273
|
+
<% unless bad_request?(exception) %>
|
274
|
+
<div id="get">
|
275
|
+
<h3 id="get-info">GET</h3>
|
276
|
+
<% if req.GET and not req.GET.empty? %>
|
277
|
+
<table class="req">
|
278
|
+
<tr>
|
279
|
+
<th>Variable</th>
|
280
|
+
<th>Value</th>
|
281
|
+
</tr>
|
282
|
+
<% req.GET.sort_by { |k, v| k.to_s }.each { |key, val| %>
|
283
|
+
<tr>
|
284
|
+
<td><%=h key %></td>
|
285
|
+
<td class="code"><div><%=h val.inspect %></div></td>
|
286
|
+
</tr>
|
287
|
+
<% } %>
|
288
|
+
</table>
|
289
|
+
<% else %>
|
290
|
+
<p class="no-data">No GET data.</p>
|
291
|
+
<% end %>
|
292
|
+
<div class="clear"></div>
|
293
|
+
</div> <!-- /GET -->
|
294
|
+
|
295
|
+
<div id="post">
|
296
|
+
<h3 id="post-info">POST</h3>
|
297
|
+
<% if req.POST and not req.POST.empty? %>
|
298
|
+
<table class="req">
|
299
|
+
<tr>
|
300
|
+
<th>Variable</th>
|
301
|
+
<th>Value</th>
|
302
|
+
</tr>
|
303
|
+
<% req.POST.sort_by { |k, v| k.to_s }.each { |key, val| %>
|
304
|
+
<tr>
|
305
|
+
<td><%=h key %></td>
|
306
|
+
<td class="code"><div><%=h val.inspect %></div></td>
|
307
|
+
</tr>
|
308
|
+
<% } %>
|
309
|
+
</table>
|
310
|
+
<% else %>
|
311
|
+
<p class="no-data">No POST data.</p>
|
312
|
+
<% end %>
|
313
|
+
<div class="clear"></div>
|
314
|
+
</div> <!-- /POST -->
|
315
|
+
<% end %>
|
308
316
|
|
309
317
|
<div id="cookies">
|
310
318
|
<h3 id="cookie-info">COOKIES</h3>
|
data/lib/sinatra/version.rb
CHANGED
data/sinatra.gemspec
CHANGED
@@ -17,6 +17,6 @@ Gem::Specification.new 'sinatra', Sinatra::VERSION do |s|
|
|
17
17
|
|
18
18
|
s.add_dependency 'rack', '~> 2.0'
|
19
19
|
s.add_dependency 'tilt', '~> 2.0'
|
20
|
-
s.add_dependency 'rack-protection', '2.0.0.
|
21
|
-
s.add_dependency 'mustermann', '1.0.0
|
20
|
+
s.add_dependency 'rack-protection', '2.0.0.rc1'
|
21
|
+
s.add_dependency 'mustermann', '1.0.0'
|
22
22
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sinatra
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.0.
|
4
|
+
version: 2.0.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Blake Mizerany
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date:
|
14
|
+
date: 2017-03-04 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: rack
|
@@ -47,28 +47,28 @@ dependencies:
|
|
47
47
|
requirements:
|
48
48
|
- - '='
|
49
49
|
- !ruby/object:Gem::Version
|
50
|
-
version: 2.0.0.
|
50
|
+
version: 2.0.0.rc1
|
51
51
|
type: :runtime
|
52
52
|
prerelease: false
|
53
53
|
version_requirements: !ruby/object:Gem::Requirement
|
54
54
|
requirements:
|
55
55
|
- - '='
|
56
56
|
- !ruby/object:Gem::Version
|
57
|
-
version: 2.0.0.
|
57
|
+
version: 2.0.0.rc1
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: mustermann
|
60
60
|
requirement: !ruby/object:Gem::Requirement
|
61
61
|
requirements:
|
62
62
|
- - '='
|
63
63
|
- !ruby/object:Gem::Version
|
64
|
-
version: 1.0.0
|
64
|
+
version: 1.0.0
|
65
65
|
type: :runtime
|
66
66
|
prerelease: false
|
67
67
|
version_requirements: !ruby/object:Gem::Requirement
|
68
68
|
requirements:
|
69
69
|
- - '='
|
70
70
|
- !ruby/object:Gem::Version
|
71
|
-
version: 1.0.0
|
71
|
+
version: 1.0.0
|
72
72
|
description: Sinatra is a DSL for quickly creating web applications in Ruby with minimal
|
73
73
|
effort.
|
74
74
|
email: sinatrarb@googlegroups.com
|
@@ -151,4 +151,3 @@ signing_key:
|
|
151
151
|
specification_version: 4
|
152
152
|
summary: Classy web-development dressed in a DSL
|
153
153
|
test_files: []
|
154
|
-
has_rdoc:
|