roda 3.73.0 → 3.74.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG +4 -0
- data/README.rdoc +13 -24
- data/doc/conventions.rdoc +1 -1
- data/doc/release_notes/3.74.0.txt +28 -0
- data/lib/roda/plugins/redirect_http_to_https.rb +99 -0
- data/lib/roda/plugins/route_csrf.rb +4 -2
- data/lib/roda/plugins/sessions.rb +2 -1
- data/lib/roda/response.rb +7 -11
- data/lib/roda/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ae3f95331c6c3d69453feb96a7dbd3629a6d5f52bd9d1862edecab893d95a36f
|
|
4
|
+
data.tar.gz: c5457f54b2ca5a9971f93a23db10abe3b6fd16a743e2651749ec14c480c248a3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f314713b33ec4400e5ef8849c6a3e30f1b5956b428dea55a5bf45855fef4a965f9b417063182cc4412effa592a7d311715cf4541826781675ca26bd20f202ca3
|
|
7
|
+
data.tar.gz: 735cb4cf3e5480be4462d88ccb0090001e7eca27bfe7338a923f5f190730095037ff0c77e1cbe3c875b137175bc7022b8d0611ccbf8b82426cbbaec5b7802149
|
data/CHANGELOG
CHANGED
data/README.rdoc
CHANGED
|
@@ -723,7 +723,7 @@ Note that when subclassing, Roda only does a shallow clone of the settings.
|
|
|
723
723
|
|
|
724
724
|
If you store nested structures and plan to mutate them in subclasses,
|
|
725
725
|
it is your responsibility to dup the nested structures inside +Roda.inherited+
|
|
726
|
-
(making sure to call +super+). This should be is done so that
|
|
726
|
+
(making sure to call +super+). This should be is done so that modifications
|
|
727
727
|
to the parent class made after subclassing do _not_ affect the subclass, and
|
|
728
728
|
vice-versa.
|
|
729
729
|
|
|
@@ -851,9 +851,8 @@ should use an appropriate external middleware.
|
|
|
851
851
|
It is possible to use other session cookie middleware such as
|
|
852
852
|
<tt>Rack::Session::Cookie</tt>, but other middleware may not have the same security
|
|
853
853
|
features that Roda's session support does. For example, the session cookies used by
|
|
854
|
-
the <tt>Rack::Session::Cookie</tt> middleware
|
|
855
|
-
|
|
856
|
-
when using <tt>Rack::Session::Cookie</tt>.
|
|
854
|
+
the <tt>Rack::Session::Cookie</tt> middleware provided by Rack before Rack 3 are not
|
|
855
|
+
encrypted, just signed to prevent tampering.
|
|
857
856
|
|
|
858
857
|
For any cookie-based sessions, make sure that the necessary secrets (+:secret+ option)
|
|
859
858
|
are not disclosed to an attacker. Knowledge of the
|
|
@@ -960,17 +959,17 @@ application level using using the +default_headers+ plugin:
|
|
|
960
959
|
Strict-Transport-Security :: Enforces SSL/TLS Connections to the application.
|
|
961
960
|
X-Content-Type-Options :: Forces some browsers to respect a declared Content-Type header.
|
|
962
961
|
X-Frame-Options :: Provides click-jacking protection by not allowing usage inside a frame.
|
|
963
|
-
|
|
962
|
+
Only include this if you want to support and protect old browsers that
|
|
963
|
+
do not support Content-Security-Policy.
|
|
964
964
|
|
|
965
965
|
Example:
|
|
966
966
|
|
|
967
967
|
class App < Roda
|
|
968
968
|
plugin :default_headers,
|
|
969
969
|
'Content-Type'=>'text/html',
|
|
970
|
-
'Strict-Transport-Security'=>'max-age=
|
|
970
|
+
'Strict-Transport-Security'=>'max-age=63072000; includeSubDomains',
|
|
971
971
|
'X-Content-Type-Options'=>'nosniff',
|
|
972
|
-
'X-Frame-Options'=>'deny'
|
|
973
|
-
'X-XSS-Protection'=>'1; mode=block'
|
|
972
|
+
'X-Frame-Options'=>'deny'
|
|
974
973
|
end
|
|
975
974
|
|
|
976
975
|
=== Rendering Templates Derived From User Input
|
|
@@ -1007,25 +1006,16 @@ constants and removing them when any of the reloadable loaded files changes. It
|
|
|
1007
1006
|
+require+ and +require_relative+ when activated (usually in the development environment). No
|
|
1008
1007
|
configurations other than +reloadable_paths+ are required.
|
|
1009
1008
|
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
versions of your app. rerun is faster as it only reloads the app on changes, whereas
|
|
1013
|
-
shotgun reloads the app on every request. Both work without any changes to application
|
|
1009
|
+
{rerun}[https://github.com/alexch/rerun] uses a fork/exec approach for loading new
|
|
1010
|
+
versions of your app. It work without any changes to application
|
|
1014
1011
|
code, but may be slower as they have to reload the entire application on every change.
|
|
1015
|
-
However, for small apps that load quickly,
|
|
1016
|
-
|
|
1017
|
-
{Rack::Reloader}[https://github.com/rack/rack/blob/master/lib/rack/reloader.rb] ships
|
|
1018
|
-
with rack and just reloads monitored files when they change, without unloading constants.
|
|
1019
|
-
It's fast but may cause issues in cases where you remove classes, constants, or methods,
|
|
1020
|
-
or when you are not clearing out cached data manually when files are reloaded.
|
|
1012
|
+
However, for small apps that load quickly, it may be a good approach.
|
|
1021
1013
|
|
|
1022
1014
|
There is no one reloading solution that is the best for all applications and development
|
|
1023
1015
|
approaches. Consider your needs and the tradeoffs of each of the reloading approaches,
|
|
1024
|
-
and pick the one you think will work best.
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
(unless you're running on JRuby or Windows), and only consider other options if rerun or
|
|
1028
|
-
shotgun are not fast enough.
|
|
1016
|
+
and pick the one you think will work best. If you are unsure where to start,
|
|
1017
|
+
it may be best to start with Zeitwerk, and only consider other options if it does not
|
|
1018
|
+
work well for you.
|
|
1029
1019
|
|
|
1030
1020
|
== Plugins
|
|
1031
1021
|
|
|
@@ -1144,4 +1134,3 @@ MIT
|
|
|
1144
1134
|
== Maintainer
|
|
1145
1135
|
|
|
1146
1136
|
Jeremy Evans <code@jeremyevans.net>
|
|
1147
|
-
|
data/doc/conventions.rdoc
CHANGED
|
@@ -55,7 +55,7 @@ via <tt>irb -r ./models</tt>, without loading the Roda application.
|
|
|
55
55
|
migrations.
|
|
56
56
|
|
|
57
57
|
+spec/+ (or +test/+ should contain your specifications/tests. For a small application, it's recommended
|
|
58
|
-
to
|
|
58
|
+
to have a single file for your model tests, and a single file for your web/integration tests.
|
|
59
59
|
|
|
60
60
|
+Rakefile+ should contain the rake tasks for the application. The convention is that the
|
|
61
61
|
default rake task will run all specs/tests related to the application. If you are using
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
= New Features
|
|
2
|
+
|
|
3
|
+
* A redirect_http_to_https plugin has been added, redirecting HTTP
|
|
4
|
+
requests to the same path on an HTTPS site. Using the routing tree,
|
|
5
|
+
you can control where to do the redirection, which allows you to
|
|
6
|
+
easily have part of your site accessible via HTTP, with sensitive
|
|
7
|
+
sections requiring HTTPS:
|
|
8
|
+
|
|
9
|
+
plugin :redirect_http_to_https
|
|
10
|
+
|
|
11
|
+
route do |r|
|
|
12
|
+
# routes available via both HTTP and HTTPS
|
|
13
|
+
r.redirect_http_to_https
|
|
14
|
+
# routes available only via HTTPS
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
If you want to redirect to HTTPS for all routes in the routing tree, you
|
|
18
|
+
can have r.redirect_http_to_https as the very first method call in the
|
|
19
|
+
routing tree. Note that in Roda it is possible to handle routing before
|
|
20
|
+
the normal routing tree using before hooks. The static_routing and
|
|
21
|
+
heartbeat plugins use this feature. If you would like to handle routes
|
|
22
|
+
before the normal routing tree, you can setup a before hook:
|
|
23
|
+
|
|
24
|
+
plugin :hooks
|
|
25
|
+
|
|
26
|
+
before do
|
|
27
|
+
request.redirect_http_to_https
|
|
28
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
class Roda
|
|
5
|
+
module RodaPlugins
|
|
6
|
+
# The redirect_http_to_https plugin exposes a +redirect_http_to_https+
|
|
7
|
+
# request method that redirects HTTP requests to HTTPS, helping to ensure
|
|
8
|
+
# that future requests by the same browser will be submitted securely.
|
|
9
|
+
#
|
|
10
|
+
# You should use this plugin if you have an application that can receive
|
|
11
|
+
# requests using both HTTP and HTTPS, and you want to make sure that all
|
|
12
|
+
# or a subset of routes are only handled for HTTPS requests.
|
|
13
|
+
#
|
|
14
|
+
# The reason this exposes a request method is so that you can choose where
|
|
15
|
+
# in your routing tree to do the redirection:
|
|
16
|
+
#
|
|
17
|
+
# route do |r|
|
|
18
|
+
# # routes available via both HTTP and HTTPS
|
|
19
|
+
# r.redirect_http_to_https
|
|
20
|
+
# # routes available only via HTTPS
|
|
21
|
+
# end
|
|
22
|
+
#
|
|
23
|
+
# If you want to redirect to HTTPS for all routes in the routing tree, you
|
|
24
|
+
# can have this as the very first method call in the routing tree. Note that
|
|
25
|
+
# in Roda it is possible to handle routing before the normal routing tree
|
|
26
|
+
# using before hooks. The static_routing and heartbeat plugins use this
|
|
27
|
+
# feature. If you would like to handle routes before the normal routing tree,
|
|
28
|
+
# you can setup a before hook:
|
|
29
|
+
#
|
|
30
|
+
# plugin :hooks
|
|
31
|
+
#
|
|
32
|
+
# before do
|
|
33
|
+
# request.redirect_http_to_https
|
|
34
|
+
# end
|
|
35
|
+
module RedirectHttpToHttps
|
|
36
|
+
status_map = Hash.new(307)
|
|
37
|
+
status_map['GET'] = status_map['HEAD'] = 301
|
|
38
|
+
status_map.freeze
|
|
39
|
+
DEFAULTS = {:status_map => status_map}.freeze
|
|
40
|
+
private_constant :DEFAULTS
|
|
41
|
+
|
|
42
|
+
# Configures redirection from HTTP to HTTPS. Available options:
|
|
43
|
+
#
|
|
44
|
+
# :body :: The body used in the redirect. If not set, uses an empty body.
|
|
45
|
+
# :headers :: Any additional headers used in the redirect response. By default,
|
|
46
|
+
# no additional headers are set, the only header used is the Location header.
|
|
47
|
+
# :host :: The host to redirect to. If not set, redirects to the same host as the HTTP
|
|
48
|
+
# requested to. It is highly recommended that you set this if requests with
|
|
49
|
+
# arbitrary Host headers can be submitted to the application.
|
|
50
|
+
# :port :: The port to use in the redirect. By default, will not set an explicit port,
|
|
51
|
+
# so that it will implicitly use the HTTPS default port of 443.
|
|
52
|
+
# :status_map :: A hash mapping request methods to response status codes. By default,
|
|
53
|
+
# uses a hash that redirects GET and HEAD requests with a 301 status,
|
|
54
|
+
# and other request methods with a 307 status.
|
|
55
|
+
def self.configure(app, opts=OPTS)
|
|
56
|
+
previous = app.opts[:redirect_http_to_https] || DEFAULTS
|
|
57
|
+
opts = app.opts[:redirect_http_to_https] = previous.merge(opts)
|
|
58
|
+
opts[:port_string] = opts[:port] ? ":#{opts[:port]}".freeze : "".freeze
|
|
59
|
+
opts[:prefix] = opts[:host] ? "https://#{opts[:host]}#{opts[:port_string]}".freeze : nil
|
|
60
|
+
opts.freeze
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
module RequestMethods
|
|
64
|
+
# Redirect HTTP requests to HTTPS. While this doesn't secure the
|
|
65
|
+
# current request, it makes it more likely that the browser will submit
|
|
66
|
+
# future requests securely via HTTPS.
|
|
67
|
+
def redirect_http_to_https
|
|
68
|
+
return if ssl?
|
|
69
|
+
|
|
70
|
+
opts = roda_class.opts[:redirect_http_to_https]
|
|
71
|
+
|
|
72
|
+
res = response
|
|
73
|
+
|
|
74
|
+
if body = opts[:body]
|
|
75
|
+
res.write(body)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
if headers = opts[:headers]
|
|
79
|
+
res.headers.merge!(headers)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
path = if prefix = opts[:prefix]
|
|
83
|
+
prefix + fullpath
|
|
84
|
+
else
|
|
85
|
+
"https://#{host}#{opts[:port_string]}#{fullpath}"
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
unless status = opts[:status_map][@env['REQUEST_METHOD']]
|
|
89
|
+
raise RodaError, "redirect_http_to_https :status_map provided does not support #{@env['REQUEST_METHOD']}"
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
redirect(path, status)
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
register_plugin(:redirect_http_to_https, RedirectHttpToHttps)
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -22,9 +22,11 @@ class Roda
|
|
|
22
22
|
# and request path even if they have access to a token that is not
|
|
23
23
|
# specific to request method and request path. To get this security
|
|
24
24
|
# benefit, you must ensure an attacker does not have access to the
|
|
25
|
-
# session. Rack::Session::Cookie
|
|
25
|
+
# session. Rack::Session::Cookie versions shipped with Rack before
|
|
26
|
+
# Rack 3 use signed sessions, not encrypted
|
|
26
27
|
# sessions, so if the attacker has the ability to read cookie data
|
|
27
|
-
# and you are using Rack::Session::Cookie,
|
|
28
|
+
# and you are using one of those Rack::Session::Cookie versions,
|
|
29
|
+
# it will still be possible
|
|
28
30
|
# for an attacker to generate valid CSRF tokens specific to arbitrary
|
|
29
31
|
# request method and request path. Roda's session plugin uses
|
|
30
32
|
# encrypted sessions and therefore is safe even if the attacker can
|
|
@@ -40,7 +40,8 @@ class Roda
|
|
|
40
40
|
#
|
|
41
41
|
# Session secrets can be rotated. See options below.
|
|
42
42
|
#
|
|
43
|
-
# The sessions plugin can transparently upgrade sessions from Rack::Session::Cookie
|
|
43
|
+
# The sessions plugin can transparently upgrade sessions from versions of Rack::Session::Cookie
|
|
44
|
+
# shipped with Rack before Rack 3,
|
|
44
45
|
# if the default Rack::Session::Cookie coder and HMAC are used, see options below.
|
|
45
46
|
# It is recommended to only enable transparent upgrades for a brief transition period,
|
|
46
47
|
# and remove support for them once old sessions have converted or timed out.
|
data/lib/roda/response.rb
CHANGED
|
@@ -10,19 +10,15 @@ class Roda
|
|
|
10
10
|
# headers used internally by Roda can be lower case on Rack 3, so that it is
|
|
11
11
|
# possible to use a plain hash of response headers instead of using Rack::Headers.
|
|
12
12
|
module RodaResponseHeaders
|
|
13
|
-
|
|
14
|
-
Content-Security-Policy Content-Security-Policy-Report-Only Content-Type
|
|
15
|
-
ETag Expires Last-Modified Link Location Set-Cookie Transfer-Encoding Vary'.freeze.each(&:freeze)
|
|
13
|
+
downcase = defined?(Rack::Headers) && Rack::Headers.is_a?(Class)
|
|
16
14
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const_set(mixed_case.gsub('-', '_').upcase!.to_sym, mixed_case.freeze)
|
|
15
|
+
%w'Allow Cache-Control Content-Disposition Content-Encoding Content-Length
|
|
16
|
+
Content-Security-Policy Content-Security-Policy-Report-Only Content-Type
|
|
17
|
+
ETag Expires Last-Modified Link Location Set-Cookie Transfer-Encoding Vary'.
|
|
18
|
+
each do |value|
|
|
19
|
+
value = value.downcase if downcase
|
|
20
|
+
const_set(value.gsub('-', '_').upcase!.to_sym, value.freeze)
|
|
24
21
|
end
|
|
25
|
-
end
|
|
26
22
|
end
|
|
27
23
|
|
|
28
24
|
# Base class used for Roda responses. The instance methods for this
|
data/lib/roda/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: roda
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.74.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jeremy Evans
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-
|
|
11
|
+
date: 2023-11-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rack
|
|
@@ -247,6 +247,7 @@ extra_rdoc_files:
|
|
|
247
247
|
- doc/release_notes/3.71.0.txt
|
|
248
248
|
- doc/release_notes/3.72.0.txt
|
|
249
249
|
- doc/release_notes/3.73.0.txt
|
|
250
|
+
- doc/release_notes/3.74.0.txt
|
|
250
251
|
- doc/release_notes/3.8.0.txt
|
|
251
252
|
- doc/release_notes/3.9.0.txt
|
|
252
253
|
files:
|
|
@@ -327,6 +328,7 @@ files:
|
|
|
327
328
|
- doc/release_notes/3.71.0.txt
|
|
328
329
|
- doc/release_notes/3.72.0.txt
|
|
329
330
|
- doc/release_notes/3.73.0.txt
|
|
331
|
+
- doc/release_notes/3.74.0.txt
|
|
330
332
|
- doc/release_notes/3.8.0.txt
|
|
331
333
|
- doc/release_notes/3.9.0.txt
|
|
332
334
|
- lib/roda.rb
|
|
@@ -428,6 +430,7 @@ files:
|
|
|
428
430
|
- lib/roda/plugins/public.rb
|
|
429
431
|
- lib/roda/plugins/r.rb
|
|
430
432
|
- lib/roda/plugins/recheck_precompiled_assets.rb
|
|
433
|
+
- lib/roda/plugins/redirect_http_to_https.rb
|
|
431
434
|
- lib/roda/plugins/relative_path.rb
|
|
432
435
|
- lib/roda/plugins/render.rb
|
|
433
436
|
- lib/roda/plugins/render_coverage.rb
|