Hello community,

here is the log from the commit of package rubygem-sinatra for openSUSE:Factory 
checked in at 2020-10-05 19:33:51
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/rubygem-sinatra (Old)
 and      /work/SRC/openSUSE:Factory/.rubygem-sinatra.new.4249 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "rubygem-sinatra"

Mon Oct  5 19:33:51 2020 rev:10 rq:838082 version:2.1.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/rubygem-sinatra/rubygem-sinatra.changes  
2020-03-09 11:41:19.109289508 +0100
+++ 
/work/SRC/openSUSE:Factory/.rubygem-sinatra.new.4249/rubygem-sinatra.changes    
    2020-10-05 19:33:51.701243363 +0200
@@ -1,0 +2,41 @@
+Fri Sep 25 14:57:26 UTC 2020 - Stephan Kulow <co...@suse.com>
+
+updated to version 2.1.0
+ see installed CHANGELOG.md
+
+  ## 2.1.0 / 2020-09-05
+  
+  * Fix additional Ruby 2.7 keyword warnings 
[#1586](https://github.com/sinatra/sinatra/pull/1586) by Stefan Sundin
+  
+  * Drop Ruby 2.2 support 
[#1455](https://github.com/sinatra/sinatra/pull/1455) by Eloy Pérez
+  
+  * Add Rack::Protection::ReferrerPolicy 
[#1291](https://github.com/sinatra/sinatra/pull/1291) by Stefan Sundin
+  
+  * Add `default_content_type` setting. Fixes 
[#1238](https://github.com/sinatra/sinatra/pull/1238) 
[#1239](https://github.com/sinatra/sinatra/pull/1239) by Mike Pastore
+  
+  * Allow `set :<engine>` in sinatra-namespace 
[#1255](https://github.com/sinatra/sinatra/pull/1255) by Christian Höppner
+  
+  * Use prepend instead of include for helpers. Fixes 
[#1213](https://github.com/sinatra/sinatra/pull/1213) 
[#1214](https://github.com/sinatra/sinatra/pull/1214) by Mike Pastore
+  
+  * Fix issue with passed routes and provides Fixes 
[#1095](https://github.com/sinatra/sinatra/pull/1095) 
[#1606](https://github.com/sinatra/sinatra/pull/1606) by Mike Pastore, Jordan 
Owens
+  
+  * Add QuietLogger that excludes pathes from Rack::CommonLogger 
[1250](https://github.com/sinatra/sinatra/pull/1250) by Christoph Wagner
+  
+  * Sinatra::Contrib dependency updates. Fixes 
[#1207](https://github.com/sinatra/sinatra/pull/1207) 
[#1411](https://github.com/sinatra/sinatra/pull/1411) by Mike Pastore
+  
+  * Allow CSP to fallback to default-src. Fixes 
[#1484](https://github.com/sinatra/sinatra/pull/1484) 
[#1490](https://github.com/sinatra/sinatra/pull/1490) by Jordan Owens
+  
+  * Replace `origin_whitelist` with `permitted_origins`. Closes 
[#1620](https://github.com/sinatra/sinatra/issues/1620) 
[#1625](https://github.com/sinatra/sinatra/pull/1625) by rhymes
+  
+  * Use Rainbows instead of thin for async/stream features. Closes 
[#1624](https://github.com/sinatra/sinatra/issues/1624) 
[#1627](https://github.com/sinatra/sinatra/pull/1627) by Ryuichi KAWAMATA
+  
+  * Enable EscapedParams if passed via settings. Closes 
[#1615](https://github.com/sinatra/sinatra/issues/1615) 
[#1632](https://github.com/sinatra/sinatra/issues/1632) by Anders Bälter
+  
+  * Support for parameters in mime types. Fixes 
[#1141](https://github.com/sinatra/sinatra/issues/1141) by John Hope
+  
+  * Handle null byte when serving static files 
[#1574](https://github.com/sinatra/sinatra/issues/1574) by Kush Fanikiso
+  
+  * Improve development support and documentation and source code by Olle 
Jonsson, Pierre-Adrien Buisson, Shota Iguchi
+  
+
+-------------------------------------------------------------------

Old:
----
  sinatra-2.0.8.1.gem

New:
----
  sinatra-2.1.0.gem

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ rubygem-sinatra.spec ++++++
--- /var/tmp/diff_new_pack.y8Cd6c/_old  2020-10-05 19:33:52.273243922 +0200
+++ /var/tmp/diff_new_pack.y8Cd6c/_new  2020-10-05 19:33:52.277243926 +0200
@@ -24,12 +24,12 @@
 #
 
 Name:           rubygem-sinatra
-Version:        2.0.8.1
+Version:        2.1.0
 Release:        0
 %define mod_name sinatra
 %define mod_full_name %{mod_name}-%{version}
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
-BuildRequires:  %{ruby >= 2.2.0}
+BuildRequires:  %{ruby >= 2.3.0}
 BuildRequires:  %{rubygem gem2rpm}
 BuildRequires:  %{rubygem rdoc > 3.10}
 BuildRequires:  ruby-macros >= 5

++++++ sinatra-2.0.8.1.gem -> sinatra-2.1.0.gem ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/CHANGELOG.md new/CHANGELOG.md
--- old/CHANGELOG.md    2020-01-01 21:02:13.000000000 +0100
+++ new/CHANGELOG.md    2020-09-04 20:46:28.000000000 +0200
@@ -1,3 +1,37 @@
+## 2.1.0 / 2020-09-05
+
+* Fix additional Ruby 2.7 keyword warnings 
[#1586](https://github.com/sinatra/sinatra/pull/1586) by Stefan Sundin
+
+* Drop Ruby 2.2 support [#1455](https://github.com/sinatra/sinatra/pull/1455) 
by Eloy Pérez
+
+* Add Rack::Protection::ReferrerPolicy 
[#1291](https://github.com/sinatra/sinatra/pull/1291) by Stefan Sundin
+
+* Add `default_content_type` setting. Fixes 
[#1238](https://github.com/sinatra/sinatra/pull/1238) 
[#1239](https://github.com/sinatra/sinatra/pull/1239) by Mike Pastore
+
+* Allow `set :<engine>` in sinatra-namespace 
[#1255](https://github.com/sinatra/sinatra/pull/1255) by Christian Höppner
+
+* Use prepend instead of include for helpers. Fixes 
[#1213](https://github.com/sinatra/sinatra/pull/1213) 
[#1214](https://github.com/sinatra/sinatra/pull/1214) by Mike Pastore
+
+* Fix issue with passed routes and provides Fixes 
[#1095](https://github.com/sinatra/sinatra/pull/1095) 
[#1606](https://github.com/sinatra/sinatra/pull/1606) by Mike Pastore, Jordan 
Owens
+
+* Add QuietLogger that excludes pathes from Rack::CommonLogger 
[1250](https://github.com/sinatra/sinatra/pull/1250) by Christoph Wagner
+
+* Sinatra::Contrib dependency updates. Fixes 
[#1207](https://github.com/sinatra/sinatra/pull/1207) 
[#1411](https://github.com/sinatra/sinatra/pull/1411) by Mike Pastore
+
+* Allow CSP to fallback to default-src. Fixes 
[#1484](https://github.com/sinatra/sinatra/pull/1484) 
[#1490](https://github.com/sinatra/sinatra/pull/1490) by Jordan Owens
+
+* Replace `origin_whitelist` with `permitted_origins`. Closes 
[#1620](https://github.com/sinatra/sinatra/issues/1620) 
[#1625](https://github.com/sinatra/sinatra/pull/1625) by rhymes
+
+* Use Rainbows instead of thin for async/stream features. Closes 
[#1624](https://github.com/sinatra/sinatra/issues/1624) 
[#1627](https://github.com/sinatra/sinatra/pull/1627) by Ryuichi KAWAMATA
+
+* Enable EscapedParams if passed via settings. Closes 
[#1615](https://github.com/sinatra/sinatra/issues/1615) 
[#1632](https://github.com/sinatra/sinatra/issues/1632) by Anders Bälter
+
+* Support for parameters in mime types. Fixes 
[#1141](https://github.com/sinatra/sinatra/issues/1141) by John Hope
+
+* Handle null byte when serving static files 
[#1574](https://github.com/sinatra/sinatra/issues/1574) by Kush Fanikiso
+
+* Improve development support and documentation and source code by Olle 
Jonsson, Pierre-Adrien Buisson, Shota Iguchi
+
 ## 2.0.8.1 / 2020-01-02
 
 * Allow multiple hashes to be passed in `merge` and `merge!` for 
`Sinatra::IndifferentHash` 
[#1572](https://github.com/sinatra/sinatra/pull/1572) by Shota Iguchi
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Gemfile new/Gemfile
--- old/Gemfile 2020-01-01 21:02:13.000000000 +0100
+++ new/Gemfile 2020-09-04 20:46:28.000000000 +0200
@@ -41,7 +41,8 @@
   gem 'puma'
   gem 'yajl-ruby'
   gem 'nokogiri'
-  gem 'thin'
+  gem 'rainbows'
+  gem 'eventmachine'
   gem 'slim', '~> 2.0'
   gem 'coffee-script', '>= 2.0'
   gem 'rdoc'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/README.de.md new/README.de.md
--- old/README.de.md    2020-01-01 21:02:13.000000000 +0100
+++ new/README.de.md    2020-09-04 20:46:28.000000000 +0200
@@ -434,7 +434,7 @@
 einen anderen Ort zu definieren, indem man die `:public_folder`-Option setzt:
 
 ```ruby
-set :public_folder, File.dirname(__FILE__) + '/static'
+set :public_folder, __dir__ + '/static'
 ```
 
 Zu beachten ist, dass der Ordnername `public` nicht Teil der URL ist.
@@ -3120,9 +3120,9 @@
 Die folgenden Versionen werden offiziell unterstützt:
 
 <dl>
-  <dt>Ruby 2.2</dt>
+  <dt>Ruby 2.3</dt>
   <dd>
-    2.2 wird vollständig unterstützt. Es gibt derzeit keine Pläne die
+    2.3 wird vollständig unterstützt. Es gibt derzeit keine Pläne die
     offizielle Unterstützung zu beenden
   </dd>
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/README.es.md new/README.es.md
--- old/README.es.md    2020-01-01 21:02:13.000000000 +0100
+++ new/README.es.md    2020-09-04 20:46:28.000000000 +0200
@@ -430,7 +430,7 @@
 opción `:public_folder`:
 
 ```ruby
-set :public_folder, File.dirname(__FILE__) + '/static'
+set :public_folder, __dir__ + '/static'
 ```
 
 Note que el nombre del directorio público no está incluido en la URL. Por
@@ -3083,9 +3083,9 @@
 Las siguientes versiones de Ruby son soportadas oficialmente:
 
 <dl>
-  <dt>Ruby 2.2</dt>
+  <dt>Ruby 2.3</dt>
     <dd>
-      2.2 Es totalmente compatible y recomendado. Actualmente no hay planes
+      2.3 Es totalmente compatible y recomendado. Actualmente no hay planes
       soltar el apoyo oficial para ello.
     </dd>
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/README.fr.md new/README.fr.md
--- old/README.fr.md    2020-01-01 21:02:13.000000000 +0100
+++ new/README.fr.md    2020-09-04 20:46:28.000000000 +0200
@@ -26,8 +26,12 @@
 ruby mon_application.rb
 ```
 
-Le résultat est visible sur :
-[http://localhost:4567](http://localhost:4567)
+Le résultat est visible sur : [http://localhost:4567](http://localhost:4567)
+
+Le code que vous avez modifié ne sera pas pris en compte tant que vous ne
+redémarrerez pas le serveur. Pensez à redémarrer le serveur à chaque
+modification ou utilisez
+[sinatra/reloader](http://www.sinatrarb.com/contrib/reloader).
 
 Il est recommandé d'exécuter également `gem install thin`, pour que
 Sinatra utilise le server Thin quand il est disponible.
@@ -55,11 +59,13 @@
             * [Templates Markdown](#templates-markdown)
             * [Templates Textile](#templates-textile)
             * [Templates RDoc](#templates-rdoc)
+            * [Templates Asciidoc](#templates-asciidoc)
             * [Templates Radius](#templates-radius)
             * [Templates Markaby](#templates-markaby)
             * [Templates RABL](#templates-rabl)
             * [Templates Slim](#templates-slim)
             * [Templates Creole](#templates-creole)
+            * [Templates MediaWiki](#templates-mediawiki)
             * [Templates CoffeeScript](#templates-coffeescript)
             * [Templates Stylus](#templates-stylus)
             * [Templates Yajl](#templates-yajl)
@@ -70,6 +76,7 @@
         * [Templates nommés](#templates-nommés)
         * [Associer des extensions de 
fichier](#associer-des-extensions-de-fichier)
         * [Ajouter son propre moteur de 
rendu](#ajouter-son-propre-moteur-de-rendu)
+        * [Utiliser des règles personnalisées pour la recherche de 
templates](#utiliser-des-règles-personnalisées-pour-la-recherche-de-templates)
     * [Filtres](#filtres)
     * [Helpers](#helpers)
         * [Utiliser les sessions](#utiliser-les-sessions)
@@ -91,7 +98,7 @@
     * [Configuration](#configuration)
         * [Se protéger des attaques](#se-protéger-des-attaques)
         * [Paramètres disponibles](#paramètres-disponibles)
-    * [Environements](#environements)
+    * [Environnements](#environnements)
     * [Gérer les erreurs](#gérer-les-erreurs)
         * [NotFound](#notfound)
         * [Error](#error)
@@ -157,9 +164,18 @@
 end
 ```
 
-Les routes sont évaluées  dans l'ordre où elles ont été définies. La première
+Les routes sont évaluées dans l'ordre où elles ont été définies. La première
 route qui correspond à la requête est appelée.
 
+Les routes se terminant par un slash sont différentes de celles qui n'en
+comportent pas :
+
+```ruby
+get '/foo' do
+  # Ne correspond pas à "GET /foo/"
+end
+```
+
 Les masques peuvent inclure des paramètres nommés, accessibles par
 l'intermédiaire du hash `params` :
 
@@ -242,10 +258,24 @@
 end
 ```
 
-A ce propos, à moins d'avoir désactivé la protection contre les attaques par
+À ce propos, à moins d'avoir désactivé la protection contre les attaques par
 "path transversal" (voir plus loin), l'URL demandée peut avoir été modifiée
 avant d'être comparée à vos routes.
 
+Vous pouvez personnaliser les options 
[Mustermann](https://github.com/sinatra/mustermann#readme)
+utilisées pour une route donnée en fournissant un hash `:mustermann_opts` :
+
+```ruby
+get '\A/articles\z', :mustermann_opts => { :type => :regexp, :check_anchors => 
false } do
+  # répond exactement à /articles, avec un ancrage explicite
+  "Si tu réponds à un pattern ancré tape dans tes mains !
+end
+```
+
+Cela ressemble à une [condition](#conditions), mais ce n'en est pas une !
+Ces options seront mergées dans le hash global `:mustermann_opts` décrit
+[plus bas](#paramètres-disponibles).
+
 ## Conditions
 
 Les routes peuvent définir toutes sortes de conditions, comme par exemple le
@@ -400,7 +430,7 @@
 Les fichiers du dossier `./public` sont servis de façon statique. Vous pouvez 
spécifier un autre dossier avec le paramètre `:public_folder` :
 
 ```ruby
-set :public_folder, File.dirname(__FILE__) + '/statique'
+set :public_folder, __dir__ + '/statique'
 ```
 
 Notez que le nom du dossier public n'apparait pas dans l'URL. Le fichier
@@ -541,6 +571,15 @@
 ```
 
 Utilisera la chaine de caractères comme template pour générer la réponse.
+Vous pouvez spécifier un `:path` et `:line` optionnels pour une trace plus
+claire s'il existe un chemin dans le système de fichiers ou une ligne
+associés à cette chaîne de caractères :
+
+```ruby
+get '/' do
+  haml '%div.title Bonjour le monde', :path => 'exemples/fichier.haml', :line 
=> 3
+end
+```
 
 ### Langages de template disponibles
 
@@ -826,7 +865,28 @@
 possible d’utiliser un moteur de rendu différent pour le template et
 pour le layout en utilisant l’option `:layout_engine`.
 
+#### Templates Asciidoc
+
+<table>
+  <tr>
+    <td>Dépendances</td>
+    <td><a href="http://asciidoctor.org/"; 
title="Asciidoctor">Asciidoctor</a></td>
+  </tr>
+  <tr>
+    <td>Extensions de fichier</td>
+    <td><tt>.asciidoc</tt>, <tt>.adoc</tt> and <tt>.ad</tt></td>
+  </tr>
+  <tr>
+    <td>Exemple</td>
+    <td><tt>asciidoc :README, :layout_engine => :erb</tt></td>
+  </tr>
+</table>
+
+Comme vous ne pouvez pas appeler de méthodes Ruby depuis un template
+AsciiDoc, vous aurez sûrement à lui passer des variables locales.
+
 #### Templates Radius
+
 <table>
   <tr>
     <td>Dépendances</td>
@@ -936,6 +996,44 @@
 d'utiliser un moteur de rendu différent pour le template et pour le layout
 en utilisant l'option `:layout_engine`.
 
+#### Templates MediaWiki
+
+<table>
+  <tr>
+    <td>Dépendances</td>
+    <td><a href="https://github.com/nricciar/wikicloth"; 
title="WikiCloth">WikiCloth</a></td>
+  </tr>
+  <tr>
+    <td>Extensions de fichier</td>
+    <td><tt>.mediawiki</tt> and <tt>.mw</tt></td>
+  </tr>
+  <tr>
+    <td>Exemple</td>
+    <td><tt>mediawiki :wiki, :layout_engine => :erb</tt></td>
+  </tr>
+</table>
+
+Il n’est pas possible d’appeler de méthodes Ruby depuis Mediawiki, ni de lui
+passer de variables locales. Par conséquent, il sera souvent utilisé en
+combinaison avec un autre moteur de rendu :
+
+```ruby
+erb :overview, :locals => { :text => mediawiki(:introduction) }
+```
+
+Notez que vous pouvez également appeler la méthode `mediawiki` depuis un
+autre template :
+
+```ruby
+%h1 Bonjour depuis Haml !
+%p= mediawiki(:bienvenue)
+```
+
+Comme vous ne pouvez pas appeler de méthodes Ruby depuis MediaWiki, vous ne 
pouvez
+pas utiliser de layouts écrits en MediaWiki. Toutefois, il est
+possible d’utiliser un moteur de rendu différent pour le template et
+pour le layout en utilisant l’option `:layout_engine`.
+
 #### Templates CoffeeScript
 
 <table>
@@ -1078,12 +1176,12 @@
 end
 ```
 
-Ceci est généralement nécessaire lorsque l'on veut utiliser un template depuis 
un autre template (partiel) et qu'il faut donc adapter le nom des variables.  
+Ceci est généralement nécessaire lorsque l'on veut utiliser un template depuis 
un autre template (partiel) et qu'il faut donc adapter le nom des variables.
 
 ### Templates avec `yield` et layouts imbriqués
 
 En général, un layout est un simple template qui appelle `yield`. Ce genre de
-template peut s'utiliser via l'option `:template`  comme décrit précédemment ou
+template peut s'utiliser via l'option `:template` comme décrit précédemment ou
 peut être rendu depuis un bloc :
 
 ```ruby
@@ -1203,6 +1301,23 @@
 
 Utilisera `./views/index.monmoteur`. Voir [le projet 
Github](https://github.com/rtomayko/tilt) pour en savoir plus sur Tilt.
 
+### Utiliser des règles personnalisées pour la recherche de templates
+
+Pour implémenter votre propre mécanisme de recherche de templates, vous
+pouvez écrire votre propre méthode `#find_template` :
+
+```ruby
+configure do
+  set :views, [ './vues/a', './vues/b' ]
+end
+
+def find_template(vues, nom, moteur, &bloc)
+  Array(vues).each do |v|
+    super(v, nom, moteur, &bloc)
+  end
+end
+```
+
 ## Filtres
 
 Les filtres `before` sont exécutés avant chaque requête, dans le même contexte
@@ -1542,7 +1657,7 @@
     # prévient le client qu'un nouveau message est arrivé
     out << params['message'] << "\n"
 
-    # indique au client de se connecter à nouveau
+    # indique au client de se connecter à nouveau
     out.close
   end
 
@@ -1551,6 +1666,10 @@
 end
 ```
 
+Il est aussi possible pour le client de fermer la connexion en essayant
+d'écrire sur le socket. Pour cette raison, il est recommandé de vérifier
+`out.closed?` avant d'essayer d'y écrire.
+
 ### Journalisation (Logging)
 
 Dans le contexte de la requête, la méthode utilitaire `logger` expose une
@@ -1792,12 +1911,6 @@
     le nom du fichier dans la réponse, par défaut le nom du fichier envoyé.
   </dd>
 
-  <dt>last_modified</dt>
-  <dd>
-    valeur pour l’en-tête Last-Modified, par défaut la date de modification du
-    fichier.
-  </dd>
-
   <dt>type</dt>
   <dd>
     type de contenu à utiliser, deviné à partir de l’extension de fichier si
@@ -1816,7 +1929,6 @@
   <dt>status</dt>
   <dd>
     code état à renvoyer. Utile quand un fichier statique sert de page 
d’erreur.
-
     Si le gestionnaire Rack le supporte, d'autres moyens que le streaming via 
le
     processus Ruby seront utilisés. Si vous utilisez cette méthode, Sinatra 
gérera
     automatiquement les requêtes de type range.
@@ -1962,8 +2074,8 @@
 set :views, ['views', 'templates']
 
 helpers do
-  def find_template(views, name, engine, &block)
-    Array(views).each { |v| super(v, name, engine, &block) }
+  def find_template(vues, nom, moteur, &bloc)
+    Array(vues).each { |v| super(v, nom, moteur, &bloc) }
   end
 end
 ```
@@ -2142,6 +2254,12 @@
   <dt>port</dt>
   <dd>port à écouter. Utiliser seulement pour le serveur intégré.</dd>
 
+  <dt>mustermann_opts</dt>
+  <dd>
+    Un hash d'options à passer à Mustermann.new lors de la compilation
+    des chemins de routes
+  </dd>
+
   <dt>prefixed_redirects</dt>
   <dd>si oui ou non <tt>request.script_name</tt> doit être inséré dans les
   redirections si un chemin non absolu est utilisé. Ainsi, <tt>redirect
@@ -2161,6 +2279,12 @@
   paramètre <tt>static</tt>). Si non défini, il découle du paramètre
   <tt>app_file</tt>.</dd>
 
+  <dt>quiet</dt>
+  <dd>
+    Désactive les journaux (logs) générés par les commandes start et stop
+    de Sinatra. <tt>false</tt> par défaut.
+  </dd>
+
   <dt>reload_templates</dt>
   <dd>si oui ou non les templates doivent être rechargés entre les requêtes.
   Activé en mode développement.</dd>
@@ -2187,11 +2311,27 @@
   défaut [‘thin’, ‘mongrel’, ‘webrick’], l’ordre indiquant la
   priorité.</dd>
 
+  <dt>server_settings</dt>
+  <dd>
+    Si vous utilisez un serveur Webrick, sans doute pour votre environnement de
+    développement, vous pouvez passer des options à <tt>server_settings</tt>,
+    comme <tt>SSLEnable</tt> ou <tt>SSLVerifyClient</tt>. Cependant, les
+    serveurs comme Puma et Thin ne le permettent pas, et vous pouvez donc
+    définir <tt>server_settings</tt> en tant que méthode lorsque vous appelez
+    <tt>configure</tt>.
+  </dd>
+
   <dt>sessions</dt>
   <dd>active le support des sessions basées sur les cookies, en utilisant
   <tt>Rack::Session::Cookie</tt>. Reportez-vous à la section ‘Utiliser les
   sessions’ pour plus d’informations.</dd>
 
+  <dt>session_store</dt>
+  <dd>
+    Le middleware Rack utilisé pour les sessions. 
<tt>Rack::Session::Cookie</tt>
+    par défaut. Voir la section 'Utiliser les sessions' pour plus de détails.
+  </dd>
+
   <dt>show_exceptions</dt>
   <dd>affiche la trace de l’erreur dans le navigateur lorsqu’une exception se
   produit. Désactivé par défaut sauf lorsque <tt>environment</tt> est
@@ -2214,6 +2354,9 @@
   <dd>à définir à <tt>true</tt> pour indiquer à Thin d’utiliser
   <tt>EventMachine.defer</tt> pour traiter la requête.</dd>
 
+  <dt>traps</dt>
+  <dd>Indique si Sinatra doit gérer les signaux système.</dd>
+
   <dt>views</dt>
   <dd>chemin pour le dossier des vues. Si non défini, il découle du paramètre
   <tt>app_file</tt>.</dd>
@@ -2225,10 +2368,10 @@
   </dd>
 </dl>
 
-## Environements
+## Environnements
 
 Il existe trois environnements prédéfinis : `"development"`,
-`"production"` et `"test"`. Les environements peuvent être
+`"production"` et `"test"`. Les environnements peuvent être
 sélectionné via la variable d'environnement `APP_ENV`. Sa valeur par défaut
 est `"development"`. Dans ce mode, tous les templates sont rechargés à
 chaque requête. Des handlers spécifiques pour `not_found` et
@@ -2276,7 +2419,15 @@
 ### Error
 
 Le gestionnaire `error` est invoqué à chaque fois qu'une exception est
-soulevée dans une route ou un filtre. L'objet exception est accessible via la
+soulevée dans une route ou un filtre. Notez qu'en développement, il ne
+sera exécuté que si vous définissez l'option show exceptions à
+`:after_handler` :
+
+```ruby
+set :show_exceptions, :after_handler
+```
+
+L'objet exception est accessible via la
 variable Rack `sinatra.error` :
 
 ```ruby
@@ -2285,7 +2436,7 @@
 end
 ```
 
-Erreur sur mesure :
+Erreur personnalisée :
 
 ```ruby
 error MonErreurSurMesure do
@@ -2412,6 +2563,9 @@
 end
 ```
 
+Note : si vous utilisez le style modulaire de Sinatra, remplacez
+`Sinatra::Application` par le nom de la classe de votre application.
+
 ## Sinatra::Base - Les Middlewares, Bibliothèques, et Applications Modulaires
 
 Définir votre application au niveau supérieur fonctionne bien dans le cas des
@@ -2818,9 +2972,9 @@
 require 'sinatra/base'
 
 classe App < Sinatra::Base
-  get '/' do
+  get '/' do
     'Bonjour le monde !'
-  end
+  end
 end
 
 App.run!
@@ -2839,31 +2993,9 @@
 Les versions suivantes de Ruby sont officiellement supportées :
 
 <dl>
-  <dt>Ruby 1.8.7</dt>
-  <dd>
-    1.8.7 est complètement supporté, toutefois si rien ne vous en empêche,
-    nous vous recommandons de faire une mise à jour ou bien de passer à JRuby
-    ou Rubinius. Le support de Ruby 1.8.7 ne sera pas supprimé avant la sortie
-    de Sinatra 2.0. Ruby 1.8.6 n’est plus supporté.
-  </dd>
-
-  <dt>Ruby 1.9.2</dt>
-  <dd>
-    1.9.2 est totalement supporté. N’utilisez pas 1.9.2p0 car il provoque des
-    erreurs de segmentation à l’exécution de Sinatra. Son support continuera
-    au minimum jusqu’à la sortie de Sinatra 1.5.
-  </dd>
-
-  <dt>Ruby 1.9.3</dt>
-  <dd>
-    1.9.3 est totalement supporté et recommandé. Nous vous rappelons que passer
-    à 1.9.3 depuis une version précédente annulera toutes les sessions. 1.9.3
-    sera supporté jusqu'à la sortie de Sinatra 2.0.
-  </dd>
-
-  <dt>Ruby 2.0.0</dt>
+  <dt>Ruby 2.2</dt>
   <dd>
-    2.0.0 est totalement supporté et recommandé. L'abandon de son support
+    2.2 est totalement supporté et recommandé. L'abandon de son support
     officiel n'est pas à l'ordre du jour.
   </dd>
 
@@ -2881,6 +3013,8 @@
   </dd>
 </dl>
 
+Les versions antérieures à 2.2.2 ne sont plus supportées depuis Sinatra 2.0.
+
 Nous gardons également un oeil sur les versions Ruby à venir.
 
 Les implémentations Ruby suivantes ne sont pas officiellement supportées mais
@@ -2953,43 +3087,6 @@
 bundle exec ruby myapp.rb
 ```
 
-### Faire un clone local
-
-Si vous ne souhaitez pas employer Bundler, vous pouvez cloner Sinatra en local
-dans votre projet et démarrez votre application avec le dossier `sinatra/lib`
-dans le `$LOAD_PATH` :
-
-```shell
-cd myapp
-git clone git://github.com/sinatra/sinatra.git
-ruby -I sinatra/lib myapp.rb
-```
-
-Et de temps en temps, vous devrez récupérer la dernière version du code source
-de Sinatra :
-
-```shell
-cd myapp/sinatra
-git pull
-```
-
-### Installer globalement
-
-Une dernière méthode consiste à construire la gem vous-même :
-
-```shell
-git clone git://github.com/sinatra/sinatra.git
-cd sinatra
-rake sinatra.gemspec
-rake install
-```
-
-Si vous installez les gems en tant que root, vous devez encore faire un :
-
-```shell
-sudo rake install
-```
-
 ## Versions
 
 Sinatra se conforme aux [versions sémantiques](http://semver.org/), aussi bien
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/README.hu.md new/README.hu.md
--- old/README.hu.md    2020-01-01 21:02:13.000000000 +0100
+++ new/README.hu.md    2020-09-04 20:46:28.000000000 +0200
@@ -120,7 +120,7 @@
 történik, de természetesen más könyvtárat is megadhatsz erre a célra,
 mégpedig a :public_folder kapcsoló beállításával:
 
-  set :public_folder, File.dirname(__FILE__) + '/static'
+  set :public_folder, __dir__ + '/static'
 
 Fontos megjegyezni, hogy a nyilvános könyvtár neve nem szerepel az URL-ben.
 A ./public/css/style.css fájl az
@@ -131,7 +131,7 @@
 A sablonfájlokat rendszerint a  `./views` könyvtárba helyezzük, de
 itt is lehetőség nyílik egyéb könyvtár használatára:
 
-  set :views, File.dirname(__FILE__) + '/templates'
+  set :views, __dir__ + '/templates'
 
 Nagyon fontos észben tartani, hogy a sablononkra mindig szimbólumokkal
 hivatkozunk, még akkor is, ha egyéb (ebben az esetben a
@@ -700,7 +700,7 @@
 az alkalmazásodban:
 
 ```ruby
-  $LOAD_PATH.unshift File.dirname(__FILE__) + '/sinatra/lib'
+  $LOAD_PATH.unshift __dir__ + '/sinatra/lib'
   require 'rubygems'
   require 'sinatra'
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/README.ja.md new/README.ja.md
--- old/README.ja.md    2020-01-01 21:02:13.000000000 +0100
+++ new/README.ja.md    2020-09-04 20:46:28.000000000 +0200
@@ -386,7 +386,7 @@
 `:public_folder`オプションを指定することで別の場所を指定することができます。
 
 ```ruby
-set :public_folder, File.dirname(__FILE__) + '/static'
+set :public_folder, __dir__ + '/static'
 ```
 
 ノート: この静的ファイル用のディレクトリ名はURL中に含まれません。
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/README.ko.md new/README.ko.md
--- old/README.ko.md    2020-01-01 21:02:13.000000000 +0100
+++ new/README.ko.md    2020-09-04 20:46:28.000000000 +0200
@@ -385,7 +385,7 @@
 변경하려면 `:public_folder` 옵션을 지정하면 됩니다.
 
 ```ruby
-set :public_folder, File.dirname(__FILE__) + '/static'
+set :public_folder, __dir__ + '/static'
 ```
 
 public 디렉터리명은 URL에 포함되지 않는다는 점에 주의하세요.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/README.md new/README.md
--- old/README.md       2020-01-01 21:02:13.000000000 +0100
+++ new/README.md       2020-09-04 20:46:28.000000000 +0200
@@ -34,7 +34,7 @@
 Please restart the server every time you change or use
 [sinatra/reloader](http://www.sinatrarb.com/contrib/reloader).
 
-It is recommended to also run `gem install thin`, which Sinatra will
+It is recommended to also run `gem install puma`, which Sinatra will
 pick up if available.
 
 ## Table of Contents
@@ -427,7 +427,7 @@
 a different location by setting the `:public_folder` option:
 
 ```ruby
-set :public_folder, File.dirname(__FILE__) + '/static'
+set :public_folder, __dir__ + '/static'
 ```
 
 Note that the public directory name is not included in the URL. A file
@@ -1293,7 +1293,7 @@
 
 ```ruby
 configure do
-  set :views [ './views/a', './views/b' ]
+  set :views, [ './views/a', './views/b' ]
 end
 
 def find_template(views, name, engine, &block)
@@ -1685,36 +1685,52 @@
 
 If the optional parameter is set to `keep_open`, it will not call `close` on
 the stream object, allowing you to close it at any later point in the
-execution flow. This only works on evented servers, like Thin and Rainbows.
+execution flow. This only works on evented servers, like Rainbows.
 Other servers will still close the stream:
 
 ```ruby
-# long polling
+# config.ru
+require 'sinatra/base'
 
-set :server, :thin
-connections = []
+class App < Sinatra::Base
+  connections = []
 
-get '/subscribe' do
-  # register a client's interest in server events
-  stream(:keep_open) do |out|
-    connections << out
-    # purge dead connections
-    connections.reject!(&:closed?)
+  get '/subscribe', provides: 'text/event-stream'  do
+    # register a client's interest in server events
+    stream(:keep_open) do |out|
+      connections << out
+      # purge dead connections
+      connections.reject!(&:closed?)
+    end
   end
-end
 
-post '/:message' do
-  connections.each do |out|
-    # notify client that a new message has arrived
-    out << params['message'] << "\n"
+  post '/' do
+    connections.each do |out|
+      # notify client that a new message has arrived
+      out << "data: #{params[:msg]}\n\n"
+
+      # indicate client to connect again
+      out.close
+    end
 
-    # indicate client to connect again
-    out.close
+    204 # response without entity body
   end
+end
+
+run App
+```
 
-  # acknowledge
-  "message received"
+```ruby
+# rainbows.conf
+Rainbows! do
+  use :EventMachine
 end
+````
+
+Run:
+
+```shell
+rainbows -c rainbows.conf
 ```
 
 It's also possible for the client to close the connection when trying to
@@ -2264,6 +2280,15 @@
       used for built-in server.
     </dd>
 
+  <dt>default_content_type</dt>
+  <dd>
+    Content-Type to assume if unknown (defaults to <tt>"text/html"</tt>). Set
+    to <tt>nil</tt> to not set a default Content-Type on every response; when
+    configured so, you must set the Content-Type manually when emitting content
+    or the user-agent will have to sniff it (or, if <tt>nosniff</tt> is enabled
+    in Rack::Protection::XSSHeader, assume <tt>application/octet-stream</tt>).
+  </dd>
+
   <dt>default_encoding</dt>
     <dd>Encoding to assume if unknown (defaults to <tt>"utf-8"</tt>).</dd>
 
@@ -2368,7 +2393,7 @@
       If you are using a WEBrick web server, presumably for your development
       environment, you can pass a hash of options to <tt>server_settings</tt>,
       such as <tt>SSLEnable</tt> or <tt>SSLVerifyClient</tt>. However, web
-      servers such as Puma and Thin do not support this, so you can set
+      servers such as Puma do not support this, so you can set
       <tt>server_settings</tt> by defining it as a method when you call
       <tt>configure</tt>.
     </dd>
@@ -2419,7 +2444,7 @@
 
   <dt>threaded</dt>
     <dd>
-      If set to <tt>true</tt>, will tell Thin to use
+      If set to <tt>true</tt>, will tell server to use
       <tt>EventMachine.defer</tt> for processing the request.
     </dd>
 
@@ -3008,7 +3033,7 @@
 -p # set the port (default is 4567)
 -o # set the host (default is 0.0.0.0)
 -e # set the environment (default is development)
--s # specify rack server/handler (default is thin)
+-s # specify rack server/handler (default is puma)
 -q # turn on quiet mode for server (default is off)
 -x # turn on the mutex lock (default is off)
 ```
@@ -3020,15 +3045,15 @@
 by Konstantin_
 
 Sinatra doesn't impose any concurrency model, but leaves that to the
-underlying Rack handler (server) like Thin, Puma or WEBrick. Sinatra
+underlying Rack handler (server) like Puma or WEBrick. Sinatra
 itself is thread-safe, so there won't be any problem if the Rack handler
 uses a threaded model of concurrency. This would mean that when starting
 the server, you'd have to specify the correct invocation method for the
 specific Rack handler. The following example is a demonstration of how
-to start a multi-threaded Thin server:
+to start a multi-threaded Rainbows server:
 
 ```ruby
-# app.rb
+# config.ru
 
 require 'sinatra/base'
 
@@ -3038,23 +3063,31 @@
   end
 end
 
-App.run!
+run App
+```
 
+```ruby
+# rainbows.conf
+
+# Rainbows configurator is based on Unicorn.
+Rainbows! do
+  use :ThreadSpawn
+end
 ```
 
 To start the server, the command would be:
 
 ```shell
-thin --threaded start
+rainbows -c rainbows.conf
 ```
 
 ## Requirement
 
 The following Ruby versions are officially supported:
 <dl>
-  <dt>Ruby 2.2</dt>
+  <dt>Ruby 2.3</dt>
   <dd>
-    2.2 is fully supported and recommended. There are currently no plans to
+    2.3 is fully supported and recommended. There are currently no plans to
     drop official support for it.
   </dd>
 
@@ -3072,7 +3105,7 @@
   </dd>
 </dl>
 
-Versions of Ruby prior to 2.2.2 are no longer supported as of Sinatra 2.0.
+Versions of Ruby prior to 2.3 are no longer supported as of Sinatra 2.1.0.
 
 We also keep an eye on upcoming Ruby versions.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/README.pt-br.md new/README.pt-br.md
--- old/README.pt-br.md 2020-01-01 21:02:13.000000000 +0100
+++ new/README.pt-br.md 2020-09-04 20:46:28.000000000 +0200
@@ -444,7 +444,7 @@
 `:public_folder`
 
 ```ruby
-set :public_folder, File.dirname(__FILE__) + '/estatico'
+set :public_folder, __dir__ + '/estatico'
 ```
 
 Note que o nome do diretório público não é incluido na URL. Um arquivo
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/README.pt-pt.md new/README.pt-pt.md
--- old/README.pt-pt.md 2020-01-01 21:02:13.000000000 +0100
+++ new/README.pt-pt.md 2020-09-04 20:46:28.000000000 +0200
@@ -121,7 +121,7 @@
 `:public_folder`
 
 ```ruby
-set :public_folder, File.dirname(__FILE__) + '/estatico'
+set :public_folder, __dir__ + '/estatico'
 ```
 
 Note que o nome do directório público não é incluido no URL. Um arquivo
@@ -134,7 +134,7 @@
 utilizar um directório de views diferente:
 
 ```ruby
-set :views, File.dirname(__FILE__) + '/modelo'
+set :views, __dir__ + '/modelo'
 ```
 
 Uma coisa importante a ser lembrada é que você sempre tem as referências
@@ -757,7 +757,7 @@
 `LOAD_PATH` do seu aplicativo:
 
 ```ruby
-$LOAD_PATH.unshift File.dirname(__FILE__) + '/sinatra/lib'
+$LOAD_PATH.unshift __dir__ + '/sinatra/lib'
 require 'rubygems'
 require 'sinatra'
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/README.ru.md new/README.ru.md
--- old/README.ru.md    2020-01-01 21:02:13.000000000 +0100
+++ new/README.ru.md    2020-09-04 20:46:28.000000000 +0200
@@ -431,7 +431,7 @@
 месторасположение при помощи опции `:public_folder`:
 
 ```ruby
-set :public_folder, File.dirname(__FILE__) + '/static'
+set :public_folder, __dir__ + '/static'
 ```
 
 Учтите, что имя директории со статическими файлами не включено в URL.
@@ -3089,9 +3089,9 @@
 
 Следующие версии Ruby официально поддерживаются:
 <dl>
-  <dt>Ruby 2.2</dt>
+  <dt>Ruby 2.3</dt>
   <dd>
-    Версия 2.2 полностью поддерживается и рекомендуется. В настоящее время нет 
+    Версия 2.3 полностью поддерживается и рекомендуется. В настоящее время нет 
   планов отказаться от официальной поддержки.
   </dd>
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/README.zh.md new/README.zh.md
--- old/README.zh.md    2020-01-01 21:02:13.000000000 +0100
+++ new/README.zh.md    2020-09-04 20:46:28.000000000 +0200
@@ -393,7 +393,7 @@
 静态文件从 `./public` 目录提供服务。可以通过设置`:public_folder` 选项设定一个不同的位置:
 
 ```ruby
-set :public_folder, File.dirname(__FILE__) + '/static'
+set :public_folder, __dir__ + '/static'
 ```
 
 请注意 public 目录名并没有包含在 URL 中。文件 `./public/css/style.css` 可以通过
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/VERSION new/VERSION
--- old/VERSION 2020-01-01 21:02:13.000000000 +0100
+++ new/VERSION 2020-09-04 20:46:28.000000000 +0200
@@ -1 +1 @@
-2.0.8.1
+2.1.0
Binary files old/checksums.yaml.gz and new/checksums.yaml.gz differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/examples/chat.rb new/examples/chat.rb
--- old/examples/chat.rb        2020-01-01 21:02:13.000000000 +0100
+++ new/examples/chat.rb        2020-09-04 20:46:28.000000000 +0200
@@ -1,7 +1,8 @@
 #!/usr/bin/env ruby -I ../lib -I lib
 # coding: utf-8
+require_relative 'rainbows'
 require 'sinatra'
-set :server, 'thin'
+set :server, :rainbows
 connections = []
 
 get '/' do
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/examples/rainbows.conf new/examples/rainbows.conf
--- old/examples/rainbows.conf  1970-01-01 01:00:00.000000000 +0100
+++ new/examples/rainbows.conf  2020-09-04 20:46:28.000000000 +0200
@@ -0,0 +1,3 @@
+Rainbows! do
+  use :EventMachine
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/examples/rainbows.rb new/examples/rainbows.rb
--- old/examples/rainbows.rb    1970-01-01 01:00:00.000000000 +0100
+++ new/examples/rainbows.rb    2020-09-04 20:46:28.000000000 +0200
@@ -0,0 +1,20 @@
+require 'rainbows'
+
+module Rack
+  module Handler
+    class Rainbows
+      def self.run(app, **options)
+        rainbows_options = {
+          listeners: ["#{options[:Host]}:#{options[:Port]}"],
+          worker_processes: 1,
+          timeout: 30,
+          config_file: ::File.expand_path('rainbows.conf', __dir__),
+        }
+
+        ::Rainbows::HttpServer.new(app, rainbows_options).start.join
+      end
+    end
+
+    register :rainbows, ::Rack::Handler::Rainbows
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/examples/stream.ru new/examples/stream.ru
--- old/examples/stream.ru      2020-01-01 21:02:13.000000000 +0100
+++ new/examples/stream.ru      2020-09-04 20:46:28.000000000 +0200
@@ -2,10 +2,10 @@
 #
 # run *one* of these:
 #
-#   rackup -s mongrel stream.ru   # gem install mongrel
-#   thin -R stream.ru start       # gem install thin
-#   unicorn stream.ru             # gem install unicorn
-#   puma stream.ru                # gem install puma
+#   rackup -s mongrel stream.ru         # gem install mongrel
+#   unicorn stream.ru                   # gem install unicorn
+#   puma stream.ru                      # gem install puma
+#   rainbows -c rainbows.conf stream.ru # gem install rainbows eventmachine
 
 require 'sinatra/base'
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/sinatra/base.rb new/lib/sinatra/base.rb
--- old/lib/sinatra/base.rb     2020-01-01 21:02:13.000000000 +0100
+++ new/lib/sinatra/base.rb     2020-09-04 20:46:28.000000000 +0200
@@ -43,12 +43,11 @@
     end
 
     def preferred_type(*types)
-      accepts = accept # just evaluate once
-      return accepts.first if types.empty?
+      return accept.first if types.empty?
       types.flatten!
-      return types.first if accepts.empty?
-      accepts.detect do |pattern|
-        type = types.detect { |t| File.fnmatch(pattern, t) }
+      return types.first if accept.empty?
+      accept.detect do |accept_header|
+        type = types.detect { |t| MimeTypeEntry.new(t).accepts?(accept_header) 
}
         return type if type
       end
     end
@@ -81,8 +80,6 @@
       raise BadRequest, "Invalid query parameters: 
#{Rack::Utils.escape_html(e.message)}"
     end
 
-    private
-
     class AcceptEntry
       attr_accessor :params
       attr_reader :entry
@@ -125,6 +122,35 @@
         to_str.send(*args, &block)
       end
     end
+
+    class MimeTypeEntry
+      attr_reader :params
+
+      def initialize(entry)
+        params = entry.scan(HEADER_PARAM).map! do |s|
+          key, value = s.strip.split('=', 2)
+          value = value[1..-2].gsub(/\\(.)/, '\1') if value.start_with?('"')
+          [key, value]
+        end
+
+        @type   = entry[/[^;]+/].delete(' ')
+        @params = Hash[params]
+      end
+
+      def accepts?(entry)
+        File.fnmatch(entry, self) && matches_params?(entry.params)
+      end
+
+      def to_str
+        @type
+      end
+
+      def matches_params?(params)
+        return true if @params.empty?
+
+        params.all? { |k,v| !@params.has_key?(k) || @params[k] == v }
+      end
+    end
   end
 
   # The response object. See Rack::Response and Rack::Response::Helpers for
@@ -133,10 +159,6 @@
   # http://rubydoc.info/github/rack/rack/master/Rack/Response/Helpers
   class Response < Rack::Response
     DROP_BODY_RESPONSES = [204, 304]
-    def initialize(*)
-      super
-      headers['Content-Type'] ||= 'text/html'
-    end
 
     def body=(value)
       value = value.body while Rack::Response === value
@@ -163,7 +185,7 @@
       if calculate_content_length?
         # if some other code has already set Content-Length, don't muck with it
         # currently, this would be the static file-handler
-        headers["Content-Length"] = body.inject(0) { |l, p| l + p.bytesize 
}.to_s
+        headers["Content-Length"] = body.map(&:bytesize).reduce(0, :+).to_s
       end
 
       [status.to_i, headers, result]
@@ -184,7 +206,7 @@
     end
   end
 
-  # Some Rack handlers (Thin, Rainbows!) implement an extended body object 
protocol, however,
+  # Some Rack handlers (Rainbows!) implement an extended body object protocol, 
however,
   # some middleware (namely Rack::Lint) will break it by not mirroring the 
methods in question.
   # This middleware will detect an extended body object and will make sure it 
reaches the
   # handler directly. We do this here, so our middleware and middleware set up 
by the app will
@@ -451,7 +473,7 @@
     #
     # The close parameter specifies whether Stream#close should be called
     # after the block has been executed. This is only relevant for evented
-    # servers like Thin or Rainbows.
+    # servers like Rainbows.
     def stream(keep_open = false)
       scheduler = env['async.callback'] ? EventMachine : Stream
       current   = @params.dup
@@ -647,8 +669,6 @@
     end
   end
 
-  private
-
   # Template rendering methods. Each method takes the name of a template
   # to render as a Symbol and returns a String with the rendered output,
   # as well as an optional hash with additional options.
@@ -900,6 +920,7 @@
       super()
       @app = app
       @template_cache = Tilt::Cache.new
+      @pinned_response = nil # whether a before! filter pinned the content-type
       yield self if block_given?
     end
 
@@ -915,15 +936,14 @@
       @response = Response.new
       template_cache.clear if settings.reload_templates
 
-      @response['Content-Type'] = nil
       invoke { dispatch! }
       invoke { error_block!(response.status) } unless @env['sinatra.error']
 
       unless @response['Content-Type']
-        if Array === body and body[0].respond_to? :content_type
+        if Array === body && body[0].respond_to?(:content_type)
           content_type body[0].content_type
-        else
-          content_type :html
+        elsif default = settings.default_content_type
+          content_type default
         end
       end
 
@@ -973,15 +993,21 @@
     private
 
     # Run filters defined on the class and all superclasses.
+    # Accepts an optional block to call after each filter is applied.
     def filter!(type, base = settings)
       filter! type, base.superclass if base.superclass.respond_to?(:filters)
-      base.filters[type].each { |args| process_route(*args) }
+      base.filters[type].each do |args|
+        result = process_route(*args)
+        yield result if block_given?
+      end
     end
 
     # Run routes defined on the class and all superclasses.
     def route!(base = settings, pass_block = nil)
       if routes = base.routes[@request.request_method]
         routes.each do |pattern, conditions, block|
+          @response.delete_header('Content-Type') unless @pinned_response
+
           returned_pass_block = process_route(pattern, conditions) do |*args|
             env['sinatra.route'] = "#{@request.request_method} #{pattern}"
             route_eval { block[*args] }
@@ -1059,7 +1085,10 @@
     # a matching file is found, returns nil otherwise.
     def static!(options = {})
       return if (public_dir = settings.public_folder).nil?
-      path = 
File.expand_path("#{public_dir}#{URI_INSTANCE.unescape(request.path_info)}" )
+      path = "#{public_dir}#{URI_INSTANCE.unescape(request.path_info)}"
+      return unless valid_path?(path)
+
+      path = File.expand_path(path)
       return unless File.file?(path)
 
       env['sinatra.static_file'] = path
@@ -1094,7 +1123,9 @@
 
       invoke do
         static! if settings.static? && (request.get? || request.head?)
-        filter! :before
+        filter! :before do
+          @pinned_response = !@response['Content-Type'].nil?
+        end
         route!
       end
     rescue ::Exception => boom
@@ -1124,19 +1155,27 @@
 
       status(500) unless status.between? 400, 599
 
-      boom_message = boom.message if boom.message && boom.message != 
boom.class.name
       if server_error?
         dump_errors! boom if settings.dump_errors?
         raise boom if settings.show_exceptions? and settings.show_exceptions 
!= :after_handler
       elsif not_found?
         headers['X-Cascade'] = 'pass' if settings.x_cascade?
-        body boom_message || '<h1>Not Found</h1>'
-      elsif bad_request?
-        body boom_message || '<h1>Bad Request</h1>'
       end
 
-      res = error_block!(boom.class, boom) || error_block!(status, boom)
-      return res if res or not server_error?
+      if res = error_block!(boom.class, boom) || error_block!(status, boom)
+        return res
+      end
+
+      if not_found? || bad_request?
+        if boom.message && boom.message != boom.class.name
+          body boom.message
+        else
+          content_type 'text/html'
+          body '<h1>' + (not_found? ? 'Not Found' : 'Bad Request') + '</h1>'
+        end
+      end
+
+      return unless server_error?
       raise boom if settings.raise_errors? or settings.show_exceptions?
       error_block! Exception, boom
     end
@@ -1403,7 +1442,7 @@
       # in `extensions` available to the handlers and templates
       def helpers(*extensions, &block)
         class_eval(&block)   if block_given?
-        include(*extensions) if extensions.any?
+        prepend(*extensions) if extensions.any?
       end
 
       # Register an extension. Alternatively take a block from which an
@@ -1446,7 +1485,7 @@
       alias_method :stop!, :quit!
 
       # Run the Sinatra app as a self-hosted server using
-      # Thin, Puma, Mongrel, or WEBrick (in that order). If given a block, 
will call
+      # Puma, Mongrel, or WEBrick (in that order). If given a block, will call
       # with the constructed handler once we have taken the stage.
       def run!(options = {}, &block)
         return if running?
@@ -1523,7 +1562,7 @@
         # behavior, by ensuring an instance exists:
         prototype
         # Run the instance we created:
-        handler.run(self, server_settings) do |server|
+        handler.run(self, **server_settings) do |server|
           unless suppress_messages?
             $stderr.puts "== Sinatra (v#{Sinatra::VERSION}) has taken the 
stage on #{port} for #{environment} with backup from #{handler_name}"
           end
@@ -1777,6 +1816,7 @@
     set :add_charset, %w[javascript xml xhtml+xml].map { |t| 
"application/#{t}" }
     settings.add_charset << /^text\//
     set :mustermann_opts, {}
+    set :default_content_type, 'text/html'
 
     # explicitly generating a session secret eagerly to play nice with 
preforking
     begin
@@ -1837,7 +1877,7 @@
 
     configure :development do
       get '/__sinatra__/:image.png' do
-        filename = File.dirname(__FILE__) + 
"/images/#{params[:image].to_i}.png"
+        filename = __dir__ + "/images/#{params[:image].to_i}.png"
         content_type :png
         send_file filename
       end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/sinatra/main.rb new/lib/sinatra/main.rb
--- old/lib/sinatra/main.rb     2020-01-01 21:02:13.000000000 +0100
+++ new/lib/sinatra/main.rb     2020-09-04 20:46:28.000000000 +0200
@@ -4,11 +4,11 @@
   if ARGV.any?
     require 'optparse'
     parser = OptionParser.new { |op|
-      op.on('-p port',   'set the port (default is 4567)')                { 
|val| ParamsConfig[:port] = Integer(val) }
-      op.on('-s server', 'specify rack server/handler (default is thin)') { 
|val| ParamsConfig[:server] = val }
-      op.on('-q',        'turn on quiet mode (default is off)')           {    
   ParamsConfig[:quiet] = true }
-      op.on('-x',        'turn on the mutex lock (default is off)')       {    
   ParamsConfig[:lock] = true }
-      op.on('-e env',    'set the environment (default is development)')  do 
|val|
+      op.on('-p port',   'set the port (default is 4567)')               { 
|val| ParamsConfig[:port] = Integer(val) }
+      op.on('-s server', 'specify rack server/handler')                  { 
|val| ParamsConfig[:server] = val }
+      op.on('-q',        'turn on quiet mode (default is off)')          {     
  ParamsConfig[:quiet] = true }
+      op.on('-x',        'turn on the mutex lock (default is off)')      {     
  ParamsConfig[:lock] = true }
+      op.on('-e env',    'set the environment (default is development)') do 
|val|
         ENV['RACK_ENV'] = val
         ParamsConfig[:environment] = val.to_sym
       end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/sinatra/show_exceptions.rb 
new/lib/sinatra/show_exceptions.rb
--- old/lib/sinatra/show_exceptions.rb  2020-01-01 21:02:13.000000000 +0100
+++ new/lib/sinatra/show_exceptions.rb  2020-09-04 20:46:28.000000000 +0200
@@ -43,43 +43,8 @@
       ]
     end
 
-    # Pulled from Rack::ShowExceptions in order to override TEMPLATE.
-    # If Rack provides another way to override, this could be removed
-    # in the future.
-    def pretty(env, exception)
-      req = Rack::Request.new(env)
-
-      # This double assignment is to prevent an "unused variable" warning on
-      # Ruby 1.9.3.  Yes, it is dumb, but I don't like Ruby yelling at me.
-      path = path = (req.script_name + req.path_info).squeeze("/")
-
-      # This double assignment is to prevent an "unused variable" warning on
-      # Ruby 1.9.3.  Yes, it is dumb, but I don't like Ruby yelling at me.
-      frames = frames = exception.backtrace.map { |line|
-        frame = OpenStruct.new
-        if line =~ /(.*?):(\d+)(:in `(.*)')?/
-          frame.filename = $1
-          frame.lineno = $2.to_i
-          frame.function = $4
-
-          begin
-            lineno = frame.lineno-1
-            lines = ::File.readlines(frame.filename)
-            frame.pre_context_lineno = [lineno-CONTEXT, 0].max
-            frame.pre_context = lines[frame.pre_context_lineno...lineno]
-            frame.context_line = lines[lineno].chomp
-            frame.post_context_lineno = [lineno+CONTEXT, lines.size].min
-            frame.post_context = lines[lineno+1..frame.post_context_lineno]
-          rescue
-          end
-
-          frame
-        else
-          nil
-        end
-      }.compact
-
-      TEMPLATE.result(binding)
+    def template
+      TEMPLATE
     end
 
     private
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/sinatra/version.rb new/lib/sinatra/version.rb
--- old/lib/sinatra/version.rb  2020-01-01 21:02:13.000000000 +0100
+++ new/lib/sinatra/version.rb  2020-09-04 20:46:28.000000000 +0200
@@ -1,3 +1,3 @@
 module Sinatra
-  VERSION = '2.0.8.1'
+  VERSION = '2.1.0'
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metadata new/metadata
--- old/metadata        2020-01-01 21:02:13.000000000 +0100
+++ new/metadata        2020-09-04 20:46:28.000000000 +0200
@@ -1,7 +1,7 @@
 --- !ruby/object:Gem::Specification
 name: sinatra
 version: !ruby/object:Gem::Version
-  version: 2.0.8.1
+  version: 2.1.0
 platform: ruby
 authors:
 - Blake Mizerany
@@ -11,7 +11,7 @@
 autorequire: 
 bindir: bin
 cert_chain: []
-date: 2020-01-01 00:00:00.000000000 Z
+date: 2020-09-04 00:00:00.000000000 Z
 dependencies:
 - !ruby/object:Gem::Dependency
   name: rack
@@ -19,14 +19,14 @@
     requirements:
     - - "~>"
       - !ruby/object:Gem::Version
-        version: '2.0'
+        version: '2.2'
   type: :runtime
   prerelease: false
   version_requirements: !ruby/object:Gem::Requirement
     requirements:
     - - "~>"
       - !ruby/object:Gem::Version
-        version: '2.0'
+        version: '2.2'
 - !ruby/object:Gem::Dependency
   name: tilt
   requirement: !ruby/object:Gem::Requirement
@@ -47,14 +47,14 @@
     requirements:
     - - '='
       - !ruby/object:Gem::Version
-        version: 2.0.8.1
+        version: 2.1.0
   type: :runtime
   prerelease: false
   version_requirements: !ruby/object:Gem::Requirement
     requirements:
     - - '='
       - !ruby/object:Gem::Version
-        version: 2.0.8.1
+        version: 2.1.0
 - !ruby/object:Gem::Dependency
   name: mustermann
   requirement: !ruby/object:Gem::Requirement
@@ -112,6 +112,8 @@
 - SECURITY.md
 - VERSION
 - examples/chat.rb
+- examples/rainbows.conf
+- examples/rainbows.rb
 - examples/simple.rb
 - examples/stream.ru
 - lib/sinatra.rb
@@ -148,15 +150,14 @@
   requirements:
   - - ">="
     - !ruby/object:Gem::Version
-      version: 2.2.0
+      version: 2.3.0
 required_rubygems_version: !ruby/object:Gem::Requirement
   requirements:
   - - ">="
     - !ruby/object:Gem::Version
       version: '0'
 requirements: []
-rubyforge_project: 
-rubygems_version: 2.7.3
+rubygems_version: 3.1.2
 signing_key: 
 specification_version: 4
 summary: Classy web-development dressed in a DSL
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sinatra.gemspec new/sinatra.gemspec
--- old/sinatra.gemspec 2020-01-01 21:02:13.000000000 +0100
+++ new/sinatra.gemspec 2020-09-04 20:46:28.000000000 +0200
@@ -46,9 +46,9 @@
 EOF
   end
 
-  s.required_ruby_version = '>= 2.2.0'
+  s.required_ruby_version = '>= 2.3.0'
 
-  s.add_dependency 'rack', '~> 2.0'
+  s.add_dependency 'rack', '~> 2.2'
   s.add_dependency 'tilt', '~> 2.0'
   s.add_dependency 'rack-protection', version
   s.add_dependency 'mustermann', '~> 1.0'


Reply via email to