rack-robustness 1.2.0 → 2.0.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.md +56 -0
- data/Gemfile +2 -7
- data/README.md +16 -8
- data/lib/rack/robustness/version.rb +8 -0
- data/lib/rack/robustness.rb +22 -6
- data/spec/test_header_names.rb +98 -0
- data/spec/test_last_resort.rb +6 -6
- data/spec/test_robustness.rb +8 -8
- data/tasks/gem.rake +1 -1
- metadata +60 -43
- data/Gemfile.lock +0 -33
- data/Manifest.txt +0 -15
- data/rack-robustness.gemspec +0 -188
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 13cdad67517d9891e673d38c26fd1efa91fafd03bbf52d552fef3b779596e572
|
|
4
|
+
data.tar.gz: b58b64c4c92eb4a1659aaffc31153c8bbf70bb507c1b9864c06a02b8a1142efa
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 41fa4ce5a8f8f7bf2ff190c5c3a44515162526a3777d41d22bc959b5873db6a82d99f475d617be0e75397ffe37240585e84e495799144ba52100987412c241b7
|
|
7
|
+
data.tar.gz: 4a262606fedaaf85c842cc43d899cc652a1563bfb606838a1debb6a393d3edba260f3c68a42634bda9ca1c08ebc74fe0d3f6f429d8a4e826dcf0778046ea56de
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,59 @@
|
|
|
1
|
+
## 2.0.0 / 2026-09-29
|
|
2
|
+
|
|
3
|
+
The Rack 3 release.
|
|
4
|
+
|
|
5
|
+
* BREAKING: response header names are now emitted in lowercase, as required
|
|
6
|
+
by the Rack 3 SPEC ("Header keys must not contain uppercase ASCII
|
|
7
|
+
characters"). Names given to the DSL are normalized, so `'content-type'`,
|
|
8
|
+
`'Content-Type'` and `'CONTENT-TYPE'` all name the same header:
|
|
9
|
+
|
|
10
|
+
use Rack::Robustness do |g|
|
|
11
|
+
g.headers 'X-Error' => 'boom' # emitted as x-error
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
Under Rack 3 this was mostly already the case, since Rack::Response
|
|
15
|
+
normalizes what it is given. The path that was genuinely non-compliant was
|
|
16
|
+
the last resort response, returned as a raw triple when error handling
|
|
17
|
+
itself fails. Header names are case-insensitive on the wire, so the change
|
|
18
|
+
is invisible to clients; it is only visible to code asserting on the raw
|
|
19
|
+
Rack triple, or to a middleware reading headers case-sensitively.
|
|
20
|
+
|
|
21
|
+
* BREAKING: fixed the default headers silently winning over a configured one
|
|
22
|
+
written in another case. `g.headers('content-type' => 'application/json')`
|
|
23
|
+
used to be ignored, the `'Content-Type' => 'text/plain'` default taking
|
|
24
|
+
precedence, because the two keys did not collide and clauses are applied
|
|
25
|
+
with `||=`. Lowercase being what Rack 3 users naturally write, this was
|
|
26
|
+
easy to hit and silent. Applications that worked around it by writing
|
|
27
|
+
`'Content-Type'` are unaffected.
|
|
28
|
+
|
|
29
|
+
* BREAKING: Ruby >= 3.2 is now required, and the test matrix covers 3.2, 3.3
|
|
30
|
+
and 3.4. Ruby 2.7 and 3.1 have both reached end of life.
|
|
31
|
+
|
|
32
|
+
* BREAKING: Rack 3 is now required. Rack 2 reached its last feature release
|
|
33
|
+
in 2022 and nothing here is worth keeping a compatibility branch for. Stay
|
|
34
|
+
on the 1.x line if you are still on Rack 2.
|
|
35
|
+
|
|
36
|
+
* `rack` is now a proper runtime dependency, `>= 3.0, < 4.0`. It was only a
|
|
37
|
+
development dependency before, even though the middleware has always used
|
|
38
|
+
`Rack::Request` and `Rack::Response`. `lib/rack/robustness.rb` requires it
|
|
39
|
+
explicitly rather than assuming the host application already did.
|
|
40
|
+
|
|
41
|
+
* The version moved to `rack/robustness/version.rb`, so that the gemspec can
|
|
42
|
+
read it without loading Rack, which would activate a Rack version before
|
|
43
|
+
Bundler gets to constrain it.
|
|
44
|
+
|
|
45
|
+
* Fixed `rake` being entirely broken: `tasks/gem.rake` eval'd the gemspec
|
|
46
|
+
without a filename, so `__FILE__` resolved to `(eval)` and the `$LOAD_PATH`
|
|
47
|
+
entry it computes pointed nowhere.
|
|
48
|
+
|
|
49
|
+
* Development dependencies were stale to the point of being wrong (rspec
|
|
50
|
+
~> 2.12 while the suite is rspec 3, rake ~> 10, rack ~> 1.5). They now
|
|
51
|
+
match what is actually used, rack-test included, moving from 0.6 to 2.x.
|
|
52
|
+
|
|
53
|
+
* The gemspec dropped its Noe boilerplate, along with `Manifest.txt` and the
|
|
54
|
+
dangling `rack-robustness.noespec` entry it carried. `.travis.yml` is
|
|
55
|
+
removed too, CI having moved to GitHub Actions.
|
|
56
|
+
|
|
1
57
|
## 1.2.0 / 2023-06-09
|
|
2
58
|
|
|
3
59
|
* Modernize with test matrix on ruby 2.7, 3.1, and 3.2
|
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Rack::Robustness is the rescue clause of your Rack's call stack. In other words, a middleware that ensures the robustness of your web stack, because exceptions occur either intentionally or unintentionally. Rack::Robustness is the rack middleware you would have written manually (see below) but provides a DSL for scaling from zero configuration (a default shield) to specific rescue clauses for specific errors.
|
|
4
4
|
|
|
5
|
-
[](https://gemnasium.com/blambeau/rack-robustness)
|
|
5
|
+
[](https://github.com/blambeau/rack-robustness/actions/workflows/integration.yml)
|
|
7
6
|
|
|
8
7
|
```ruby
|
|
9
8
|
##
|
|
@@ -19,9 +18,9 @@ class Robustness
|
|
|
19
18
|
def call(env)
|
|
20
19
|
@app.call(env)
|
|
21
20
|
rescue ArgumentError => ex
|
|
22
|
-
[400, { '
|
|
21
|
+
[400, { 'content-type' => 'text/plain' }, [ ex.message ] ] # suppose the message can be safely used
|
|
23
22
|
rescue SecurityError => ex
|
|
24
|
-
[403, { '
|
|
23
|
+
[403, { 'content-type' => 'text/plain' }, [ ex.message ] ]
|
|
25
24
|
ensure
|
|
26
25
|
env['rack.errors'].write(ex.message) if ex
|
|
27
26
|
end
|
|
@@ -48,6 +47,15 @@ use Rack::Robustness do |g|
|
|
|
48
47
|
end
|
|
49
48
|
```
|
|
50
49
|
|
|
50
|
+
## Requirements
|
|
51
|
+
|
|
52
|
+
Ruby >= 3.2 and Rack 3. Use the 1.x line if you are still on Rack 2.
|
|
53
|
+
|
|
54
|
+
Response header names are always emitted in lowercase, as the Rack 3 SPEC
|
|
55
|
+
requires. You may write them in any case you like -- `'content-type'`,
|
|
56
|
+
`'Content-Type'` and `'CONTENT-TYPE'` all name the same header -- they are
|
|
57
|
+
normalized before reaching the response.
|
|
58
|
+
|
|
51
59
|
## Links
|
|
52
60
|
|
|
53
61
|
* https://github.com/blambeau/rack-robustness
|
|
@@ -178,7 +186,7 @@ end
|
|
|
178
186
|
#
|
|
179
187
|
# Respond with
|
|
180
188
|
# status: 500,
|
|
181
|
-
# headers: {'
|
|
189
|
+
# headers: {'content-type' => 'text/plain'}
|
|
182
190
|
# body: [ "Sorry, an error occured." ]
|
|
183
191
|
#
|
|
184
192
|
use Rack::Robustness
|
|
@@ -194,7 +202,7 @@ use Rack::Robustness
|
|
|
194
202
|
#
|
|
195
203
|
use Rack::Robustness do |g|
|
|
196
204
|
g.status 400
|
|
197
|
-
g.headers '
|
|
205
|
+
g.headers 'content-type' => 'text/html'
|
|
198
206
|
g.content_type 'text/html' # shortcut over headers
|
|
199
207
|
g.body "<p>an error occured</p>"
|
|
200
208
|
end
|
|
@@ -212,10 +220,10 @@ use Rack::Robustness do |g|
|
|
|
212
220
|
g.status{|ex| ArgumentError===ex ? 400 : 500 }
|
|
213
221
|
|
|
214
222
|
# global dynamic headers
|
|
215
|
-
g.headers{|ex| {'
|
|
223
|
+
g.headers{|ex| {'content-type' => 'text/plain', ...} }
|
|
216
224
|
|
|
217
225
|
# local dynamic and/or static headers
|
|
218
|
-
g.headers '
|
|
226
|
+
g.headers 'content-type' => lambda{|ex| ... },
|
|
219
227
|
'Foo' => 'Bar'
|
|
220
228
|
|
|
221
229
|
# dynamic content type
|
data/lib/rack/robustness.rb
CHANGED
|
@@ -1,7 +1,19 @@
|
|
|
1
|
+
require 'rack'
|
|
2
|
+
require 'rack/robustness/version'
|
|
3
|
+
|
|
1
4
|
module Rack
|
|
2
5
|
class Robustness
|
|
3
6
|
|
|
4
|
-
|
|
7
|
+
# Downcases header names, as required by the Rack 3 SPEC: "Header keys
|
|
8
|
+
# must not contain uppercase ASCII characters (A-Z)".
|
|
9
|
+
#
|
|
10
|
+
# Header names are case-insensitive on the wire, so this is applied to
|
|
11
|
+
# whatever the DSL is given, rather than rejecting capitalized names.
|
|
12
|
+
def self.normalize_headers(headers)
|
|
13
|
+
headers.each_with_object({}) do |(name, value), normalized|
|
|
14
|
+
normalized[name.to_s.downcase] = value
|
|
15
|
+
end
|
|
16
|
+
end
|
|
5
17
|
|
|
6
18
|
def self.new(app, &bl)
|
|
7
19
|
return super(app) if bl.nil? and not(Robustness==self)
|
|
@@ -22,7 +34,7 @@ module Rack
|
|
|
22
34
|
@rescue_clauses = {}
|
|
23
35
|
@ensure_clauses = []
|
|
24
36
|
@status_clause = 500
|
|
25
|
-
@headers_clause = {'
|
|
37
|
+
@headers_clause = {'content-type' => "text/plain"}
|
|
26
38
|
@body_clause = ["Sorry, a fatal error occured."]
|
|
27
39
|
@response_builder = lambda{|ex| ::Rack::Response.new }
|
|
28
40
|
@catch_all = true
|
|
@@ -67,12 +79,12 @@ module Rack
|
|
|
67
79
|
if h.nil?
|
|
68
80
|
@headers_clause = bl
|
|
69
81
|
else
|
|
70
|
-
@headers_clause.merge!(h)
|
|
82
|
+
@headers_clause.merge!(Robustness.normalize_headers(h))
|
|
71
83
|
end
|
|
72
84
|
end
|
|
73
85
|
|
|
74
86
|
def content_type(ct=nil, &bl)
|
|
75
|
-
headers('
|
|
87
|
+
headers('content-type' => ct || bl)
|
|
76
88
|
end
|
|
77
89
|
|
|
78
90
|
def body(b=nil, &bl)
|
|
@@ -181,8 +193,12 @@ module Rack
|
|
|
181
193
|
@response.status = handle_value(ex, status)
|
|
182
194
|
end
|
|
183
195
|
|
|
196
|
+
# `headers` may come from a block, and therefore carry names in any case.
|
|
197
|
+
# They are normalized here so that a name given as 'Content-Type' and one
|
|
198
|
+
# given as 'content-type' are the same header.
|
|
184
199
|
def handle_headers(ex, headers)
|
|
185
|
-
handle_value(ex, headers)
|
|
200
|
+
normalized = Robustness.normalize_headers(handle_value(ex, headers))
|
|
201
|
+
normalized.each_pair do |key,value|
|
|
186
202
|
@response[key] ||= handle_value(ex, value)
|
|
187
203
|
end
|
|
188
204
|
end
|
|
@@ -203,7 +219,7 @@ module Rack
|
|
|
203
219
|
|
|
204
220
|
def last_resort(ex)
|
|
205
221
|
[ 500,
|
|
206
|
-
{'
|
|
222
|
+
{'content-type' => 'text/plain'},
|
|
207
223
|
[ 'An internal error occured, sorry for the disagreement.' ] ]
|
|
208
224
|
end
|
|
209
225
|
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
# The Rack 3 SPEC requires response header names to be lowercase: "Header keys
|
|
4
|
+
# must not contain uppercase ASCII characters (A-Z)".
|
|
5
|
+
#
|
|
6
|
+
# These examples look at the raw response triple on purpose. Rack::Test, and
|
|
7
|
+
# Rack::Response itself, normalize header names on read, so going through
|
|
8
|
+
# `last_response` would hide both a capitalized name and a duplicated one.
|
|
9
|
+
describe Rack::Robustness, 'header names' do
|
|
10
|
+
|
|
11
|
+
def headers_of(app)
|
|
12
|
+
_, headers, _ = app.to_app.call(Rack::MockRequest.env_for("/"))
|
|
13
|
+
headers
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def failing_app(&bl)
|
|
17
|
+
Rack::Builder.new do
|
|
18
|
+
use Rack::Robustness, &bl
|
|
19
|
+
run lambda{|env| raise ArgumentError, "an argument error" }
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
context 'with the default configuration' do
|
|
24
|
+
it 'emits a lowercase content-type' do
|
|
25
|
+
expect(headers_of(failing_app).keys).to eq(['content-type'])
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
context 'on the happy path' do
|
|
30
|
+
let(:app) {
|
|
31
|
+
Rack::Builder.new do
|
|
32
|
+
use Rack::Robustness
|
|
33
|
+
run lambda{|env| [200, {'Content-Type' => 'text/plain'}, ['happy']] }
|
|
34
|
+
end
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
it 'emits lowercase names, whatever the application uses' do
|
|
38
|
+
expect(headers_of(app)).to eq({'content-type' => 'text/plain'})
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
context 'when the DSL is given capitalized names' do
|
|
43
|
+
it 'emits them lowercased, without duplicating content-type' do
|
|
44
|
+
app = failing_app do |g|
|
|
45
|
+
g.headers 'Content-Type' => 'text/test', 'X-Foo' => 'Bar'
|
|
46
|
+
end
|
|
47
|
+
expect(headers_of(app)).to eq({
|
|
48
|
+
'content-type' => 'text/test',
|
|
49
|
+
'x-foo' => 'Bar'
|
|
50
|
+
})
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Before 2.0.0 the default headers were keyed 'Content-Type', so configuring
|
|
55
|
+
# 'content-type' added a *second* entry rather than overriding. Since the
|
|
56
|
+
# clauses are applied with `||=`, the default won and the configured value
|
|
57
|
+
# was silently dropped -- and lowercase is precisely what Rack 3 users write.
|
|
58
|
+
context 'when the DSL overrides a default header in another case' do
|
|
59
|
+
['content-type', 'Content-Type', 'CONTENT-TYPE'].each do |name|
|
|
60
|
+
it "honours the value given as #{name}" do
|
|
61
|
+
app = failing_app{|g| g.headers name => 'application/json' }
|
|
62
|
+
expect(headers_of(app)).to eq({'content-type' => 'application/json'})
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
context 'when a headers block returns capitalized names' do
|
|
68
|
+
it 'emits them lowercased' do
|
|
69
|
+
app = failing_app do |g|
|
|
70
|
+
g.headers{|ex| { 'Content-Type' => 'text/test', 'X-Foo' => 'Bar' } }
|
|
71
|
+
end
|
|
72
|
+
expect(headers_of(app)).to eq({
|
|
73
|
+
'content-type' => 'text/test',
|
|
74
|
+
'x-foo' => 'Bar'
|
|
75
|
+
})
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
context 'when a rescue clause returns capitalized names' do
|
|
80
|
+
it 'emits them lowercased' do
|
|
81
|
+
app = failing_app do |g|
|
|
82
|
+
g.rescue(ArgumentError){|ex| [400, {'X-Foo' => 'Bar'}, ['nope']] }
|
|
83
|
+
end
|
|
84
|
+
expect(headers_of(app).keys.sort).to eq(['content-type', 'x-foo'])
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
context 'in last resort' do
|
|
89
|
+
it 'emits a lowercase content-type' do
|
|
90
|
+
app = Rack::Builder.new do
|
|
91
|
+
use(Rack::Robustness){|g| g.response{|ex| NoSuchResponseClass.new } }
|
|
92
|
+
run lambda{|env| raise ArgumentError, "an argument error" }
|
|
93
|
+
end
|
|
94
|
+
expect(headers_of(app).keys).to eq(['content-type'])
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
end
|
data/spec/test_last_resort.rb
CHANGED
|
@@ -16,15 +16,15 @@ describe Rack::Robustness, 'last resort' do
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
it 'reraises the internal error' do
|
|
19
|
-
|
|
19
|
+
expect{
|
|
20
20
|
get '/argument-error'
|
|
21
|
-
}.
|
|
21
|
+
}.to raise_error(NameError, /NoSuchResponseClass/)
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
it 'passes into the ensure block with the original error' do
|
|
25
|
-
|
|
25
|
+
expect{
|
|
26
26
|
get '/argument-error'
|
|
27
|
-
}.
|
|
27
|
+
}.to raise_error(NameError, /NoSuchResponseClass/)
|
|
28
28
|
expect($seen_ex).to be_a(ArgumentError)
|
|
29
29
|
end
|
|
30
30
|
end
|
|
@@ -53,9 +53,9 @@ describe Rack::Robustness, 'last resort' do
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
it 'reraises the internal error' do
|
|
56
|
-
|
|
56
|
+
expect{
|
|
57
57
|
get '/argument-error'
|
|
58
|
-
}.
|
|
58
|
+
}.to raise_error(NameError, /NoSuchResponseClass/)
|
|
59
59
|
end
|
|
60
60
|
end
|
|
61
61
|
|
data/spec/test_robustness.rb
CHANGED
|
@@ -65,7 +65,7 @@ describe Rack::Robustness do
|
|
|
65
65
|
|
|
66
66
|
it 'set the specified headers on error' do
|
|
67
67
|
get '/argument-error'
|
|
68
|
-
last_response.headers['Foo'].
|
|
68
|
+
expect(last_response.headers['Foo']).to eq('Bar')
|
|
69
69
|
expect(last_response.content_type).to eq("text/test")
|
|
70
70
|
end
|
|
71
71
|
end
|
|
@@ -130,13 +130,13 @@ describe Rack::Robustness do
|
|
|
130
130
|
|
|
131
131
|
it 'correctly sets the specified headers on an ArgumentError' do
|
|
132
132
|
get '/argument-error'
|
|
133
|
-
last_response.headers['Foo'].
|
|
133
|
+
expect(last_response.headers['Foo']).to eq('Bar')
|
|
134
134
|
expect(last_response.content_type).to eq("text/arg")
|
|
135
135
|
end
|
|
136
136
|
|
|
137
137
|
it 'correctly sets the specified headers on a TypeError' do
|
|
138
138
|
get '/type-error'
|
|
139
|
-
last_response.headers['Foo'].
|
|
139
|
+
expect(last_response.headers['Foo']).to eq('Bar')
|
|
140
140
|
expect(last_response.content_type).to eq("text/other")
|
|
141
141
|
end
|
|
142
142
|
end
|
|
@@ -152,7 +152,7 @@ describe Rack::Robustness do
|
|
|
152
152
|
|
|
153
153
|
after do
|
|
154
154
|
# if merges the default headers in any way
|
|
155
|
-
last_response.headers['Foo'].
|
|
155
|
+
expect(last_response.headers['Foo']).to eq('Bar')
|
|
156
156
|
end
|
|
157
157
|
|
|
158
158
|
it 'uses the response on ArgumentError' do
|
|
@@ -214,9 +214,9 @@ describe Rack::Robustness do
|
|
|
214
214
|
end
|
|
215
215
|
|
|
216
216
|
it 'raises on unknown error' do
|
|
217
|
-
|
|
217
|
+
expect{
|
|
218
218
|
get '/type-error'
|
|
219
|
-
}.
|
|
219
|
+
}.to raise_error(TypeError)
|
|
220
220
|
end
|
|
221
221
|
end
|
|
222
222
|
|
|
@@ -236,9 +236,9 @@ describe Rack::Robustness do
|
|
|
236
236
|
end
|
|
237
237
|
|
|
238
238
|
it 'raises on unknown error' do
|
|
239
|
-
|
|
239
|
+
expect{
|
|
240
240
|
get '/type-error'
|
|
241
|
-
}.
|
|
241
|
+
}.to raise_error(TypeError)
|
|
242
242
|
end
|
|
243
243
|
end
|
|
244
244
|
|
data/tasks/gem.rake
CHANGED
|
@@ -2,7 +2,7 @@ require 'rubygems/package_task'
|
|
|
2
2
|
|
|
3
3
|
# Dynamically load the gem spec
|
|
4
4
|
gemspec_file = File.expand_path('../../rack-robustness.gemspec', __FILE__)
|
|
5
|
-
gemspec = Kernel.eval(File.read(gemspec_file))
|
|
5
|
+
gemspec = Kernel.eval(File.read(gemspec_file), binding, gemspec_file)
|
|
6
6
|
|
|
7
7
|
Gem::PackageTask.new(gemspec) do |t|
|
|
8
8
|
|
metadata
CHANGED
|
@@ -1,71 +1,94 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rack-robustness
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Bernard Lambeau
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
|
-
name:
|
|
13
|
+
name: rack
|
|
15
14
|
requirement: !ruby/object:Gem::Requirement
|
|
16
15
|
requirements:
|
|
17
|
-
- - "
|
|
16
|
+
- - ">="
|
|
18
17
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
20
|
-
|
|
18
|
+
version: '3.0'
|
|
19
|
+
- - "<"
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '4.0'
|
|
22
|
+
type: :runtime
|
|
21
23
|
prerelease: false
|
|
22
24
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
25
|
requirements:
|
|
24
|
-
- - "
|
|
26
|
+
- - ">="
|
|
25
27
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '
|
|
28
|
+
version: '3.0'
|
|
29
|
+
- - "<"
|
|
30
|
+
- !ruby/object:Gem::Version
|
|
31
|
+
version: '4.0'
|
|
27
32
|
- !ruby/object:Gem::Dependency
|
|
28
|
-
name:
|
|
33
|
+
name: rack-test
|
|
29
34
|
requirement: !ruby/object:Gem::Requirement
|
|
30
35
|
requirements:
|
|
31
|
-
- - "
|
|
36
|
+
- - ">="
|
|
32
37
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '2.
|
|
38
|
+
version: '2.0'
|
|
39
|
+
- - "<"
|
|
40
|
+
- !ruby/object:Gem::Version
|
|
41
|
+
version: '3.0'
|
|
34
42
|
type: :development
|
|
35
43
|
prerelease: false
|
|
36
44
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
45
|
requirements:
|
|
38
|
-
- - "
|
|
46
|
+
- - ">="
|
|
47
|
+
- !ruby/object:Gem::Version
|
|
48
|
+
version: '2.0'
|
|
49
|
+
- - "<"
|
|
39
50
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '
|
|
51
|
+
version: '3.0'
|
|
41
52
|
- !ruby/object:Gem::Dependency
|
|
42
|
-
name:
|
|
53
|
+
name: rake
|
|
43
54
|
requirement: !ruby/object:Gem::Requirement
|
|
44
55
|
requirements:
|
|
45
|
-
- - "
|
|
56
|
+
- - ">="
|
|
46
57
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: '
|
|
58
|
+
version: '13.0'
|
|
59
|
+
- - "<"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '14.0'
|
|
48
62
|
type: :development
|
|
49
63
|
prerelease: false
|
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
65
|
requirements:
|
|
52
|
-
- - "
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '13.0'
|
|
69
|
+
- - "<"
|
|
53
70
|
- !ruby/object:Gem::Version
|
|
54
|
-
version: '
|
|
71
|
+
version: '14.0'
|
|
55
72
|
- !ruby/object:Gem::Dependency
|
|
56
|
-
name:
|
|
73
|
+
name: rspec
|
|
57
74
|
requirement: !ruby/object:Gem::Requirement
|
|
58
75
|
requirements:
|
|
59
|
-
- - "
|
|
76
|
+
- - ">="
|
|
77
|
+
- !ruby/object:Gem::Version
|
|
78
|
+
version: '3.12'
|
|
79
|
+
- - "<"
|
|
60
80
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '0
|
|
81
|
+
version: '4.0'
|
|
62
82
|
type: :development
|
|
63
83
|
prerelease: false
|
|
64
84
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
85
|
requirements:
|
|
66
|
-
- - "
|
|
86
|
+
- - ">="
|
|
67
87
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: '
|
|
88
|
+
version: '3.12'
|
|
89
|
+
- - "<"
|
|
90
|
+
- !ruby/object:Gem::Version
|
|
91
|
+
version: '4.0'
|
|
69
92
|
description: Rack::Robustness provides you with an easy way to handle errors in your
|
|
70
93
|
stack, for making web applications more robust.
|
|
71
94
|
email:
|
|
@@ -73,22 +96,21 @@ email:
|
|
|
73
96
|
executables: []
|
|
74
97
|
extensions: []
|
|
75
98
|
extra_rdoc_files:
|
|
76
|
-
- README.md
|
|
77
99
|
- CHANGELOG.md
|
|
78
100
|
- LICENCE.md
|
|
101
|
+
- README.md
|
|
79
102
|
files:
|
|
80
103
|
- CHANGELOG.md
|
|
81
104
|
- Gemfile
|
|
82
|
-
- Gemfile.lock
|
|
83
105
|
- LICENCE.md
|
|
84
|
-
- Manifest.txt
|
|
85
106
|
- README.md
|
|
86
107
|
- Rakefile
|
|
87
108
|
- lib/rack/robustness.rb
|
|
88
|
-
- rack
|
|
109
|
+
- lib/rack/robustness/version.rb
|
|
89
110
|
- spec/spec_helper.rb
|
|
90
111
|
- spec/test_context.rb
|
|
91
112
|
- spec/test_ensure.rb
|
|
113
|
+
- spec/test_header_names.rb
|
|
92
114
|
- spec/test_last_resort.rb
|
|
93
115
|
- spec/test_rescue.rb
|
|
94
116
|
- spec/test_response.rb
|
|
@@ -97,9 +119,13 @@ files:
|
|
|
97
119
|
- tasks/gem.rake
|
|
98
120
|
- tasks/test.rake
|
|
99
121
|
homepage: https://github.com/blambeau/rack-robustness
|
|
100
|
-
licenses:
|
|
101
|
-
|
|
102
|
-
|
|
122
|
+
licenses:
|
|
123
|
+
- MIT
|
|
124
|
+
metadata:
|
|
125
|
+
homepage_uri: https://github.com/blambeau/rack-robustness
|
|
126
|
+
source_code_uri: https://github.com/blambeau/rack-robustness
|
|
127
|
+
changelog_uri: https://github.com/blambeau/rack-robustness/blob/master/CHANGELOG.md
|
|
128
|
+
bug_tracker_uri: https://github.com/blambeau/rack-robustness/issues
|
|
103
129
|
rdoc_options: []
|
|
104
130
|
require_paths:
|
|
105
131
|
- lib
|
|
@@ -107,23 +133,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
107
133
|
requirements:
|
|
108
134
|
- - ">="
|
|
109
135
|
- !ruby/object:Gem::Version
|
|
110
|
-
version: '
|
|
136
|
+
version: '3.2'
|
|
111
137
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
112
138
|
requirements:
|
|
113
139
|
- - ">="
|
|
114
140
|
- !ruby/object:Gem::Version
|
|
115
141
|
version: '0'
|
|
116
142
|
requirements: []
|
|
117
|
-
rubygems_version: 3.
|
|
118
|
-
signing_key:
|
|
143
|
+
rubygems_version: 3.6.9
|
|
119
144
|
specification_version: 4
|
|
120
145
|
summary: Rack::Robustness, the rescue clause of your Rack stack.
|
|
121
|
-
test_files:
|
|
122
|
-
- spec/test_response.rb
|
|
123
|
-
- spec/test_rescue.rb
|
|
124
|
-
- spec/test_robustness.rb
|
|
125
|
-
- spec/test_subclass.rb
|
|
126
|
-
- spec/test_ensure.rb
|
|
127
|
-
- spec/test_context.rb
|
|
128
|
-
- spec/spec_helper.rb
|
|
129
|
-
- spec/test_last_resort.rb
|
|
146
|
+
test_files: []
|
data/Gemfile.lock
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
GEM
|
|
2
|
-
remote: http://rubygems.org/
|
|
3
|
-
specs:
|
|
4
|
-
diff-lcs (1.5.0)
|
|
5
|
-
rack (2.2.7)
|
|
6
|
-
rack-test (0.6.2)
|
|
7
|
-
rack (>= 1.0)
|
|
8
|
-
rake (13.0.6)
|
|
9
|
-
rspec (3.12.0)
|
|
10
|
-
rspec-core (~> 3.12.0)
|
|
11
|
-
rspec-expectations (~> 3.12.0)
|
|
12
|
-
rspec-mocks (~> 3.12.0)
|
|
13
|
-
rspec-core (3.12.2)
|
|
14
|
-
rspec-support (~> 3.12.0)
|
|
15
|
-
rspec-expectations (3.12.3)
|
|
16
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
|
17
|
-
rspec-support (~> 3.12.0)
|
|
18
|
-
rspec-mocks (3.12.5)
|
|
19
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
|
20
|
-
rspec-support (~> 3.12.0)
|
|
21
|
-
rspec-support (3.12.0)
|
|
22
|
-
|
|
23
|
-
PLATFORMS
|
|
24
|
-
ruby
|
|
25
|
-
|
|
26
|
-
DEPENDENCIES
|
|
27
|
-
rack (~> 2)
|
|
28
|
-
rack-test (~> 0.6)
|
|
29
|
-
rake (~> 13)
|
|
30
|
-
rspec (~> 3)
|
|
31
|
-
|
|
32
|
-
BUNDLED WITH
|
|
33
|
-
2.4.6
|
data/Manifest.txt
DELETED
data/rack-robustness.gemspec
DELETED
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
# We require your library, mainly to have access to the VERSION number.
|
|
2
|
-
# Feel free to set $version manually.
|
|
3
|
-
$LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
|
|
4
|
-
require "rack/robustness"
|
|
5
|
-
$version = Rack::Robustness::VERSION.dup.to_s
|
|
6
|
-
|
|
7
|
-
#
|
|
8
|
-
# This is your Gem specification. Default values are provided so that your library
|
|
9
|
-
# should be correctly packaged given what you have described in the .noespec file.
|
|
10
|
-
#
|
|
11
|
-
Gem::Specification.new do |s|
|
|
12
|
-
|
|
13
|
-
################################################################### ABOUT YOUR GEM
|
|
14
|
-
|
|
15
|
-
# Gem name (required)
|
|
16
|
-
s.name = "rack-robustness"
|
|
17
|
-
|
|
18
|
-
# Gem version (required)
|
|
19
|
-
s.version = $version
|
|
20
|
-
|
|
21
|
-
# A short summary of this gem
|
|
22
|
-
#
|
|
23
|
-
# This is displayed in `gem list -d`.
|
|
24
|
-
s.summary = "Rack::Robustness, the rescue clause of your Rack stack."
|
|
25
|
-
|
|
26
|
-
# A long description of this gem (required)
|
|
27
|
-
#
|
|
28
|
-
# The description should be more detailed than the summary. For example,
|
|
29
|
-
# you might wish to copy the entire README into the description.
|
|
30
|
-
s.description = "Rack::Robustness provides you with an easy way to handle errors in your stack, for making web applications more robust."
|
|
31
|
-
|
|
32
|
-
# The URL of this gem home page (optional)
|
|
33
|
-
s.homepage = "https://github.com/blambeau/rack-robustness"
|
|
34
|
-
|
|
35
|
-
# Gem publication date (required but auto)
|
|
36
|
-
#
|
|
37
|
-
# Today is automatically used by default, uncomment only if
|
|
38
|
-
# you know what you do!
|
|
39
|
-
#
|
|
40
|
-
# s.date = Time.now.strftime('%Y-%m-%d')
|
|
41
|
-
|
|
42
|
-
# The license(s) for the library. Each license must be a short name, no
|
|
43
|
-
# more than 64 characters.
|
|
44
|
-
#
|
|
45
|
-
# s.licences = %w{}
|
|
46
|
-
|
|
47
|
-
# The rubyforge project this gem lives under (optional)
|
|
48
|
-
#
|
|
49
|
-
# s.rubyforge_project = nil
|
|
50
|
-
|
|
51
|
-
################################################################### ABOUT THE AUTHORS
|
|
52
|
-
|
|
53
|
-
# The list of author names who wrote this gem.
|
|
54
|
-
#
|
|
55
|
-
# If you are providing multiple authors and multiple emails they should be
|
|
56
|
-
# in the same order.
|
|
57
|
-
#
|
|
58
|
-
s.authors = ["Bernard Lambeau"]
|
|
59
|
-
|
|
60
|
-
# Contact emails for this gem
|
|
61
|
-
#
|
|
62
|
-
# If you are providing multiple authors and multiple emails they should be
|
|
63
|
-
# in the same order.
|
|
64
|
-
#
|
|
65
|
-
# NOTE: Somewhat strangly this attribute is always singular!
|
|
66
|
-
# Don't replace by s.emails = ...
|
|
67
|
-
s.email = ["blambeau@gmail.com"]
|
|
68
|
-
|
|
69
|
-
################################################################### PATHS, FILES, BINARIES
|
|
70
|
-
|
|
71
|
-
# Paths in the gem to add to $LOAD_PATH when this gem is
|
|
72
|
-
# activated (required).
|
|
73
|
-
#
|
|
74
|
-
# The default 'lib' is typically sufficient.
|
|
75
|
-
s.require_paths = ["lib"]
|
|
76
|
-
|
|
77
|
-
# Files included in this gem.
|
|
78
|
-
#
|
|
79
|
-
# By default, we take all files included in the Manifest.txt file on root
|
|
80
|
-
# of the project. Entries of the manifest are interpreted as Dir[...]
|
|
81
|
-
# patterns so that lazy people may use wilcards like lib/**/*
|
|
82
|
-
#
|
|
83
|
-
here = File.expand_path(File.dirname(__FILE__))
|
|
84
|
-
s.files = File.readlines(File.join(here, 'Manifest.txt')).
|
|
85
|
-
inject([]){|files, pattern| files + Dir[File.join(here, pattern.strip)]}.
|
|
86
|
-
collect{|x| x[(1+here.size)..-1]}
|
|
87
|
-
|
|
88
|
-
# Test files included in this gem.
|
|
89
|
-
#
|
|
90
|
-
s.test_files = Dir["test/**/*"] + Dir["spec/**/*"]
|
|
91
|
-
|
|
92
|
-
# The path in the gem for executable scripts (optional)
|
|
93
|
-
#
|
|
94
|
-
s.bindir = "bin"
|
|
95
|
-
|
|
96
|
-
# Executables included in the gem.
|
|
97
|
-
#
|
|
98
|
-
s.executables = (Dir["bin/*"]).collect{|f| File.basename(f)}
|
|
99
|
-
|
|
100
|
-
################################################################### REQUIREMENTS & INSTALL
|
|
101
|
-
# Remember the gem version requirements operators and schemes:
|
|
102
|
-
# = Equals version
|
|
103
|
-
# != Not equal to version
|
|
104
|
-
# > Greater than version
|
|
105
|
-
# < Less than version
|
|
106
|
-
# >= Greater than or equal to
|
|
107
|
-
# <= Less than or equal to
|
|
108
|
-
# ~> Approximately greater than
|
|
109
|
-
#
|
|
110
|
-
# Don't forget to have a look at http://lmgtfy.com/?q=Ruby+Versioning+Policies
|
|
111
|
-
# for setting your gem version.
|
|
112
|
-
#
|
|
113
|
-
# For your requirements to other gems, remember that
|
|
114
|
-
# ">= 2.2.0" (optimistic: specify minimal version)
|
|
115
|
-
# ">= 2.2.0", "< 3.0" (pessimistic: not greater than the next major)
|
|
116
|
-
# "~> 2.2" (shortcut for ">= 2.2.0", "< 3.0")
|
|
117
|
-
# "~> 2.2.0" (shortcut for ">= 2.2.0", "< 2.3.0")
|
|
118
|
-
#
|
|
119
|
-
|
|
120
|
-
#
|
|
121
|
-
# One call to add_dependency('gem_name', 'gem version requirement') for each
|
|
122
|
-
# runtime dependency. These gems will be installed with your gem.
|
|
123
|
-
# One call to add_development_dependency('gem_name', 'gem version requirement')
|
|
124
|
-
# for each development dependency. These gems are required for developers
|
|
125
|
-
#
|
|
126
|
-
s.add_development_dependency("rake", "~> 10.0")
|
|
127
|
-
s.add_development_dependency("rspec", "~> 2.12")
|
|
128
|
-
s.add_development_dependency("rack", "~> 1.5")
|
|
129
|
-
s.add_development_dependency("rack-test", "~> 0.6")
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
# The version of ruby required by this gem
|
|
133
|
-
#
|
|
134
|
-
# Uncomment and set this if your gem requires specific ruby versions.
|
|
135
|
-
#
|
|
136
|
-
# s.required_ruby_version = ">= 0"
|
|
137
|
-
|
|
138
|
-
# The RubyGems version required by this gem
|
|
139
|
-
#
|
|
140
|
-
# s.required_rubygems_version = ">= 0"
|
|
141
|
-
|
|
142
|
-
# The platform this gem runs on. See Gem::Platform for details.
|
|
143
|
-
#
|
|
144
|
-
# s.platform = nil
|
|
145
|
-
|
|
146
|
-
# Extensions to build when installing the gem.
|
|
147
|
-
#
|
|
148
|
-
# Valid types of extensions are extconf.rb files, configure scripts
|
|
149
|
-
# and rakefiles or mkrf_conf files.
|
|
150
|
-
#
|
|
151
|
-
s.extensions = []
|
|
152
|
-
|
|
153
|
-
# External (to RubyGems) requirements that must be met for this gem to work.
|
|
154
|
-
# It’s simply information for the user.
|
|
155
|
-
#
|
|
156
|
-
s.requirements = nil
|
|
157
|
-
|
|
158
|
-
# A message that gets displayed after the gem is installed
|
|
159
|
-
#
|
|
160
|
-
# Uncomment and set this if you want to say something to the user
|
|
161
|
-
# after gem installation
|
|
162
|
-
#
|
|
163
|
-
s.post_install_message = nil
|
|
164
|
-
|
|
165
|
-
################################################################### SECURITY
|
|
166
|
-
|
|
167
|
-
# The key used to sign this gem. See Gem::Security for details.
|
|
168
|
-
#
|
|
169
|
-
# s.signing_key = nil
|
|
170
|
-
|
|
171
|
-
# The certificate chain used to sign this gem. See Gem::Security for
|
|
172
|
-
# details.
|
|
173
|
-
#
|
|
174
|
-
# s.cert_chain = []
|
|
175
|
-
|
|
176
|
-
################################################################### RDOC
|
|
177
|
-
|
|
178
|
-
# An ARGV style array of options to RDoc
|
|
179
|
-
#
|
|
180
|
-
# See 'rdoc --help' about this
|
|
181
|
-
#
|
|
182
|
-
s.rdoc_options = []
|
|
183
|
-
|
|
184
|
-
# Extra files to add to RDoc such as README
|
|
185
|
-
#
|
|
186
|
-
s.extra_rdoc_files = Dir["README.md"] + Dir["CHANGELOG.md"] + Dir["LICENCE.md"]
|
|
187
|
-
|
|
188
|
-
end
|