rack-berater 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a1fad5e57124897f72b0fac11bf460c6b3dc279d057f56f22127ec32274d782d
4
+ data.tar.gz: aa7e1c738a450ff6fb72aa9b92e1211ed51c544f801a2ffef475a2a89805db5c
5
+ SHA512:
6
+ metadata.gz: 0ec05fa53c35aea22a9c29e93b5d509c8a161364542641ada1af1c421320d671cd634dc8ab74abc597f38a056fb3d8638b69786cf82e26357b0ace12bf483ee9
7
+ data.tar.gz: c9f1c61d05ac9f297b88fad401fdf635cd553a15d2040a2fc7e45282fe2776e00967b8e7181cec5a621c5cb69771676cf7d70a34ee63e6be2b74dd7784b7b7d2
@@ -0,0 +1,37 @@
1
+ module Rack
2
+ module Berater
3
+ class Handler
4
+ def initialize(app, options = {})
5
+ @app = app
6
+ @options = {
7
+ status_code: options.fetch(:status_code, 429),
8
+ body: options.fetch(:body, true),
9
+ }
10
+ end
11
+
12
+ def call(env)
13
+ @app.call(env)
14
+ rescue ::Berater::Overloaded => e
15
+ code = @options[:status_code]
16
+ body = case @options[:body]
17
+ when true
18
+ Rack::Utils::HTTP_STATUS_CODES[code]
19
+ when nil, false
20
+ nil
21
+ when String
22
+ @options[:body]
23
+ when Proc
24
+ @options[:body].call(env, e)
25
+ else
26
+ raise ArgumentError, "invalid :body option: #{@options[:body]}"
27
+ end
28
+
29
+ [
30
+ code,
31
+ {},
32
+ [ body ].compact,
33
+ ]
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,11 @@
1
+ require 'rails/railtie'
2
+
3
+ module Rack
4
+ module Berater
5
+ class Railtie < Rails::Railtie
6
+ initializer "rack.berater.initializer" do |app|
7
+ app.middleware.use Rack::Berater
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ module Rack
2
+ module Berater
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,9 @@
1
+ require "rack/berater/version"
2
+
3
+ module Rack
4
+ module Berater
5
+ autoload :Handler, "rack/berater/handler"
6
+ # autoload :Limiter, "rack/berater/limiter"
7
+ autoload :Railtie, "rack/berater/railtie"
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ require "berater"
2
+ require "rack"
3
+ require "rack/berater"
@@ -0,0 +1,98 @@
1
+ describe Rack::Berater::Handler do
2
+ let(:app) do
3
+ Rack::Builder.new do
4
+ use Rack::Lint
5
+ run (lambda do |env|
6
+ raise ::Berater::Overloaded if ::Berater.test_mode == :fail
7
+ [200, {"Content-Type" => "text/plain"}, ["OK"]]
8
+ end)
9
+ end
10
+ end
11
+ let(:response) { get "/" }
12
+
13
+ shared_examples "works nominally" do
14
+ it { expect(response.status).to eq 200 }
15
+ it { expect(response.body).to eq "OK" }
16
+ end
17
+
18
+ context "without Handler" do
19
+ include_examples "works nominally"
20
+
21
+ it "does not catch limit errors" do
22
+ Berater.test_mode = :fail
23
+ expect {
24
+ response
25
+ }.to be_overloaded
26
+ end
27
+ end
28
+
29
+ context "with Handler using default settings" do
30
+ context "with default settings" do
31
+ before { app.use described_class }
32
+
33
+ include_examples "works nominally"
34
+
35
+ it "catches and transforms limit errors" do
36
+ Berater.test_mode = :fail
37
+ expect(response.status).to eq 429
38
+ expect(response.body).to eq "Too Many Requests"
39
+ end
40
+ end
41
+ end
42
+
43
+ context "with Handler using custom settings" do
44
+ before do
45
+ app.use described_class, options
46
+ Berater.test_mode = :fail
47
+ end
48
+
49
+ context "with custom status code" do
50
+ let(:options) { { status_code: 503 } }
51
+
52
+ it "catches and transforms limit errors" do
53
+ expect(response.status).to eq 503
54
+ expect(response.body).to eq "Service Unavailable"
55
+ end
56
+ end
57
+
58
+ context "with body disabled" do
59
+ let(:options) { { body: false } }
60
+
61
+ it "should not send a body" do
62
+ expect(response.body).to be_empty
63
+ end
64
+ end
65
+
66
+ context "with body nil" do
67
+ let(:options) { { body: nil } }
68
+
69
+ it "should not send a body" do
70
+ expect(response.body).to be_empty
71
+ end
72
+ end
73
+
74
+ context "with custom body" do
75
+ let(:body) { "none shall pass!" }
76
+ let(:options) { { body: body } }
77
+
78
+ it "should send the custom string" do
79
+ expect(response.body).to eq body
80
+ end
81
+ end
82
+
83
+ context "with a dynamic body" do
84
+ let(:body) { "none shall pass!" }
85
+ let(:fn) { proc { body } }
86
+ let(:options) { { body: fn } }
87
+
88
+ it "should call the Proc and send the result" do
89
+ expect(response.body).to eq body
90
+ end
91
+
92
+ it "should pass in the env and error" do
93
+ expect(fn).to receive(:call).with(Hash, ::Berater::Overloaded)
94
+ response
95
+ end
96
+ end
97
+ end
98
+ end
metadata ADDED
@@ -0,0 +1,147 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rack-berater
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Daniel Pepper
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-09-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: berater
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rack
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: byebug
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: codecov
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rack-test
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: simplecov
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: "..."
112
+ email:
113
+ executables: []
114
+ extensions: []
115
+ extra_rdoc_files: []
116
+ files:
117
+ - lib/rack-berater.rb
118
+ - lib/rack/berater.rb
119
+ - lib/rack/berater/handler.rb
120
+ - lib/rack/berater/railtie.rb
121
+ - lib/rack/berater/version.rb
122
+ - spec/handler_spec.rb
123
+ homepage: https://github.com/dpep/rack-berater
124
+ licenses:
125
+ - MIT
126
+ metadata: {}
127
+ post_install_message:
128
+ rdoc_options: []
129
+ require_paths:
130
+ - lib
131
+ required_ruby_version: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - ">="
134
+ - !ruby/object:Gem::Version
135
+ version: '0'
136
+ required_rubygems_version: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ requirements: []
142
+ rubygems_version: 3.0.8
143
+ signing_key:
144
+ specification_version: 4
145
+ summary: Rack::Berater
146
+ test_files:
147
+ - spec/handler_spec.rb