rails-hush 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +85 -0
- data/Rakefile +27 -0
- data/lib/rails-hush.rb +1 -0
- data/lib/rails_hush.rb +4 -0
- data/lib/rails_hush/middleware/hush_one.rb +24 -0
- data/lib/rails_hush/middleware/hush_two.rb +51 -0
- data/lib/rails_hush/middleware/simple_renderer.rb +38 -0
- data/lib/rails_hush/railtie.rb +18 -0
- data/lib/rails_hush/version.rb +3 -0
- data/lib/tasks/rails_hush_tasks.rake +4 -0
- metadata +97 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6867245caf963cbc37708518d67b491ba280abe0e8bfa4499a9f1b814ee2bd03
|
4
|
+
data.tar.gz: 728cefe68ef32e5ad5554fb1b3b027219ead3102d7fca17a04c96969b01cc03b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 13f9d62b027e8df242a42ef15f5f5c5e235496749f2132202785acd9a7d43069f410ad9f808b3b091d71ddd1b4180eb97ee7d93e3e8be0ca7c190b4f4dc47355
|
7
|
+
data.tar.gz: 8804b6f1eeba38238fc022732aa63b5bafb67b109f88598f21c96079bb67217750e39a266d9a756db71d8dcb8cc7fbcee6582b0e8511823ac235f3b7711701ae
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2019 thomas morgan
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
# RailsHush
|
2
|
+
|
3
|
+
RailsHush hushes worthless Rails exceptions & logs, such as those caused by bots and crawlers.
|
4
|
+
|
5
|
+
Rails generates a number of exceptions that, while useful in development, are quite noisy in production. This is expecially true because of the volume of bots deliberately sending malformed traffic to your Rails app. Unfortunately, by default Rails dutifully logs exceptions and backtraces for all of this, and depending on your exception notification system of choice, may trigger unnecessary notifications.
|
6
|
+
|
7
|
+
In addition to bots, if your app has an API and is used by third-parties, they may generate a variety of errors while integrating with your app. These too don't need to be logged, but it is useful if the error messages are more helpful than simply "bad request". RailsHush takes care of this for you.
|
8
|
+
|
9
|
+
RailsHush will...
|
10
|
+
|
11
|
+
* Silence backtrace logging for a wide array of errors that aren't related to your actual app code
|
12
|
+
* Return various 4xx HTTP status codes, instead of 500
|
13
|
+
* Provide basic, helpful error messages to 3rd-parties integrating with your app
|
14
|
+
* Properly trigger "Completed..." log entries at the end of invalid requests
|
15
|
+
* Using standard active_support notifications, for compatibility with non-default logging solutions
|
16
|
+
|
17
|
+
RailsHush honors Rails settings for `show_exceptions` and `consider_all_requests_local`. With Rails' defaults, it will only activate in production and will not interfere with debugging while in development or test. The exceptions that are hushed are very selective; actual app errors should continue to raise exceptions as normal, even in production.
|
18
|
+
|
19
|
+
|
20
|
+
## Installation
|
21
|
+
Add this line to your Rails application's Gemfile:
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
gem 'rails-hush'
|
25
|
+
```
|
26
|
+
|
27
|
+
And then execute:
|
28
|
+
```bash
|
29
|
+
$ bundle
|
30
|
+
```
|
31
|
+
|
32
|
+
|
33
|
+
## Usage
|
34
|
+
|
35
|
+
By default, works automatically upon installation. Most of the time, configuration is not necessary.
|
36
|
+
|
37
|
+
|
38
|
+
#### Configuration
|
39
|
+
|
40
|
+
RailsHush does support a couple of configuration options:
|
41
|
+
|
42
|
+
To disable automatic loading of middleware:
|
43
|
+
|
44
|
+
# Phase one (early) middleware
|
45
|
+
config.rails_hush.use_one = true
|
46
|
+
# Phase two (late) middleware
|
47
|
+
config.rails_hush.use_two = true
|
48
|
+
|
49
|
+
Then add the middleware on your own:
|
50
|
+
|
51
|
+
# Phase one
|
52
|
+
app.middleware.insert 0, RailsHush::HushOne
|
53
|
+
# Phase two
|
54
|
+
app.middleware.insert_after ActionDispatch::DebugExceptions, RailsHush::HushTwo
|
55
|
+
|
56
|
+
RailsHush also has a replaceable renderer, in case you don't like the default json/xml output:
|
57
|
+
|
58
|
+
config.rails_hush.renderer = lambda do |status, content_type, error|
|
59
|
+
# status - integer, eg: 400
|
60
|
+
# content_type - a Mime::Type instance, eg: Mime[:json]
|
61
|
+
# error = RailsHush's default text error message, eg: "some error"
|
62
|
+
# You may replace it with your own based on status or anything else.
|
63
|
+
...
|
64
|
+
# the block must return a Rack-compatible response:
|
65
|
+
headers = {}
|
66
|
+
body = {my: 'payload'}.to_json
|
67
|
+
[status, headers, [body]]
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
#### Testing
|
72
|
+
|
73
|
+
Rails' default "test" environment settings are quite different than "production". While the default settings are quite appropriate, with them it is near impossible to test the actual behavior of RailsHush, because it will effectively be disabled in "test". On the whole, it's recommended to just rely on RailsHush's own test suite. However, if you really want to test its behavior inside your app, change the following in `environments/test.rb`:
|
74
|
+
|
75
|
+
config.consider_all_requests_local = false
|
76
|
+
config.action_dispatch.show_exceptions = true
|
77
|
+
|
78
|
+
|
79
|
+
## Contributing
|
80
|
+
|
81
|
+
Contributions welcome. Please use standard Github Pull Requests.
|
82
|
+
|
83
|
+
|
84
|
+
## License
|
85
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'RailsHush'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'bundler/gem_tasks'
|
18
|
+
|
19
|
+
require 'rake/testtask'
|
20
|
+
|
21
|
+
Rake::TestTask.new(:test) do |t|
|
22
|
+
t.libs << 'test'
|
23
|
+
t.pattern = 'test/**/*_test.rb'
|
24
|
+
t.verbose = false
|
25
|
+
end
|
26
|
+
|
27
|
+
task default: :test
|
data/lib/rails-hush.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'rails_hush'
|
data/lib/rails_hush.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
module RailsHush
|
2
|
+
class HushOne
|
3
|
+
include SimpleRenderer
|
4
|
+
|
5
|
+
def initialize(app, renderer=nil)
|
6
|
+
@app = app
|
7
|
+
@renderer ||= Rails.application.config.rails_hush.renderer || method(:default_renderer)
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
request = ActionDispatch::Request.new env
|
12
|
+
if request.show_exceptions? && !request.get_header("action_dispatch.show_detailed_exceptions")
|
13
|
+
begin
|
14
|
+
@app.call(env)
|
15
|
+
rescue ActionController::UnknownHttpMethod
|
16
|
+
render 405, request, 'Unrecognized HTTP method'
|
17
|
+
end
|
18
|
+
else
|
19
|
+
@app.call(env)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module RailsHush
|
2
|
+
class HushTwo
|
3
|
+
include SimpleRenderer
|
4
|
+
|
5
|
+
def initialize(app, renderer=nil)
|
6
|
+
@app = app
|
7
|
+
@renderer ||= Rails.application.config.rails_hush.renderer || method(:default_renderer)
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
request = ActionDispatch::Request.new env
|
12
|
+
if request.show_exceptions? && !request.get_header("action_dispatch.show_detailed_exceptions")
|
13
|
+
begin
|
14
|
+
_, headers, body = response = @app.call(env)
|
15
|
+
if headers['X-Cascade'] == 'pass'
|
16
|
+
body.close if body.respond_to?(:close)
|
17
|
+
raise ActionController::RoutingError, "No route matches [#{env['REQUEST_METHOD']}] #{env['PATH_INFO'].inspect}"
|
18
|
+
end
|
19
|
+
response
|
20
|
+
|
21
|
+
rescue ActionController::BadRequest => x
|
22
|
+
if x.message =~ /(Invalid encoding for parameter|invalid %-encoding)/
|
23
|
+
log_request 400, request
|
24
|
+
render 400, request, 'Invalid string or encoding'
|
25
|
+
else
|
26
|
+
raise x
|
27
|
+
end
|
28
|
+
rescue ActionDispatch::Http::Parameters::ParseError
|
29
|
+
log_request 400, request
|
30
|
+
render 400, request, 'Unable to parse request body'
|
31
|
+
rescue ActionController::RoutingError => x
|
32
|
+
log_request 404, request
|
33
|
+
render 404, request
|
34
|
+
rescue ActionController::UnknownHttpMethod
|
35
|
+
log_request 405, request
|
36
|
+
render 405, request, 'Unrecognized HTTP method'
|
37
|
+
rescue ActionController::UnknownFormat
|
38
|
+
render 406, request, 'Invalid format'
|
39
|
+
rescue Mime::Type::InvalidMimeType
|
40
|
+
log_request 406, request
|
41
|
+
render 406, request, 'Invalid media type'
|
42
|
+
rescue ActionController::ParameterMissing => x
|
43
|
+
render 422, request, "Required parameter missing or empty: #{x.param}"
|
44
|
+
end
|
45
|
+
else
|
46
|
+
@app.call(env)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module SimpleRenderer
|
2
|
+
|
3
|
+
def log_request(status, request)
|
4
|
+
payload = {
|
5
|
+
params: (request.filtered_parameters rescue {}),
|
6
|
+
headers: request.headers,
|
7
|
+
format: (request.format.ref rescue :text),
|
8
|
+
method: (request.request_method rescue 'INVALID'),
|
9
|
+
path: request.fullpath,
|
10
|
+
status: status
|
11
|
+
}
|
12
|
+
ActiveSupport::Notifications.instrument "process_action.action_controller", payload
|
13
|
+
end
|
14
|
+
|
15
|
+
def render(status, request, error=nil)
|
16
|
+
begin
|
17
|
+
content_type = request.formats.first
|
18
|
+
rescue Mime::Type::InvalidMimeType
|
19
|
+
content_type = Mime[:text]
|
20
|
+
end
|
21
|
+
error ||= Rack::Utils::HTTP_STATUS_CODES.fetch(status, Rack::Utils::HTTP_STATUS_CODES[500])
|
22
|
+
@renderer.call(status, content_type, error)
|
23
|
+
end
|
24
|
+
|
25
|
+
def default_renderer(status, content_type, error)
|
26
|
+
body = { status: status, error: error }
|
27
|
+
format = "to_#{content_type.to_sym}" if content_type
|
28
|
+
if format && body.respond_to?(format)
|
29
|
+
body = body.public_send(format)
|
30
|
+
else
|
31
|
+
content_type = 'application/json'
|
32
|
+
body = body.to_json
|
33
|
+
end
|
34
|
+
[status, { "Content-Type" => "#{content_type}; charset=#{ActionDispatch::Response.default_charset}",
|
35
|
+
"Content-Length" => body.bytesize.to_s }, [body]]
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module RailsHush
|
2
|
+
class Railtie < Rails::Railtie
|
3
|
+
config.rails_hush = ActiveSupport::OrderedOptions.new
|
4
|
+
config.rails_hush.use_one = true
|
5
|
+
config.rails_hush.use_two = true
|
6
|
+
config.rails_hush.renderer = nil
|
7
|
+
|
8
|
+
initializer 'railshush.init' do |app|
|
9
|
+
if config.rails_hush.use_one
|
10
|
+
app.middleware.insert 0, RailsHush::HushOne
|
11
|
+
end
|
12
|
+
if config.rails_hush.use_two
|
13
|
+
app.middleware.insert_after ActionDispatch::DebugExceptions, RailsHush::HushTwo
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rails-hush
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- thomas morgan
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-11-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 6.0.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 6.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: sqlite3
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
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: minitest-reporters
|
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
|
+
description: Hushes worthless Rails exceptions & logs, such as those caused by bots
|
56
|
+
and crawlers.
|
57
|
+
email:
|
58
|
+
- tm@iprog.com
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- MIT-LICENSE
|
64
|
+
- README.md
|
65
|
+
- Rakefile
|
66
|
+
- lib/rails-hush.rb
|
67
|
+
- lib/rails_hush.rb
|
68
|
+
- lib/rails_hush/middleware/hush_one.rb
|
69
|
+
- lib/rails_hush/middleware/hush_two.rb
|
70
|
+
- lib/rails_hush/middleware/simple_renderer.rb
|
71
|
+
- lib/rails_hush/railtie.rb
|
72
|
+
- lib/rails_hush/version.rb
|
73
|
+
- lib/tasks/rails_hush_tasks.rake
|
74
|
+
homepage: https://github.com/zarqman/rails-hush
|
75
|
+
licenses:
|
76
|
+
- MIT
|
77
|
+
metadata: {}
|
78
|
+
post_install_message:
|
79
|
+
rdoc_options: []
|
80
|
+
require_paths:
|
81
|
+
- lib
|
82
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
87
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
requirements: []
|
93
|
+
rubygems_version: 3.0.6
|
94
|
+
signing_key:
|
95
|
+
specification_version: 4
|
96
|
+
summary: Hushes worthless Rails exceptions & logs
|
97
|
+
test_files: []
|