Sinatra Two Point Oh!
Today, I’m pleased to FINALLY announce that Sinatra 2.0 was released!
If you haven’t been following along, the major version bump includes a lot of changes significant to the future of the project.
In this post, you will see the full details including what’s new, what’s gone, and everything packed into the two point oh release.
Before we begin, I have to thank everyone who contributed, helped test pre-releases, and continues to use and support the project.
Releases
Sinatra 2.0 includes the release of the following gems, and associated verions:
sinatra
: v2.0.0sinatra-contrib
: v2.0.0mustermann
: v1.0.0mustermann-contrib
: v1.0.0rack-protection
: v2.0.0
You can download all of these gems from rubygems.org.
Major features
- Rack 2.0 support, Rack 1.x is no longer supported
- Ruby 2.2+ support, Ruby < 2.2 is no longer supported
- Sinatra router replaced with Mustermann
- Compatible with Rails 5! :trollface:
Sinatra core
Many of you have been waiting since before the Rails 5 release, for a Sinatra 2.0 pre-release.
Before we get into the changes, I want to address something.
Why 2.0 was delayed
First, there was a ridiculous number of tickets asking for a release, so many that I actually lost count to be honest.
Let me just say, thank you everyone for your patience and I hope that this release is worth the wait!
To put it short.
When I took on the challenge of releasing Sinatra 2.0, my goal was to not only bump minimum dependency requirements – but also make sure Sinatra is well maintained and provide the level of class people have come to expect from the project and it’s previous maintainer.
With that said, I hope the following features and changes that went into the release can live up to (not only mine) but everyone’s expectations.
Features
- Use Mustermann for patterns PR by Konstantin Haase
- Server now provides
-q
flag for quiet mode, which disables start/stop messages PR by Vasiliy - Session middleware can now be specified with
:session_store
setting PR by Jordan Owens APP_ENV
is now preferred and recommended overRACK_ENV
for setting environment PR by Damien Mathieu- Reel support PR by Patricio Mac Adden
Changes
The following notable changes are also included in this release.
- Make route params available during error handling PR by Jeremy Evans
- Unify
not_found
anderror
404 behavior PR by Jeremy Evans - Enable Ruby 2.3
frozen_string_literal
feature PR by Vladimir Kochnev - Add Sinatra::ShowExceptions::TEMPLATE and patched Rack::ShowExceptions to prefer Sinatra template commit by Zachary Scott
- Sinatra::Runner is used internally for integration tests PR by Nick Sutterer
- Fix case-sensitivity issue in
uri
method PR by rennex - Use
Rack::Utils.status_code
to allowstatus
helper to use symbol as well as numeric codes PR by Tobias H. Michaelsen - Improved error handling for invalid params through Rack PR by Jordan Owens
- Ensure template is cached only once PR by Patrik Rak
- Use same
session_secret
for classic and modular apps in development PR by Marcus Stollsteimer - Improve Session Secret documentation to encourage better security practices PR by Glenn Rempe
- Exposed global and per-route options for Mustermann route parsing PR by Mike Pastore
- Capture exception messages of raised NotFound and BadRequest PR by Mike Pastore
- Add
:strict_paths
option for managing trailing slashes PR by namusyaka - Add full IndifferentHash implementation to params PR by Mike Pastore and PR by John Hope
Now let’s take a look at the peripheral work that went into the release of Sinatra 2.0.
Sinatra::Contrib
This gem provides a bunch of helpful extensions for common patterns that can be applied to your Sinatra application. Take a look at the documentation for a list of what you get.
The biggest change to the sinatra-contrib
gem is that it is now bundled in the Sinatra source tree. Ticket by Zachary Scott.
Since the release, if you install the gem though you shouldn’t notice any difference. Alternitively you can install the gem from source, like so:
# Gemfile
github 'sinatra/sinatra' do
gem 'sinatra-contrib'
end
This will fetch the sinatra git source and install the gem from the tree.
Also, we’ve consolidated the bug trackers, and you can now find sinatra-contrib
related issues under this label.
Features
Here are the new features in Sinatra::Contrib
.
- Sinatra::Contrib is now bundled in the Sinatra source tree PR
- Sinatra::ContentFor added
clear_content_for
method PR by Ben Darlow - Sinatra::Namespace support for Mustermann PR by Vasiliy and Jordan Owens (PR)
- Sinatra::RequiredParams for permitting required query parameters PR by Daisuke Taniwaki
- Sinatra::Runner PR by Nick Sutterer
- Sinatra::WebDAV PR by Yegor Timoshenko Originally submitted by Mark Bates
- Sinatra::Reloader added
after_reload
hook which allows manual reload changes when triggered PR by Jhimy Fernandes Villar
Changes
And the following notable changes that went into the release.
- Migrate specs to RSpec 3.4 PR by Jhimy Fernandes Villar
- Sinatra::ConfigFile allow ERB syntax in YML files PR by Jhimy Fernandes Villar
- Sinatra::ContentFor renders given block if specified key is not found PR by Micah Redding
- Sinatra::ContentFor can yield an immediate value, similar to ActionView PR by Ryo Nakamura
- Sinatra::LinkHeader to use “,\n” (comma, new-line) as delimiter PR by petedmarsh
- Sinatra::Namespace allow using
redirect_to
in a namespace PR by Jhimy Fernandes Villar - Sinatra::RespondWith swallow exception from
Tilt
onLoadError
for missing template PR by Matt Austin - Sinatra::RespondWith now raises a 500 error if formatting fails commit
- Make Rack::Test a development dependency PR by Mike Pastore
- Add explicit set method to contrib/cookies to override cookie settings PR by Andrew Allen
- Avoid executing filters even if prefix matches with other namespace PR by namusyaka
Removals
- Sinatra::Decompile is no longer necessary after added Mustermann support commit by Zachary Scott
For full details, compare the pre-merged diff and milestone.
Rack::Protection
This gem is designed to provide several middleware for protecting your applications against common web attacks. Take a look at the documentation for more information.
The biggest change to the rack-protection
gem is that it is now bundled in the Sinatra source tree. PR by Zachary Scott.
Although I must admit, this change wasn’t without pitfalls, I apologize to everyone affected during the transition time.
Since the release, if you install the gem though you shouldn’t notice. Alternitively you can install the gem from source, like so:
# Gemfile
github 'sinatra/sinatra' do
gem 'rack-protection'
end
This will fetch the sinatra git source and install the gem from the tree.
Also, we’ve consolidated the bug trackers, and you can now find rack-protection
related issues under this label.
Features
Here are the new features in Rack::Protection
- Rack::Protection::ContentSecurityPolicy PR by Christian Meier with Level 2 and 3 Directives in PR by Glenn Rempe
- Rack::Protection::HttpOrigin and AuthenticityToken added
:allow_if
option to specify allowable urls PR by Nathan Stitt - Rack::Protection::CookieTossing PR by Jordan Owens
- Rack::Protection::AuthenticityToken prevent BREACH attack PR by Jordan Owens
- Added
:without_session
option to initializer to easily skip session-based protections commit by Zachary Scott
Changes
Along with the following notable changes that went into the release.
- Migrate spaces to RSpec 3 PR by Maurizio De Santis
- Rack::Protection::StrictTransport PR by Maciej Moleda
- Rack::Protection::JsonCsrf closes body on prevented attack PR by Konstantin Haase
- Use Rack::Utils.secure_compare when checking CSRF tokens commit by Andreas Karlsson
- Rack::Protection::EscapedParams ensures Tempfile is untouched PR by Albert Engelbrecht
- Adds preload option to Rack:Protection:StrictTransport PR by Ed Robinson
- Add
allow_if
option to bypass json csrf protection PR by Jordan Owens
For full details, compare the pre-merged diff.
Mustermann
Mustermann is a powerful library with many features and compatible params
parsing interface. It will replace the existing router in Sinatra for version 2.0.
Take a look at the documentation for more information.
Apart from the features and changes to the core of Mustermann
, which I will list below, the biggest change in the first stable release is organizational.
mustermann-everything
gem is deprecatedmustermann-contrib
has replaced it, including all non-core extensions
Please check the PR for the full list of included plugins, but I hope this change will make maintaining and releasing Mustermann much simpler from now on.
Features
Here are the latest features in Mustermann
version 1.0.
- Rails patterns: Add Rails 5.0 compatibility mode, make it default. commit by Konstantin Haase
- Add concatenation support (
Mustermann::Pattern#+
). commit by Konstantin Haase - Mustermann::Grape PR by namusyaka
-
Implement shorthand for ({foo} {bar}) pattern PR by namusyaka - Sinatra patterns: Allow
|
outside of parens commit by Konstantin Haase Mustermann::Sinatra#|
may now generate a Sinatra pattern instead of a real composite commit by Konstantin Haase
Changes
Along with the following notable changes that went into the release.
- Moved non-core extensions to meta
mustermann-contrib
gem PR by Zachary Scott - Move Tool::EqualityMap from
tool
gem to Mustermann::EqualityMap PR by Michael Stock - Remove routers (they were out of scope for the main gem). commit by Konstantin Haase
For the full details, compare the diff.
Wrapping up
In the end, there’s still more work to be done on the project and a bright future ahead.
At the time of writing this, there are almost 30 open issues and about 10 pull requests.
There are a number of places where Sinatra could improve, and although I’ve added a number of tickets for features, I’d like to end this by briefly listing some of these areas specifically.
Logging
Currently, Sinatra uses Rack::Logger
middleware under the hood with a little bit extra.
This logger is barebones, and I’m sure we could build a much nicer logging API by ourselves that would prove more useful for dealing with production services.
Streaming
There have been a number of discussions on streaming, but I feel this is something that could definitely be improved.
While, there are some missing features mentioned, when this API was originally implemented Rack’s hijack api was still unfinished.
I don’t exactly know the best route for this, but probably start with something in the Rack layer – like is already being discussed. Then we can provide an API on top of that inside Sinatra’s DSL. For added bonus, we could wrap something like Sinatra::Streaming to make it really nice.
Exception Handling
The current implementation for error handling comes down to “handle_exception!”.
This method to me looks like it’s begging for a refactor, and just the cause of a bad API design (sorry).
What I mean is, it could definitely be improved, and maybe it’s “bad design” but hey it works! Right!
Also take a look at “error_block!” and “dump_errors!”.. what!
All of this along with a middleware, called “ShowExceptions”, for displaying errors both/either in plain-text and/or html.
Wait there’s more!
Without going into too much detail, route dispatch (including before/after filters) needs work. As well, @rkh has mentioned wanting to improve the Template API.
There is also stuff like an implementation of “indifferent_params” and “indifferent_hash”, that could be upstreamed in Ruby.
At any rate, there’s more than a few things here as well as a number of great ideas from @rkh himself that should keep us busy for a while.
Briefly about deprecations
One thing I want to say before I end this post, please please please pleeeease:
Do not send PRs to remove deprecations or unfactored code without good reason.
I won’t consider any changes like this until we start thinking about version 2.1
.
Thank you
At any rate, I hope that Sinatra 2.0 is everything you hoped for and more, and apologize if your patch or bug wasn’t included in the release.
Thank you everyone who has contributed over the years to this project, and continues to ensure it lives on.
In the words of the great Nat King Cole, you’re unforgettable.