roda 3.83.0 → 3.84.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/lib/roda/plugins/hsts.rb +35 -0
- data/lib/roda/response.rb +1 -1
- data/lib/roda/version.rb +1 -1
- metadata +4 -179
- data/CHANGELOG +0 -691
- data/README.rdoc +0 -1136
- data/doc/conventions.rdoc +0 -177
- data/doc/release_notes/3.0.0.txt +0 -84
- data/doc/release_notes/3.1.0.txt +0 -24
- data/doc/release_notes/3.10.0.txt +0 -132
- data/doc/release_notes/3.11.0.txt +0 -54
- data/doc/release_notes/3.12.0.txt +0 -19
- data/doc/release_notes/3.13.0.txt +0 -38
- data/doc/release_notes/3.14.0.txt +0 -36
- data/doc/release_notes/3.14.1.txt +0 -43
- data/doc/release_notes/3.15.0.txt +0 -21
- data/doc/release_notes/3.16.0.txt +0 -52
- data/doc/release_notes/3.17.0.txt +0 -62
- data/doc/release_notes/3.18.0.txt +0 -170
- data/doc/release_notes/3.19.0.txt +0 -229
- data/doc/release_notes/3.2.0.txt +0 -22
- data/doc/release_notes/3.20.0.txt +0 -7
- data/doc/release_notes/3.21.0.txt +0 -5
- data/doc/release_notes/3.22.0.txt +0 -24
- data/doc/release_notes/3.23.0.txt +0 -28
- data/doc/release_notes/3.24.0.txt +0 -14
- data/doc/release_notes/3.25.0.txt +0 -12
- data/doc/release_notes/3.26.0.txt +0 -15
- data/doc/release_notes/3.27.0.txt +0 -15
- data/doc/release_notes/3.28.0.txt +0 -13
- data/doc/release_notes/3.29.0.txt +0 -15
- data/doc/release_notes/3.3.0.txt +0 -291
- data/doc/release_notes/3.30.0.txt +0 -14
- data/doc/release_notes/3.31.0.txt +0 -11
- data/doc/release_notes/3.32.0.txt +0 -42
- data/doc/release_notes/3.33.0.txt +0 -8
- data/doc/release_notes/3.34.0.txt +0 -17
- data/doc/release_notes/3.35.0.txt +0 -12
- data/doc/release_notes/3.36.0.txt +0 -17
- data/doc/release_notes/3.37.0.txt +0 -42
- data/doc/release_notes/3.38.0.txt +0 -5
- data/doc/release_notes/3.39.0.txt +0 -16
- data/doc/release_notes/3.4.0.txt +0 -24
- data/doc/release_notes/3.40.0.txt +0 -24
- data/doc/release_notes/3.41.0.txt +0 -9
- data/doc/release_notes/3.42.0.txt +0 -21
- data/doc/release_notes/3.43.0.txt +0 -34
- data/doc/release_notes/3.44.0.txt +0 -23
- data/doc/release_notes/3.45.0.txt +0 -22
- data/doc/release_notes/3.46.0.txt +0 -19
- data/doc/release_notes/3.47.0.txt +0 -13
- data/doc/release_notes/3.48.0.txt +0 -10
- data/doc/release_notes/3.49.0.txt +0 -18
- data/doc/release_notes/3.5.0.txt +0 -31
- data/doc/release_notes/3.50.0.txt +0 -21
- data/doc/release_notes/3.51.0.txt +0 -20
- data/doc/release_notes/3.52.0.txt +0 -20
- data/doc/release_notes/3.53.0.txt +0 -14
- data/doc/release_notes/3.54.0.txt +0 -48
- data/doc/release_notes/3.55.0.txt +0 -12
- data/doc/release_notes/3.56.0.txt +0 -33
- data/doc/release_notes/3.57.0.txt +0 -34
- data/doc/release_notes/3.58.0.txt +0 -16
- data/doc/release_notes/3.59.0.txt +0 -17
- data/doc/release_notes/3.6.0.txt +0 -21
- data/doc/release_notes/3.60.0.txt +0 -56
- data/doc/release_notes/3.61.0.txt +0 -24
- data/doc/release_notes/3.62.0.txt +0 -41
- data/doc/release_notes/3.63.0.txt +0 -36
- data/doc/release_notes/3.64.0.txt +0 -26
- data/doc/release_notes/3.65.0.txt +0 -12
- data/doc/release_notes/3.66.0.txt +0 -23
- data/doc/release_notes/3.67.0.txt +0 -25
- data/doc/release_notes/3.68.0.txt +0 -21
- data/doc/release_notes/3.69.0.txt +0 -33
- data/doc/release_notes/3.7.0.txt +0 -123
- data/doc/release_notes/3.70.0.txt +0 -19
- data/doc/release_notes/3.71.0.txt +0 -33
- data/doc/release_notes/3.72.0.txt +0 -48
- data/doc/release_notes/3.73.0.txt +0 -33
- data/doc/release_notes/3.74.0.txt +0 -28
- data/doc/release_notes/3.75.0.txt +0 -19
- data/doc/release_notes/3.76.0.txt +0 -18
- data/doc/release_notes/3.77.0.txt +0 -8
- data/doc/release_notes/3.78.0.txt +0 -99
- data/doc/release_notes/3.79.0.txt +0 -148
- data/doc/release_notes/3.8.0.txt +0 -27
- data/doc/release_notes/3.80.0.txt +0 -31
- data/doc/release_notes/3.81.0.txt +0 -24
- data/doc/release_notes/3.82.0.txt +0 -43
- data/doc/release_notes/3.83.0.txt +0 -6
- data/doc/release_notes/3.9.0.txt +0 -67
data/doc/conventions.rdoc
DELETED
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
= Conventions
|
|
2
|
-
|
|
3
|
-
This guide goes over conventions for directory layout and file layout for Roda applications.
|
|
4
|
-
You are free to ignore these conventions, they mostly exist to help users who are unsure how
|
|
5
|
-
to structure their Roda applications.
|
|
6
|
-
|
|
7
|
-
== Directory Layout
|
|
8
|
-
|
|
9
|
-
Which directory layout to use should reflect the size of your application.
|
|
10
|
-
|
|
11
|
-
=== Small Applications
|
|
12
|
-
|
|
13
|
-
For a small application, the following directory layout is recommended:
|
|
14
|
-
|
|
15
|
-
Rakefile
|
|
16
|
-
app_name.rb
|
|
17
|
-
assets/
|
|
18
|
-
config.ru
|
|
19
|
-
db.rb
|
|
20
|
-
migrate/
|
|
21
|
-
models.rb
|
|
22
|
-
models/
|
|
23
|
-
public/
|
|
24
|
-
spec/
|
|
25
|
-
views/
|
|
26
|
-
|
|
27
|
-
+app_name.rb+ should contain the Roda application, and should reflect the name of your application.
|
|
28
|
-
So, if your application is named +FooBar+, you should use +foo_bar.rb+.
|
|
29
|
-
|
|
30
|
-
+config.ru+ should contain the code the webserver uses to determine which application to run.
|
|
31
|
-
|
|
32
|
-
+views/+ should contain your template files. This assumes you are using the +render+ plugin
|
|
33
|
-
and server-side rendering. If you are creating a single page application and just serving
|
|
34
|
-
JSON, then you won't need a +views+ directory. For small applications, all view files should be
|
|
35
|
-
in the +views+ directory.
|
|
36
|
-
|
|
37
|
-
+public/+ should contain any static files that should be served directly by the webserver.
|
|
38
|
-
Again, for pure JSON applications, you won't need a +public+ directory.
|
|
39
|
-
|
|
40
|
-
+assets/+ should contain the source files for your CSS and javascript assets. If you are
|
|
41
|
-
not using the +assets+ plugin, you won't need an +assets+ directory.
|
|
42
|
-
|
|
43
|
-
+db.rb+ should contain the minimum code to setup a database connection, without loading any of
|
|
44
|
-
the applications models. This can be required in cases where you don't want the models loaded,
|
|
45
|
-
such as when running migrations. This file should be required by +models.rb+.
|
|
46
|
-
|
|
47
|
-
+models.rb+ should contain all code related to your ORM. This file should be required
|
|
48
|
-
by +app_name.rb+. This keeps your model code separate from your web code, making it easier
|
|
49
|
-
to use outside of your web code. It allows you to get an IRB shell for accessing your models
|
|
50
|
-
via <tt>irb -r ./models</tt>, without loading the Roda application.
|
|
51
|
-
|
|
52
|
-
+models/+ should contain your ORM models, with a separate file per model class.
|
|
53
|
-
|
|
54
|
-
+migrate/+ should create your database migration files, if you are using an ORM that uses
|
|
55
|
-
migrations.
|
|
56
|
-
|
|
57
|
-
+spec/+ (or +test/+ should contain your specifications/tests. For a small application, it's recommended
|
|
58
|
-
to have a single file for your model tests, and a single file for your web/integration tests.
|
|
59
|
-
|
|
60
|
-
+Rakefile+ should contain the rake tasks for the application. The convention is that the
|
|
61
|
-
default rake task will run all specs/tests related to the application. If you are using
|
|
62
|
-
the +assets+ plugin, you should have an <tt>assets:precompile</tt> task for precompiling
|
|
63
|
-
assets.
|
|
64
|
-
|
|
65
|
-
=== Large Applications
|
|
66
|
-
|
|
67
|
-
Large applications generally need more structure:
|
|
68
|
-
|
|
69
|
-
Rakefile
|
|
70
|
-
app_name.rb
|
|
71
|
-
assets/
|
|
72
|
-
helpers/
|
|
73
|
-
migrate/
|
|
74
|
-
models.rb
|
|
75
|
-
models/
|
|
76
|
-
public/
|
|
77
|
-
routes/
|
|
78
|
-
prefix1.rb
|
|
79
|
-
prefix2.rb
|
|
80
|
-
spec/
|
|
81
|
-
models/
|
|
82
|
-
web/
|
|
83
|
-
views/
|
|
84
|
-
prefix1/
|
|
85
|
-
prefix2/
|
|
86
|
-
|
|
87
|
-
For larger apps, the +Rakefile+, +assets/+, +migrate+, +models.rb+, +models/+, +public/+, remain the same.
|
|
88
|
-
|
|
89
|
-
+app_name.rb+ should use the +hash_branch_view_subdir+ plugin (which builds on the +hash_branches+ and
|
|
90
|
-
+view_options+ plugin), or the +multi_run+ plugin.
|
|
91
|
-
The routes used by the +hash_branches+ or +multi_run+ should be stored in routing files in the +routes/+
|
|
92
|
-
directory, with one file per prefix.
|
|
93
|
-
|
|
94
|
-
For specs/tests, you should have +spec/models/+ and +spec/web/+, with one file per model in +spec/models/+
|
|
95
|
-
and one file per prefix in +spec/web/+. Substitute +spec+ with +test+ if that is what you are using as the
|
|
96
|
-
name of the directory.
|
|
97
|
-
|
|
98
|
-
You should have a separate view subdirectory per prefix. With the +hash_branch_view_subdir+, the application
|
|
99
|
-
will automatically set a separate view subdirectory per routing tree branch.
|
|
100
|
-
|
|
101
|
-
+helpers/+ should be used to store helper methods for your application, that you call in your routing files
|
|
102
|
-
and views. In a small application, these methods should just be specified in +app_name.rb+
|
|
103
|
-
|
|
104
|
-
=== Really Large Applications
|
|
105
|
-
|
|
106
|
-
For very large applications, it's expected that there will be deviations from these conventions. However,
|
|
107
|
-
it is recommended to use the +hash_branch_view_subdir+ or +multi_run+ plugins to organize your application, and have
|
|
108
|
-
subdirectories in the +routes/+ directory, and nested subdirectories in the +views/+ directory.
|
|
109
|
-
|
|
110
|
-
== Roda Application File Layout
|
|
111
|
-
|
|
112
|
-
=== Small Applications
|
|
113
|
-
|
|
114
|
-
For a small application, the convention in Roda is to layout your Roda application file (+app_name.rb+) like this:
|
|
115
|
-
|
|
116
|
-
require 'roda'
|
|
117
|
-
require_relative 'models'
|
|
118
|
-
|
|
119
|
-
class AppName < Roda
|
|
120
|
-
SOME_CONSTANT = 1
|
|
121
|
-
|
|
122
|
-
use SomeMiddleware
|
|
123
|
-
|
|
124
|
-
plugin :render, escape: true
|
|
125
|
-
plugin :assets
|
|
126
|
-
|
|
127
|
-
route do |r|
|
|
128
|
-
# ...
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
def view_method
|
|
132
|
-
'foo'
|
|
133
|
-
end
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
You should first require +roda+ and +./models+, followed by any other libraries needed by the
|
|
137
|
-
application.
|
|
138
|
-
|
|
139
|
-
You should subclass Roda and make the application's name the name of the Roda subclass.
|
|
140
|
-
Inside the subclass, you first define the constants used by the application. Then you add
|
|
141
|
-
any middleware used by the application, followed by loading any plugins used by the application.
|
|
142
|
-
Then you add the route block for the application. After the route block, define the instance methods
|
|
143
|
-
used in your route block or views.
|
|
144
|
-
|
|
145
|
-
=== Large Applications
|
|
146
|
-
|
|
147
|
-
For larger applications, there are some slight changes to the Roda application file layout:
|
|
148
|
-
|
|
149
|
-
require 'roda'
|
|
150
|
-
require_relative 'models'
|
|
151
|
-
|
|
152
|
-
class AppName < Roda
|
|
153
|
-
SOME_CONSTANT = 1
|
|
154
|
-
|
|
155
|
-
use SomeMiddleware
|
|
156
|
-
|
|
157
|
-
plugin :render, escape: true, layout: './layout'
|
|
158
|
-
plugin :assets
|
|
159
|
-
plugin :hash_branch_view_subdir
|
|
160
|
-
Dir['routes/*.rb'].each{|f| require_relative f}
|
|
161
|
-
|
|
162
|
-
route do |r|
|
|
163
|
-
r.hash_branches('')
|
|
164
|
-
|
|
165
|
-
r.root do
|
|
166
|
-
# ...
|
|
167
|
-
end
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
Dir['helpers/*.rb'].each{|f| require_relative f}
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
After loading the +hash_branch_view_subdir+ plugin, you require all of your
|
|
174
|
-
routing files. Inside your route block, instead of defining your routes, you just call
|
|
175
|
-
+r.hash_branches+, which will dispatch to all of your routing files. After your route
|
|
176
|
-
block, you require all of your helper files containing the instance methods for your
|
|
177
|
-
route block or views, instead of defining the methods directly.
|
data/doc/release_notes/3.0.0.txt
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
= Major Changes
|
|
2
|
-
|
|
3
|
-
* String matchers now match literally by default, for simplicity,
|
|
4
|
-
understandability, and performance. Use the String class matcher
|
|
5
|
-
or a symbol matcher to match arbitrary segments.
|
|
6
|
-
|
|
7
|
-
# Before
|
|
8
|
-
r.is "artists/:name" do |artist_name|
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
# Now
|
|
12
|
-
r.is "artists", String do |artist_name|
|
|
13
|
-
end
|
|
14
|
-
# or
|
|
15
|
-
r.is "artists", :name do |artist_name|
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
You can use the placeholder_string_matchers plugin to restore
|
|
19
|
-
the historical behavior if you don't want to modify your
|
|
20
|
-
routes.
|
|
21
|
-
|
|
22
|
-
* Using an unsupported matcher now raises an error, making it
|
|
23
|
-
more likely to detect using a unexpected value as a matcher
|
|
24
|
-
(which previously matched everything).
|
|
25
|
-
|
|
26
|
-
* Have a route/match block return an unsupported value now
|
|
27
|
-
raises an error if nothing has been written to the body, making
|
|
28
|
-
it more likely to detect using an unexpected value as a block
|
|
29
|
-
result (which previously was ignored).
|
|
30
|
-
|
|
31
|
-
= Backwards Compatibility
|
|
32
|
-
|
|
33
|
-
* Deprecated plugins, features, and constants have been removed.
|
|
34
|
-
Before upgrading to 3.0.0, please upgrade to 2.29.0 first and
|
|
35
|
-
fix any deprecation warnings.
|
|
36
|
-
|
|
37
|
-
* Ruby 1.8.7 support has been dropped. Ruby 1.9.2 is the new
|
|
38
|
-
minimum supported version.
|
|
39
|
-
|
|
40
|
-
* The :check_paths render plugin option now defaults to true so that
|
|
41
|
-
generated template paths are checked by default, reducing the risk
|
|
42
|
-
of rendering arbitrary files.
|
|
43
|
-
|
|
44
|
-
* The assets plugin now defaults to using subresource integrity
|
|
45
|
-
with SHA256 for compiled assets, and using SHA256 instead of
|
|
46
|
-
SHA1 for compiled asset hashes.
|
|
47
|
-
|
|
48
|
-
* Subclassing a Roda app that uses the render plugin now always
|
|
49
|
-
uses a copy of the superclass's template cache.
|
|
50
|
-
|
|
51
|
-
* Using a Roda app as middleware now always uses a subclass
|
|
52
|
-
of the app for the middleware.
|
|
53
|
-
|
|
54
|
-
* public_send is now used instead of send internally unless it is
|
|
55
|
-
expected that private methods will be called.
|
|
56
|
-
|
|
57
|
-
* The match methods added by the symbol_matchers and hash_matchers
|
|
58
|
-
plugins are now private instead of public.
|
|
59
|
-
|
|
60
|
-
= Other Improvements
|
|
61
|
-
|
|
62
|
-
* The streaming plugin has been greatly simplified, by dropping
|
|
63
|
-
deprecated compatibility for EventMachine.
|
|
64
|
-
|
|
65
|
-
* It is now possible to reset the :include_request option to false
|
|
66
|
-
in the json and json_parser plugins by loading the plugin a
|
|
67
|
-
second time with the option set.
|
|
68
|
-
|
|
69
|
-
* The precompile_templates plugin now always sorts locals. This
|
|
70
|
-
plugin should now be used with Tilt 2.0.1+ (which also sorts
|
|
71
|
-
locals), though it will still work with earlier Tilt versions.
|
|
72
|
-
|
|
73
|
-
* The multi_run plugin now recomputes the regexp when freezing the
|
|
74
|
-
app.
|
|
75
|
-
|
|
76
|
-
= Deprecated Features
|
|
77
|
-
|
|
78
|
-
These features will be removed in Roda 3.1.0:
|
|
79
|
-
|
|
80
|
-
* Roda.thread_safe_cache is now deprecated. RodaCache is now used
|
|
81
|
-
as the thread-safe cache class.
|
|
82
|
-
|
|
83
|
-
* RodaRequest#placeholder_string_matcher? (private method) is now
|
|
84
|
-
deprecated and always returns false.
|
data/doc/release_notes/3.1.0.txt
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
= New Features
|
|
2
|
-
|
|
3
|
-
* A :timestamp_paths option has been added to the assets plugin to
|
|
4
|
-
include timestamps in paths in non-compiled mode. This can fix
|
|
5
|
-
asset staleness issues when using a caching proxy. This is
|
|
6
|
-
not needed in compiled mode, as the asset file names include the
|
|
7
|
-
hash of the asset. It is not the default in non-compiled mode,
|
|
8
|
-
as few people would use a caching proxy in non-compiled mode.
|
|
9
|
-
|
|
10
|
-
= Other Improvements
|
|
11
|
-
|
|
12
|
-
* Make set_layout_locals and set_view_locals in branch_locals
|
|
13
|
-
plugin work when the other is not called.
|
|
14
|
-
|
|
15
|
-
* When testing support for uglifier usability as a JS asset
|
|
16
|
-
compressor, handle case where uglifier is installed but there is
|
|
17
|
-
no available javascript runtime.
|
|
18
|
-
|
|
19
|
-
= Backwards Compatibility
|
|
20
|
-
|
|
21
|
-
* The deprecated Roda.thread_safe_cache method has been removed.
|
|
22
|
-
|
|
23
|
-
* The deprecated private RodaRequest#placeholder_string_matcher?
|
|
24
|
-
method has been removed.
|
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
= New Features
|
|
2
|
-
|
|
3
|
-
* A sessions plugin has been added that supports encrypted and
|
|
4
|
-
signed sessions. This plugin is now the recommended way to
|
|
5
|
-
implement sessions, replacing the previously recommended
|
|
6
|
-
Rack::Session::Cookie middleware.
|
|
7
|
-
|
|
8
|
-
The sessions plugin encrypts session data using the AES-256-CTR
|
|
9
|
-
cipher, and then signs the encrypted data with HMAC-SHA-256. By
|
|
10
|
-
doing this, attackers must be able to forge a valid HMAC before
|
|
11
|
-
they can try to exploit possible weaknesses in the encryption,
|
|
12
|
-
such as timing attacks during decryption that are dependent on
|
|
13
|
-
attacker chosen initialization vectors or ciphertext.
|
|
14
|
-
|
|
15
|
-
In addition to encryption and a stronger default signature
|
|
16
|
-
algorithm compared to Rack::Session::Cookie, the sessions
|
|
17
|
-
plugin has the following benefits:
|
|
18
|
-
|
|
19
|
-
* Built in session expiration enabeld by default, to mitigate
|
|
20
|
-
possible session replay issues (default: 30 days since session
|
|
21
|
-
creation, 7 days since last update).
|
|
22
|
-
|
|
23
|
-
* Padding by default to minimize information leakage due to
|
|
24
|
-
differing session data sizes (session data padded to
|
|
25
|
-
a multiple of 32 bytes by default before encryption).
|
|
26
|
-
|
|
27
|
-
* Automatic deflate compression of large sessions before
|
|
28
|
-
encryption (by default if session data is over 128 bytes).
|
|
29
|
-
|
|
30
|
-
* JSON is used for serialization instead of Marshal, preventing
|
|
31
|
-
remote code execution vulnerabilities if the session secret
|
|
32
|
-
is disclosed. Note that this means that many ruby types do not
|
|
33
|
-
round trip in the session, such as Symbol and Time instances.
|
|
34
|
-
This will probably be the largest barrier to adoption, as you
|
|
35
|
-
need to make sure your application only uses types that
|
|
36
|
-
round-trip through JSON before you start using the sessions
|
|
37
|
-
plugin.
|
|
38
|
-
|
|
39
|
-
* A plain hash is used for the session, instead of a hash-like
|
|
40
|
-
object. One consequence of this is that keys in the session
|
|
41
|
-
are not automatically converted to strings.
|
|
42
|
-
Rack::Session::Cookie converts session keys to strings for
|
|
43
|
-
keys at the top level, but not for keys in subhashes.
|
|
44
|
-
|
|
45
|
-
* In general sessions are smaller even if deflate compression is not
|
|
46
|
-
used, despite requiring 16 bytes for the cipher initialization
|
|
47
|
-
vector. The main reason for this is that the sessions plugin does
|
|
48
|
-
not set a session id, since one is not needed for cookie sessions.
|
|
49
|
-
|
|
50
|
-
* The sessions plugin requires a :secret option be set that is
|
|
51
|
-
at least 64 bytes, so that users have to make a determined
|
|
52
|
-
effort to use weak secrets.
|
|
53
|
-
|
|
54
|
-
* The HMAC calculation considers the cookie key, so that if the
|
|
55
|
-
same session secret is used for multiple applications with
|
|
56
|
-
different cookie keys, an attacker cannot use the session from
|
|
57
|
-
one application in a different application.
|
|
58
|
-
|
|
59
|
-
The sessions plugin ties into the Roda#session method instead
|
|
60
|
-
of being a rack middleware. This makes it about twice as
|
|
61
|
-
fast as Rack::Session::Cookie if the session is not accessed.
|
|
62
|
-
If the session is accessed, the sessions plugin is roughly
|
|
63
|
-
as fast as Rack::Session::Cookie, even though it uses a
|
|
64
|
-
stronger HMAC and has to encrypt and decrypt the session.
|
|
65
|
-
|
|
66
|
-
Because the sessions plugin is not a middleware, it does not
|
|
67
|
-
offer session support to other middleware, only to the app
|
|
68
|
-
itself. If you would like to use the same approach as the
|
|
69
|
-
sessions plugin uses but would like support for middleware to
|
|
70
|
-
access the sessions, a roda/session_middleware file has been
|
|
71
|
-
added. This file contains RodaSessionMiddleware, which is a
|
|
72
|
-
middleware that can be used by any other Rack app for session
|
|
73
|
-
support, and which uses a SessionHash class similar to the one used
|
|
74
|
-
by Rack::Session::Cookie.
|
|
75
|
-
|
|
76
|
-
To integrate with other plugins that can optionally use symbols
|
|
77
|
-
or strings in sessions, the sessions plugin sets the
|
|
78
|
-
:sessions_convert_symbols application option to true. Other plugins
|
|
79
|
-
can check for this application option, and if set, should use
|
|
80
|
-
strings instead of symbols in the session.
|
|
81
|
-
|
|
82
|
-
The sessions plugin should be loaded after the flash plugin if both
|
|
83
|
-
are used in the same application, so that the flash is rotated
|
|
84
|
-
correctly in the session.
|
|
85
|
-
|
|
86
|
-
* The middleware plugin now supports a :handle_result option, which
|
|
87
|
-
can be any callable object. If set, this object is called with the
|
|
88
|
-
environment of the request and the rack response after either the
|
|
89
|
-
Roda app or next middleware returns the rack response. The rack
|
|
90
|
-
response can be modified by the callable object, and the response
|
|
91
|
-
(after possible modification) will be returned to the previous
|
|
92
|
-
middleware. Example:
|
|
93
|
-
|
|
94
|
-
plugin :middleware, :handle_result=>(proc do |env, res|
|
|
95
|
-
res[1]['MyHeader'] = 'HeaderValue'
|
|
96
|
-
end)
|
|
97
|
-
|
|
98
|
-
* The :json_parser and :json_serializer application options are now
|
|
99
|
-
supported. If set, these options are used for parsing and
|
|
100
|
-
serializing JSON instead of the default of JSON.parse and .to_json.
|
|
101
|
-
|
|
102
|
-
= Other Improvements
|
|
103
|
-
|
|
104
|
-
* RodaRequest initialization is now faster by avoiding 1-2 method
|
|
105
|
-
calls.
|
|
106
|
-
|
|
107
|
-
* typecast_params.Integer in the typecast_params plugin now handles
|
|
108
|
-
numeric input as long the numeric input does not have fractional
|
|
109
|
-
parts. This makes it more usable when handling JSON input.
|
|
110
|
-
|
|
111
|
-
* If the flash is empty after the request is processed, the flash
|
|
112
|
-
session key is removed from the session instead of being left as
|
|
113
|
-
an empty hash. If addition to making the session smaller, this
|
|
114
|
-
makes the session appear empty if there are no other keys in the
|
|
115
|
-
session, which works better with the sessions plugin as empty
|
|
116
|
-
sessions will remove the session cookie completely.
|
|
117
|
-
|
|
118
|
-
= Backwards Compatibility
|
|
119
|
-
|
|
120
|
-
* The flash plugin now uses '_flash' instead of :_flash as the session
|
|
121
|
-
key. When using session middleware that uses
|
|
122
|
-
Rack::Session::Abstract::SessionHash to store the session (e.g.
|
|
123
|
-
Rack::Session::Cookie), session keys are converted internally to
|
|
124
|
-
strings, so this change will not affect you unless you are using
|
|
125
|
-
alternative session support. Even if your session does treat
|
|
126
|
-
:_flash different than '_flash' in keys, the plugin will still work
|
|
127
|
-
because it will try :_flash if there is no value for '_flash'. This
|
|
128
|
-
change was made to support the sessions plugin, which doesn't
|
|
129
|
-
convert keys to strings.
|
|
130
|
-
|
|
131
|
-
* This DEFAULT_PARSER and DEFAULT_SERIALIZER constants from the
|
|
132
|
-
the json_parser and json plugins have been removed.
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
= Improvements
|
|
2
|
-
|
|
3
|
-
* The order in which internal plugin before and after hooks are run
|
|
4
|
-
when multiple plugins are loaded is now fixed and does not depend
|
|
5
|
-
on the order in which the plugins are loaded. This can prevent
|
|
6
|
-
some issues in cases the plugins were not loaded in the order
|
|
7
|
-
previously recommended in the documentation.
|
|
8
|
-
|
|
9
|
-
Internal plugin before hooks are now run in the following order:
|
|
10
|
-
|
|
11
|
-
* hooks
|
|
12
|
-
* heartbeat
|
|
13
|
-
* static_routing
|
|
14
|
-
|
|
15
|
-
and internal plugin after hooks are now run in the following order:
|
|
16
|
-
|
|
17
|
-
* class_level_routing
|
|
18
|
-
* status_handler
|
|
19
|
-
* head
|
|
20
|
-
* flash
|
|
21
|
-
* session
|
|
22
|
-
* hooks
|
|
23
|
-
|
|
24
|
-
* Default compression of sessions over 128 bytes in length has been
|
|
25
|
-
disabled in the sessions plugin. Compression of sessions must now
|
|
26
|
-
be manually enabled if it is desired by setting :gzip_over to an
|
|
27
|
-
integer.
|
|
28
|
-
|
|
29
|
-
This change is being made to avoid possible compression ratio
|
|
30
|
-
attacks if both sensitive data and user-submitted data are stored in
|
|
31
|
-
the session. Such attacks were mitigated by the sessions plugin's
|
|
32
|
-
default use of padding after compression, and the JSON serialization
|
|
33
|
-
format used, but disabling compression avoids the possibility.
|
|
34
|
-
|
|
35
|
-
This does not affect backwards compatibility, as compressed sessions
|
|
36
|
-
will still be decompressed correctly, unless the size of the session
|
|
37
|
-
cookie when not using compression is over 4096 bytes.
|
|
38
|
-
|
|
39
|
-
= Backwards Compatibility
|
|
40
|
-
|
|
41
|
-
* When using the error_handler plugin, if routing raises an exception that
|
|
42
|
-
is handled by the error handler, but an exception is raised by a plugin
|
|
43
|
-
internal after hook after the error handler has been run, the exception
|
|
44
|
-
will be logged to the rack.errors entry in the environment, but it will
|
|
45
|
-
be otherwise ignored.
|
|
46
|
-
|
|
47
|
-
Exceptions raised inside the error handler will continue to be be raised
|
|
48
|
-
to the application's caller.
|
|
49
|
-
|
|
50
|
-
Additionally, the error_handler plugin no longers call before hooks
|
|
51
|
-
during error handling.
|
|
52
|
-
|
|
53
|
-
* A private Roda#_call method has been added. This could potentially
|
|
54
|
-
cause issues for applications that add their own _call method.
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
= New Features
|
|
2
|
-
|
|
3
|
-
* A common_logger plugin has been added for common log support. This
|
|
4
|
-
offers about 30% better performance than Rack::CommonLogger, with
|
|
5
|
-
the following differences:
|
|
6
|
-
|
|
7
|
-
* When timing requests, doesn't consider middleware or proxy the
|
|
8
|
-
body, so timing information is just the time that Roda takes
|
|
9
|
-
to process the request.
|
|
10
|
-
* Only looks for "Content-Length" as a header, not different
|
|
11
|
-
capitalizations (Roda only uses "Content-Length" internally).
|
|
12
|
-
* Logs to $stderr instead of rack.errors in request environment
|
|
13
|
-
if a logger object is not explicitly passed.
|
|
14
|
-
|
|
15
|
-
= Other Improvements
|
|
16
|
-
|
|
17
|
-
* Internal before/after hook methods now use more descriptive names
|
|
18
|
-
for easier debugging, with a naming format designed to not
|
|
19
|
-
conflict with hook methods in external plugins.
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
= New Features
|
|
2
|
-
|
|
3
|
-
* An exception_page plugin has been added for displaying debugging
|
|
4
|
-
information for a given exception. It is based on
|
|
5
|
-
Rack::ShowExceptions, with the following differences:
|
|
6
|
-
|
|
7
|
-
* Not a middleware, so it doesn't handle exceptions itself, and
|
|
8
|
-
has no effect on the callstack unless the exception_page
|
|
9
|
-
method is called.
|
|
10
|
-
* Supports external javascript and stylesheets, allowing context
|
|
11
|
-
toggling to work in applications that use a content security
|
|
12
|
-
policy to restrict inline javascript and stylesheets (:assets,
|
|
13
|
-
:css_file, and :js_file options).
|
|
14
|
-
* Has fewer dependencies (does not require ostruct and erb).
|
|
15
|
-
* Sets the Content-Type for the response, and returns the body
|
|
16
|
-
string, but does not modify other headers or the response status.
|
|
17
|
-
* Supports a configurable amount of context lines in backtraces
|
|
18
|
-
(:context option).
|
|
19
|
-
* Supports optional JSON formatted output, if used with the json
|
|
20
|
-
plugin (:json option).
|
|
21
|
-
|
|
22
|
-
Because this plugin just adds a method you can call, you can
|
|
23
|
-
selectively choose when to display a debugging page and when not
|
|
24
|
-
to, as well as customize the debugging parameters on a per-call
|
|
25
|
-
basis (such as returning JSON formatted debugging information
|
|
26
|
-
for JSON requests, and HTML formatted debugging information for
|
|
27
|
-
normal requests).
|
|
28
|
-
|
|
29
|
-
= Other Improvements
|
|
30
|
-
|
|
31
|
-
* The common_logger plugin now correctly handles cases where an
|
|
32
|
-
exception is being raised and there is no rack response to
|
|
33
|
-
introspect.
|
|
34
|
-
|
|
35
|
-
= Backwards Compatibility
|
|
36
|
-
|
|
37
|
-
* Stream#write in the streaming plugin now returns the number of
|
|
38
|
-
bytes written instead of self, so it works with IO.copy_stream.
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
= New Features
|
|
2
|
-
|
|
3
|
-
* The convert! and convert_each! methods in the typecast_params plugin
|
|
4
|
-
now support a :raise option for handling missing parameters specified
|
|
5
|
-
as arguments to the methods.
|
|
6
|
-
|
|
7
|
-
If the :raise option is set to false for convert! and the parameter
|
|
8
|
-
argument is missing, then no conversion is done and an empty hash
|
|
9
|
-
is returned:
|
|
10
|
-
|
|
11
|
-
typecast_params.convert!('missing', raise: false) do |tp|
|
|
12
|
-
# ...
|
|
13
|
-
end
|
|
14
|
-
# => {}
|
|
15
|
-
|
|
16
|
-
If the :raise option is set to false for convert_each! and a :keys
|
|
17
|
-
option is given, any key not present is ignored and nil will be
|
|
18
|
-
returned for the converted value
|
|
19
|
-
|
|
20
|
-
typecast_params.convert_each!(:keys=>['present', 'missing'], raise: false) do |tp|
|
|
21
|
-
tp.int('b')
|
|
22
|
-
end
|
|
23
|
-
# => [{'b'=>1}, nil]
|
|
24
|
-
|
|
25
|
-
= Other Improvements
|
|
26
|
-
|
|
27
|
-
* The :symbolize setting to the convert! and convert_each! methods in
|
|
28
|
-
the typecast_params plugin is no longer persisted beyond the call
|
|
29
|
-
to the method. This fixes unexpected behavior if you do:
|
|
30
|
-
|
|
31
|
-
typecast_params.convert!(:symbolize=>true) do |tp|
|
|
32
|
-
# ...
|
|
33
|
-
end
|
|
34
|
-
typecast_params.convert! do |tp|
|
|
35
|
-
# ...
|
|
36
|
-
end
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
= Security Fix
|
|
2
|
-
|
|
3
|
-
* Do not post-process content_for block result with template engine
|
|
4
|
-
|
|
5
|
-
Since 2.8.0, the content_for block result was post-processed with the
|
|
6
|
-
template engine. There is no actual need to do so, as content_for is
|
|
7
|
-
not designed to render output, it is designed to store already
|
|
8
|
-
rendered output. This post-processing was introduced when support for
|
|
9
|
-
haml templates was added in 2.8.0.
|
|
10
|
-
|
|
11
|
-
Post-processing the output with the template engine is generally a
|
|
12
|
-
no-op for most usage as most output does not contain template
|
|
13
|
-
metaprogramming characters, which is why this went undetected for so
|
|
14
|
-
long. However, if a content_for block return value contained
|
|
15
|
-
unescaped user input, it was probably vulnerable to remote code
|
|
16
|
-
execution if the default ERB template engine is used, the same as if
|
|
17
|
-
the user input was passed directly to the render or view method.
|
|
18
|
-
|
|
19
|
-
Example of a vulnerable usage (assuming automatic escaping is not
|
|
20
|
-
enabled) would be:
|
|
21
|
-
|
|
22
|
-
<% content_for :foo do %>
|
|
23
|
-
User name: <%= request.params['user_name'] %>
|
|
24
|
-
<% end %>
|
|
25
|
-
|
|
26
|
-
Such usage is likely vulnerable to cross site scripting unless the
|
|
27
|
-
content_for output is escaped before being displayed, even without
|
|
28
|
-
the content_for template post-processing. However, the post-processing
|
|
29
|
-
turned it from a cross site scripting vulnerability into a remote code
|
|
30
|
-
execution vulnerability. For non-ERB template engines, whether the
|
|
31
|
-
post-processing introduced a vulnerability depends on the template
|
|
32
|
-
engine.
|
|
33
|
-
|
|
34
|
-
Note that if you were correctly escaping user input in your ERB
|
|
35
|
-
templates (either automatically or manually), you are unlikely to be
|
|
36
|
-
vulnerable as the escaping escaped the ERB template metacharacters
|
|
37
|
-
(< and >). For non-ERB templates, escaping the output may not have
|
|
38
|
-
mitigated the vulnerability, depending on what metacharacters
|
|
39
|
-
the template engine uses and whether the escaping will modify them.
|
|
40
|
-
|
|
41
|
-
Calling content_for with an argument was not vulnerable as no
|
|
42
|
-
post-processing was done on the argument, it was only done on
|
|
43
|
-
the block result.
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
= New Features
|
|
2
|
-
|
|
3
|
-
* The render plugin :escape option value can now be a string or an
|
|
4
|
-
array of strings, and then the plugin will will only add the
|
|
5
|
-
:escape template option for those specific template engines given.
|
|
6
|
-
By default, the :escape plugin option adds the :escape template
|
|
7
|
-
option for all engines, which breaks the usage with some engines
|
|
8
|
-
(such as the rcsv engine).
|
|
9
|
-
|
|
10
|
-
* The convert! and convert_each! methods in the typecast_params plugin
|
|
11
|
-
now support a :skip_missing option to support not storing missing
|
|
12
|
-
parameters:
|
|
13
|
-
|
|
14
|
-
typecast_params.convert! do |tp|
|
|
15
|
-
tp.int('missing')
|
|
16
|
-
end
|
|
17
|
-
# => {'missing'=>nil}
|
|
18
|
-
typecast_params.convert!(skip_missing: false) do |tp|
|
|
19
|
-
tp.int('missing')
|
|
20
|
-
end
|
|
21
|
-
# => {}
|