sinatra 3.0.0 → 3.1.0
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 +65 -3
- data/CONTRIBUTING.md +11 -11
- data/Gemfile +14 -3
- data/MAINTENANCE.md +2 -2
- data/README.md +128 -18
- data/Rakefile +10 -19
- data/VERSION +1 -1
- data/examples/chat.rb +20 -9
- data/examples/lifecycle_events.rb +20 -0
- data/examples/stream.ru +0 -1
- data/lib/sinatra/base.rb +104 -25
- data/lib/sinatra/version.rb +1 -1
- data/sinatra.gemspec +1 -1
- metadata +7 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 315dee3d85d7778ffa48e041bd60370e9e89ecd3c01dbf0cf9450e41c62dc0d8
|
|
4
|
+
data.tar.gz: '083a914c0b520684471e2715ec091c67ca8121bfb8b5d4cf410307d6e14e4ac5'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2790a4d58595f0f89667c5fd4530dde2de532ddaf02628f373162cc47d393732b1c9475ab59775c756750dfb52e60e7091118936ac8e70739fb266b46f82d3bd
|
|
7
|
+
data.tar.gz: eb74f34bf0b9a681557809c656754312eb266e66c3b68fcabbf95699c3273cf4d998e3969224b09df9127ff90f5d34fba5bc93b1ff0c321b4a7646ddfcc0b6b7
|
data/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,60 @@
|
|
|
1
|
-
##
|
|
1
|
+
## Unreleased
|
|
2
|
+
|
|
3
|
+
* _Your new feature here._
|
|
4
|
+
|
|
5
|
+
## 3.1.0 / 2023-08-07
|
|
6
|
+
|
|
7
|
+
* New: Add sass support via sass-embedded [#1911] by なつき
|
|
8
|
+
|
|
9
|
+
* New: Add start and stop callbacks [#1913] by Jevin Sew
|
|
10
|
+
|
|
11
|
+
* New: Warn on dropping sessions [#1900] by Jonathan del Strother
|
|
12
|
+
|
|
13
|
+
* New: Make Puma the default server [#1924] by Patrik Ragnarsson
|
|
14
|
+
|
|
15
|
+
* Fix: Remove use of Tilt::Cache [#1922] by Jeremy Evans (allows use of Tilt 2.2.0 without deprecation warning)
|
|
16
|
+
|
|
17
|
+
* Fix: rack-protection: specify rack version requirement [#1932] by Patrik Ragnarsson
|
|
18
|
+
|
|
19
|
+
[#1913]: https://github.com/sinatra/sinatra/pull/1913
|
|
20
|
+
[#1900]: https://github.com/sinatra/sinatra/pull/1900
|
|
21
|
+
[#1924]: https://github.com/sinatra/sinatra/pull/1924
|
|
22
|
+
[#1922]: https://github.com/sinatra/sinatra/pull/1922
|
|
23
|
+
[#1932]: https://github.com/sinatra/sinatra/pull/1932
|
|
24
|
+
|
|
25
|
+
## 3.0.6 / 2023-04-11
|
|
26
|
+
|
|
27
|
+
* Fix: Add support to keep open streaming connections with Puma [#1858](https://github.com/sinatra/sinatra/pull/1858) by Jordan Owens
|
|
28
|
+
|
|
29
|
+
* Fix: Avoid crash in `uri` helper on Integer input [#1890](https://github.com/sinatra/sinatra/pull/1890) by Patrik Ragnarsson
|
|
30
|
+
|
|
31
|
+
* Fix: Rescue `RuntimeError` when trying to use `SecureRandom` [#1888](https://github.com/sinatra/sinatra/pull/1888) by Stefan Sundin
|
|
32
|
+
|
|
33
|
+
## 3.0.5 / 2022-12-16
|
|
34
|
+
|
|
35
|
+
* Fix: Add Zeitwerk compatibility. [#1831](https://github.com/sinatra/sinatra/pull/1831) by Dawid Janczak
|
|
36
|
+
|
|
37
|
+
* Fix: Allow CALLERS_TO_IGNORE to be overridden
|
|
38
|
+
|
|
39
|
+
## 3.0.4 / 2022-11-25
|
|
40
|
+
|
|
41
|
+
* Fix: Escape filename in the Content-Disposition header. [#1841](https://github.com/sinatra/sinatra/pull/1841) by Kunpei Sakai
|
|
42
|
+
|
|
43
|
+
## 3.0.3 / 2022-11-11
|
|
44
|
+
|
|
45
|
+
* Fix: fixed ReDoS for Rack::Protection::IPSpoofing. [#1823](https://github.com/sinatra/sinatra/pull/1823) by @ooooooo-q
|
|
46
|
+
|
|
47
|
+
## 3.0.2 / 2022-10-01
|
|
48
|
+
|
|
49
|
+
* New: Add Haml 6 support. [#1820](https://github.com/sinatra/sinatra/pull/1820) by Jordan Owens
|
|
50
|
+
|
|
51
|
+
## 3.0.1 / 2022-09-26
|
|
52
|
+
|
|
53
|
+
* Fix: Revert removal of rack-protection.rb. [#1814](https://github.com/sinatra/sinatra/pull/1814) by Olle Jonsson
|
|
54
|
+
|
|
55
|
+
* Fix: Revert change to server start and stop messaging by using Kernel#warn. Renamed internal warn method warn_for_deprecation. [#1818](https://github.com/sinatra/sinatra/pull/1818) by Jordan Owens
|
|
56
|
+
|
|
57
|
+
## 3.0.0 / 2022-09-26
|
|
2
58
|
|
|
3
59
|
* New: Add Falcon support. [#1794](https://github.com/sinatra/sinatra/pull/1794) by Samuel Williams and @horaciob
|
|
4
60
|
|
|
@@ -44,6 +100,12 @@
|
|
|
44
100
|
|
|
45
101
|
* Docs: Japanese documentation: Make Session section reflect changes done to README.md. [#1731](https://github.com/sinatra/sinatra/pull/1731) by @shu-i-chi
|
|
46
102
|
|
|
103
|
+
## 2.2.3 / 2022-11-25
|
|
104
|
+
|
|
105
|
+
* Fix: Escape filename in the Content-Disposition header. [#1841](https://github.com/sinatra/sinatra/pull/1841) by Kunpei Sakai
|
|
106
|
+
|
|
107
|
+
* Fix: fixed ReDoS for Rack::Protection::IPSpoofing. [#1823](https://github.com/sinatra/sinatra/pull/1823) by @ooooooo-q
|
|
108
|
+
|
|
47
109
|
## 2.2.2 / 2022-07-23
|
|
48
110
|
|
|
49
111
|
* Update mustermann dependency to version 2.
|
|
@@ -56,6 +118,8 @@
|
|
|
56
118
|
|
|
57
119
|
## 2.2.0 / 2022-02-15
|
|
58
120
|
|
|
121
|
+
* Breaking change: Add `#select`, `#reject` and `#compact` methods to `Sinatra::IndifferentHash`. If hash keys need to be converted to symbols, call `#to_h` to get a `Hash` instance first. [#1711](https://github.com/sinatra/sinatra/pull/1711) by Olivier Bellone
|
|
122
|
+
|
|
59
123
|
* Handle EOFError raised by Rack and return Bad Request 400 status. [#1743](https://github.com/sinatra/sinatra/pull/1743) by tamazon
|
|
60
124
|
|
|
61
125
|
* Minor refactors in `base.rb`. [#1640](https://github.com/sinatra/sinatra/pull/1640) by ceclinux
|
|
@@ -86,8 +150,6 @@
|
|
|
86
150
|
|
|
87
151
|
* Remove unnecessary `test_files` from the gemspec. [#1712](https://github.com/sinatra/sinatra/pull/1712) by Masataka Pocke Kuwabara
|
|
88
152
|
|
|
89
|
-
* Add `#select`, `#reject` and `#compact` methods to `Sinatra::IndifferentHash`. [#1711](https://github.com/sinatra/sinatra/pull/1711) by Olivier Bellone
|
|
90
|
-
|
|
91
153
|
* Docs: Spanish documentation: Update README.es.md with removal of Thin. [#1630](https://github.com/sinatra/sinatra/pull/1630) by Espartaco Palma
|
|
92
154
|
|
|
93
155
|
* Docs: German documentation: Fixed typos in German README.md. [#1648](https://github.com/sinatra/sinatra/pull/1648) by Juri
|
data/CONTRIBUTING.md
CHANGED
|
@@ -65,21 +65,21 @@ track patch requests.
|
|
|
65
65
|
also has its own [Git repository](http://github.com/sinatra/sinatra-recipes).
|
|
66
66
|
|
|
67
67
|
* [The Introduction](http://www.sinatrarb.com/intro.html) is generated from
|
|
68
|
-
Sinatra's [README file](http://github.com/sinatra/sinatra/blob/
|
|
68
|
+
Sinatra's [README file](http://github.com/sinatra/sinatra/blob/main/README.md).
|
|
69
69
|
|
|
70
70
|
* If you want to help translating the documentation, the README is already
|
|
71
71
|
available in
|
|
72
|
-
[Japanese](http://github.com/sinatra/sinatra/blob/
|
|
73
|
-
[German](http://github.com/sinatra/sinatra/blob/
|
|
74
|
-
[Chinese](https://github.com/sinatra/sinatra/blob/
|
|
75
|
-
[Russian](https://github.com/sinatra/sinatra/blob/
|
|
76
|
-
[European](https://github.com/sinatra/sinatra/blob/
|
|
77
|
-
[Brazilian](https://github.com/sinatra/sinatra/blob/
|
|
72
|
+
[Japanese](http://github.com/sinatra/sinatra/blob/main/README.ja.md),
|
|
73
|
+
[German](http://github.com/sinatra/sinatra/blob/main/README.de.md),
|
|
74
|
+
[Chinese](https://github.com/sinatra/sinatra/blob/main/README.zh.md),
|
|
75
|
+
[Russian](https://github.com/sinatra/sinatra/blob/main/README.ru.md),
|
|
76
|
+
[European](https://github.com/sinatra/sinatra/blob/main/README.pt-pt.md) and
|
|
77
|
+
[Brazilian](https://github.com/sinatra/sinatra/blob/main/README.pt-br.md)
|
|
78
78
|
Portuguese,
|
|
79
|
-
[French](https://github.com/sinatra/sinatra/blob/
|
|
80
|
-
[Spanish](https://github.com/sinatra/sinatra/blob/
|
|
81
|
-
[Korean](https://github.com/sinatra/sinatra/blob/
|
|
82
|
-
[Hungarian](https://github.com/sinatra/sinatra/blob/
|
|
79
|
+
[French](https://github.com/sinatra/sinatra/blob/main/README.fr.md),
|
|
80
|
+
[Spanish](https://github.com/sinatra/sinatra/blob/main/README.es.md),
|
|
81
|
+
[Korean](https://github.com/sinatra/sinatra/blob/main/README.ko.md), and
|
|
82
|
+
[Hungarian](https://github.com/sinatra/sinatra/blob/main/README.hu.md).
|
|
83
83
|
The translations tend to fall behind the English version. Translations into
|
|
84
84
|
other languages would also be appreciated.
|
|
85
85
|
|
data/Gemfile
CHANGED
|
@@ -15,9 +15,14 @@ gem 'rake'
|
|
|
15
15
|
|
|
16
16
|
rack_version = ENV['rack'].to_s
|
|
17
17
|
rack_version = nil if rack_version.empty? || (rack_version == 'stable')
|
|
18
|
-
rack_version = { github: 'rack/rack' } if rack_version == '
|
|
18
|
+
rack_version = { github: 'rack/rack' } if rack_version == 'head'
|
|
19
19
|
gem 'rack', rack_version
|
|
20
20
|
|
|
21
|
+
puma_version = ENV['puma'].to_s
|
|
22
|
+
puma_version = nil if puma_version.empty? || (puma_version == 'stable')
|
|
23
|
+
puma_version = { github: 'puma/puma' } if puma_version == 'head'
|
|
24
|
+
gem 'puma', puma_version
|
|
25
|
+
|
|
21
26
|
gem 'minitest', '~> 5.0'
|
|
22
27
|
gem 'rack-test', github: 'rack/rack-test'
|
|
23
28
|
gem 'rubocop', '~> 1.32.0', require: false
|
|
@@ -26,6 +31,12 @@ gem 'yard'
|
|
|
26
31
|
gem 'rack-protection', path: 'rack-protection'
|
|
27
32
|
gem 'sinatra-contrib', path: 'sinatra-contrib'
|
|
28
33
|
|
|
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
|
+
|
|
29
40
|
gem 'activesupport', '~> 6.1'
|
|
30
41
|
|
|
31
42
|
gem 'asciidoctor'
|
|
@@ -34,18 +45,18 @@ gem 'commonmarker', '~> 0.23.4', platforms: [:ruby]
|
|
|
34
45
|
gem 'erubi'
|
|
35
46
|
gem 'eventmachine'
|
|
36
47
|
gem 'falcon', '~> 0.40', platforms: [:ruby]
|
|
37
|
-
gem 'haml', '~>
|
|
48
|
+
gem 'haml', '~> 6'
|
|
38
49
|
gem 'kramdown'
|
|
39
50
|
gem 'liquid'
|
|
40
51
|
gem 'markaby'
|
|
41
52
|
gem 'nokogiri', '> 1.5.0'
|
|
42
53
|
gem 'pandoc-ruby', '~> 2.0.2'
|
|
43
|
-
gem 'puma'
|
|
44
54
|
gem 'rabl'
|
|
45
55
|
gem 'rainbows', platforms: [:mri] # uses #fork
|
|
46
56
|
gem 'rdiscount', platforms: [:ruby]
|
|
47
57
|
gem 'rdoc'
|
|
48
58
|
gem 'redcarpet', platforms: [:ruby]
|
|
59
|
+
gem 'sass-embedded', '~> 1.54'
|
|
49
60
|
gem 'simplecov', require: false
|
|
50
61
|
gem 'slim', '~> 4'
|
|
51
62
|
gem 'yajl-ruby', platforms: [:ruby]
|
data/MAINTENANCE.md
CHANGED
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
### Releases
|
|
6
6
|
|
|
7
|
-
The next major version of Sinatra will be released from the
|
|
7
|
+
The next major version of Sinatra will be released from the main branch. Each version will be tagged so it will be possible to branch of should there be a need for bug fixes and other updates.
|
|
8
8
|
|
|
9
9
|
## Issues
|
|
10
10
|
|
|
11
11
|
### New features
|
|
12
12
|
|
|
13
|
-
New features will only be added to the
|
|
13
|
+
New features will only be added to the main branch and will not be made available in point releases.
|
|
14
14
|
|
|
15
15
|
### Bug fixes
|
|
16
16
|
|
data/README.md
CHANGED
|
@@ -54,6 +54,8 @@ pick up if available.
|
|
|
54
54
|
- [Erb Templates](#erb-templates)
|
|
55
55
|
- [Builder Templates](#builder-templates)
|
|
56
56
|
- [Nokogiri Templates](#nokogiri-templates)
|
|
57
|
+
- [Sass Templates](#sass-templates)
|
|
58
|
+
- [Scss Templates](#scss-templates)
|
|
57
59
|
- [Liquid Templates](#liquid-templates)
|
|
58
60
|
- [Markdown Templates](#markdown-templates)
|
|
59
61
|
- [RDoc Templates](#rdoc-templates)
|
|
@@ -93,6 +95,7 @@ pick up if available.
|
|
|
93
95
|
- [Configuration](#configuration)
|
|
94
96
|
- [Configuring attack protection](#configuring-attack-protection)
|
|
95
97
|
- [Available Settings](#available-settings)
|
|
98
|
+
- [Lifecycle Events](#lifecycle-events)
|
|
96
99
|
- [Environments](#environments)
|
|
97
100
|
- [Error Handling](#error-handling)
|
|
98
101
|
- [Not Found](#not-found)
|
|
@@ -649,6 +652,39 @@ It also takes a block for inline templates (see [example](#inline-templates)).
|
|
|
649
652
|
|
|
650
653
|
It also takes a block for inline templates (see [example](#inline-templates)).
|
|
651
654
|
|
|
655
|
+
#### Sass Templates
|
|
656
|
+
|
|
657
|
+
<table>
|
|
658
|
+
<tr>
|
|
659
|
+
<td>Dependency</td>
|
|
660
|
+
<td><a href="https://github.com/ntkme/sass-embedded-host-ruby" title="sass-embedded">sass-embedded</a></td>
|
|
661
|
+
</tr>
|
|
662
|
+
<tr>
|
|
663
|
+
<td>File Extension</td>
|
|
664
|
+
<td><tt>.sass</tt></td>
|
|
665
|
+
</tr>
|
|
666
|
+
<tr>
|
|
667
|
+
<td>Example</td>
|
|
668
|
+
<td><tt>sass :stylesheet, :style => :expanded</tt></td>
|
|
669
|
+
</tr>
|
|
670
|
+
</table>
|
|
671
|
+
|
|
672
|
+
#### Scss Templates
|
|
673
|
+
|
|
674
|
+
<table>
|
|
675
|
+
<tr>
|
|
676
|
+
<td>Dependency</td>
|
|
677
|
+
<td><a href="https://github.com/ntkme/sass-embedded-host-ruby" title="sass-embedded">sass-embedded</a></td>
|
|
678
|
+
</tr>
|
|
679
|
+
<tr>
|
|
680
|
+
<td>File Extension</td>
|
|
681
|
+
<td><tt>.scss</tt></td>
|
|
682
|
+
</tr>
|
|
683
|
+
<tr>
|
|
684
|
+
<td>Example</td>
|
|
685
|
+
<td><tt>scss :stylesheet, :style => :expanded</tt></td>
|
|
686
|
+
</tr>
|
|
687
|
+
</table>
|
|
652
688
|
|
|
653
689
|
#### Liquid Templates
|
|
654
690
|
|
|
@@ -938,7 +974,7 @@ __END__
|
|
|
938
974
|
|
|
939
975
|
@@ layout
|
|
940
976
|
%html
|
|
941
|
-
|
|
977
|
+
!= yield
|
|
942
978
|
|
|
943
979
|
@@ index
|
|
944
980
|
%div.title Hello world.
|
|
@@ -984,7 +1020,7 @@ To associate a file extension with a template engine, use
|
|
|
984
1020
|
`tt` for Haml templates, you can do the following:
|
|
985
1021
|
|
|
986
1022
|
```ruby
|
|
987
|
-
Tilt.register
|
|
1023
|
+
Tilt.register Tilt[:haml], :tt
|
|
988
1024
|
```
|
|
989
1025
|
|
|
990
1026
|
### Adding Your Own Template Engine
|
|
@@ -992,7 +1028,7 @@ Tilt.register :tt, Tilt[:haml]
|
|
|
992
1028
|
First, register your engine with Tilt, then create a rendering method:
|
|
993
1029
|
|
|
994
1030
|
```ruby
|
|
995
|
-
Tilt.register :myat
|
|
1031
|
+
Tilt.register MyAwesomeTemplateEngine, :myat
|
|
996
1032
|
|
|
997
1033
|
helpers do
|
|
998
1034
|
def myat(*args) render(:myat, *args) end
|
|
@@ -1933,7 +1969,7 @@ end
|
|
|
1933
1969
|
### Configuring attack protection
|
|
1934
1970
|
|
|
1935
1971
|
Sinatra is using
|
|
1936
|
-
[Rack::Protection](https://github.com/sinatra/sinatra/tree/
|
|
1972
|
+
[Rack::Protection](https://github.com/sinatra/sinatra/tree/main/rack-protection#readme) to
|
|
1937
1973
|
defend your application against common, opportunistic attacks. You can
|
|
1938
1974
|
easily disable this behavior (which will open up your application to tons
|
|
1939
1975
|
of common vulnerabilities):
|
|
@@ -2089,9 +2125,13 @@ set :protection, :session => true
|
|
|
2089
2125
|
|
|
2090
2126
|
<dt>raise_errors</dt>
|
|
2091
2127
|
<dd>
|
|
2092
|
-
Raise
|
|
2128
|
+
Raise unhandled errors (will stop application). Enabled by default when
|
|
2093
2129
|
<tt>environment</tt> is set to <tt>"test"</tt>, disabled otherwise.
|
|
2094
2130
|
</dd>
|
|
2131
|
+
<dd>
|
|
2132
|
+
Any explicitly defined error handlers always override this setting. See
|
|
2133
|
+
the "Error" section below.
|
|
2134
|
+
</dd>
|
|
2095
2135
|
|
|
2096
2136
|
<dt>run</dt>
|
|
2097
2137
|
<dd>
|
|
@@ -2184,6 +2224,24 @@ set :protection, :session => true
|
|
|
2184
2224
|
</dd>
|
|
2185
2225
|
</dl>
|
|
2186
2226
|
|
|
2227
|
+
## Lifecycle Events
|
|
2228
|
+
|
|
2229
|
+
There are 2 lifecycle events currently exposed by Sinatra. One when the server starts and one when it stops.
|
|
2230
|
+
|
|
2231
|
+
They can be used like this:
|
|
2232
|
+
|
|
2233
|
+
```ruby
|
|
2234
|
+
on_start do
|
|
2235
|
+
puts "===== Booting up ====="
|
|
2236
|
+
end
|
|
2237
|
+
|
|
2238
|
+
on_stop do
|
|
2239
|
+
puts "===== Shutting down ====="
|
|
2240
|
+
end
|
|
2241
|
+
```
|
|
2242
|
+
|
|
2243
|
+
Note that these callbacks only work when using Sinatra to start the web server.
|
|
2244
|
+
|
|
2187
2245
|
## Environments
|
|
2188
2246
|
|
|
2189
2247
|
There are three predefined `environments`: `"development"`,
|
|
@@ -2240,6 +2298,14 @@ show exceptions option to `:after_handler`:
|
|
|
2240
2298
|
set :show_exceptions, :after_handler
|
|
2241
2299
|
```
|
|
2242
2300
|
|
|
2301
|
+
A catch-all error handler can be defined with `error` and a block:
|
|
2302
|
+
|
|
2303
|
+
```ruby
|
|
2304
|
+
error do
|
|
2305
|
+
'Sorry there was a nasty error'
|
|
2306
|
+
end
|
|
2307
|
+
```
|
|
2308
|
+
|
|
2243
2309
|
The exception object can be obtained from the `sinatra.error` Rack variable:
|
|
2244
2310
|
|
|
2245
2311
|
```ruby
|
|
@@ -2248,7 +2314,7 @@ error do
|
|
|
2248
2314
|
end
|
|
2249
2315
|
```
|
|
2250
2316
|
|
|
2251
|
-
|
|
2317
|
+
Pass an error class as an argument to create handlers for custom errors:
|
|
2252
2318
|
|
|
2253
2319
|
```ruby
|
|
2254
2320
|
error MyCustomError do
|
|
@@ -2294,6 +2360,51 @@ Sinatra installs special `not_found` and `error` handlers when
|
|
|
2294
2360
|
running under the development environment to display nice stack traces
|
|
2295
2361
|
and additional debugging information in your browser.
|
|
2296
2362
|
|
|
2363
|
+
### Behavior with `raise_errors` option
|
|
2364
|
+
|
|
2365
|
+
When `raise_errors` option is `true`, errors that are unhandled are raised
|
|
2366
|
+
outside of the application. Additionally, any errors that would have been
|
|
2367
|
+
caught by the catch-all error handler are raised.
|
|
2368
|
+
|
|
2369
|
+
For example, consider the following configuration:
|
|
2370
|
+
|
|
2371
|
+
```ruby
|
|
2372
|
+
# First handler
|
|
2373
|
+
error MyCustomError do
|
|
2374
|
+
'A custom message'
|
|
2375
|
+
end
|
|
2376
|
+
|
|
2377
|
+
# Second handler
|
|
2378
|
+
error do
|
|
2379
|
+
'A catch-all message'
|
|
2380
|
+
end
|
|
2381
|
+
```
|
|
2382
|
+
|
|
2383
|
+
If `raise_errors` is `false`:
|
|
2384
|
+
|
|
2385
|
+
* When `MyCustomError` or descendant is raised, the first handler is invoked.
|
|
2386
|
+
The HTTP response body will contain `"A custom message"`.
|
|
2387
|
+
* When any other error is raised, the second handler is invoked. The HTTP
|
|
2388
|
+
response body will contain `"A catch-all message"`.
|
|
2389
|
+
|
|
2390
|
+
If `raise_errors` is `true`:
|
|
2391
|
+
|
|
2392
|
+
* When `MyCustomError` or descendant is raised, the behavior is identical to
|
|
2393
|
+
when `raise_errors` is `false`, described above.
|
|
2394
|
+
* When any other error is raised, the second handler is *not* invoked, and
|
|
2395
|
+
the error is raised outside of the application.
|
|
2396
|
+
* If the environment is `production`, the HTTP response body will contain
|
|
2397
|
+
a generic error message, e.g. `"An unhandled lowlevel error occurred. The
|
|
2398
|
+
application logs may have details."`
|
|
2399
|
+
* If the environment is not `production`, the HTTP response body will contain
|
|
2400
|
+
the verbose error backtrace.
|
|
2401
|
+
* Regardless of environment, if `show_exceptions` is set to `:after_handler`,
|
|
2402
|
+
the HTTP response body will contain the verbose error backtrace.
|
|
2403
|
+
|
|
2404
|
+
In the `test` environment, `raise_errors` is set to `true` by default. This
|
|
2405
|
+
means that in order to write a test for a catch-all error handler,
|
|
2406
|
+
`raise_errors` must temporarily be set to `false` for that particular test.
|
|
2407
|
+
|
|
2297
2408
|
## Rack Middleware
|
|
2298
2409
|
|
|
2299
2410
|
Sinatra rides on [Rack](https://rack.github.io/), a minimal standard
|
|
@@ -2319,7 +2430,7 @@ end
|
|
|
2319
2430
|
```
|
|
2320
2431
|
|
|
2321
2432
|
The semantics of `use` are identical to those defined for the
|
|
2322
|
-
[Rack::Builder](
|
|
2433
|
+
[Rack::Builder](https://www.rubydoc.info/github/rack/rack/main/Rack/Builder) DSL
|
|
2323
2434
|
(most frequently used from rackup files). For example, the `use` method
|
|
2324
2435
|
accepts multiple/variable args as well as blocks:
|
|
2325
2436
|
|
|
@@ -2335,7 +2446,7 @@ many of these components automatically based on configuration so you
|
|
|
2335
2446
|
typically don't have to `use` them explicitly.
|
|
2336
2447
|
|
|
2337
2448
|
You can find useful middleware in
|
|
2338
|
-
[rack](https://github.com/rack/rack/tree/
|
|
2449
|
+
[rack](https://github.com/rack/rack/tree/main/lib/rack),
|
|
2339
2450
|
[rack-contrib](https://github.com/rack/rack-contrib#readme),
|
|
2340
2451
|
or in the [Rack wiki](https://github.com/rack/rack/wiki/List-of-Middleware).
|
|
2341
2452
|
|
|
@@ -2343,7 +2454,7 @@ or in the [Rack wiki](https://github.com/rack/rack/wiki/List-of-Middleware).
|
|
|
2343
2454
|
|
|
2344
2455
|
Sinatra tests can be written using any Rack-based testing library or
|
|
2345
2456
|
framework.
|
|
2346
|
-
[Rack::Test](
|
|
2457
|
+
[Rack::Test](https://www.rubydoc.info/github/rack/rack-test/main/frames)
|
|
2347
2458
|
is recommended:
|
|
2348
2459
|
|
|
2349
2460
|
```ruby
|
|
@@ -2838,7 +2949,7 @@ Running Sinatra on a not officially supported Ruby flavor means that if things o
|
|
|
2838
2949
|
## The Bleeding Edge
|
|
2839
2950
|
|
|
2840
2951
|
If you would like to use Sinatra's latest bleeding-edge code, feel free
|
|
2841
|
-
to run your application against the
|
|
2952
|
+
to run your application against the main branch, it should be rather
|
|
2842
2953
|
stable.
|
|
2843
2954
|
|
|
2844
2955
|
We also push out prerelease gems from time to time, so you can do a
|
|
@@ -2887,20 +2998,19 @@ SemVerTag.
|
|
|
2887
2998
|
|
|
2888
2999
|
## Further Reading
|
|
2889
3000
|
|
|
2890
|
-
* [Project Website](
|
|
3001
|
+
* [Project Website](https://sinatrarb.com/) - Additional documentation,
|
|
2891
3002
|
news, and links to other resources.
|
|
2892
|
-
* [Contributing](
|
|
3003
|
+
* [Contributing](https://sinatrarb.com/contributing) - Find a bug? Need
|
|
2893
3004
|
help? Have a patch?
|
|
2894
3005
|
* [Issue tracker](https://github.com/sinatra/sinatra/issues)
|
|
2895
3006
|
* [Twitter](https://twitter.com/sinatra)
|
|
2896
3007
|
* [Mailing List](https://groups.google.com/forum/#!forum/sinatrarb)
|
|
2897
3008
|
* IRC: [#sinatra](irc://chat.freenode.net/#sinatra) on [Freenode](https://freenode.net)
|
|
2898
|
-
* [Sinatra & Friends](https://
|
|
2899
|
-
([get an invite](https://sinatra-slack.herokuapp.com/))
|
|
3009
|
+
* [Sinatra & Friends](https://discord.gg/ncjsfsNHh7) on Discord
|
|
2900
3010
|
* [Sinatra Book](https://github.com/sinatra/sinatra-book) - Cookbook Tutorial
|
|
2901
3011
|
* [Sinatra Recipes](http://recipes.sinatrarb.com/) - Community contributed
|
|
2902
3012
|
recipes
|
|
2903
|
-
* API documentation for the [latest release](
|
|
2904
|
-
or the [current HEAD](
|
|
2905
|
-
[RubyDoc](
|
|
2906
|
-
* [CI
|
|
3013
|
+
* API documentation for the [latest release](https://www.rubydoc.info/gems/sinatra)
|
|
3014
|
+
or the [current HEAD](https://www.rubydoc.info/github/sinatra/sinatra) on
|
|
3015
|
+
[RubyDoc](https://www.rubydoc.info/)
|
|
3016
|
+
* [CI Actions](https://github.com/sinatra/sinatra/actions)
|
data/Rakefile
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'rake/clean'
|
|
4
|
-
require '
|
|
4
|
+
require 'minitest/test_task'
|
|
5
5
|
require 'fileutils'
|
|
6
6
|
require 'date'
|
|
7
7
|
|
|
8
8
|
task default: :test
|
|
9
|
-
task spec: :test
|
|
10
|
-
|
|
11
|
-
CLEAN.include '**/*.rbc'
|
|
12
9
|
|
|
13
10
|
def source_version
|
|
14
11
|
@source_version ||= File.read(File.expand_path('VERSION', __dir__)).strip
|
|
@@ -24,27 +21,20 @@ def prev_version
|
|
|
24
21
|
source_version.gsub(/\d+$/) { |s| s.to_i - 1 }
|
|
25
22
|
end
|
|
26
23
|
|
|
27
|
-
#
|
|
24
|
+
# Tests ===============================================================
|
|
28
25
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
t.ruby_opts = ['-r rubygems'] if defined? Gem
|
|
26
|
+
Minitest::TestTask.create # Default `test` task
|
|
27
|
+
Minitest::TestTask.create(:'test:core') do |t|
|
|
32
28
|
t.warning = true
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
Rake::TestTask.new(:'test:core') do |t|
|
|
36
|
-
core_tests = %w[
|
|
29
|
+
t.test_globs = %w[
|
|
37
30
|
base delegator encoding extensions filter
|
|
38
31
|
helpers mapped_error middleware rdoc
|
|
39
32
|
readme request response result route_added_hook
|
|
40
33
|
routing server settings sinatra static templates
|
|
41
|
-
]
|
|
42
|
-
t.test_files = core_tests.map { |n| "test/#{n}_test.rb" }
|
|
43
|
-
t.ruby_opts = ['-r rubygems'] if defined? Gem
|
|
44
|
-
t.warning = true
|
|
34
|
+
].map { |n| "test/#{n}_test.rb" }
|
|
45
35
|
end
|
|
46
36
|
|
|
47
|
-
#
|
|
37
|
+
# Test code coverage ==================================================
|
|
48
38
|
|
|
49
39
|
namespace :test do
|
|
50
40
|
desc 'Measures test coverage'
|
|
@@ -54,6 +44,7 @@ namespace :test do
|
|
|
54
44
|
Rake::Task['test'].invoke
|
|
55
45
|
end
|
|
56
46
|
end
|
|
47
|
+
CLEAN.include('coverage')
|
|
57
48
|
|
|
58
49
|
# Website =============================================================
|
|
59
50
|
|
|
@@ -208,11 +199,11 @@ if defined?(Gem)
|
|
|
208
199
|
rack-protection/lib/rack/protection
|
|
209
200
|
].each do |path|
|
|
210
201
|
path = File.join(path, 'version.rb')
|
|
211
|
-
|
|
202
|
+
File.write(path, File.read(path).sub(/VERSION = '(.+?)'/, "VERSION = '#{source_version}'"))
|
|
212
203
|
end
|
|
213
204
|
|
|
214
|
-
#git commit --allow-empty -a -m '#{source_version} release' &&
|
|
215
205
|
sh <<-SH
|
|
206
|
+
git commit --allow-empty -a -m '#{source_version} release' &&
|
|
216
207
|
git tag -s v#{source_version} -m '#{source_version} release' &&
|
|
217
208
|
git push && (git push origin || true) &&
|
|
218
209
|
git push --tags && (git push origin --tags || true)
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.
|
|
1
|
+
3.1.0
|
data/examples/chat.rb
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env ruby -I ../lib -I lib
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
# This example does *not* work properly with WEBrick or other
|
|
5
|
+
# servers that buffer output. To shut down the server, close any
|
|
6
|
+
# open browser tabs that are connected to the chat server.
|
|
5
7
|
|
|
6
8
|
require 'sinatra'
|
|
7
|
-
set :server, :
|
|
8
|
-
connections =
|
|
9
|
+
set :server, :puma
|
|
10
|
+
connections = Set.new
|
|
9
11
|
|
|
10
12
|
get '/' do
|
|
11
13
|
halt erb(:login) unless params[:user]
|
|
@@ -14,13 +16,22 @@ end
|
|
|
14
16
|
|
|
15
17
|
get '/stream', provides: 'text/event-stream' do
|
|
16
18
|
stream :keep_open do |out|
|
|
17
|
-
connections
|
|
18
|
-
|
|
19
|
+
if connections.add?(out)
|
|
20
|
+
out.callback { connections.delete(out) }
|
|
21
|
+
end
|
|
22
|
+
out << "heartbeat:\n"
|
|
23
|
+
sleep 1
|
|
24
|
+
rescue
|
|
25
|
+
out.close
|
|
19
26
|
end
|
|
20
27
|
end
|
|
21
28
|
|
|
22
29
|
post '/' do
|
|
23
|
-
connections.each
|
|
30
|
+
connections.each do |out|
|
|
31
|
+
out << "data: #{params[:msg]}\n\n"
|
|
32
|
+
rescue
|
|
33
|
+
out.close
|
|
34
|
+
end
|
|
24
35
|
204 # response without entity body
|
|
25
36
|
end
|
|
26
37
|
|
|
@@ -37,10 +48,10 @@ __END__
|
|
|
37
48
|
</html>
|
|
38
49
|
|
|
39
50
|
@@ login
|
|
40
|
-
<form action=
|
|
51
|
+
<form action="/">
|
|
41
52
|
<label for='user'>User Name:</label>
|
|
42
|
-
<input name=
|
|
43
|
-
<input type=
|
|
53
|
+
<input name="user" value="" />
|
|
54
|
+
<input type="submit" value="GO!" />
|
|
44
55
|
</form>
|
|
45
56
|
|
|
46
57
|
@@ chat
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/usr/bin/env ruby -I ../lib -I lib
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'sinatra'
|
|
5
|
+
|
|
6
|
+
get('/') do
|
|
7
|
+
'This shows how lifecycle events work'
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
on_start do
|
|
11
|
+
puts "=============="
|
|
12
|
+
puts " Booting up"
|
|
13
|
+
puts "=============="
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
on_stop do
|
|
17
|
+
puts "================="
|
|
18
|
+
puts " Shutting down"
|
|
19
|
+
puts "================="
|
|
20
|
+
end
|
data/examples/stream.ru
CHANGED
data/lib/sinatra/base.rb
CHANGED
|
@@ -19,7 +19,7 @@ require 'sinatra/version'
|
|
|
19
19
|
|
|
20
20
|
module Sinatra
|
|
21
21
|
# The request object. See Rack::Request for more info:
|
|
22
|
-
#
|
|
22
|
+
# https://rubydoc.info/github/rack/rack/main/Rack/Request
|
|
23
23
|
class Request < Rack::Request
|
|
24
24
|
HEADER_PARAM = /\s*[\w.]+=(?:[\w.]+|"(?:[^"\\]|\\.)*")?\s*/.freeze
|
|
25
25
|
HEADER_VALUE_WITH_PARAMS = %r{(?:(?:\w+|\*)/(?:\w+(?:\.|-|\+)?|\*)*)\s*(?:;#{HEADER_PARAM})*}.freeze
|
|
@@ -158,8 +158,8 @@ module Sinatra
|
|
|
158
158
|
|
|
159
159
|
# The response object. See Rack::Response and Rack::Response::Helpers for
|
|
160
160
|
# more info:
|
|
161
|
-
#
|
|
162
|
-
#
|
|
161
|
+
# https://rubydoc.info/github/rack/rack/main/Rack/Response
|
|
162
|
+
# https://rubydoc.info/github/rack/rack/main/Rack/Response/Helpers
|
|
163
163
|
class Response < Rack::Response
|
|
164
164
|
DROP_BODY_RESPONSES = [204, 304].freeze
|
|
165
165
|
|
|
@@ -291,7 +291,7 @@ module Sinatra
|
|
|
291
291
|
elsif value
|
|
292
292
|
# Rack 2.0 returns a Rack::File::Iterator here instead of
|
|
293
293
|
# Rack::File as it was in the previous API.
|
|
294
|
-
unless request.head? || value.is_a?(Rack::
|
|
294
|
+
unless request.head? || value.is_a?(Rack::Files::Iterator) || value.is_a?(Stream)
|
|
295
295
|
headers.delete 'Content-Length'
|
|
296
296
|
end
|
|
297
297
|
response.body = value
|
|
@@ -317,7 +317,7 @@ module Sinatra
|
|
|
317
317
|
# Generates the absolute URI for a given path in the app.
|
|
318
318
|
# Takes Rack routers and reverse proxies into account.
|
|
319
319
|
def uri(addr = nil, absolute = true, add_script_name = true)
|
|
320
|
-
return addr if addr =~ /\A[a-z][a-z0-9+.\-]*:/i
|
|
320
|
+
return addr if addr.to_s =~ /\A[a-z][a-z0-9+.\-]*:/i
|
|
321
321
|
|
|
322
322
|
uri = [host = String.new]
|
|
323
323
|
if absolute
|
|
@@ -396,13 +396,20 @@ module Sinatra
|
|
|
396
396
|
response['Content-Type'] = mime_type
|
|
397
397
|
end
|
|
398
398
|
|
|
399
|
+
# https://html.spec.whatwg.org/#multipart-form-data
|
|
400
|
+
MULTIPART_FORM_DATA_REPLACEMENT_TABLE = {
|
|
401
|
+
'"' => '%22',
|
|
402
|
+
"\r" => '%0D',
|
|
403
|
+
"\n" => '%0A'
|
|
404
|
+
}.freeze
|
|
405
|
+
|
|
399
406
|
# Set the Content-Disposition to "attachment" with the specified filename,
|
|
400
407
|
# instructing the user agents to prompt to save.
|
|
401
408
|
def attachment(filename = nil, disposition = :attachment)
|
|
402
409
|
response['Content-Disposition'] = disposition.to_s.dup
|
|
403
410
|
return unless filename
|
|
404
411
|
|
|
405
|
-
params = format('; filename="%s"', File.basename(filename))
|
|
412
|
+
params = format('; filename="%s"', File.basename(filename).gsub(/["\r\n]/, MULTIPART_FORM_DATA_REPLACEMENT_TABLE))
|
|
406
413
|
response['Content-Disposition'] << params
|
|
407
414
|
ext = File.extname(filename)
|
|
408
415
|
content_type(ext) unless response['Content-Type'] || ext.empty?
|
|
@@ -422,7 +429,7 @@ module Sinatra
|
|
|
422
429
|
|
|
423
430
|
last_modified opts[:last_modified] if opts[:last_modified]
|
|
424
431
|
|
|
425
|
-
file = Rack::
|
|
432
|
+
file = Rack::Files.new(File.dirname(settings.app_file))
|
|
426
433
|
result = file.serving(request, path)
|
|
427
434
|
|
|
428
435
|
result[1].each { |k, v| headers[k] ||= v }
|
|
@@ -467,8 +474,9 @@ module Sinatra
|
|
|
467
474
|
@back.call(self)
|
|
468
475
|
rescue Exception => e
|
|
469
476
|
@scheduler.schedule { raise e }
|
|
477
|
+
ensure
|
|
478
|
+
close unless @keep_open
|
|
470
479
|
end
|
|
471
|
-
close unless @keep_open
|
|
472
480
|
end
|
|
473
481
|
end
|
|
474
482
|
|
|
@@ -499,7 +507,16 @@ module Sinatra
|
|
|
499
507
|
def stream(keep_open = false)
|
|
500
508
|
scheduler = env['async.callback'] ? EventMachine : Stream
|
|
501
509
|
current = @params.dup
|
|
502
|
-
|
|
510
|
+
stream = if scheduler == Stream && keep_open
|
|
511
|
+
Stream.new(scheduler, false) do |out|
|
|
512
|
+
until out.closed?
|
|
513
|
+
with_params(current) { yield(out) }
|
|
514
|
+
end
|
|
515
|
+
end
|
|
516
|
+
else
|
|
517
|
+
Stream.new(scheduler, keep_open) { |out| with_params(current) { yield(out) } }
|
|
518
|
+
end
|
|
519
|
+
body stream
|
|
503
520
|
end
|
|
504
521
|
|
|
505
522
|
# Specify response freshness policy for HTTP caches (Cache-Control header).
|
|
@@ -709,7 +726,7 @@ module Sinatra
|
|
|
709
726
|
# Possible options are:
|
|
710
727
|
# :content_type The content type to use, same arguments as content_type.
|
|
711
728
|
# :layout If set to something falsy, no layout is rendered, otherwise
|
|
712
|
-
# the specified layout is used
|
|
729
|
+
# the specified layout is used (Ignored for `sass`)
|
|
713
730
|
# :layout_engine Engine to use for rendering the layout.
|
|
714
731
|
# :locals A hash with local variables that should be available
|
|
715
732
|
# in the template
|
|
@@ -735,6 +752,20 @@ module Sinatra
|
|
|
735
752
|
render(:haml, template, options, locals, &block)
|
|
736
753
|
end
|
|
737
754
|
|
|
755
|
+
def sass(template, options = {}, locals = {})
|
|
756
|
+
options[:default_content_type] = :css
|
|
757
|
+
options[:exclude_outvar] = true
|
|
758
|
+
options[:layout] = nil
|
|
759
|
+
render :sass, template, options, locals
|
|
760
|
+
end
|
|
761
|
+
|
|
762
|
+
def scss(template, options = {}, locals = {})
|
|
763
|
+
options[:default_content_type] = :css
|
|
764
|
+
options[:exclude_outvar] = true
|
|
765
|
+
options[:layout] = nil
|
|
766
|
+
render :scss, template, options, locals
|
|
767
|
+
end
|
|
768
|
+
|
|
738
769
|
def builder(template = nil, options = {}, locals = {}, &block)
|
|
739
770
|
options[:default_content_type] = :xml
|
|
740
771
|
render_ruby(:builder, template, options, locals, &block)
|
|
@@ -845,7 +876,11 @@ module Sinatra
|
|
|
845
876
|
catch(:layout_missing) { return render(layout_engine, layout, options, locals) { output } }
|
|
846
877
|
end
|
|
847
878
|
|
|
848
|
-
|
|
879
|
+
if content_type
|
|
880
|
+
# sass-embedded returns a frozen string
|
|
881
|
+
output = +output
|
|
882
|
+
output.extend(ContentTyped).content_type = content_type
|
|
883
|
+
end
|
|
849
884
|
output
|
|
850
885
|
end
|
|
851
886
|
|
|
@@ -897,6 +932,35 @@ module Sinatra
|
|
|
897
932
|
end
|
|
898
933
|
end
|
|
899
934
|
|
|
935
|
+
# Extremely simple template cache implementation.
|
|
936
|
+
# * Not thread-safe.
|
|
937
|
+
# * Size is unbounded.
|
|
938
|
+
# * Keys are not copied defensively, and should not be modified after
|
|
939
|
+
# being passed to #fetch. More specifically, the values returned by
|
|
940
|
+
# key#hash and key#eql? should not change.
|
|
941
|
+
#
|
|
942
|
+
# Implementation copied from Tilt::Cache.
|
|
943
|
+
class TemplateCache
|
|
944
|
+
def initialize
|
|
945
|
+
@cache = {}
|
|
946
|
+
end
|
|
947
|
+
|
|
948
|
+
# Caches a value for key, or returns the previously cached value.
|
|
949
|
+
# If a value has been previously cached for key then it is
|
|
950
|
+
# returned. Otherwise, block is yielded to and its return value
|
|
951
|
+
# which may be nil, is cached under key and returned.
|
|
952
|
+
def fetch(*key)
|
|
953
|
+
@cache.fetch(key) do
|
|
954
|
+
@cache[key] = yield
|
|
955
|
+
end
|
|
956
|
+
end
|
|
957
|
+
|
|
958
|
+
# Clears the cache.
|
|
959
|
+
def clear
|
|
960
|
+
@cache = {}
|
|
961
|
+
end
|
|
962
|
+
end
|
|
963
|
+
|
|
900
964
|
# Base class for all Sinatra applications and middleware.
|
|
901
965
|
class Base
|
|
902
966
|
include Rack::Utils
|
|
@@ -911,7 +975,7 @@ module Sinatra
|
|
|
911
975
|
def initialize(app = nil, **_kwargs)
|
|
912
976
|
super()
|
|
913
977
|
@app = app
|
|
914
|
-
@template_cache =
|
|
978
|
+
@template_cache = TemplateCache.new
|
|
915
979
|
@pinned_response = nil # whether a before! filter pinned the content-type
|
|
916
980
|
yield self if block_given?
|
|
917
981
|
end
|
|
@@ -1209,10 +1273,15 @@ module Sinatra
|
|
|
1209
1273
|
%r{rubygems/(custom|core_ext/kernel)_require\.rb$}, # rubygems require hacks
|
|
1210
1274
|
/active_support/, # active_support require hacks
|
|
1211
1275
|
%r{bundler(/(?:runtime|inline))?\.rb}, # bundler require hacks
|
|
1212
|
-
/<internal
|
|
1276
|
+
/<internal:/, # internal in ruby >= 1.9.2
|
|
1277
|
+
%r{zeitwerk/kernel\.rb} # Zeitwerk kernel#require decorator
|
|
1213
1278
|
].freeze
|
|
1214
1279
|
|
|
1215
|
-
attr_reader :routes, :filters, :templates, :errors
|
|
1280
|
+
attr_reader :routes, :filters, :templates, :errors, :on_start_callback, :on_stop_callback
|
|
1281
|
+
|
|
1282
|
+
def callers_to_ignore
|
|
1283
|
+
CALLERS_TO_IGNORE
|
|
1284
|
+
end
|
|
1216
1285
|
|
|
1217
1286
|
# Removes all routes, filters, middleware and extension hooks from the
|
|
1218
1287
|
# current class (not routes/filters/... defined by its superclass).
|
|
@@ -1401,6 +1470,14 @@ module Sinatra
|
|
|
1401
1470
|
filters[type] << compile!(type, path, block, **options)
|
|
1402
1471
|
end
|
|
1403
1472
|
|
|
1473
|
+
def on_start(&on_start_callback)
|
|
1474
|
+
@on_start_callback = on_start_callback
|
|
1475
|
+
end
|
|
1476
|
+
|
|
1477
|
+
def on_stop(&on_stop_callback)
|
|
1478
|
+
@on_stop_callback = on_stop_callback
|
|
1479
|
+
end
|
|
1480
|
+
|
|
1404
1481
|
# Add a route condition. The route is considered non-matching when the
|
|
1405
1482
|
# block returns false.
|
|
1406
1483
|
def condition(name = "#{caller.first[/`.*'/]} condition", &block)
|
|
@@ -1408,7 +1485,7 @@ module Sinatra
|
|
|
1408
1485
|
end
|
|
1409
1486
|
|
|
1410
1487
|
def public=(value)
|
|
1411
|
-
|
|
1488
|
+
warn_for_deprecation ':public is no longer used to avoid overloading Module#public, use :public_folder or :public_dir instead'
|
|
1412
1489
|
set(:public_folder, value)
|
|
1413
1490
|
end
|
|
1414
1491
|
|
|
@@ -1490,12 +1567,14 @@ module Sinatra
|
|
|
1490
1567
|
warn '== Sinatra has ended his set (crowd applauds)' unless suppress_messages?
|
|
1491
1568
|
set :running_server, nil
|
|
1492
1569
|
set :handler_name, nil
|
|
1570
|
+
|
|
1571
|
+
on_stop_callback.call unless on_stop_callback.nil?
|
|
1493
1572
|
end
|
|
1494
1573
|
|
|
1495
1574
|
alias stop! quit!
|
|
1496
1575
|
|
|
1497
1576
|
# Run the Sinatra app as a self-hosted server using
|
|
1498
|
-
# Puma, Falcon,
|
|
1577
|
+
# Puma, Falcon, or WEBrick (in that order). If given a block, will call
|
|
1499
1578
|
# with the constructed handler once we have taken the stage.
|
|
1500
1579
|
def run!(options = {}, &block)
|
|
1501
1580
|
return if running?
|
|
@@ -1577,7 +1656,7 @@ module Sinatra
|
|
|
1577
1656
|
set :running_server, server
|
|
1578
1657
|
set :handler_name, handler_name
|
|
1579
1658
|
server.threaded = settings.threaded if server.respond_to? :threaded=
|
|
1580
|
-
|
|
1659
|
+
on_start_callback.call unless on_start_callback.nil?
|
|
1581
1660
|
yield server if block_given?
|
|
1582
1661
|
end
|
|
1583
1662
|
end
|
|
@@ -1772,15 +1851,15 @@ module Sinatra
|
|
|
1772
1851
|
end
|
|
1773
1852
|
|
|
1774
1853
|
# used for deprecation warnings
|
|
1775
|
-
def
|
|
1776
|
-
|
|
1854
|
+
def warn_for_deprecation(message)
|
|
1855
|
+
warn message + "\n\tfrom #{cleaned_caller.first.join(':')}"
|
|
1777
1856
|
end
|
|
1778
1857
|
|
|
1779
1858
|
# Like Kernel#caller but excluding certain magic entries
|
|
1780
1859
|
def cleaned_caller(keep = 3)
|
|
1781
1860
|
caller(1)
|
|
1782
1861
|
.map! { |line| line.split(/:(?=\d|in )/, 3)[0, keep] }
|
|
1783
|
-
.reject { |file, *_|
|
|
1862
|
+
.reject { |file, *_| callers_to_ignore.any? { |pattern| file =~ pattern } }
|
|
1784
1863
|
end
|
|
1785
1864
|
end
|
|
1786
1865
|
|
|
@@ -1826,8 +1905,9 @@ module Sinatra
|
|
|
1826
1905
|
begin
|
|
1827
1906
|
require 'securerandom'
|
|
1828
1907
|
set :session_secret, SecureRandom.hex(64)
|
|
1829
|
-
rescue LoadError, NotImplementedError
|
|
1908
|
+
rescue LoadError, NotImplementedError, RuntimeError
|
|
1830
1909
|
# SecureRandom raises a NotImplementedError if no random device is available
|
|
1910
|
+
# RuntimeError raised due to broken openssl backend: https://bugs.ruby-lang.org/issues/19230
|
|
1831
1911
|
set :session_secret, format('%064x', Kernel.rand((2**256) - 1))
|
|
1832
1912
|
end
|
|
1833
1913
|
|
|
@@ -1847,11 +1927,10 @@ module Sinatra
|
|
|
1847
1927
|
|
|
1848
1928
|
ruby_engine = defined?(RUBY_ENGINE) && RUBY_ENGINE
|
|
1849
1929
|
|
|
1850
|
-
server.unshift 'puma'
|
|
1851
|
-
server.unshift 'falcon' if ruby_engine != 'jruby'
|
|
1852
|
-
server.unshift 'mongrel' if ruby_engine.nil?
|
|
1853
1930
|
server.unshift 'thin' if ruby_engine != 'jruby'
|
|
1931
|
+
server.unshift 'falcon' if ruby_engine != 'jruby'
|
|
1854
1932
|
server.unshift 'trinidad' if ruby_engine == 'jruby'
|
|
1933
|
+
server.unshift 'puma'
|
|
1855
1934
|
|
|
1856
1935
|
set :absolute_redirects, true
|
|
1857
1936
|
set :prefixed_redirects, false
|
|
@@ -1968,7 +2047,7 @@ module Sinatra
|
|
|
1968
2047
|
delegate :get, :patch, :put, :post, :delete, :head, :options, :link, :unlink,
|
|
1969
2048
|
:template, :layout, :before, :after, :error, :not_found, :configure,
|
|
1970
2049
|
:set, :mime_type, :enable, :disable, :use, :development?, :test?,
|
|
1971
|
-
:production?, :helpers, :settings, :register
|
|
2050
|
+
:production?, :helpers, :settings, :register, :on_start, :on_stop
|
|
1972
2051
|
|
|
1973
2052
|
class << self
|
|
1974
2053
|
attr_accessor :target
|
data/lib/sinatra/version.rb
CHANGED
data/sinatra.gemspec
CHANGED
|
@@ -36,7 +36,7 @@ RubyGems 2.0 or newer is required to protect against public gem pushes. You can
|
|
|
36
36
|
|
|
37
37
|
s.metadata = {
|
|
38
38
|
'source_code_uri' => 'https://github.com/sinatra/sinatra',
|
|
39
|
-
'changelog_uri' => 'https://github.com/sinatra/sinatra/blob/
|
|
39
|
+
'changelog_uri' => 'https://github.com/sinatra/sinatra/blob/main/CHANGELOG.md',
|
|
40
40
|
'homepage_uri' => 'http://sinatrarb.com/',
|
|
41
41
|
'bug_tracker_uri' => 'https://github.com/sinatra/sinatra/issues',
|
|
42
42
|
'mailing_list_uri' => 'http://groups.google.com/group/sinatrarb',
|
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: 3.
|
|
4
|
+
version: 3.1.0
|
|
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: 2023-08-07 00:00:00.000000000 Z
|
|
15
15
|
dependencies:
|
|
16
16
|
- !ruby/object:Gem::Dependency
|
|
17
17
|
name: mustermann
|
|
@@ -53,14 +53,14 @@ dependencies:
|
|
|
53
53
|
requirements:
|
|
54
54
|
- - '='
|
|
55
55
|
- !ruby/object:Gem::Version
|
|
56
|
-
version: 3.
|
|
56
|
+
version: 3.1.0
|
|
57
57
|
type: :runtime
|
|
58
58
|
prerelease: false
|
|
59
59
|
version_requirements: !ruby/object:Gem::Requirement
|
|
60
60
|
requirements:
|
|
61
61
|
- - '='
|
|
62
62
|
- !ruby/object:Gem::Version
|
|
63
|
-
version: 3.
|
|
63
|
+
version: 3.1.0
|
|
64
64
|
- !ruby/object:Gem::Dependency
|
|
65
65
|
name: tilt
|
|
66
66
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -110,6 +110,7 @@ files:
|
|
|
110
110
|
- SECURITY.md
|
|
111
111
|
- VERSION
|
|
112
112
|
- examples/chat.rb
|
|
113
|
+
- examples/lifecycle_events.rb
|
|
113
114
|
- examples/rainbows.conf
|
|
114
115
|
- examples/rainbows.rb
|
|
115
116
|
- examples/simple.rb
|
|
@@ -128,7 +129,7 @@ licenses:
|
|
|
128
129
|
- MIT
|
|
129
130
|
metadata:
|
|
130
131
|
source_code_uri: https://github.com/sinatra/sinatra
|
|
131
|
-
changelog_uri: https://github.com/sinatra/sinatra/blob/
|
|
132
|
+
changelog_uri: https://github.com/sinatra/sinatra/blob/main/CHANGELOG.md
|
|
132
133
|
homepage_uri: http://sinatrarb.com/
|
|
133
134
|
bug_tracker_uri: https://github.com/sinatra/sinatra/issues
|
|
134
135
|
mailing_list_uri: http://groups.google.com/group/sinatrarb
|
|
@@ -154,7 +155,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
154
155
|
- !ruby/object:Gem::Version
|
|
155
156
|
version: '0'
|
|
156
157
|
requirements: []
|
|
157
|
-
rubygems_version: 3.
|
|
158
|
+
rubygems_version: 3.4.18
|
|
158
159
|
signing_key:
|
|
159
160
|
specification_version: 4
|
|
160
161
|
summary: Classy web-development dressed in a DSL
|