sinatra 3.2.0 → 4.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +46 -5
- data/Gemfile +25 -30
- data/README.md +40 -24
- data/VERSION +1 -1
- data/lib/sinatra/base.rb +83 -31
- data/lib/sinatra/indifferent_hash.rb +1 -7
- data/lib/sinatra/middleware/logger.rb +21 -0
- data/lib/sinatra/show_exceptions.rb +2 -2
- data/lib/sinatra/version.rb +1 -1
- data/sinatra.gemspec +4 -2
- metadata +49 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 491154a9e29e4c218d9245fd73024818e7dfa6c75ba1d74220e46498841bb54e
|
4
|
+
data.tar.gz: 42259b9becde7268d9b95abc783d896c864a6c84b3e1dd6d40d7f351a350f626
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 43a69c7f07afab191eacc80d7837d9bdbd81701a51973309395b47e9efacb010234a0a66e27503b6edc213f5f8321e426f2f8ad9f7cc7e247e908613d14081c6
|
7
|
+
data.tar.gz: f2fb4deeb5f8e44a5a6a59663080f143c2a1dac1d21a5ca8301728b265a8ba2fcf3e0815c692af0791230289d4ddaf548a317e2f4295cf24b45e5cdec47dc86e
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,47 @@
|
|
1
|
-
##
|
1
|
+
## 4.1.1 / 2024-11-20
|
2
2
|
|
3
|
-
*
|
3
|
+
* Fix: Restore WEBrick support ([#2067](https://github.com/sinatra/sinatra/pull/2067))
|
4
|
+
|
5
|
+
## 4.1.0 / 2024-11-18
|
6
|
+
|
7
|
+
* New: Add `host_authorization` setting ([#2053](https://github.com/sinatra/sinatra/pull/2053))
|
8
|
+
* Defaults to `.localhost`, `.test` and any IP address in development mode.
|
9
|
+
* Security: addresses [CVE-2024-21510](https://github.com/advisories/GHSA-hxx2-7vcw-mqr3).
|
10
|
+
* Fix: Return an instance of `Sinatra::IndifferentHash` when calling `#except` ([#2044](https://github.com/sinatra/sinatra/pull/2044))
|
11
|
+
* Fix: Address warning from `URI` for Ruby 3.4 ([#2060](https://github.com/sinatra/sinatra/pull/2060))
|
12
|
+
* Fix: `rackup` no longer depends on WEBrick, recommend Puma instead ([`4a558503`](https://github.com/sinatra/sinatra/commit/4a558503a0ee41f26d4ebc07b478340e8a8a5ed6))
|
13
|
+
* Fix: Zeitwerk 2.7.0+ compatibility ([#2050](https://github.com/sinatra/sinatra/pull/2050))
|
14
|
+
* Fix: Address warning about Hash construction for Ruby 3.4 ([#2028](https://github.com/sinatra/sinatra/pull/2028))
|
15
|
+
* Fix: Declare missing dependencies for Ruby 3.5 ([#2032](https://github.com/sinatra/sinatra/pull/2032))
|
16
|
+
* Fix: Compatibility with `--enable-frozen-string-literal` ([#2033](https://github.com/sinatra/sinatra/pull/2033))
|
17
|
+
* Fix: Rack 3.1 compatibility ([#2035](https://github.com/sinatra/sinatra/pull/2035))
|
18
|
+
* Don't depend on `Rack::Logger`
|
19
|
+
* Don't delete `content-length` header when `Rack::Files` is used
|
20
|
+
|
21
|
+
## 4.0.0. / 2024-01-19
|
22
|
+
|
23
|
+
* New: Add support for Rack 3 ([#1857])
|
24
|
+
* Note: you may want to read the [Rack 3 Upgrade Guide]
|
25
|
+
|
26
|
+
* Require Ruby 2.7.8 as minimum Ruby version ([#1993])
|
27
|
+
|
28
|
+
* Breaking change: Drop support for Rack 2 ([#1857])
|
29
|
+
* Note: when using Sinatra to start the web server, you now need the `rackup` gem installed
|
30
|
+
|
31
|
+
* Breaking change: Remove the `IndifferentHash` initializer ([#1982])
|
32
|
+
|
33
|
+
* Breaking change: Disable `session_hijacking` protection by default ([#1984])
|
34
|
+
|
35
|
+
* Breaking change: Remove `Rack::Protection::EncryptedCookie` ([#1989])
|
36
|
+
* Note: cookies are still encrypted (by [`Rack::Session::Cookie`])
|
37
|
+
|
38
|
+
[#1857]: https://github.com/sinatra/sinatra/pull/1857
|
39
|
+
[#1993]: https://github.com/sinatra/sinatra/pull/1993
|
40
|
+
[#1982]: https://github.com/sinatra/sinatra/pull/1982
|
41
|
+
[#1984]: https://github.com/sinatra/sinatra/pull/1984
|
42
|
+
[#1989]: https://github.com/sinatra/sinatra/pull/1989
|
43
|
+
[`Rack::Session::Cookie`]: https://github.com/rack/rack-session
|
44
|
+
[Rack 3 Upgrade Guide]: https://github.com/rack/rack/blob/main/UPGRADE-GUIDE.md
|
4
45
|
|
5
46
|
## 3.2.0 / 2023-12-29
|
6
47
|
|
@@ -23,7 +64,7 @@
|
|
23
64
|
[#1949]: https://github.com/sinatra/sinatra/pull/1949
|
24
65
|
[#1952]: https://github.com/sinatra/sinatra/pull/1952
|
25
66
|
[#1960]: https://github.com/sinatra/sinatra/pull/1960
|
26
|
-
[#1975]: https://github.com/sinatra/sinatra/pull/
|
67
|
+
[#1975]: https://github.com/sinatra/sinatra/pull/1975
|
27
68
|
|
28
69
|
## 3.1.0 / 2023-08-07
|
29
70
|
|
@@ -222,7 +263,7 @@
|
|
222
263
|
|
223
264
|
* Fix issue with passed routes and provides Fixes [#1095](https://github.com/sinatra/sinatra/pull/1095) [#1606](https://github.com/sinatra/sinatra/pull/1606) by Mike Pastore, Jordan Owens
|
224
265
|
|
225
|
-
* Add QuietLogger that excludes
|
266
|
+
* Add QuietLogger that excludes paths from Rack::CommonLogger [1250](https://github.com/sinatra/sinatra/pull/1250) by Christoph Wagner
|
226
267
|
|
227
268
|
* Sinatra::Contrib dependency updates. Fixes [#1207](https://github.com/sinatra/sinatra/pull/1207) [#1411](https://github.com/sinatra/sinatra/pull/1411) by Mike Pastore
|
228
269
|
|
@@ -1588,7 +1629,7 @@ the 1.0 release:
|
|
1588
1629
|
Hash structure. e.g., "post[title]=Hello&post[body]=World" yields
|
1589
1630
|
params: {'post' => {'title' => 'Hello', 'body' => 'World'}}.
|
1590
1631
|
|
1591
|
-
* Regular expressions may now be used in route
|
1632
|
+
* Regular expressions may now be used in route patterns; captures are
|
1592
1633
|
available at "params[:captures]".
|
1593
1634
|
|
1594
1635
|
* New ":provides" route condition takes an array of mime types and
|
data/Gemfile
CHANGED
@@ -1,13 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Why use bundler?
|
4
|
-
# Well, not all development dependencies install on all rubies. Moreover, `gem
|
5
|
-
# install sinatra --development` doesn't work, as it will also try to install
|
6
|
-
# development dependencies of our dependencies, and those are not conflict free.
|
7
|
-
# So, here we are, `bundle install`.
|
8
|
-
#
|
9
|
-
# If you have issues with a gem: `bundle install --without-coffee-script`.
|
10
|
-
|
11
3
|
source 'https://rubygems.org'
|
12
4
|
gemspec
|
13
5
|
|
@@ -18,11 +10,22 @@ rack_version = nil if rack_version.empty? || (rack_version == 'stable')
|
|
18
10
|
rack_version = { github: 'rack/rack' } if rack_version == 'head'
|
19
11
|
gem 'rack', rack_version
|
20
12
|
|
13
|
+
rack_session_version = ENV['rack_session'].to_s
|
14
|
+
rack_session_version = nil if rack_session_version.empty? || (rack_session_version == 'stable')
|
15
|
+
rack_session_version = { github: 'rack/rack-session' } if rack_session_version == 'head'
|
16
|
+
gem 'rack-session', rack_session_version
|
17
|
+
|
18
|
+
gem 'rackup'
|
19
|
+
|
21
20
|
puma_version = ENV['puma'].to_s
|
22
21
|
puma_version = nil if puma_version.empty? || (puma_version == 'stable')
|
23
22
|
puma_version = { github: 'puma/puma' } if puma_version == 'head'
|
24
23
|
gem 'puma', puma_version
|
25
24
|
|
25
|
+
zeitwerk_version = ENV['zeitwerk'].to_s
|
26
|
+
zeitwerk_version = nil if zeitwerk_version.empty? || (zeitwerk_version == 'stable')
|
27
|
+
gem 'zeitwerk', zeitwerk_version
|
28
|
+
|
26
29
|
gem 'minitest', '~> 5.0'
|
27
30
|
gem 'rack-test'
|
28
31
|
gem 'rubocop', '~> 1.32.0', require: false
|
@@ -31,15 +34,9 @@ gem 'yard' # used by rake doc
|
|
31
34
|
gem 'rack-protection', path: 'rack-protection'
|
32
35
|
gem 'sinatra-contrib', path: 'sinatra-contrib'
|
33
36
|
|
34
|
-
# traces 0.10.0 started to use Ruby 2.7 syntax without specifying required Ruby version
|
35
|
-
# https://github.com/socketry/traces/pull/8#discussion_r1237988182
|
36
|
-
# async-http 0.60.2 added traces 0.10.0 as dependency
|
37
|
-
# https://github.com/socketry/async-http/pull/124/files#r1237988899
|
38
|
-
gem 'traces', '< 0.10.0' if RUBY_VERSION >= '2.6.0' && RUBY_VERSION < '2.7.0'
|
39
|
-
|
40
37
|
gem 'asciidoctor'
|
41
38
|
gem 'builder'
|
42
|
-
gem 'childprocess'
|
39
|
+
gem 'childprocess', '>= 5'
|
43
40
|
gem 'commonmarker', '~> 0.23.4', platforms: [:ruby]
|
44
41
|
gem 'erubi'
|
45
42
|
gem 'eventmachine'
|
@@ -47,25 +44,23 @@ gem 'falcon', '~> 0.40', platforms: [:ruby]
|
|
47
44
|
gem 'haml', '~> 6'
|
48
45
|
gem 'kramdown'
|
49
46
|
gem 'liquid'
|
50
|
-
|
51
|
-
# and does not specify required_ruby_version
|
52
|
-
if RUBY_VERSION >= '2.6.0' && RUBY_VERSION < '2.7.0'
|
53
|
-
gem 'markaby', '< 0.9.1'
|
54
|
-
else
|
55
|
-
gem 'markaby'
|
56
|
-
end
|
47
|
+
gem 'markaby'
|
57
48
|
gem 'nokogiri', '> 1.5.0'
|
49
|
+
gem 'ostruct'
|
58
50
|
gem 'pandoc-ruby', '~> 2.0.2'
|
59
51
|
gem 'rabl'
|
60
|
-
|
61
|
-
gem 'rdiscount', '< 2.2.7.2' # https://github.com/oracle/truffleruby/issues/3362
|
62
|
-
else
|
63
|
-
gem 'rdiscount', platforms: [:ruby]
|
64
|
-
end
|
52
|
+
gem 'rdiscount', platforms: [:ruby]
|
65
53
|
gem 'rdoc'
|
66
54
|
gem 'redcarpet', platforms: [:ruby]
|
67
|
-
gem 'sass-embedded', '~> 1.54'
|
68
55
|
gem 'simplecov', require: false
|
69
|
-
gem 'slim', '~>
|
56
|
+
gem 'slim', '~> 5'
|
70
57
|
gem 'yajl-ruby', platforms: [:ruby]
|
71
|
-
gem '
|
58
|
+
gem 'webrick'
|
59
|
+
|
60
|
+
# sass-embedded depends on google-protobuf
|
61
|
+
# which fails to be installed on JRuby and TruffleRuby under aarch64
|
62
|
+
# https://github.com/jruby/jruby/issues/8062
|
63
|
+
# https://github.com/protocolbuffers/protobuf/issues/11935
|
64
|
+
java = %w(jruby truffleruby).include?(RUBY_ENGINE)
|
65
|
+
aarch64 = RbConfig::CONFIG["target_cpu"] == 'aarch64'
|
66
|
+
gem 'sass-embedded', '~> 1.54' unless java && aarch64
|
data/README.md
CHANGED
@@ -15,11 +15,10 @@ get '/' do
|
|
15
15
|
end
|
16
16
|
```
|
17
17
|
|
18
|
-
Install the
|
18
|
+
Install the gems needed:
|
19
19
|
|
20
20
|
```shell
|
21
|
-
gem install sinatra
|
22
|
-
gem install puma # or any other server
|
21
|
+
gem install sinatra rackup puma
|
23
22
|
```
|
24
23
|
|
25
24
|
And run with:
|
@@ -1922,7 +1921,7 @@ set :protection, :except => :path_traversal
|
|
1922
1921
|
You can also hand in an array in order to disable a list of protections:
|
1923
1922
|
|
1924
1923
|
```ruby
|
1925
|
-
set :protection, :except => [:path_traversal, :
|
1924
|
+
set :protection, :except => [:path_traversal, :remote_token]
|
1926
1925
|
```
|
1927
1926
|
|
1928
1927
|
By default, Sinatra will only set up session based protection if `:sessions`
|
@@ -1993,6 +1992,33 @@ set :protection, :session => true
|
|
1993
1992
|
<tt>"development"</tt> if not available.
|
1994
1993
|
</dd>
|
1995
1994
|
|
1995
|
+
<dt>host_authorization</dt>
|
1996
|
+
<dd>
|
1997
|
+
<p>
|
1998
|
+
You can pass a hash of options to <tt>host_authorization</tt>,
|
1999
|
+
to be used by the <tt>Rack::Protection::HostAuthorization</tt> middleware.
|
2000
|
+
</p>
|
2001
|
+
<p>
|
2002
|
+
The middleware can block requests with unrecognized hostnames, to prevent DNS rebinding
|
2003
|
+
and other host header attacks. It checks the <tt>Host</tt>, <tt>X-Forwarded-Host</tt>
|
2004
|
+
and <tt>Forwarded</tt> headers.
|
2005
|
+
</p>
|
2006
|
+
<p>
|
2007
|
+
Useful options are:
|
2008
|
+
<ul>
|
2009
|
+
<li><tt>permitted_hosts</tt> – an array of hostnames (and <tt>IPAddr</tt> objects) your app recognizes
|
2010
|
+
<ul>
|
2011
|
+
<li>in the <tt>development</tt> environment, it is set to <tt>.localhost</tt>, <tt>.test</tt> and any IPv4/IPv6 address</li>
|
2012
|
+
<li>if empty, any hostname is permitted (the default for any other environment)</li>
|
2013
|
+
</ul>
|
2014
|
+
</li>
|
2015
|
+
<li><tt>status</tt> – the HTTP status code used in the response when a request is blocked (defaults to <tt>403</tt>)</li>
|
2016
|
+
<li><tt>message</tt> – the body used in the response when a request is blocked (defaults to <tt>Host not permitted</tt>)</li>
|
2017
|
+
<li><tt>allow_if</tt> – supply a <tt>Proc</tt> to use custom allow/deny logic, the proc is passed the request environment</li>
|
2018
|
+
</ul>
|
2019
|
+
</p>
|
2020
|
+
</dd>
|
2021
|
+
|
1996
2022
|
<dt>logging</dt>
|
1997
2023
|
<dd>Use the logger.</dd>
|
1998
2024
|
|
@@ -2086,12 +2112,8 @@ set :protection, :session => true
|
|
2086
2112
|
|
2087
2113
|
<dt>server_settings</dt>
|
2088
2114
|
<dd>
|
2089
|
-
|
2090
|
-
|
2091
|
-
such as <tt>SSLEnable</tt> or <tt>SSLVerifyClient</tt>. However, web
|
2092
|
-
servers such as Puma do not support this, so you can set
|
2093
|
-
<tt>server_settings</tt> by defining it as a method when you call
|
2094
|
-
<tt>configure</tt>.
|
2115
|
+
You can pass a hash of options to <tt>server_settings</tt>,
|
2116
|
+
such as <tt>Host</tt> or <tt>Port</tt>.
|
2095
2117
|
</dd>
|
2096
2118
|
|
2097
2119
|
<dt>sessions</dt>
|
@@ -2812,7 +2834,7 @@ _Paraphrasing from
|
|
2812
2834
|
by Konstantin_
|
2813
2835
|
|
2814
2836
|
Sinatra doesn't impose any concurrency model but leaves that to the
|
2815
|
-
underlying Rack handler (server) like Puma or
|
2837
|
+
underlying Rack handler (server) like Puma or Falcon. Sinatra
|
2816
2838
|
itself is thread-safe, so there won't be any problem if the Rack handler
|
2817
2839
|
uses a threaded model of concurrency.
|
2818
2840
|
|
@@ -2820,30 +2842,24 @@ uses a threaded model of concurrency.
|
|
2820
2842
|
|
2821
2843
|
The following Ruby versions are officially supported:
|
2822
2844
|
<dl>
|
2823
|
-
<dt>Ruby
|
2845
|
+
<dt>Ruby</dt>
|
2824
2846
|
<dd>
|
2825
|
-
|
2826
|
-
drop official support for it.
|
2847
|
+
<a href="https://www.ruby-lang.org/en/downloads/">The stable releases</a> are fully supported and recommended.
|
2827
2848
|
</dd>
|
2828
2849
|
|
2829
|
-
<dt>
|
2850
|
+
<dt>TruffleRuby</dt>
|
2830
2851
|
<dd>
|
2831
|
-
|
2832
|
-
<tt>gem install puma</tt>.
|
2852
|
+
The latest stable release of TruffleRuby is supported.
|
2833
2853
|
</dd>
|
2834
2854
|
|
2835
2855
|
<dt>JRuby</dt>
|
2836
2856
|
<dd>
|
2837
|
-
The latest stable release of JRuby is
|
2838
|
-
recommended to use C extensions with JRuby.
|
2839
|
-
<tt>gem install trinidad</tt>.
|
2857
|
+
The latest stable release of JRuby is supported. It is not
|
2858
|
+
recommended to use C extensions with JRuby.
|
2840
2859
|
</dd>
|
2841
2860
|
</dl>
|
2842
2861
|
|
2843
|
-
Versions of Ruby before 2.
|
2844
|
-
|
2845
|
-
We also keep an eye on upcoming Ruby versions. Expect upcoming
|
2846
|
-
3.x releases to be fully supported.
|
2862
|
+
Versions of Ruby before 2.7.8 are no longer supported as of Sinatra 4.0.0.
|
2847
2863
|
|
2848
2864
|
Sinatra should work on any operating system supported by the chosen Ruby
|
2849
2865
|
implementation.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
4.1.1
|
data/lib/sinatra/base.rb
CHANGED
@@ -2,13 +2,19 @@
|
|
2
2
|
|
3
3
|
# external dependencies
|
4
4
|
require 'rack'
|
5
|
+
begin
|
6
|
+
require 'rackup'
|
7
|
+
rescue LoadError
|
8
|
+
end
|
5
9
|
require 'tilt'
|
6
10
|
require 'rack/protection'
|
11
|
+
require 'rack/session'
|
7
12
|
require 'mustermann'
|
8
13
|
require 'mustermann/sinatra'
|
9
14
|
require 'mustermann/regular'
|
10
15
|
|
11
16
|
# stdlib dependencies
|
17
|
+
require 'ipaddr'
|
12
18
|
require 'time'
|
13
19
|
require 'uri'
|
14
20
|
|
@@ -17,6 +23,8 @@ require 'sinatra/indifferent_hash'
|
|
17
23
|
require 'sinatra/show_exceptions'
|
18
24
|
require 'sinatra/version'
|
19
25
|
|
26
|
+
require_relative 'middleware/logger'
|
27
|
+
|
20
28
|
module Sinatra
|
21
29
|
# The request object. See Rack::Request for more info:
|
22
30
|
# https://rubydoc.info/github/rack/rack/main/Rack/Request
|
@@ -56,7 +64,7 @@ module Sinatra
|
|
56
64
|
alias secure? ssl?
|
57
65
|
|
58
66
|
def forwarded?
|
59
|
-
|
67
|
+
!forwarded_authority.nil?
|
60
68
|
end
|
61
69
|
|
62
70
|
def safe?
|
@@ -176,8 +184,8 @@ module Sinatra
|
|
176
184
|
result = body
|
177
185
|
|
178
186
|
if drop_content_info?
|
179
|
-
headers.delete '
|
180
|
-
headers.delete '
|
187
|
+
headers.delete 'content-length'
|
188
|
+
headers.delete 'content-type'
|
181
189
|
end
|
182
190
|
|
183
191
|
if drop_body?
|
@@ -186,9 +194,9 @@ module Sinatra
|
|
186
194
|
end
|
187
195
|
|
188
196
|
if calculate_content_length?
|
189
|
-
# if some other code has already set
|
197
|
+
# if some other code has already set content-length, don't muck with it
|
190
198
|
# currently, this would be the static file-handler
|
191
|
-
headers['
|
199
|
+
headers['content-length'] = body.map(&:bytesize).reduce(0, :+).to_s
|
192
200
|
end
|
193
201
|
|
194
202
|
[status, headers, result]
|
@@ -197,7 +205,7 @@ module Sinatra
|
|
197
205
|
private
|
198
206
|
|
199
207
|
def calculate_content_length?
|
200
|
-
headers['
|
208
|
+
headers['content-type'] && !headers['content-length'] && (Array === body)
|
201
209
|
end
|
202
210
|
|
203
211
|
def drop_content_info?
|
@@ -289,10 +297,8 @@ module Sinatra
|
|
289
297
|
def block.each; yield(call) end
|
290
298
|
response.body = block
|
291
299
|
elsif value
|
292
|
-
|
293
|
-
|
294
|
-
unless request.head? || value.is_a?(Rack::Files::Iterator) || value.is_a?(Stream)
|
295
|
-
headers.delete 'Content-Length'
|
300
|
+
unless request.head? || value.is_a?(Rack::Files::BaseIterator) || value.is_a?(Stream)
|
301
|
+
headers.delete 'content-length'
|
296
302
|
end
|
297
303
|
response.body = value
|
298
304
|
else
|
@@ -302,7 +308,10 @@ module Sinatra
|
|
302
308
|
|
303
309
|
# Halt processing and redirect to the URI provided.
|
304
310
|
def redirect(uri, *args)
|
305
|
-
|
311
|
+
# SERVER_PROTOCOL is required in Rack 3, fall back to HTTP_VERSION
|
312
|
+
# for servers not updated for Rack 3 (like Puma 5)
|
313
|
+
http_version = env['SERVER_PROTOCOL'] || env['HTTP_VERSION']
|
314
|
+
if (http_version == 'HTTP/1.1') && (env['REQUEST_METHOD'] != 'GET')
|
306
315
|
status 303
|
307
316
|
else
|
308
317
|
status 302
|
@@ -372,10 +381,10 @@ module Sinatra
|
|
372
381
|
Base.mime_type(type)
|
373
382
|
end
|
374
383
|
|
375
|
-
# Set the
|
384
|
+
# Set the content-type of the response body given a media type or file
|
376
385
|
# extension.
|
377
386
|
def content_type(type = nil, params = {})
|
378
|
-
return response['
|
387
|
+
return response['content-type'] unless type
|
379
388
|
|
380
389
|
default = params.delete :default
|
381
390
|
mime_type = mime_type(type) || default
|
@@ -393,7 +402,7 @@ module Sinatra
|
|
393
402
|
"#{key}=#{val}"
|
394
403
|
end.join(', ')
|
395
404
|
end
|
396
|
-
response['
|
405
|
+
response['content-type'] = mime_type
|
397
406
|
end
|
398
407
|
|
399
408
|
# https://html.spec.whatwg.org/#multipart-form-data
|
@@ -412,12 +421,12 @@ module Sinatra
|
|
412
421
|
params = format('; filename="%s"', File.basename(filename).gsub(/["\r\n]/, MULTIPART_FORM_DATA_REPLACEMENT_TABLE))
|
413
422
|
response['Content-Disposition'] << params
|
414
423
|
ext = File.extname(filename)
|
415
|
-
content_type(ext) unless response['
|
424
|
+
content_type(ext) unless response['content-type'] || ext.empty?
|
416
425
|
end
|
417
426
|
|
418
427
|
# Use the contents of the file at +path+ as the response body.
|
419
428
|
def send_file(path, opts = {})
|
420
|
-
if opts[:type] || !response['
|
429
|
+
if opts[:type] || !response['content-type']
|
421
430
|
content_type opts[:type] || File.extname(path), default: 'application/octet-stream'
|
422
431
|
end
|
423
432
|
|
@@ -433,7 +442,7 @@ module Sinatra
|
|
433
442
|
result = file.serving(request, path)
|
434
443
|
|
435
444
|
result[1].each { |k, v| headers[k] ||= v }
|
436
|
-
headers['
|
445
|
+
headers['content-length'] = result[1]['content-length']
|
437
446
|
opts[:status] &&= Integer(opts[:status])
|
438
447
|
halt (opts[:status] || result[0]), result[2]
|
439
448
|
rescue Errno::ENOENT
|
@@ -966,7 +975,7 @@ module Sinatra
|
|
966
975
|
include Helpers
|
967
976
|
include Templates
|
968
977
|
|
969
|
-
URI_INSTANCE = URI::
|
978
|
+
URI_INSTANCE = defined?(URI::RFC2396_PARSER) ? URI::RFC2396_PARSER : URI::RFC2396_Parser.new
|
970
979
|
|
971
980
|
attr_accessor :app, :env, :request, :response, :params
|
972
981
|
attr_reader :template_cache
|
@@ -995,7 +1004,7 @@ module Sinatra
|
|
995
1004
|
invoke { dispatch! }
|
996
1005
|
invoke { error_block!(response.status) } unless @env['sinatra.error']
|
997
1006
|
|
998
|
-
unless @response['
|
1007
|
+
unless @response['content-type']
|
999
1008
|
if Array === body && body[0].respond_to?(:content_type)
|
1000
1009
|
content_type body[0].content_type
|
1001
1010
|
elsif (default = settings.default_content_type)
|
@@ -1058,7 +1067,7 @@ module Sinatra
|
|
1058
1067
|
routes = base.routes[@request.request_method]
|
1059
1068
|
|
1060
1069
|
routes&.each do |pattern, conditions, block|
|
1061
|
-
response.delete_header('
|
1070
|
+
response.delete_header('content-type') unless @pinned_response
|
1062
1071
|
|
1063
1072
|
returned_pass_block = process_route(pattern, conditions) do |*args|
|
1064
1073
|
env['sinatra.route'] = "#{@request.request_method} #{pattern}"
|
@@ -1179,7 +1188,7 @@ module Sinatra
|
|
1179
1188
|
invoke do
|
1180
1189
|
static! if settings.static? && (request.get? || request.head?)
|
1181
1190
|
filter! :before do
|
1182
|
-
@pinned_response = !response['
|
1191
|
+
@pinned_response = !response['content-type'].nil?
|
1183
1192
|
end
|
1184
1193
|
route!
|
1185
1194
|
end
|
@@ -1286,7 +1295,7 @@ module Sinatra
|
|
1286
1295
|
/active_support/, # active_support require hacks
|
1287
1296
|
%r{bundler(/(?:runtime|inline))?\.rb}, # bundler require hacks
|
1288
1297
|
/<internal:/, # internal in ruby >= 1.9.2
|
1289
|
-
%r{zeitwerk/kernel\.rb}
|
1298
|
+
%r{zeitwerk/(core_ext/)?kernel\.rb} # Zeitwerk kernel#require decorator
|
1290
1299
|
].freeze
|
1291
1300
|
|
1292
1301
|
attr_reader :routes, :filters, :templates, :errors, :on_start_callback, :on_stop_callback
|
@@ -1460,7 +1469,13 @@ module Sinatra
|
|
1460
1469
|
# mime_types :js # => ['application/javascript', 'text/javascript']
|
1461
1470
|
def mime_types(type)
|
1462
1471
|
type = mime_type type
|
1463
|
-
type =~ %r{^application/(xml|javascript)$}
|
1472
|
+
if type =~ %r{^application/(xml|javascript)$}
|
1473
|
+
[type, "text/#{$1}"]
|
1474
|
+
elsif type =~ %r{^text/(xml|javascript)$}
|
1475
|
+
[type, "application/#{$1}"]
|
1476
|
+
else
|
1477
|
+
[type]
|
1478
|
+
end
|
1464
1479
|
end
|
1465
1480
|
|
1466
1481
|
# Define a before filter; runs before all requests within the same
|
@@ -1586,13 +1601,30 @@ module Sinatra
|
|
1586
1601
|
alias stop! quit!
|
1587
1602
|
|
1588
1603
|
# Run the Sinatra app as a self-hosted server using
|
1589
|
-
# Puma, Falcon
|
1604
|
+
# Puma, Falcon (in that order). If given a block, will call
|
1590
1605
|
# with the constructed handler once we have taken the stage.
|
1591
1606
|
def run!(options = {}, &block)
|
1607
|
+
unless defined?(Rackup::Handler)
|
1608
|
+
rackup_warning = <<~MISSING_RACKUP
|
1609
|
+
Sinatra could not start, the required gems weren't found!
|
1610
|
+
|
1611
|
+
Add them to your bundle with:
|
1612
|
+
|
1613
|
+
bundle add rackup puma
|
1614
|
+
|
1615
|
+
or install them with:
|
1616
|
+
|
1617
|
+
gem install rackup puma
|
1618
|
+
|
1619
|
+
MISSING_RACKUP
|
1620
|
+
warn rackup_warning
|
1621
|
+
exit 1
|
1622
|
+
end
|
1623
|
+
|
1592
1624
|
return if running?
|
1593
1625
|
|
1594
1626
|
set options
|
1595
|
-
handler =
|
1627
|
+
handler = Rackup::Handler.pick(server)
|
1596
1628
|
handler_name = handler.name.gsub(/.*::/, '')
|
1597
1629
|
server_settings = settings.respond_to?(:server_settings) ? settings.server_settings : {}
|
1598
1630
|
server_settings.merge!(Port: port, Host: bind)
|
@@ -1724,7 +1756,7 @@ module Sinatra
|
|
1724
1756
|
types.map! { |t| mime_types(t) }
|
1725
1757
|
types.flatten!
|
1726
1758
|
condition do
|
1727
|
-
response_content_type = response['
|
1759
|
+
response_content_type = response['content-type']
|
1728
1760
|
preferred_type = request.preferred_type(types)
|
1729
1761
|
|
1730
1762
|
if response_content_type
|
@@ -1790,6 +1822,7 @@ module Sinatra
|
|
1790
1822
|
setup_logging builder
|
1791
1823
|
setup_sessions builder
|
1792
1824
|
setup_protection builder
|
1825
|
+
setup_host_authorization builder
|
1793
1826
|
end
|
1794
1827
|
|
1795
1828
|
def setup_middleware(builder)
|
@@ -1806,7 +1839,7 @@ module Sinatra
|
|
1806
1839
|
end
|
1807
1840
|
|
1808
1841
|
def setup_null_logger(builder)
|
1809
|
-
builder.use
|
1842
|
+
builder.use Sinatra::Middleware::Logger, ::Logger::FATAL
|
1810
1843
|
end
|
1811
1844
|
|
1812
1845
|
def setup_common_logger(builder)
|
@@ -1815,9 +1848,9 @@ module Sinatra
|
|
1815
1848
|
|
1816
1849
|
def setup_custom_logger(builder)
|
1817
1850
|
if logging.respond_to? :to_int
|
1818
|
-
builder.use
|
1851
|
+
builder.use Sinatra::Middleware::Logger, logging
|
1819
1852
|
else
|
1820
|
-
builder.use
|
1853
|
+
builder.use Sinatra::Middleware::Logger
|
1821
1854
|
end
|
1822
1855
|
end
|
1823
1856
|
|
@@ -1838,6 +1871,10 @@ module Sinatra
|
|
1838
1871
|
builder.use Rack::Protection, options
|
1839
1872
|
end
|
1840
1873
|
|
1874
|
+
def setup_host_authorization(builder)
|
1875
|
+
builder.use Rack::Protection::HostAuthorization, host_authorization
|
1876
|
+
end
|
1877
|
+
|
1841
1878
|
def setup_sessions(builder)
|
1842
1879
|
return unless sessions?
|
1843
1880
|
|
@@ -1901,7 +1938,7 @@ module Sinatra
|
|
1901
1938
|
set :dump_errors, proc { !test? }
|
1902
1939
|
set :show_exceptions, proc { development? }
|
1903
1940
|
set :sessions, false
|
1904
|
-
set :session_store, Rack::
|
1941
|
+
set :session_store, Rack::Session::Cookie
|
1905
1942
|
set :logging, false
|
1906
1943
|
set :protection, true
|
1907
1944
|
set :method_override, false
|
@@ -1932,10 +1969,25 @@ module Sinatra
|
|
1932
1969
|
set :running_server, nil
|
1933
1970
|
set :handler_name, nil
|
1934
1971
|
set :traps, true
|
1935
|
-
set :server, %w[
|
1972
|
+
set :server, %w[webrick]
|
1936
1973
|
set :bind, proc { development? ? 'localhost' : '0.0.0.0' }
|
1937
1974
|
set :port, Integer(ENV['PORT'] && !ENV['PORT'].empty? ? ENV['PORT'] : 4567)
|
1938
1975
|
set :quiet, false
|
1976
|
+
set :host_authorization, ->() do
|
1977
|
+
if development?
|
1978
|
+
{
|
1979
|
+
permitted_hosts: [
|
1980
|
+
"localhost",
|
1981
|
+
".localhost",
|
1982
|
+
".test",
|
1983
|
+
IPAddr.new("0.0.0.0/0"),
|
1984
|
+
IPAddr.new("::/0"),
|
1985
|
+
]
|
1986
|
+
}
|
1987
|
+
else
|
1988
|
+
{}
|
1989
|
+
end
|
1990
|
+
end
|
1939
1991
|
|
1940
1992
|
ruby_engine = defined?(RUBY_ENGINE) && RUBY_ENGINE
|
1941
1993
|
|
@@ -43,12 +43,6 @@ module Sinatra
|
|
43
43
|
new.merge!(Hash[*args])
|
44
44
|
end
|
45
45
|
|
46
|
-
def initialize(*args)
|
47
|
-
args.map!(&method(:convert_value))
|
48
|
-
|
49
|
-
super(*args)
|
50
|
-
end
|
51
|
-
|
52
46
|
def default(*args)
|
53
47
|
args.map!(&method(:convert_key))
|
54
48
|
|
@@ -191,7 +185,7 @@ module Sinatra
|
|
191
185
|
def except(*keys)
|
192
186
|
keys.map!(&method(:convert_key))
|
193
187
|
|
194
|
-
super(*keys)
|
188
|
+
self.class[super(*keys)]
|
195
189
|
end if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.0")
|
196
190
|
|
197
191
|
private
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
module Sinatra
|
6
|
+
module Middleware
|
7
|
+
class Logger
|
8
|
+
def initialize(app, level = ::Logger::INFO)
|
9
|
+
@app, @level = app, level
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(env)
|
13
|
+
logger = ::Logger.new(env[Rack::RACK_ERRORS])
|
14
|
+
logger.level = @level
|
15
|
+
|
16
|
+
env[Rack::RACK_LOGGER] = logger
|
17
|
+
@app.call(env)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/sinatra/version.rb
CHANGED
data/sinatra.gemspec
CHANGED
@@ -43,10 +43,12 @@ RubyGems 2.0 or newer is required to protect against public gem pushes. You can
|
|
43
43
|
'documentation_uri' => 'https://www.rubydoc.info/gems/sinatra'
|
44
44
|
}
|
45
45
|
|
46
|
-
s.required_ruby_version = '>= 2.
|
46
|
+
s.required_ruby_version = '>= 2.7.8'
|
47
47
|
|
48
|
+
s.add_dependency 'logger', '>= 1.6.0'
|
48
49
|
s.add_dependency 'mustermann', '~> 3.0'
|
49
|
-
s.add_dependency 'rack', '
|
50
|
+
s.add_dependency 'rack', '>= 3.0.0', '< 4'
|
50
51
|
s.add_dependency 'rack-protection', version
|
52
|
+
s.add_dependency 'rack-session', '>= 2.0.0', '< 3'
|
51
53
|
s.add_dependency 'tilt', '~> 2.0'
|
52
54
|
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:
|
4
|
+
version: 4.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Blake Mizerany
|
@@ -11,8 +11,22 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date:
|
14
|
+
date: 2024-11-20 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: logger
|
18
|
+
requirement: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.6.0
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.6.0
|
16
30
|
- !ruby/object:Gem::Dependency
|
17
31
|
name: mustermann
|
18
32
|
requirement: !ruby/object:Gem::Requirement
|
@@ -31,36 +45,56 @@ dependencies:
|
|
31
45
|
name: rack
|
32
46
|
requirement: !ruby/object:Gem::Requirement
|
33
47
|
requirements:
|
34
|
-
- - "~>"
|
35
|
-
- !ruby/object:Gem::Version
|
36
|
-
version: '2.2'
|
37
48
|
- - ">="
|
38
49
|
- !ruby/object:Gem::Version
|
39
|
-
version:
|
50
|
+
version: 3.0.0
|
51
|
+
- - "<"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '4'
|
40
54
|
type: :runtime
|
41
55
|
prerelease: false
|
42
56
|
version_requirements: !ruby/object:Gem::Requirement
|
43
57
|
requirements:
|
44
|
-
- - "~>"
|
45
|
-
- !ruby/object:Gem::Version
|
46
|
-
version: '2.2'
|
47
58
|
- - ">="
|
48
59
|
- !ruby/object:Gem::Version
|
49
|
-
version:
|
60
|
+
version: 3.0.0
|
61
|
+
- - "<"
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '4'
|
50
64
|
- !ruby/object:Gem::Dependency
|
51
65
|
name: rack-protection
|
52
66
|
requirement: !ruby/object:Gem::Requirement
|
53
67
|
requirements:
|
54
68
|
- - '='
|
55
69
|
- !ruby/object:Gem::Version
|
56
|
-
version:
|
70
|
+
version: 4.1.1
|
57
71
|
type: :runtime
|
58
72
|
prerelease: false
|
59
73
|
version_requirements: !ruby/object:Gem::Requirement
|
60
74
|
requirements:
|
61
75
|
- - '='
|
62
76
|
- !ruby/object:Gem::Version
|
63
|
-
version:
|
77
|
+
version: 4.1.1
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: rack-session
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: 2.0.0
|
85
|
+
- - "<"
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '3'
|
88
|
+
type: :runtime
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: 2.0.0
|
95
|
+
- - "<"
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '3'
|
64
98
|
- !ruby/object:Gem::Dependency
|
65
99
|
name: tilt
|
66
100
|
requirement: !ruby/object:Gem::Requirement
|
@@ -105,6 +139,7 @@ files:
|
|
105
139
|
- lib/sinatra/images/500.png
|
106
140
|
- lib/sinatra/indifferent_hash.rb
|
107
141
|
- lib/sinatra/main.rb
|
142
|
+
- lib/sinatra/middleware/logger.rb
|
108
143
|
- lib/sinatra/show_exceptions.rb
|
109
144
|
- lib/sinatra/version.rb
|
110
145
|
- sinatra.gemspec
|
@@ -132,14 +167,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
132
167
|
requirements:
|
133
168
|
- - ">="
|
134
169
|
- !ruby/object:Gem::Version
|
135
|
-
version: 2.
|
170
|
+
version: 2.7.8
|
136
171
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
137
172
|
requirements:
|
138
173
|
- - ">="
|
139
174
|
- !ruby/object:Gem::Version
|
140
175
|
version: '0'
|
141
176
|
requirements: []
|
142
|
-
rubygems_version: 3.5.
|
177
|
+
rubygems_version: 3.5.22
|
143
178
|
signing_key:
|
144
179
|
specification_version: 4
|
145
180
|
summary: Classy web-development dressed in a DSL
|