sinatra 1.4.6 → 1.4.7
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/AUTHORS.md +5 -2
- data/{CHANGES → CHANGELOG.md} +17 -1
- data/CONTRIBUTING.md +100 -0
- data/LICENSE +2 -2
- data/README.de.md +78 -41
- data/README.es.md +200 -165
- data/README.fr.md +364 -338
- data/README.hu.md +7 -7
- data/README.ja.md +199 -167
- data/README.ko.md +222 -183
- data/README.md +218 -179
- data/README.pt-br.md +146 -112
- data/README.pt-pt.md +63 -63
- data/README.ru.md +158 -35
- data/README.zh.md +1941 -1235
- data/Rakefile +2 -2
- data/lib/sinatra/base.rb +16 -24
- data/lib/sinatra/ext.rb +17 -0
- data/lib/sinatra/show_exceptions.rb +13 -7
- data/lib/sinatra/version.rb +1 -1
- data/sinatra.gemspec +1 -1
- data/test/public/hello+world.txt +1 -0
- data/test/routing_test.rb +44 -0
- data/test/static_test.rb +30 -0
- metadata +9 -6
data/Rakefile
CHANGED
@@ -182,8 +182,8 @@ if defined?(Gem)
|
|
182
182
|
end
|
183
183
|
|
184
184
|
task 'release' => ['test', package('.gem')] do
|
185
|
-
if File.binread("
|
186
|
-
fail 'please update
|
185
|
+
if File.binread("CHANGELOG.md") =~ /= \d\.\d\.\d . not yet released$/i
|
186
|
+
fail 'please update the changelog first' unless %x{git symbolic-ref HEAD} == "refs/heads/prerelease\n"
|
187
187
|
end
|
188
188
|
|
189
189
|
sh <<-SH
|
data/lib/sinatra/base.rb
CHANGED
@@ -10,6 +10,7 @@ require 'uri'
|
|
10
10
|
|
11
11
|
# other files we need
|
12
12
|
require 'sinatra/show_exceptions'
|
13
|
+
require 'sinatra/ext'
|
13
14
|
require 'sinatra/version'
|
14
15
|
|
15
16
|
module Sinatra
|
@@ -1034,7 +1035,7 @@ module Sinatra
|
|
1034
1035
|
# a matching file is found, returns nil otherwise.
|
1035
1036
|
def static!(options = {})
|
1036
1037
|
return if (public_dir = settings.public_folder).nil?
|
1037
|
-
path = File.expand_path("#{public_dir}#{unescape(request.path_info)}" )
|
1038
|
+
path = File.expand_path("#{public_dir}#{URI_INSTANCE.unescape(request.path_info)}" )
|
1038
1039
|
return unless File.file?(path)
|
1039
1040
|
|
1040
1041
|
env['sinatra.static_file'] = path
|
@@ -1617,25 +1618,21 @@ module Sinatra
|
|
1617
1618
|
if path.respond_to? :to_str
|
1618
1619
|
keys = []
|
1619
1620
|
|
1620
|
-
# We append a / at the end if there was one.
|
1621
|
-
# Reason: Splitting does not split off an empty
|
1622
|
-
# string at the end if the split separator
|
1623
|
-
# is at the end.
|
1624
|
-
#
|
1625
|
-
postfix = '/' if path =~ /\/\z/
|
1626
|
-
|
1627
1621
|
# Split the path into pieces in between forward slashes.
|
1622
|
+
# A negative number is given as the second argument of path.split
|
1623
|
+
# because with this number, the method does not ignore / at the end
|
1624
|
+
# and appends an empty string at the end of the return value.
|
1628
1625
|
#
|
1629
|
-
segments = path.split('/').map! do |segment|
|
1626
|
+
segments = path.split('/', -1).map! do |segment|
|
1630
1627
|
ignore = []
|
1631
1628
|
|
1632
1629
|
# Special character handling.
|
1633
1630
|
#
|
1634
|
-
pattern = segment.to_str.gsub(/[^\?\%\\\/\:\*\w]/) do |c|
|
1631
|
+
pattern = segment.to_str.gsub(/[^\?\%\\\/\:\*\w]|:(?!\w)/) do |c|
|
1635
1632
|
ignore << escaped(c).join if c.match(/[\.@]/)
|
1636
1633
|
patt = encoded(c)
|
1637
1634
|
patt.gsub(/%[\da-fA-F]{2}/) do |match|
|
1638
|
-
match.split(//).map! {|char| char
|
1635
|
+
match.split(//).map! { |char| char == char.downcase ? char : "[#{char}#{char.downcase}]" }.join
|
1639
1636
|
end
|
1640
1637
|
end
|
1641
1638
|
|
@@ -1658,16 +1655,12 @@ module Sinatra
|
|
1658
1655
|
|
1659
1656
|
# Special case handling.
|
1660
1657
|
#
|
1661
|
-
if
|
1662
|
-
|
1663
|
-
|
1664
|
-
|
1665
|
-
segments << parts.join
|
1666
|
-
else
|
1667
|
-
segments << segment
|
1668
|
-
end
|
1658
|
+
if last_segment = segments[-1] and last_segment.match(/\[\^\\\./)
|
1659
|
+
parts = last_segment.rpartition(/\[\^\\\./)
|
1660
|
+
parts[1] = '[^'
|
1661
|
+
segments[-1] = parts.join
|
1669
1662
|
end
|
1670
|
-
[/\A#{segments.join('/')}
|
1663
|
+
[/\A#{segments.join('/')}\z/, keys]
|
1671
1664
|
elsif path.respond_to?(:keys) && path.respond_to?(:match)
|
1672
1665
|
[path, path.keys]
|
1673
1666
|
elsif path.respond_to?(:names) && path.respond_to?(:match)
|
@@ -1698,10 +1691,7 @@ module Sinatra
|
|
1698
1691
|
end
|
1699
1692
|
unsafe_patterns = unsafe_ignore.map! do |unsafe|
|
1700
1693
|
chars = unsafe.split(//).map! do |char|
|
1701
|
-
|
1702
|
-
char <<= char.tr('A-Z', 'a-z')
|
1703
|
-
end
|
1704
|
-
char
|
1694
|
+
char == char.downcase ? char : char + char.downcase
|
1705
1695
|
end
|
1706
1696
|
|
1707
1697
|
"|(?:%[^#{chars[0]}].|%[#{chars[0]}][^#{chars[1]}])"
|
@@ -1776,6 +1766,8 @@ module Sinatra
|
|
1776
1766
|
begin
|
1777
1767
|
return Rack::Handler.get(server_name.to_s)
|
1778
1768
|
rescue LoadError, NameError
|
1769
|
+
rescue ArgumentError
|
1770
|
+
Sinatra::Ext.get_handler(server_name.to_s)
|
1779
1771
|
end
|
1780
1772
|
end
|
1781
1773
|
fail "Server handler (#{servers.join(',')}) not found."
|
data/lib/sinatra/ext.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# This can be removed once rack/rack@2fd9df71 is released
|
2
|
+
module Sinatra
|
3
|
+
module Ext
|
4
|
+
def self.get_handler(str)
|
5
|
+
begin
|
6
|
+
::Object.const_get("Object", false)
|
7
|
+
def self._const_get(str, inherit = true)
|
8
|
+
Rack::Handler.const_get(str, inherit)
|
9
|
+
end
|
10
|
+
rescue
|
11
|
+
def self._const_get(str, inherit = true)
|
12
|
+
Rack::Handler.const_get(str)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -1,4 +1,8 @@
|
|
1
|
-
|
1
|
+
begin
|
2
|
+
require 'rack/show_exceptions'
|
3
|
+
rescue LoadError
|
4
|
+
require 'rack/showexceptions'
|
5
|
+
end
|
2
6
|
|
3
7
|
module Sinatra
|
4
8
|
# Sinatra::ShowExceptions catches all exceptions raised from the app it
|
@@ -24,23 +28,25 @@ module Sinatra
|
|
24
28
|
|
25
29
|
if prefers_plain_text?(env)
|
26
30
|
content_type = "text/plain"
|
27
|
-
|
31
|
+
exception = dump_exception(e)
|
28
32
|
else
|
29
33
|
content_type = "text/html"
|
30
|
-
|
34
|
+
exception = pretty(env, e)
|
31
35
|
end
|
32
36
|
|
33
37
|
env["rack.errors"] = errors
|
34
38
|
|
35
39
|
# Post 893a2c50 in rack/rack, the #pretty method above, implemented in
|
36
40
|
# Rack::ShowExceptions, returns a String instead of an array.
|
37
|
-
body = Array(
|
41
|
+
body = Array(exception)
|
38
42
|
|
39
43
|
[
|
40
44
|
500,
|
41
|
-
|
42
|
-
|
43
|
-
|
45
|
+
{
|
46
|
+
"Content-Type" => content_type,
|
47
|
+
"Content-Length" => Rack::Utils.bytesize(body.join).to_s
|
48
|
+
},
|
49
|
+
body
|
44
50
|
]
|
45
51
|
end
|
46
52
|
|
data/lib/sinatra/version.rb
CHANGED
data/sinatra.gemspec
CHANGED
@@ -13,7 +13,7 @@ Gem::Specification.new 'sinatra', Sinatra::VERSION do |s|
|
|
13
13
|
s.extra_rdoc_files = s.files.select { |p| p =~ /^README/ } << 'LICENSE'
|
14
14
|
s.rdoc_options = %w[--line-numbers --inline-source --title Sinatra --main README.rdoc --encoding=UTF-8]
|
15
15
|
|
16
|
-
s.add_dependency 'rack', '~> 1.
|
16
|
+
s.add_dependency 'rack', '~> 1.5'
|
17
17
|
s.add_dependency 'tilt', '>= 1.3', '< 3'
|
18
18
|
s.add_dependency 'rack-protection', '~> 1.4'
|
19
19
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
This is a test intended for the + sign in urls for static serving
|
data/test/routing_test.rb
CHANGED
@@ -99,6 +99,50 @@ class RoutingTest < Minitest::Test
|
|
99
99
|
assert_body "foo/bar"
|
100
100
|
end
|
101
101
|
|
102
|
+
it "it handles encoded colons correctly" do
|
103
|
+
mock_app {
|
104
|
+
get("/:") { 'a' }
|
105
|
+
get("/a/:") { 'b' }
|
106
|
+
get("/a/:/b") { 'c' }
|
107
|
+
get("/a/b:") { 'd' }
|
108
|
+
get("/a/b: ") { 'e' }
|
109
|
+
}
|
110
|
+
get '/:'
|
111
|
+
assert_equal 200, status
|
112
|
+
assert_body "a"
|
113
|
+
get '/%3a'
|
114
|
+
assert_equal 200, status
|
115
|
+
assert_body "a"
|
116
|
+
|
117
|
+
get '/a/:'
|
118
|
+
assert_equal 200, status
|
119
|
+
assert_body "b"
|
120
|
+
get '/a/%3a'
|
121
|
+
assert_equal 200, status
|
122
|
+
assert_body "b"
|
123
|
+
|
124
|
+
get '/a/:/b'
|
125
|
+
assert_equal 200, status
|
126
|
+
assert_body "c"
|
127
|
+
get '/a/%3A/b'
|
128
|
+
assert_equal 200, status
|
129
|
+
assert_body "c"
|
130
|
+
|
131
|
+
get '/a/b:'
|
132
|
+
assert_equal 200, status
|
133
|
+
assert_body "d"
|
134
|
+
get '/a/b%3a'
|
135
|
+
assert_equal 200, status
|
136
|
+
assert_body "d"
|
137
|
+
|
138
|
+
get '/a/b%3a%20'
|
139
|
+
assert_equal 200, status
|
140
|
+
assert_body "e"
|
141
|
+
get '/a/b%3a+'
|
142
|
+
assert_equal 200, status
|
143
|
+
assert_body "e"
|
144
|
+
end
|
145
|
+
|
102
146
|
it "overrides the content-type in error handlers" do
|
103
147
|
mock_app {
|
104
148
|
before { content_type 'text/plain' }
|
data/test/static_test.rb
CHANGED
@@ -233,4 +233,34 @@ class StaticTest < Minitest::Test
|
|
233
233
|
assert response.headers.include?('Last-Modified')
|
234
234
|
end
|
235
235
|
|
236
|
+
it 'serves files with a + sign in the path' do
|
237
|
+
mock_app do
|
238
|
+
set :static, true
|
239
|
+
set :public_folder, File.join(File.dirname(__FILE__), 'public')
|
240
|
+
end
|
241
|
+
|
242
|
+
get "/hello+world.txt"
|
243
|
+
|
244
|
+
real_path = File.join(File.dirname(__FILE__), 'public', 'hello+world.txt')
|
245
|
+
assert ok?
|
246
|
+
assert_equal File.read(real_path), body
|
247
|
+
assert_equal File.size(real_path).to_s, response['Content-Length']
|
248
|
+
assert response.headers.include?('Last-Modified')
|
249
|
+
end
|
250
|
+
|
251
|
+
it 'serves files with a URL encoded + sign (%2B) in the path' do
|
252
|
+
mock_app do
|
253
|
+
set :static, true
|
254
|
+
set :public_folder, File.join(File.dirname(__FILE__), 'public')
|
255
|
+
end
|
256
|
+
|
257
|
+
get "/hello%2bworld.txt"
|
258
|
+
|
259
|
+
real_path = File.join(File.dirname(__FILE__), 'public', 'hello+world.txt')
|
260
|
+
assert ok?
|
261
|
+
assert_equal File.read(real_path), body
|
262
|
+
assert_equal File.size(real_path).to_s, response['Content-Length']
|
263
|
+
assert response.headers.include?('Last-Modified')
|
264
|
+
end
|
265
|
+
|
236
266
|
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: 1.4.
|
4
|
+
version: 1.4.7
|
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: 2016-01-24 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: rack
|
@@ -19,14 +19,14 @@ dependencies:
|
|
19
19
|
requirements:
|
20
20
|
- - "~>"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '1.
|
22
|
+
version: '1.5'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - "~>"
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: '1.
|
29
|
+
version: '1.5'
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
31
|
name: tilt
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
@@ -82,7 +82,8 @@ extra_rdoc_files:
|
|
82
82
|
files:
|
83
83
|
- ".yardopts"
|
84
84
|
- AUTHORS.md
|
85
|
-
-
|
85
|
+
- CHANGELOG.md
|
86
|
+
- CONTRIBUTING.md
|
86
87
|
- Gemfile
|
87
88
|
- LICENSE
|
88
89
|
- README.de.md
|
@@ -102,6 +103,7 @@ files:
|
|
102
103
|
- examples/stream.ru
|
103
104
|
- lib/sinatra.rb
|
104
105
|
- lib/sinatra/base.rb
|
106
|
+
- lib/sinatra/ext.rb
|
105
107
|
- lib/sinatra/images/404.png
|
106
108
|
- lib/sinatra/images/500.png
|
107
109
|
- lib/sinatra/main.rb
|
@@ -135,6 +137,7 @@ files:
|
|
135
137
|
- test/middleware_test.rb
|
136
138
|
- test/nokogiri_test.rb
|
137
139
|
- test/public/favicon.ico
|
140
|
+
- test/public/hello+world.txt
|
138
141
|
- test/rabl_test.rb
|
139
142
|
- test/rack_test.rb
|
140
143
|
- test/radius_test.rb
|
@@ -233,7 +236,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
233
236
|
version: '0'
|
234
237
|
requirements: []
|
235
238
|
rubyforge_project:
|
236
|
-
rubygems_version: 2.
|
239
|
+
rubygems_version: 2.5.1
|
237
240
|
signing_key:
|
238
241
|
specification_version: 4
|
239
242
|
summary: Classy web-development dressed in a DSL
|