sinatra 2.1.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.
data/README.md CHANGED
@@ -1,8 +1,7 @@
1
1
  # Sinatra
2
2
 
3
- [![Gem Version](https://badge.fury.io/rb/sinatra.svg)](http://badge.fury.io/rb/sinatra)
4
- [![Build Status](https://secure.travis-ci.org/sinatra/sinatra.svg)](https://travis-ci.org/sinatra/sinatra)
5
- [![SemVer](https://api.dependabot.com/badges/compatibility_score?dependency-name=sinatra&package-manager=bundler&version-scheme=semver)](https://dependabot.com/compatibility-score.html?dependency-name=sinatra&package-manager=bundler&version-scheme=semver)
3
+ [![Gem Version](https://badge.fury.io/rb/sinatra.svg)](https://badge.fury.io/rb/sinatra)
4
+ [![Testing](https://github.com/sinatra/sinatra/actions/workflows/test.yml/badge.svg)](https://github.com/sinatra/sinatra/actions/workflows/test.yml)
6
5
 
7
6
  Sinatra is a [DSL](https://en.wikipedia.org/wiki/Domain-specific_language) for
8
7
  quickly creating web applications in Ruby with minimal effort:
@@ -16,10 +15,10 @@ get '/' do
16
15
  end
17
16
  ```
18
17
 
19
- Install the gem:
18
+ Install the gems needed:
20
19
 
21
20
  ```shell
22
- gem install sinatra
21
+ gem install sinatra rackup puma
23
22
  ```
24
23
 
25
24
  And run with:
@@ -31,101 +30,95 @@ ruby myapp.rb
31
30
  View at: [http://localhost:4567](http://localhost:4567)
32
31
 
33
32
  The code you changed will not take effect until you restart the server.
34
- Please restart the server every time you change or use
35
- [sinatra/reloader](http://www.sinatrarb.com/contrib/reloader).
33
+ Please restart the server every time you change or use a code reloader
34
+ like [rerun](https://github.com/alexch/rerun) or
35
+ [rack-unreloader](https://github.com/jeremyevans/rack-unreloader).
36
36
 
37
37
  It is recommended to also run `gem install puma`, which Sinatra will
38
38
  pick up if available.
39
39
 
40
40
  ## Table of Contents
41
41
 
42
- * [Sinatra](#sinatra)
43
- * [Table of Contents](#table-of-contents)
44
- * [Routes](#routes)
45
- * [Conditions](#conditions)
46
- * [Return Values](#return-values)
47
- * [Custom Route Matchers](#custom-route-matchers)
48
- * [Static Files](#static-files)
49
- * [Views / Templates](#views--templates)
50
- * [Literal Templates](#literal-templates)
51
- * [Available Template Languages](#available-template-languages)
52
- * [Haml Templates](#haml-templates)
53
- * [Erb Templates](#erb-templates)
54
- * [Builder Templates](#builder-templates)
55
- * [Nokogiri Templates](#nokogiri-templates)
56
- * [Sass Templates](#sass-templates)
57
- * [SCSS Templates](#scss-templates)
58
- * [Less Templates](#less-templates)
59
- * [Liquid Templates](#liquid-templates)
60
- * [Markdown Templates](#markdown-templates)
61
- * [Textile Templates](#textile-templates)
62
- * [RDoc Templates](#rdoc-templates)
63
- * [AsciiDoc Templates](#asciidoc-templates)
64
- * [Radius Templates](#radius-templates)
65
- * [Markaby Templates](#markaby-templates)
66
- * [RABL Templates](#rabl-templates)
67
- * [Slim Templates](#slim-templates)
68
- * [Creole Templates](#creole-templates)
69
- * [MediaWiki Templates](#mediawiki-templates)
70
- * [CoffeeScript Templates](#coffeescript-templates)
71
- * [Stylus Templates](#stylus-templates)
72
- * [Yajl Templates](#yajl-templates)
73
- * [WLang Templates](#wlang-templates)
74
- * [Accessing Variables in Templates](#accessing-variables-in-templates)
75
- * [Templates with `yield` and nested layouts](#templates-with-yield-and-nested-layouts)
76
- * [Inline Templates](#inline-templates)
77
- * [Named Templates](#named-templates)
78
- * [Associating File Extensions](#associating-file-extensions)
79
- * [Adding Your Own Template Engine](#adding-your-own-template-engine)
80
- * [Using Custom Logic for Template Lookup](#using-custom-logic-for-template-lookup)
81
- * [Filters](#filters)
82
- * [Helpers](#helpers)
83
- * [Using Sessions](#using-sessions)
84
- * [Session Secret Security](#session-secret-security)
85
- * [Session Config](#session-config)
86
- * [Choosing Your Own Session Middleware](#choosing-your-own-session-middleware)
87
- * [Halting](#halting)
88
- * [Passing](#passing)
89
- * [Triggering Another Route](#triggering-another-route)
90
- * [Setting Body, Status Code and Headers](#setting-body-status-code-and-headers)
91
- * [Streaming Responses](#streaming-responses)
92
- * [Logging](#logging)
93
- * [Mime Types](#mime-types)
94
- * [Generating URLs](#generating-urls)
95
- * [Browser Redirect](#browser-redirect)
96
- * [Cache Control](#cache-control)
97
- * [Sending Files](#sending-files)
98
- * [Accessing the Request Object](#accessing-the-request-object)
99
- * [Attachments](#attachments)
100
- * [Dealing with Date and Time](#dealing-with-date-and-time)
101
- * [Looking Up Template Files](#looking-up-template-files)
102
- * [Configuration](#configuration)
103
- * [Configuring attack protection](#configuring-attack-protection)
104
- * [Available Settings](#available-settings)
105
- * [Environments](#environments)
106
- * [Error Handling](#error-handling)
107
- * [Not Found](#not-found)
108
- * [Error](#error)
109
- * [Rack Middleware](#rack-middleware)
110
- * [Testing](#testing)
111
- * [Sinatra::Base - Middleware, Libraries, and Modular Apps](#sinatrabase---middleware-libraries-and-modular-apps)
112
- * [Modular vs. Classic Style](#modular-vs-classic-style)
113
- * [Serving a Modular Application](#serving-a-modular-application)
114
- * [Using a Classic Style Application with a config.ru](#using-a-classic-style-application-with-a-configru)
115
- * [When to use a config.ru?](#when-to-use-a-configru)
116
- * [Using Sinatra as Middleware](#using-sinatra-as-middleware)
117
- * [Dynamic Application Creation](#dynamic-application-creation)
118
- * [Scopes and Binding](#scopes-and-binding)
119
- * [Application/Class Scope](#applicationclass-scope)
120
- * [Request/Instance Scope](#requestinstance-scope)
121
- * [Delegation Scope](#delegation-scope)
122
- * [Command Line](#command-line)
123
- * [Multi-threading](#multi-threading)
124
- * [Requirement](#requirement)
125
- * [The Bleeding Edge](#the-bleeding-edge)
126
- * [With Bundler](#with-bundler)
127
- * [Versioning](#versioning)
128
- * [Further Reading](#further-reading)
42
+ - [Sinatra](#sinatra)
43
+ - [Table of Contents](#table-of-contents)
44
+ - [Routes](#routes)
45
+ - [Conditions](#conditions)
46
+ - [Return Values](#return-values)
47
+ - [Custom Route Matchers](#custom-route-matchers)
48
+ - [Static Files](#static-files)
49
+ - [Views / Templates](#views--templates)
50
+ - [Literal Templates](#literal-templates)
51
+ - [Available Template Languages](#available-template-languages)
52
+ - [Haml Templates](#haml-templates)
53
+ - [Erb Templates](#erb-templates)
54
+ - [Builder Templates](#builder-templates)
55
+ - [Nokogiri Templates](#nokogiri-templates)
56
+ - [Sass Templates](#sass-templates)
57
+ - [Scss Templates](#scss-templates)
58
+ - [Liquid Templates](#liquid-templates)
59
+ - [Markdown Templates](#markdown-templates)
60
+ - [RDoc Templates](#rdoc-templates)
61
+ - [AsciiDoc Templates](#asciidoc-templates)
62
+ - [Markaby Templates](#markaby-templates)
63
+ - [RABL Templates](#rabl-templates)
64
+ - [Slim Templates](#slim-templates)
65
+ - [Yajl Templates](#yajl-templates)
66
+ - [Accessing Variables in Templates](#accessing-variables-in-templates)
67
+ - [Templates with `yield` and nested layouts](#templates-with-yield-and-nested-layouts)
68
+ - [Inline Templates](#inline-templates)
69
+ - [Named Templates](#named-templates)
70
+ - [Associating File Extensions](#associating-file-extensions)
71
+ - [Adding Your Own Template Engine](#adding-your-own-template-engine)
72
+ - [Using Custom Logic for Template Lookup](#using-custom-logic-for-template-lookup)
73
+ - [Filters](#filters)
74
+ - [Helpers](#helpers)
75
+ - [Using Sessions](#using-sessions)
76
+ - [Session Secret Security](#session-secret-security)
77
+ - [Session Config](#session-config)
78
+ - [Choosing Your Own Session Middleware](#choosing-your-own-session-middleware)
79
+ - [Halting](#halting)
80
+ - [Passing](#passing)
81
+ - [Triggering Another Route](#triggering-another-route)
82
+ - [Setting Body, Status Code, and Headers](#setting-body-status-code-and-headers)
83
+ - [Streaming Responses](#streaming-responses)
84
+ - [Logging](#logging)
85
+ - [Mime Types](#mime-types)
86
+ - [Generating URLs](#generating-urls)
87
+ - [Browser Redirect](#browser-redirect)
88
+ - [Cache Control](#cache-control)
89
+ - [Sending Files](#sending-files)
90
+ - [Accessing the Request Object](#accessing-the-request-object)
91
+ - [Attachments](#attachments)
92
+ - [Dealing with Date and Time](#dealing-with-date-and-time)
93
+ - [Looking Up Template Files](#looking-up-template-files)
94
+ - [Configuration](#configuration)
95
+ - [Configuring attack protection](#configuring-attack-protection)
96
+ - [Available Settings](#available-settings)
97
+ - [Lifecycle Events](#lifecycle-events)
98
+ - [Environments](#environments)
99
+ - [Error Handling](#error-handling)
100
+ - [Not Found](#not-found)
101
+ - [Error](#error)
102
+ - [Rack Middleware](#rack-middleware)
103
+ - [Testing](#testing)
104
+ - [Sinatra::Base - Middleware, Libraries, and Modular Apps](#sinatrabase---middleware-libraries-and-modular-apps)
105
+ - [Modular vs. Classic Style](#modular-vs-classic-style)
106
+ - [Serving a Modular Application](#serving-a-modular-application)
107
+ - [Using a Classic Style Application with a config.ru](#using-a-classic-style-application-with-a-configru)
108
+ - [When to use a config.ru?](#when-to-use-a-configru)
109
+ - [Using Sinatra as Middleware](#using-sinatra-as-middleware)
110
+ - [Dynamic Application Creation](#dynamic-application-creation)
111
+ - [Scopes and Binding](#scopes-and-binding)
112
+ - [Application/Class Scope](#applicationclass-scope)
113
+ - [Request/Instance Scope](#requestinstance-scope)
114
+ - [Delegation Scope](#delegation-scope)
115
+ - [Command Line](#command-line)
116
+ - [Multi-threading](#multi-threading)
117
+ - [Requirement](#requirement)
118
+ - [The Bleeding Edge](#the-bleeding-edge)
119
+ - [With Bundler](#with-bundler)
120
+ - [Versioning](#versioning)
121
+ - [Further Reading](#further-reading)
129
122
 
130
123
  ## Routes
131
124
 
@@ -344,11 +337,11 @@ end
344
337
  ## Return Values
345
338
 
346
339
  The return value of a route block determines at least the response body
347
- passed on to the HTTP client, or at least the next middleware in the
340
+ passed on to the HTTP client or at least the next middleware in the
348
341
  Rack stack. Most commonly, this is a string, as in the above examples.
349
342
  But other values are also accepted.
350
343
 
351
- You can return any object that would either be a valid Rack response, Rack
344
+ You can return an object that would either be a valid Rack response, Rack
352
345
  body object or HTTP status code:
353
346
 
354
347
  * An Array with three elements: `[status (Integer), headers (Hash), response
@@ -372,7 +365,7 @@ get('/') { Stream.new }
372
365
  ```
373
366
 
374
367
  You can also use the `stream` helper method ([described below](#streaming-responses)) to reduce
375
- boiler plate and embed the streaming logic in the route.
368
+ boilerplate and embed the streaming logic in the route.
376
369
 
377
370
  ## Custom Route Matchers
378
371
 
@@ -382,15 +375,16 @@ stop there. You can easily define your own matchers:
382
375
 
383
376
  ```ruby
384
377
  class AllButPattern
385
- Match = Struct.new(:captures)
386
-
387
378
  def initialize(except)
388
- @except = except
389
- @captures = Match.new([])
379
+ @except = except
380
+ end
381
+
382
+ def to_pattern(options)
383
+ return self
390
384
  end
391
385
 
392
- def match(str)
393
- @captures unless @except === str
386
+ def params(route)
387
+ return {} unless @except === route
394
388
  end
395
389
  end
396
390
 
@@ -407,20 +401,12 @@ Note that the above example might be over-engineered, as it can also be
407
401
  expressed as:
408
402
 
409
403
  ```ruby
410
- get // do
404
+ get /.*/ do
411
405
  pass if request.path_info == "/index"
412
406
  # ...
413
407
  end
414
408
  ```
415
409
 
416
- Or, using negative look ahead:
417
-
418
- ```ruby
419
- get %r{(?!/index)} do
420
- # ...
421
- end
422
- ```
423
-
424
410
  ## Static Files
425
411
 
426
412
  Static files are served from the `./public` directory. You can specify
@@ -584,7 +570,7 @@ Some languages have multiple implementations. To specify what implementation
584
570
  to use (and to be thread-safe), you should simply require it first:
585
571
 
586
572
  ```ruby
587
- require 'rdiscount' # or require 'bluecloth'
573
+ require 'rdiscount'
588
574
  get('/') { markdown :index }
589
575
  ```
590
576
 
@@ -612,14 +598,12 @@ get('/') { markdown :index }
612
598
  <td>Dependency</td>
613
599
  <td>
614
600
  <a href="https://github.com/jeremyevans/erubi" title="erubi">erubi</a>
615
- or <a href="http://www.kuwata-lab.com/erubis/" title="erubis">erubis</a>
616
601
  or erb (included in Ruby)
617
602
  </td>
618
603
  </tr>
619
604
  <tr>
620
605
  <td>File Extensions</td>
621
- <td><tt>.erb</tt>, <tt>.rhtml</tt> or <tt>.erubi</tt> (Erubi only)
622
- or <tt>.erubis</tt> (Erubis only)</td>
606
+ <td><tt>.erb</tt>, <tt>.rhtml</tt> or <tt>.erubi</tt> (Erubi only)</td>
623
607
  </tr>
624
608
  <tr>
625
609
  <td>Example</td>
@@ -672,7 +656,7 @@ It also takes a block for inline templates (see [example](#inline-templates)).
672
656
  <table>
673
657
  <tr>
674
658
  <td>Dependency</td>
675
- <td><a href="https://sass-lang.com/" title="sass">sass</a></td>
659
+ <td><a href="https://github.com/ntkme/sass-embedded-host-ruby" title="sass-embedded">sass-embedded</a></td>
676
660
  </tr>
677
661
  <tr>
678
662
  <td>File Extension</td>
@@ -684,12 +668,12 @@ It also takes a block for inline templates (see [example](#inline-templates)).
684
668
  </tr>
685
669
  </table>
686
670
 
687
- #### SCSS Templates
671
+ #### Scss Templates
688
672
 
689
673
  <table>
690
674
  <tr>
691
675
  <td>Dependency</td>
692
- <td><a href="https://sass-lang.com/" title="sass">sass</a></td>
676
+ <td><a href="https://github.com/ntkme/sass-embedded-host-ruby" title="sass-embedded">sass-embedded</a></td>
693
677
  </tr>
694
678
  <tr>
695
679
  <td>File Extension</td>
@@ -701,23 +685,6 @@ It also takes a block for inline templates (see [example](#inline-templates)).
701
685
  </tr>
702
686
  </table>
703
687
 
704
- #### Less Templates
705
-
706
- <table>
707
- <tr>
708
- <td>Dependency</td>
709
- <td><a href="http://lesscss.org/" title="less">less</a></td>
710
- </tr>
711
- <tr>
712
- <td>File Extension</td>
713
- <td><tt>.less</tt></td>
714
- </tr>
715
- <tr>
716
- <td>Example</td>
717
- <td><tt>less :stylesheet</tt></td>
718
- </tr>
719
- </table>
720
-
721
688
  #### Liquid Templates
722
689
 
723
690
  <table>
@@ -747,9 +714,7 @@ template, you almost always want to pass locals to it.
747
714
  Anyone of:
748
715
  <a href="https://github.com/davidfstr/rdiscount" title="RDiscount">RDiscount</a>,
749
716
  <a href="https://github.com/vmg/redcarpet" title="RedCarpet">RedCarpet</a>,
750
- <a href="https://github.com/ged/bluecloth" title="BlueCloth">BlueCloth</a>,
751
717
  <a href="https://kramdown.gettalong.org/" title="kramdown">kramdown</a>,
752
- <a href="https://github.com/bhollis/maruku" title="maruku">maruku</a>
753
718
  <a href="https://github.com/gjtorikian/commonmarker" title="commonmarker">commonmarker</a>
754
719
  <a href="https://github.com/alphabetum/pandoc-ruby" title="pandoc">pandoc</a>
755
720
  </td>
@@ -784,42 +749,6 @@ Since you cannot call Ruby from Markdown, you cannot use layouts written in
784
749
  Markdown. However, it is possible to use another rendering engine for the
785
750
  template than for the layout by passing the `:layout_engine` option.
786
751
 
787
- #### Textile Templates
788
-
789
- <table>
790
- <tr>
791
- <td>Dependency</td>
792
- <td><a href="http://redcloth.org/" title="RedCloth">RedCloth</a></td>
793
- </tr>
794
- <tr>
795
- <td>File Extension</td>
796
- <td><tt>.textile</tt></td>
797
- </tr>
798
- <tr>
799
- <td>Example</td>
800
- <td><tt>textile :index, :layout_engine => :erb</tt></td>
801
- </tr>
802
- </table>
803
-
804
- It is not possible to call methods from Textile, nor to pass locals to
805
- it. You therefore will usually use it in combination with another
806
- rendering engine:
807
-
808
- ```ruby
809
- erb :overview, :locals => { :text => textile(:introduction) }
810
- ```
811
-
812
- Note that you may also call the `textile` method from within other templates:
813
-
814
- ```ruby
815
- %h1 Hello From Haml!
816
- %p= textile(:greetings)
817
- ```
818
-
819
- Since you cannot call Ruby from Textile, you cannot use layouts written in
820
- Textile. However, it is possible to use another rendering engine for the
821
- template than for the layout by passing the `:layout_engine` option.
822
-
823
752
  #### RDoc Templates
824
753
 
825
754
  <table>
@@ -875,26 +804,6 @@ template than for the layout by passing the `:layout_engine` option.
875
804
  Since you cannot call Ruby methods directly from an AsciiDoc template, you
876
805
  almost always want to pass locals to it.
877
806
 
878
- #### Radius Templates
879
-
880
- <table>
881
- <tr>
882
- <td>Dependency</td>
883
- <td><a href="https://github.com/jlong/radius" title="Radius">Radius</a></td>
884
- </tr>
885
- <tr>
886
- <td>File Extension</td>
887
- <td><tt>.radius</tt></td>
888
- </tr>
889
- <tr>
890
- <td>Example</td>
891
- <td><tt>radius :index, :locals => { :key => 'value' }</tt></td>
892
- </tr>
893
- </table>
894
-
895
- Since you cannot call Ruby methods directly from a Radius template, you
896
- almost always want to pass locals to it.
897
-
898
807
  #### Markaby Templates
899
808
 
900
809
  <table>
@@ -936,7 +845,7 @@ It also takes a block for inline templates (see [example](#inline-templates)).
936
845
  <table>
937
846
  <tr>
938
847
  <td>Dependency</td>
939
- <td><a href="http://slim-lang.com/" title="Slim Lang">Slim Lang</a></td>
848
+ <td><a href="https://slim-template.github.io/" title="Slim Lang">Slim Lang</a></td>
940
849
  </tr>
941
850
  <tr>
942
851
  <td>File Extension</td>
@@ -948,139 +857,6 @@ It also takes a block for inline templates (see [example](#inline-templates)).
948
857
  </tr>
949
858
  </table>
950
859
 
951
- #### Creole Templates
952
-
953
- <table>
954
- <tr>
955
- <td>Dependency</td>
956
- <td><a href="https://github.com/minad/creole" title="Creole">Creole</a></td>
957
- </tr>
958
- <tr>
959
- <td>File Extension</td>
960
- <td><tt>.creole</tt></td>
961
- </tr>
962
- <tr>
963
- <td>Example</td>
964
- <td><tt>creole :wiki, :layout_engine => :erb</tt></td>
965
- </tr>
966
- </table>
967
-
968
- It is not possible to call methods from Creole, nor to pass locals to it. You
969
- therefore will usually use it in combination with another rendering engine:
970
-
971
- ```ruby
972
- erb :overview, :locals => { :text => creole(:introduction) }
973
- ```
974
-
975
- Note that you may also call the `creole` method from within other templates:
976
-
977
- ```ruby
978
- %h1 Hello From Haml!
979
- %p= creole(:greetings)
980
- ```
981
-
982
- Since you cannot call Ruby from Creole, you cannot use layouts written in
983
- Creole. However, it is possible to use another rendering engine for the
984
- template than for the layout by passing the `:layout_engine` option.
985
-
986
- #### MediaWiki Templates
987
-
988
- <table>
989
- <tr>
990
- <td>Dependency</td>
991
- <td><a href="https://github.com/nricciar/wikicloth" title="WikiCloth">WikiCloth</a></td>
992
- </tr>
993
- <tr>
994
- <td>File Extension</td>
995
- <td><tt>.mediawiki</tt> and <tt>.mw</tt></td>
996
- </tr>
997
- <tr>
998
- <td>Example</td>
999
- <td><tt>mediawiki :wiki, :layout_engine => :erb</tt></td>
1000
- </tr>
1001
- </table>
1002
-
1003
- It is not possible to call methods from MediaWiki markup, nor to pass
1004
- locals to it. You therefore will usually use it in combination with
1005
- another rendering engine:
1006
-
1007
- ```ruby
1008
- erb :overview, :locals => { :text => mediawiki(:introduction) }
1009
- ```
1010
-
1011
- Note that you may also call the `mediawiki` method from within other
1012
- templates:
1013
-
1014
- ```ruby
1015
- %h1 Hello From Haml!
1016
- %p= mediawiki(:greetings)
1017
- ```
1018
-
1019
- Since you cannot call Ruby from MediaWiki, you cannot use layouts written in
1020
- MediaWiki. However, it is possible to use another rendering engine for the
1021
- template than for the layout by passing the `:layout_engine` option.
1022
-
1023
- #### CoffeeScript Templates
1024
-
1025
- <table>
1026
- <tr>
1027
- <td>Dependency</td>
1028
- <td>
1029
- <a href="https://github.com/josh/ruby-coffee-script" title="Ruby CoffeeScript">
1030
- CoffeeScript
1031
- </a> and a
1032
- <a href="https://github.com/sstephenson/execjs" title="ExecJS">
1033
- way to execute javascript
1034
- </a>
1035
- </td>
1036
- </tr>
1037
- <tr>
1038
- <td>File Extension</td>
1039
- <td><tt>.coffee</tt></td>
1040
- </tr>
1041
- <tr>
1042
- <td>Example</td>
1043
- <td><tt>coffee :index</tt></td>
1044
- </tr>
1045
- </table>
1046
-
1047
- #### Stylus Templates
1048
-
1049
- <table>
1050
- <tr>
1051
- <td>Dependency</td>
1052
- <td>
1053
- <a href="https://github.com/forgecrafted/ruby-stylus" title="Ruby Stylus">
1054
- Stylus
1055
- </a> and a
1056
- <a href="https://github.com/sstephenson/execjs" title="ExecJS">
1057
- way to execute javascript
1058
- </a>
1059
- </td>
1060
- </tr>
1061
- <tr>
1062
- <td>File Extension</td>
1063
- <td><tt>.styl</tt></td>
1064
- </tr>
1065
- <tr>
1066
- <td>Example</td>
1067
- <td><tt>stylus :index</tt></td>
1068
- </tr>
1069
- </table>
1070
-
1071
- Before being able to use Stylus templates, you need to load `stylus` and
1072
- `stylus/tilt` first:
1073
-
1074
- ```ruby
1075
- require 'sinatra'
1076
- require 'stylus'
1077
- require 'stylus/tilt'
1078
-
1079
- get '/' do
1080
- stylus :example
1081
- end
1082
- ```
1083
-
1084
860
  #### Yajl Templates
1085
861
 
1086
862
  <table>
@@ -1122,27 +898,6 @@ var resource = {"foo":"bar","baz":"qux"};
1122
898
  present(resource);
1123
899
  ```
1124
900
 
1125
- #### WLang Templates
1126
-
1127
- <table>
1128
- <tr>
1129
- <td>Dependency</td>
1130
- <td><a href="https://github.com/blambeau/wlang" title="WLang">WLang</a></td>
1131
- </tr>
1132
- <tr>
1133
- <td>File Extension</td>
1134
- <td><tt>.wlang</tt></td>
1135
- </tr>
1136
- <tr>
1137
- <td>Example</td>
1138
- <td><tt>wlang :index, :locals => { :key => 'value' }</tt></td>
1139
- </tr>
1140
- </table>
1141
-
1142
- Since calling ruby methods is not idiomatic in WLang, you almost always
1143
- want to pass locals to it. Layouts written in WLang and `yield` are
1144
- supported, though.
1145
-
1146
901
  ### Accessing Variables in Templates
1147
902
 
1148
903
  Templates are evaluated within the same context as route handlers. Instance
@@ -1201,7 +956,7 @@ end
1201
956
  ```
1202
957
 
1203
958
  Currently, the following rendering methods accept a block: `erb`, `haml`,
1204
- `liquid`, `slim `, `wlang`. Also the general `render` method accepts a block.
959
+ `liquid`, `slim `. Also, the general `render` method accepts a block.
1205
960
 
1206
961
  ### Inline Templates
1207
962
 
@@ -1218,13 +973,13 @@ __END__
1218
973
 
1219
974
  @@ layout
1220
975
  %html
1221
- = yield
976
+ != yield
1222
977
 
1223
978
  @@ index
1224
979
  %div.title Hello world.
1225
980
  ```
1226
981
 
1227
- NOTE: Inline templates defined in the source file that requires sinatra are
982
+ NOTE: Inline templates defined in the source file that requires Sinatra are
1228
983
  automatically loaded. Call `enable :inline_templates` explicitly if you
1229
984
  have inline templates in other source files.
1230
985
 
@@ -1261,10 +1016,10 @@ end
1261
1016
 
1262
1017
  To associate a file extension with a template engine, use
1263
1018
  `Tilt.register`. For instance, if you like to use the file extension
1264
- `tt` for Textile templates, you can do the following:
1019
+ `tt` for Haml templates, you can do the following:
1265
1020
 
1266
1021
  ```ruby
1267
- Tilt.register :tt, Tilt[:textile]
1022
+ Tilt.register Tilt[:haml], :tt
1268
1023
  ```
1269
1024
 
1270
1025
  ### Adding Your Own Template Engine
@@ -1272,7 +1027,7 @@ Tilt.register :tt, Tilt[:textile]
1272
1027
  First, register your engine with Tilt, then create a rendering method:
1273
1028
 
1274
1029
  ```ruby
1275
- Tilt.register :myat, MyAwesomeTemplateEngine
1030
+ Tilt.register MyAwesomeTemplateEngine, :myat
1276
1031
 
1277
1032
  helpers do
1278
1033
  def myat(*args) render(:myat, *args) end
@@ -1434,7 +1189,7 @@ For better security and usability it's
1434
1189
  secret and store it in an environment variable on each host running your
1435
1190
  application so that all of your application instances will share the same
1436
1191
  secret. You should periodically rotate this session secret to a new value.
1437
- Here are some examples of how you might create a 64 byte secret and set it:
1192
+ Here are some examples of how you might create a 64-byte secret and set it:
1438
1193
 
1439
1194
  **Session Secret Generation**
1440
1195
 
@@ -1443,22 +1198,6 @@ $ ruby -e "require 'securerandom'; puts SecureRandom.hex(64)"
1443
1198
  99ae8af...snip...ec0f262ac
1444
1199
  ```
1445
1200
 
1446
- **Session Secret Generation (Bonus Points)**
1447
-
1448
- Use the [sysrandom gem](https://github.com/cryptosphere/sysrandom#readme) to
1449
- prefer use of system RNG facilities to generate random values instead of
1450
- userspace `OpenSSL` which MRI Ruby currently defaults to:
1451
-
1452
- ```text
1453
- $ gem install sysrandom
1454
- Building native extensions. This could take a while...
1455
- Successfully installed sysrandom-1.x
1456
- 1 gem installed
1457
-
1458
- $ ruby -e "require 'sysrandom/securerandom'; puts SecureRandom.hex(64)"
1459
- 99ae8af...snip...ec0f262ac
1460
- ```
1461
-
1462
1201
  **Session Secret Environment Variable**
1463
1202
 
1464
1203
  Set a `SESSION_SECRET` environment variable for Sinatra to the value you
@@ -1472,15 +1211,11 @@ purposes only:
1472
1211
 
1473
1212
  **Session Secret App Config**
1474
1213
 
1475
- Setup your app config to fail-safe to a secure random secret
1476
- if the `SESSION_SECRET` environment variable is not available.
1477
-
1478
- For bonus points use the [sysrandom
1479
- gem](https://github.com/cryptosphere/sysrandom#readme) here as well:
1214
+ Set up your app config to fail-safe to a secure random secret
1215
+ if the `SESSION_SECRET` environment variable is not available:
1480
1216
 
1481
1217
  ```ruby
1482
1218
  require 'securerandom'
1483
- # -or- require 'sysrandom/securerandom'
1484
1219
  set :session_secret, ENV.fetch('SESSION_SECRET') { SecureRandom.hex(64) }
1485
1220
  ```
1486
1221
 
@@ -1593,7 +1328,7 @@ matching route. If no matching route is found, a 404 is returned.
1593
1328
 
1594
1329
  ### Triggering Another Route
1595
1330
 
1596
- Sometimes `pass` is not what you want, instead you would like to get the
1331
+ Sometimes `pass` is not what you want, instead, you would like to get the
1597
1332
  result of calling another route. Simply use `call` to achieve this:
1598
1333
 
1599
1334
  ```ruby
@@ -1616,13 +1351,13 @@ than a duplicate, use `call!` instead of `call`.
1616
1351
 
1617
1352
  Check out the Rack specification if you want to learn more about `call`.
1618
1353
 
1619
- ### Setting Body, Status Code and Headers
1354
+ ### Setting Body, Status Code, and Headers
1620
1355
 
1621
1356
  It is possible and recommended to set the status code and response body with
1622
- the return value of the route block. However, in some scenarios you might
1357
+ the return value of the route block. However, in some scenarios, you might
1623
1358
  want to set the body at an arbitrary point in the execution flow. You can do
1624
1359
  so with the `body` helper method. If you do so, you can use that method from
1625
- there on to access the body:
1360
+ thereon to access the body:
1626
1361
 
1627
1362
  ```ruby
1628
1363
  get '/foo' do
@@ -1645,7 +1380,7 @@ get '/foo' do
1645
1380
  headers \
1646
1381
  "Allow" => "BREW, POST, GET, PROPFIND, WHEN",
1647
1382
  "Refresh" => "Refresh: 20; https://ietf.org/rfc/rfc2324.txt"
1648
- body "I'm a tea pot!"
1383
+ body "I'm a teapot!"
1649
1384
  end
1650
1385
  ```
1651
1386
 
@@ -1678,60 +1413,16 @@ also be used to increase throughput if some but not all content depends on a
1678
1413
  slow resource.
1679
1414
 
1680
1415
  Note that the streaming behavior, especially the number of concurrent
1681
- requests, highly depends on the web server used to serve the application.
1416
+ requests, highly depends on the webserver used to serve the application.
1682
1417
  Some servers might not even support streaming at all. If the server does not
1683
1418
  support streaming, the body will be sent all at once after the block passed
1684
1419
  to `stream` finishes executing. Streaming does not work at all with Shotgun.
1685
1420
 
1686
1421
  If the optional parameter is set to `keep_open`, it will not call `close` on
1687
1422
  the stream object, allowing you to close it at any later point in the
1688
- execution flow. This only works on evented servers, like Rainbows.
1689
- Other servers will still close the stream:
1690
-
1691
- ```ruby
1692
- # config.ru
1693
- require 'sinatra/base'
1694
-
1695
- class App < Sinatra::Base
1696
- connections = []
1697
-
1698
- get '/subscribe', provides: 'text/event-stream' do
1699
- # register a client's interest in server events
1700
- stream(:keep_open) do |out|
1701
- connections << out
1702
- # purge dead connections
1703
- connections.reject!(&:closed?)
1704
- end
1705
- end
1706
-
1707
- post '/' do
1708
- connections.each do |out|
1709
- # notify client that a new message has arrived
1710
- out << "data: #{params[:msg]}\n\n"
1711
-
1712
- # indicate client to connect again
1713
- out.close
1714
- end
1715
-
1716
- 204 # response without entity body
1717
- end
1718
- end
1423
+ execution flow.
1719
1424
 
1720
- run App
1721
- ```
1722
-
1723
- ```ruby
1724
- # rainbows.conf
1725
- Rainbows! do
1726
- use :EventMachine
1727
- end
1728
- ````
1729
-
1730
- Run:
1731
-
1732
- ```shell
1733
- rainbows -c rainbows.conf
1734
- ```
1425
+ You can have a look at the [chat example](https://github.com/sinatra/sinatra/blob/main/examples/chat.rb)
1735
1426
 
1736
1427
  It's also possible for the client to close the connection when trying to
1737
1428
  write to the socket. Because of this, it's recommended to check
@@ -1763,7 +1454,7 @@ class MyApp < Sinatra::Base
1763
1454
  end
1764
1455
  ```
1765
1456
 
1766
- To avoid any logging middleware to be set up, set the `logging` setting to
1457
+ To avoid any logging middleware to be set up, set the `logging` option to
1767
1458
  `nil`. However, keep in mind that `logger` will in that case return `nil`. A
1768
1459
  common use case is when you want to set your own logger. Sinatra will use
1769
1460
  whatever it will find in `env['rack.logger']`.
@@ -1797,7 +1488,7 @@ Haml:
1797
1488
  %a{:href => url('/foo')} foo
1798
1489
  ```
1799
1490
 
1800
- It takes reverse proxies and Rack routers into account, if present.
1491
+ It takes reverse proxies and Rack routers into account - if present.
1801
1492
 
1802
1493
  This method is also aliased to `to` (see [below](#browser-redirect) for an example).
1803
1494
 
@@ -2136,7 +1827,7 @@ end
2136
1827
  Another example would be using different directories for different engines:
2137
1828
 
2138
1829
  ```ruby
2139
- set :views, :sass => 'views/sass', :haml => 'templates', :default => 'views'
1830
+ set :views, :haml => 'templates', :default => 'views'
2140
1831
 
2141
1832
  helpers do
2142
1833
  def find_template(views, name, engine, &block)
@@ -2147,7 +1838,7 @@ helpers do
2147
1838
  end
2148
1839
  ```
2149
1840
 
2150
- You can also easily wrap this up in an extension and share with others!
1841
+ You can also easily wrap this up in an extension and share it with others!
2151
1842
 
2152
1843
  Note that `find_template` does not check if the file really exists but
2153
1844
  rather calls the given block for all possible paths. This is not a
@@ -2213,7 +1904,7 @@ end
2213
1904
  ### Configuring attack protection
2214
1905
 
2215
1906
  Sinatra is using
2216
- [Rack::Protection](https://github.com/sinatra/sinatra/tree/master/rack-protection#readme) to
1907
+ [Rack::Protection](https://github.com/sinatra/sinatra/tree/main/rack-protection#readme) to
2217
1908
  defend your application against common, opportunistic attacks. You can
2218
1909
  easily disable this behavior (which will open up your application to tons
2219
1910
  of common vulnerabilities):
@@ -2230,13 +1921,13 @@ set :protection, :except => :path_traversal
2230
1921
  You can also hand in an array in order to disable a list of protections:
2231
1922
 
2232
1923
  ```ruby
2233
- set :protection, :except => [:path_traversal, :session_hijacking]
1924
+ set :protection, :except => [:path_traversal, :remote_token]
2234
1925
  ```
2235
1926
 
2236
1927
  By default, Sinatra will only set up session based protection if `:sessions`
2237
1928
  have been enabled. See '[Using Sessions](#using-sessions)'. Sometimes you may want to set up
2238
1929
  sessions "outside" of the Sinatra app, such as in the config.ru or with a
2239
- separate `Rack::Builder` instance. In that case you can still set up session
1930
+ separate `Rack::Builder` instance. In that case, you can still set up session
2240
1931
  based protection by passing the `:session` option:
2241
1932
 
2242
1933
  ```ruby
@@ -2293,7 +1984,7 @@ set :protection, :session => true
2293
1984
  <dd>Encoding to assume if unknown (defaults to <tt>"utf-8"</tt>).</dd>
2294
1985
 
2295
1986
  <dt>dump_errors</dt>
2296
- <dd>Display errors in the log.</dd>
1987
+ <dd>Display errors in the log. Enabled by default unless environment is "test".</dd>
2297
1988
 
2298
1989
  <dt>environment</dt>
2299
1990
  <dd>
@@ -2301,6 +1992,33 @@ set :protection, :session => true
2301
1992
  <tt>"development"</tt> if not available.
2302
1993
  </dd>
2303
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
+
2304
2022
  <dt>logging</dt>
2305
2023
  <dd>Use the logger.</dd>
2306
2024
 
@@ -2369,9 +2087,13 @@ set :protection, :session => true
2369
2087
 
2370
2088
  <dt>raise_errors</dt>
2371
2089
  <dd>
2372
- Raise exceptions (will stop application). Enabled by default when
2090
+ Raise unhandled errors (will stop application). Enabled by default when
2373
2091
  <tt>environment</tt> is set to <tt>"test"</tt>, disabled otherwise.
2374
2092
  </dd>
2093
+ <dd>
2094
+ Any explicitly defined error handlers always override this setting. See
2095
+ the "Error" section below.
2096
+ </dd>
2375
2097
 
2376
2098
  <dt>run</dt>
2377
2099
  <dd>
@@ -2390,12 +2112,8 @@ set :protection, :session => true
2390
2112
 
2391
2113
  <dt>server_settings</dt>
2392
2114
  <dd>
2393
- If you are using a WEBrick web server, presumably for your development
2394
- environment, you can pass a hash of options to <tt>server_settings</tt>,
2395
- such as <tt>SSLEnable</tt> or <tt>SSLVerifyClient</tt>. However, web
2396
- servers such as Puma do not support this, so you can set
2397
- <tt>server_settings</tt> by defining it as a method when you call
2398
- <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>.
2399
2117
  </dd>
2400
2118
 
2401
2119
  <dt>sessions</dt>
@@ -2464,6 +2182,24 @@ set :protection, :session => true
2464
2182
  </dd>
2465
2183
  </dl>
2466
2184
 
2185
+ ## Lifecycle Events
2186
+
2187
+ There are 2 lifecycle events currently exposed by Sinatra. One when the server starts and one when it stops.
2188
+
2189
+ They can be used like this:
2190
+
2191
+ ```ruby
2192
+ on_start do
2193
+ puts "===== Booting up ====="
2194
+ end
2195
+
2196
+ on_stop do
2197
+ puts "===== Shutting down ====="
2198
+ end
2199
+ ```
2200
+
2201
+ Note that these callbacks only work when using Sinatra to start the web server.
2202
+
2467
2203
  ## Environments
2468
2204
 
2469
2205
  There are three predefined `environments`: `"development"`,
@@ -2520,6 +2256,14 @@ show exceptions option to `:after_handler`:
2520
2256
  set :show_exceptions, :after_handler
2521
2257
  ```
2522
2258
 
2259
+ A catch-all error handler can be defined with `error` and a block:
2260
+
2261
+ ```ruby
2262
+ error do
2263
+ 'Sorry there was a nasty error'
2264
+ end
2265
+ ```
2266
+
2523
2267
  The exception object can be obtained from the `sinatra.error` Rack variable:
2524
2268
 
2525
2269
  ```ruby
@@ -2528,7 +2272,7 @@ error do
2528
2272
  end
2529
2273
  ```
2530
2274
 
2531
- Custom errors:
2275
+ Pass an error class as an argument to create handlers for custom errors:
2532
2276
 
2533
2277
  ```ruby
2534
2278
  error MyCustomError do
@@ -2574,6 +2318,51 @@ Sinatra installs special `not_found` and `error` handlers when
2574
2318
  running under the development environment to display nice stack traces
2575
2319
  and additional debugging information in your browser.
2576
2320
 
2321
+ ### Behavior with `raise_errors` option
2322
+
2323
+ When `raise_errors` option is `true`, errors that are unhandled are raised
2324
+ outside of the application. Additionally, any errors that would have been
2325
+ caught by the catch-all error handler are raised.
2326
+
2327
+ For example, consider the following configuration:
2328
+
2329
+ ```ruby
2330
+ # First handler
2331
+ error MyCustomError do
2332
+ 'A custom message'
2333
+ end
2334
+
2335
+ # Second handler
2336
+ error do
2337
+ 'A catch-all message'
2338
+ end
2339
+ ```
2340
+
2341
+ If `raise_errors` is `false`:
2342
+
2343
+ * When `MyCustomError` or descendant is raised, the first handler is invoked.
2344
+ The HTTP response body will contain `"A custom message"`.
2345
+ * When any other error is raised, the second handler is invoked. The HTTP
2346
+ response body will contain `"A catch-all message"`.
2347
+
2348
+ If `raise_errors` is `true`:
2349
+
2350
+ * When `MyCustomError` or descendant is raised, the behavior is identical to
2351
+ when `raise_errors` is `false`, described above.
2352
+ * When any other error is raised, the second handler is *not* invoked, and
2353
+ the error is raised outside of the application.
2354
+ * If the environment is `production`, the HTTP response body will contain
2355
+ a generic error message, e.g. `"An unhandled lowlevel error occurred. The
2356
+ application logs may have details."`
2357
+ * If the environment is not `production`, the HTTP response body will contain
2358
+ the verbose error backtrace.
2359
+ * Regardless of environment, if `show_exceptions` is set to `:after_handler`,
2360
+ the HTTP response body will contain the verbose error backtrace.
2361
+
2362
+ In the `test` environment, `raise_errors` is set to `true` by default. This
2363
+ means that in order to write a test for a catch-all error handler,
2364
+ `raise_errors` must temporarily be set to `false` for that particular test.
2365
+
2577
2366
  ## Rack Middleware
2578
2367
 
2579
2368
  Sinatra rides on [Rack](https://rack.github.io/), a minimal standard
@@ -2599,7 +2388,7 @@ end
2599
2388
  ```
2600
2389
 
2601
2390
  The semantics of `use` are identical to those defined for the
2602
- [Rack::Builder](http://www.rubydoc.info/github/rack/rack/master/Rack/Builder) DSL
2391
+ [Rack::Builder](https://www.rubydoc.info/github/rack/rack/main/Rack/Builder) DSL
2603
2392
  (most frequently used from rackup files). For example, the `use` method
2604
2393
  accepts multiple/variable args as well as blocks:
2605
2394
 
@@ -2615,7 +2404,7 @@ many of these components automatically based on configuration so you
2615
2404
  typically don't have to `use` them explicitly.
2616
2405
 
2617
2406
  You can find useful middleware in
2618
- [rack](https://github.com/rack/rack/tree/master/lib/rack),
2407
+ [rack](https://github.com/rack/rack/tree/main/lib/rack),
2619
2408
  [rack-contrib](https://github.com/rack/rack-contrib#readme),
2620
2409
  or in the [Rack wiki](https://github.com/rack/rack/wiki/List-of-Middleware).
2621
2410
 
@@ -2623,7 +2412,7 @@ or in the [Rack wiki](https://github.com/rack/rack/wiki/List-of-Middleware).
2623
2412
 
2624
2413
  Sinatra tests can be written using any Rack-based testing library or
2625
2414
  framework.
2626
- [Rack::Test](http://www.rubydoc.info/github/brynary/rack-test/master/frames)
2415
+ [Rack::Test](https://www.rubydoc.info/github/rack/rack-test/main/frames)
2627
2416
  is recommended:
2628
2417
 
2629
2418
  ```ruby
@@ -2717,7 +2506,7 @@ modular application.
2717
2506
  The main disadvantage of using the classic style rather than the modular
2718
2507
  style is that you will only have one Sinatra application per Ruby
2719
2508
  process. If you plan to use more than one, switch to the modular style.
2720
- There is no reason you cannot mix the modular and the classic styles.
2509
+ There is no reason you cannot mix the modular and classic styles.
2721
2510
 
2722
2511
  If switching from one style to the other, you should be aware of
2723
2512
  slightly different default settings:
@@ -2846,7 +2635,7 @@ style for running with a `config.ru`.**
2846
2635
  ### Using Sinatra as Middleware
2847
2636
 
2848
2637
  Not only is Sinatra able to use other Rack middleware, any Sinatra
2849
- application can in turn be added in front of any Rack endpoint as
2638
+ application can, in turn, be added in front of any Rack endpoint as
2850
2639
  middleware itself. This endpoint could be another Sinatra application,
2851
2640
  or any other Rack-based application (Rails/Hanami/Roda/...):
2852
2641
 
@@ -2937,7 +2726,7 @@ available.
2937
2726
  Every Sinatra application corresponds to a subclass of `Sinatra::Base`.
2938
2727
  If you are using the top-level DSL (`require 'sinatra'`), then this
2939
2728
  class is `Sinatra::Application`, otherwise it is the subclass you
2940
- created explicitly. At class level you have methods like `get` or
2729
+ created explicitly. At the class level, you have methods like `get` or
2941
2730
  `before`, but you cannot access the `request` or `session` objects, as
2942
2731
  there is only a single application class for all requests.
2943
2732
 
@@ -2960,7 +2749,7 @@ You have the application scope binding inside:
2960
2749
  * Your application class body
2961
2750
  * Methods defined by extensions
2962
2751
  * The block passed to `helpers`
2963
- * Procs/blocks used as value for `set`
2752
+ * Procs/blocks used as a value for `set`
2964
2753
  * The block passed to `Sinatra.new`
2965
2754
 
2966
2755
  You can reach the scope object (the class) like this:
@@ -3011,7 +2800,7 @@ do not share variables/state with the class scope (read: you have a different
3011
2800
 
3012
2801
  You have the delegate scope binding inside:
3013
2802
 
3014
- * The top level binding, if you did `require "sinatra"`
2803
+ * The top-level binding, if you did `require "sinatra"`
3015
2804
  * An object extended with the `Sinatra::Delegator` mixin
3016
2805
 
3017
2806
  Have a look at the code for yourself: here's the
@@ -3044,98 +2833,43 @@ _Paraphrasing from
3044
2833
  [this StackOverflow answer](https://stackoverflow.com/a/6282999/5245129)
3045
2834
  by Konstantin_
3046
2835
 
3047
- Sinatra doesn't impose any concurrency model, but leaves that to the
3048
- underlying Rack handler (server) like Puma or WEBrick. Sinatra
2836
+ Sinatra doesn't impose any concurrency model but leaves that to the
2837
+ underlying Rack handler (server) like Puma or Falcon. Sinatra
3049
2838
  itself is thread-safe, so there won't be any problem if the Rack handler
3050
- uses a threaded model of concurrency. This would mean that when starting
3051
- the server, you'd have to specify the correct invocation method for the
3052
- specific Rack handler. The following example is a demonstration of how
3053
- to start a multi-threaded Rainbows server:
3054
-
3055
- ```ruby
3056
- # config.ru
3057
-
3058
- require 'sinatra/base'
3059
-
3060
- class App < Sinatra::Base
3061
- get '/' do
3062
- "Hello, World"
3063
- end
3064
- end
3065
-
3066
- run App
3067
- ```
3068
-
3069
- ```ruby
3070
- # rainbows.conf
3071
-
3072
- # Rainbows configurator is based on Unicorn.
3073
- Rainbows! do
3074
- use :ThreadSpawn
3075
- end
3076
- ```
3077
-
3078
- To start the server, the command would be:
3079
-
3080
- ```shell
3081
- rainbows -c rainbows.conf
3082
- ```
2839
+ uses a threaded model of concurrency.
3083
2840
 
3084
2841
  ## Requirement
3085
2842
 
3086
2843
  The following Ruby versions are officially supported:
3087
2844
  <dl>
3088
- <dt>Ruby 2.3</dt>
2845
+ <dt>Ruby</dt>
3089
2846
  <dd>
3090
- 2.3 is fully supported and recommended. There are currently no plans to
3091
- drop official support for it.
2847
+ <a href="https://www.ruby-lang.org/en/downloads/">The stable releases</a> are fully supported and recommended.
3092
2848
  </dd>
3093
2849
 
3094
- <dt>Rubinius</dt>
2850
+ <dt>TruffleRuby</dt>
3095
2851
  <dd>
3096
- Rubinius is officially supported (Rubinius >= 2.x). It is recommended to
3097
- <tt>gem install puma</tt>.
2852
+ The latest stable release of TruffleRuby is supported.
3098
2853
  </dd>
3099
2854
 
3100
2855
  <dt>JRuby</dt>
3101
2856
  <dd>
3102
- The latest stable release of JRuby is officially supported. It is not
3103
- recommended to use C extensions with JRuby. It is recommended to
3104
- <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.
3105
2859
  </dd>
3106
2860
  </dl>
3107
2861
 
3108
- Versions of Ruby prior to 2.3 are no longer supported as of Sinatra 2.1.0.
3109
-
3110
- We also keep an eye on upcoming Ruby versions.
3111
-
3112
- The following Ruby implementations are not officially supported but still are
3113
- known to run Sinatra:
3114
-
3115
- * Older versions of JRuby and Rubinius
3116
- * Ruby Enterprise Edition
3117
- * MacRuby, Maglev, IronRuby
3118
- * Ruby 1.9.0 and 1.9.1 (but we do recommend against using those)
3119
-
3120
- Not being officially supported means if things only break there and not on a
3121
- supported platform, we assume it's not our issue but theirs.
3122
-
3123
- We also run our CI against ruby-head (future releases of MRI), but we
3124
- can't guarantee anything, since it is constantly moving. Expect upcoming
3125
- 2.x releases to be fully supported.
2862
+ Versions of Ruby before 2.7.8 are no longer supported as of Sinatra 4.0.0.
3126
2863
 
3127
2864
  Sinatra should work on any operating system supported by the chosen Ruby
3128
2865
  implementation.
3129
2866
 
3130
- If you run MacRuby, you should `gem install control_tower`.
3131
-
3132
- Sinatra currently doesn't run on Cardinal, SmallRuby, BlueRuby or any
3133
- Ruby version prior to 2.2.
2867
+ Running Sinatra on a not officially supported Ruby flavor means that if things only break there we assume it's not our issue but theirs.
3134
2868
 
3135
2869
  ## The Bleeding Edge
3136
2870
 
3137
2871
  If you would like to use Sinatra's latest bleeding-edge code, feel free
3138
- to run your application against the master branch, it should be rather
2872
+ to run your application against the main branch, it should be rather
3139
2873
  stable.
3140
2874
 
3141
2875
  We also push out prerelease gems from time to time, so you can do a
@@ -3184,20 +2918,19 @@ SemVerTag.
3184
2918
 
3185
2919
  ## Further Reading
3186
2920
 
3187
- * [Project Website](http://www.sinatrarb.com/) - Additional documentation,
2921
+ * [Project Website](https://sinatrarb.com/) - Additional documentation,
3188
2922
  news, and links to other resources.
3189
- * [Contributing](http://www.sinatrarb.com/contributing) - Find a bug? Need
2923
+ * [Contributing](https://sinatrarb.com/contributing) - Find a bug? Need
3190
2924
  help? Have a patch?
3191
2925
  * [Issue tracker](https://github.com/sinatra/sinatra/issues)
3192
2926
  * [Twitter](https://twitter.com/sinatra)
3193
2927
  * [Mailing List](https://groups.google.com/forum/#!forum/sinatrarb)
3194
2928
  * IRC: [#sinatra](irc://chat.freenode.net/#sinatra) on [Freenode](https://freenode.net)
3195
- * [Sinatra & Friends](https://sinatrarb.slack.com) on Slack
3196
- ([get an invite](https://sinatra-slack.herokuapp.com/))
2929
+ * [Sinatra & Friends](https://discord.gg/ncjsfsNHh7) on Discord
3197
2930
  * [Sinatra Book](https://github.com/sinatra/sinatra-book) - Cookbook Tutorial
3198
2931
  * [Sinatra Recipes](http://recipes.sinatrarb.com/) - Community contributed
3199
2932
  recipes
3200
- * API documentation for the [latest release](http://www.rubydoc.info/gems/sinatra)
3201
- or the [current HEAD](http://www.rubydoc.info/github/sinatra/sinatra) on
3202
- [RubyDoc](http://www.rubydoc.info/)
3203
- * [CI server](https://travis-ci.org/sinatra/sinatra)
2933
+ * API documentation for the [latest release](https://www.rubydoc.info/gems/sinatra)
2934
+ or the [current HEAD](https://www.rubydoc.info/github/sinatra/sinatra) on
2935
+ [RubyDoc](https://www.rubydoc.info/)
2936
+ * [CI Actions](https://github.com/sinatra/sinatra/actions)