sinatra 3.0.5 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +28 -0
- data/CONTRIBUTING.md +11 -11
- data/Gemfile +10 -3
- data/MAINTENANCE.md +2 -2
- data/README.md +124 -14
- data/Rakefile +8 -17
- 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 +86 -19
- 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
@@ -2,6 +2,34 @@
|
|
2
2
|
|
3
3
|
* _Your new feature here._
|
4
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
|
+
|
5
33
|
## 3.0.5 / 2022-12-16
|
6
34
|
|
7
35
|
* Fix: Add Zeitwerk compatibility. [#1831](https://github.com/sinatra/sinatra/pull/1831) by Dawid Janczak
|
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,12 +15,12 @@ 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
21
|
puma_version = ENV['puma'].to_s
|
22
22
|
puma_version = nil if puma_version.empty? || (puma_version == 'stable')
|
23
|
-
puma_version = { github: 'puma/puma' } if puma_version == '
|
23
|
+
puma_version = { github: 'puma/puma' } if puma_version == 'head'
|
24
24
|
gem 'puma', puma_version
|
25
25
|
|
26
26
|
gem 'minitest', '~> 5.0'
|
@@ -31,6 +31,12 @@ gem 'yard'
|
|
31
31
|
gem 'rack-protection', path: 'rack-protection'
|
32
32
|
gem 'sinatra-contrib', path: 'sinatra-contrib'
|
33
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
|
+
|
34
40
|
gem 'activesupport', '~> 6.1'
|
35
41
|
|
36
42
|
gem 'asciidoctor'
|
@@ -39,7 +45,7 @@ gem 'commonmarker', '~> 0.23.4', platforms: [:ruby]
|
|
39
45
|
gem 'erubi'
|
40
46
|
gem 'eventmachine'
|
41
47
|
gem 'falcon', '~> 0.40', platforms: [:ruby]
|
42
|
-
gem 'haml', '~>
|
48
|
+
gem 'haml', '~> 6'
|
43
49
|
gem 'kramdown'
|
44
50
|
gem 'liquid'
|
45
51
|
gem 'markaby'
|
@@ -50,6 +56,7 @@ gem 'rainbows', platforms: [:mri] # uses #fork
|
|
50
56
|
gem 'rdiscount', platforms: [:ruby]
|
51
57
|
gem 'rdoc'
|
52
58
|
gem 'redcarpet', platforms: [:ruby]
|
59
|
+
gem 'sass-embedded', '~> 1.54'
|
53
60
|
gem 'simplecov', require: false
|
54
61
|
gem 'slim', '~> 4'
|
55
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
|
|
@@ -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](
|
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/)
|
2906
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
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.0
|
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
|
@@ -429,7 +429,7 @@ module Sinatra
|
|
429
429
|
|
430
430
|
last_modified opts[:last_modified] if opts[:last_modified]
|
431
431
|
|
432
|
-
file = Rack::
|
432
|
+
file = Rack::Files.new(File.dirname(settings.app_file))
|
433
433
|
result = file.serving(request, path)
|
434
434
|
|
435
435
|
result[1].each { |k, v| headers[k] ||= v }
|
@@ -474,8 +474,9 @@ module Sinatra
|
|
474
474
|
@back.call(self)
|
475
475
|
rescue Exception => e
|
476
476
|
@scheduler.schedule { raise e }
|
477
|
+
ensure
|
478
|
+
close unless @keep_open
|
477
479
|
end
|
478
|
-
close unless @keep_open
|
479
480
|
end
|
480
481
|
end
|
481
482
|
|
@@ -506,7 +507,16 @@ module Sinatra
|
|
506
507
|
def stream(keep_open = false)
|
507
508
|
scheduler = env['async.callback'] ? EventMachine : Stream
|
508
509
|
current = @params.dup
|
509
|
-
|
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
|
510
520
|
end
|
511
521
|
|
512
522
|
# Specify response freshness policy for HTTP caches (Cache-Control header).
|
@@ -716,7 +726,7 @@ module Sinatra
|
|
716
726
|
# Possible options are:
|
717
727
|
# :content_type The content type to use, same arguments as content_type.
|
718
728
|
# :layout If set to something falsy, no layout is rendered, otherwise
|
719
|
-
# the specified layout is used
|
729
|
+
# the specified layout is used (Ignored for `sass`)
|
720
730
|
# :layout_engine Engine to use for rendering the layout.
|
721
731
|
# :locals A hash with local variables that should be available
|
722
732
|
# in the template
|
@@ -742,6 +752,20 @@ module Sinatra
|
|
742
752
|
render(:haml, template, options, locals, &block)
|
743
753
|
end
|
744
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
|
+
|
745
769
|
def builder(template = nil, options = {}, locals = {}, &block)
|
746
770
|
options[:default_content_type] = :xml
|
747
771
|
render_ruby(:builder, template, options, locals, &block)
|
@@ -852,7 +876,11 @@ module Sinatra
|
|
852
876
|
catch(:layout_missing) { return render(layout_engine, layout, options, locals) { output } }
|
853
877
|
end
|
854
878
|
|
855
|
-
|
879
|
+
if content_type
|
880
|
+
# sass-embedded returns a frozen string
|
881
|
+
output = +output
|
882
|
+
output.extend(ContentTyped).content_type = content_type
|
883
|
+
end
|
856
884
|
output
|
857
885
|
end
|
858
886
|
|
@@ -904,6 +932,35 @@ module Sinatra
|
|
904
932
|
end
|
905
933
|
end
|
906
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
|
+
|
907
964
|
# Base class for all Sinatra applications and middleware.
|
908
965
|
class Base
|
909
966
|
include Rack::Utils
|
@@ -918,7 +975,7 @@ module Sinatra
|
|
918
975
|
def initialize(app = nil, **_kwargs)
|
919
976
|
super()
|
920
977
|
@app = app
|
921
|
-
@template_cache =
|
978
|
+
@template_cache = TemplateCache.new
|
922
979
|
@pinned_response = nil # whether a before! filter pinned the content-type
|
923
980
|
yield self if block_given?
|
924
981
|
end
|
@@ -1220,7 +1277,7 @@ module Sinatra
|
|
1220
1277
|
%r{zeitwerk/kernel\.rb} # Zeitwerk kernel#require decorator
|
1221
1278
|
].freeze
|
1222
1279
|
|
1223
|
-
attr_reader :routes, :filters, :templates, :errors
|
1280
|
+
attr_reader :routes, :filters, :templates, :errors, :on_start_callback, :on_stop_callback
|
1224
1281
|
|
1225
1282
|
def callers_to_ignore
|
1226
1283
|
CALLERS_TO_IGNORE
|
@@ -1413,6 +1470,14 @@ module Sinatra
|
|
1413
1470
|
filters[type] << compile!(type, path, block, **options)
|
1414
1471
|
end
|
1415
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
|
+
|
1416
1481
|
# Add a route condition. The route is considered non-matching when the
|
1417
1482
|
# block returns false.
|
1418
1483
|
def condition(name = "#{caller.first[/`.*'/]} condition", &block)
|
@@ -1502,12 +1567,14 @@ module Sinatra
|
|
1502
1567
|
warn '== Sinatra has ended his set (crowd applauds)' unless suppress_messages?
|
1503
1568
|
set :running_server, nil
|
1504
1569
|
set :handler_name, nil
|
1570
|
+
|
1571
|
+
on_stop_callback.call unless on_stop_callback.nil?
|
1505
1572
|
end
|
1506
1573
|
|
1507
1574
|
alias stop! quit!
|
1508
1575
|
|
1509
1576
|
# Run the Sinatra app as a self-hosted server using
|
1510
|
-
# Puma, Falcon,
|
1577
|
+
# Puma, Falcon, or WEBrick (in that order). If given a block, will call
|
1511
1578
|
# with the constructed handler once we have taken the stage.
|
1512
1579
|
def run!(options = {}, &block)
|
1513
1580
|
return if running?
|
@@ -1589,7 +1656,7 @@ module Sinatra
|
|
1589
1656
|
set :running_server, server
|
1590
1657
|
set :handler_name, handler_name
|
1591
1658
|
server.threaded = settings.threaded if server.respond_to? :threaded=
|
1592
|
-
|
1659
|
+
on_start_callback.call unless on_start_callback.nil?
|
1593
1660
|
yield server if block_given?
|
1594
1661
|
end
|
1595
1662
|
end
|
@@ -1838,8 +1905,9 @@ module Sinatra
|
|
1838
1905
|
begin
|
1839
1906
|
require 'securerandom'
|
1840
1907
|
set :session_secret, SecureRandom.hex(64)
|
1841
|
-
rescue LoadError, NotImplementedError
|
1908
|
+
rescue LoadError, NotImplementedError, RuntimeError
|
1842
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
|
1843
1911
|
set :session_secret, format('%064x', Kernel.rand((2**256) - 1))
|
1844
1912
|
end
|
1845
1913
|
|
@@ -1859,11 +1927,10 @@ module Sinatra
|
|
1859
1927
|
|
1860
1928
|
ruby_engine = defined?(RUBY_ENGINE) && RUBY_ENGINE
|
1861
1929
|
|
1862
|
-
server.unshift 'puma'
|
1863
|
-
server.unshift 'falcon' if ruby_engine != 'jruby'
|
1864
|
-
server.unshift 'mongrel' if ruby_engine.nil?
|
1865
1930
|
server.unshift 'thin' if ruby_engine != 'jruby'
|
1931
|
+
server.unshift 'falcon' if ruby_engine != 'jruby'
|
1866
1932
|
server.unshift 'trinidad' if ruby_engine == 'jruby'
|
1933
|
+
server.unshift 'puma'
|
1867
1934
|
|
1868
1935
|
set :absolute_redirects, true
|
1869
1936
|
set :prefixed_redirects, false
|
@@ -1980,7 +2047,7 @@ module Sinatra
|
|
1980
2047
|
delegate :get, :patch, :put, :post, :delete, :head, :options, :link, :unlink,
|
1981
2048
|
:template, :layout, :before, :after, :error, :not_found, :configure,
|
1982
2049
|
:set, :mime_type, :enable, :disable, :use, :development?, :test?,
|
1983
|
-
:production?, :helpers, :settings, :register
|
2050
|
+
:production?, :helpers, :settings, :register, :on_start, :on_stop
|
1984
2051
|
|
1985
2052
|
class << self
|
1986
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.0
|
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.0
|
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.0
|
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
|