rack-traffic-signal 0.1.2
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 +7 -0
- data/.gitignore +12 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +21 -0
- data/README.md +127 -0
- data/Rakefile +6 -0
- data/lib/generators/rack_traffic_signal/install_generator.rb +13 -0
- data/lib/generators/templates/503.html +9 -0
- data/lib/generators/templates/initializer.rb +37 -0
- data/lib/rack/traffic_signal/config.rb +82 -0
- data/lib/rack/traffic_signal/exceptions.rb +8 -0
- data/lib/rack/traffic_signal/middleware.rb +100 -0
- data/lib/rack/traffic_signal/railtie.rb +9 -0
- data/lib/rack/traffic_signal/version.rb +5 -0
- data/lib/rack/traffic_signal.rb +44 -0
- data/lib/rack-traffic_signal.rb +1 -0
- data/rack-traffic-signal.gemspec +28 -0
- metadata +147 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 40eb82af455e2ed57cffd1166baf1b1058cfe0f5
|
4
|
+
data.tar.gz: 5cac4ded4b7c77c1ac763e3e917bcb10a7ca79cc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9fd40d70a8f47adff5c5b99b4284d6e6d4ca106f82146f1ba93f3649da019dc8ff95fb17244a811461576ae20061db1b04d5f42b114d085684f103127e0fe9bb
|
7
|
+
data.tar.gz: 05ffe11ec02523b1c9db0a2b8ced2fcb701491c359db7c56a27cc905357bc94a042767ee69f93221897094988473fd86f96e01736c2e598b5bf79fee0ab41833
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2017 keigo_yamamoto
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
# Rack::TrafficSignal
|
2
|
+
|
3
|
+
Rack::TrafficSignal is a Rack middleware to make application in maintenance mode.
|
4
|
+
You can make part of application in maintenance mode, and use different http status and response body.
|
5
|
+
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'rack-traffic-signal'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install rack-traffic-signal
|
22
|
+
|
23
|
+
If you are installing this gem to Rails application, run:
|
24
|
+
|
25
|
+
$ rails g rack_traffic_signal:install
|
26
|
+
|
27
|
+
## Usage
|
28
|
+
|
29
|
+
### Rails
|
30
|
+
|
31
|
+
Generator places initializer template and sample maintenance page.
|
32
|
+
|
33
|
+
Modify `config/initializers/rack_traffic_signal.rb` .
|
34
|
+
|
35
|
+
And add below to your `application.rb`
|
36
|
+
|
37
|
+
```ruby:application.rb
|
38
|
+
require 'rack/traffic_signal'
|
39
|
+
...
|
40
|
+
config.middleware.use(Rack::TrafficSignal::Middleware)
|
41
|
+
...
|
42
|
+
```
|
43
|
+
|
44
|
+
### Not Rails
|
45
|
+
|
46
|
+
Insert Rack::TrafficSignal::Middleware to Middleware stack manually, and create setting script.
|
47
|
+
|
48
|
+
## Setting
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
Rack::TrafficSignal.setup do |config|
|
52
|
+
# This config is used to internal_access? method.
|
53
|
+
# Only add path to this option, mantenance mode is not skipped.
|
54
|
+
config.internal_ips = ['192.168.1.1/25']
|
55
|
+
|
56
|
+
# This config is used to skip_path? method.
|
57
|
+
# Only add path to this option, mantenance mode is not skipped.
|
58
|
+
config.skip_paths = [/^\/users\/12345/]
|
59
|
+
|
60
|
+
# Default setting
|
61
|
+
config.default_status = 503
|
62
|
+
config.default_content_type = 'application/json'
|
63
|
+
config.default_body = { error: 'error' }.to_json
|
64
|
+
|
65
|
+
# Maintenance group settings
|
66
|
+
# Maintenance group defined as :<resource>_<action>
|
67
|
+
|
68
|
+
# If path defined by String, maintenance mode will be applied path is match rigidly.
|
69
|
+
# '/users' does not make maintenance mode '/users/foo'.
|
70
|
+
|
71
|
+
# If multiple setting is appliable, more general setting will be priored.
|
72
|
+
# %{/} has higher priority than %{/users/\/d+/foo/bar}
|
73
|
+
config.maintenance_group = {
|
74
|
+
# <resource>: {
|
75
|
+
# <action>: [
|
76
|
+
# { methods: [:get, :post], path: <path_to_maintenance>}
|
77
|
+
# ]
|
78
|
+
# }
|
79
|
+
users: {
|
80
|
+
register: [
|
81
|
+
{ methods: [:get], path: "/users/new"},
|
82
|
+
{ methods: [:post], path: "/users" }
|
83
|
+
],
|
84
|
+
update: [
|
85
|
+
{ methods: [:put], path: %r{/users/\d+}}
|
86
|
+
]
|
87
|
+
}
|
88
|
+
}
|
89
|
+
|
90
|
+
# Block to judge whether requested page/api is under maintenance.
|
91
|
+
# Returns Array<Symbol>
|
92
|
+
# If status array include...
|
93
|
+
# :all => all of maintenance groups are enabled.
|
94
|
+
# :<resource>_all => maintenance groups under resource
|
95
|
+
# ex) :users_all => users_register and users_update are in under maintenance
|
96
|
+
# :<resource>_<action> => maintenance group matches is in under maintenance
|
97
|
+
config.maintenance_status_by do
|
98
|
+
ENV['MAINTENANCE_STATUS'] # [:users_register, :users_update]
|
99
|
+
end
|
100
|
+
|
101
|
+
# Block to judge whether maintenance mode should be skipped.
|
102
|
+
# For example, you can skip maintenance mode with specific path or internal access.
|
103
|
+
config.skip_by do |env|
|
104
|
+
Rack::TrafficSignal.skip_path?(env) || Rack::TrafficSignal.internal_access?
|
105
|
+
end
|
106
|
+
|
107
|
+
# Block to judge whether maintenance mode should be skipped with warning.
|
108
|
+
# For example, you can skip maintenance mode with specific path or internal access.
|
109
|
+
# Warn by add 'X-RACK-TRAFFIC-SIGNAL-MAINTENANCE' to response header.
|
110
|
+
config.skip_with_warning_by do |env|
|
111
|
+
Rack::TrafficSignal.skip_path?(env) || Rack::TrafficSignal.internal_access?
|
112
|
+
end
|
113
|
+
end
|
114
|
+
```
|
115
|
+
|
116
|
+
## Contributing
|
117
|
+
|
118
|
+
1. Fork it
|
119
|
+
1. Create your feature branch (git checkout -b my-new-feature)
|
120
|
+
1. Commit your changes (git commit -am 'Add some feature')
|
121
|
+
1. Push to the branch (git push origin my-new-feature)
|
122
|
+
1. Create new Pull Request
|
123
|
+
|
124
|
+
## License
|
125
|
+
|
126
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
127
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
module RackTrafficSignal
|
2
|
+
module Generators
|
3
|
+
class InstallGenerator < ::Rails::Generators::Base
|
4
|
+
source_root File.expand_path('../../templates', __FILE__)
|
5
|
+
desc 'Install Rack::TrafficSignal to Rails application'
|
6
|
+
|
7
|
+
def install
|
8
|
+
template 'initializer.rb', 'config/initializers/rack_traffic_signal.rb'
|
9
|
+
template '503.html', 'public/503.html'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
Rack::TrafficSignal.setup do |config|
|
4
|
+
# config.internal_ips = []
|
5
|
+
# config.default_status = 503
|
6
|
+
# config.default_content_type = 'application/json'
|
7
|
+
# require 'json'
|
8
|
+
# config.default_body = '{}'.to_json
|
9
|
+
# config.maintenance_group = {
|
10
|
+
# users: {
|
11
|
+
# read: [
|
12
|
+
# { methods: [:get], path: '/api/users', status: 404 },
|
13
|
+
# { methods: [:get], path: %r{/api/users/\d+}, status: 404, content_type: 'application/json' },
|
14
|
+
# ],
|
15
|
+
# write: [
|
16
|
+
# { methods: [:post], path: '/api/users' body: { error: 'maintenance mode' }.to_json },
|
17
|
+
# { methods: [:put, :delete], path: '%r{/api/users/\d+}' }
|
18
|
+
# ]
|
19
|
+
# },
|
20
|
+
# articles: {
|
21
|
+
# read: [
|
22
|
+
# { methods: [:get], path: '/api/articles' },
|
23
|
+
# { methods: [:get], path: %r{/api/articles/\d+} },
|
24
|
+
# ],
|
25
|
+
# write: [
|
26
|
+
# { methods: [:post], path: '/api/articles' },
|
27
|
+
# { methods: [:put, :delete], path: '%r{/api/articles/\d+}' }
|
28
|
+
# ]
|
29
|
+
# },
|
30
|
+
# }
|
31
|
+
# config.maintenance_status_by do
|
32
|
+
# [:users_all, :articles_write]
|
33
|
+
# end
|
34
|
+
# config.skip_by do |env|
|
35
|
+
# false
|
36
|
+
# end
|
37
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'ipaddress'
|
2
|
+
|
3
|
+
module Rack
|
4
|
+
module TrafficSignal
|
5
|
+
class Config
|
6
|
+
|
7
|
+
attr_reader :maintenance_group
|
8
|
+
attr_accessor :internal_ips,
|
9
|
+
:skip_paths,
|
10
|
+
:default_status,
|
11
|
+
:default_content_type,
|
12
|
+
:default_body
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@internal_ips = []
|
16
|
+
@maintenance_group = { }
|
17
|
+
@default_status = 503
|
18
|
+
@default_content_type = 'application/json'
|
19
|
+
@default_body = ''
|
20
|
+
@skip_paths = [/^\/assets/]
|
21
|
+
@maintenance_status_proc = ->{ [] }
|
22
|
+
@skip_proc = ->(env){ false }
|
23
|
+
@skip_with_warning_proc = ->(env){ false }
|
24
|
+
end
|
25
|
+
|
26
|
+
def maintenance_group=(mg)
|
27
|
+
raise Rack::TrafficSignal::Exceptions::InvalidMaintenanceGroup unless valid_maintenance_group?(mg)
|
28
|
+
@maintenance_group = mg
|
29
|
+
end
|
30
|
+
|
31
|
+
def maintenance_status_by(&block)
|
32
|
+
@maintenance_status_proc = block
|
33
|
+
end
|
34
|
+
|
35
|
+
def maintenance_status
|
36
|
+
@maintenance_status_proc.call.tap do |status|
|
37
|
+
raise Rack::TrafficSignal::Exceptions::InvalidMaintenanceStatus unless status.is_a? Array
|
38
|
+
raise Rack::TrafficSignal::Exceptions::InvalidMaintenanceStatus unless status.all? do |state|
|
39
|
+
state.is_a?(Symbol) && (state == :all || state.to_s =~ /\A[A-Za-z0-9]+_[A-Za-z0-9]+\z/)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def skip_by(&block)
|
45
|
+
@skip_proc = block
|
46
|
+
end
|
47
|
+
|
48
|
+
def skip?(env)
|
49
|
+
@skip_proc.call(env)
|
50
|
+
end
|
51
|
+
|
52
|
+
def skip_with_warning_by(&block)
|
53
|
+
@skip_with_warning_proc = block
|
54
|
+
end
|
55
|
+
|
56
|
+
def skip_with_warning?(env)
|
57
|
+
@skip_with_warning_proc.call(env)
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
def valid_maintenance_group?(mg)
|
62
|
+
return false unless mg.is_a? Hash
|
63
|
+
|
64
|
+
mg.values.each do |group|
|
65
|
+
return false unless group.is_a? Hash
|
66
|
+
group.values.each do |igroup|
|
67
|
+
return false unless igroup.is_a? Array
|
68
|
+
igroup.each do |setting|
|
69
|
+
return false unless setting.key?(:methods)
|
70
|
+
return false unless setting.key? :path
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
true
|
76
|
+
|
77
|
+
rescue
|
78
|
+
false
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Rack
|
4
|
+
module TrafficSignal
|
5
|
+
class Middleware
|
6
|
+
def initialize(app)
|
7
|
+
@app = app
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
return @app.call(env) if config.skip?(env)
|
12
|
+
method = env['REQUEST_METHOD'].downcase.to_sym
|
13
|
+
path = env['PATH_INFO']
|
14
|
+
path = path.chop if path != '/' && path[-1] == '/'
|
15
|
+
|
16
|
+
applied_config = maintenance_application(method, path)
|
17
|
+
|
18
|
+
if applied_config
|
19
|
+
if config.skip_with_warning?(env)
|
20
|
+
@app.call(env).tap do |status, headers, body|
|
21
|
+
headers['X-RACK-TRAFFIC-SIGNAL-MAINTENENCE'] = '1'
|
22
|
+
end
|
23
|
+
else
|
24
|
+
build_response(applied_config)
|
25
|
+
end
|
26
|
+
else
|
27
|
+
@app.call(env)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def build_response(applied_config)
|
34
|
+
status = applied_config[:status] ? applied_config[:status] : config.default_status
|
35
|
+
content_type = applied_config[:content_type] ? applied_config[:content_type] : config.default_content_type
|
36
|
+
body = applied_config[:body] ? applied_config[:body] : config.default_body
|
37
|
+
header = { "Content-Type" => content_type, 'Content-Length' => body.bytesize.to_s }
|
38
|
+
|
39
|
+
[status, header, [body]]
|
40
|
+
end
|
41
|
+
|
42
|
+
def config_appliable?(config, method, path)
|
43
|
+
path_match = if config[:path].is_a?(String)
|
44
|
+
path == config[:path]
|
45
|
+
elsif config[:path].is_a? Regexp
|
46
|
+
path.match(config[:path])
|
47
|
+
else
|
48
|
+
false
|
49
|
+
end
|
50
|
+
|
51
|
+
path_match && config[:methods].include?(method)
|
52
|
+
end
|
53
|
+
|
54
|
+
def path_length(path)
|
55
|
+
if path.is_a? String
|
56
|
+
path.split('/').length
|
57
|
+
elsif path.is_a? Regexp
|
58
|
+
path.source.split('/').length
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def maintenance_application(method, path)
|
63
|
+
enabled_maintenance_mode = config.maintenance_status
|
64
|
+
|
65
|
+
enabled_cfg = if enabled_maintenance_mode.include? :all
|
66
|
+
config.maintenance_group.values.inject([]) do |a, p|
|
67
|
+
a + p.values
|
68
|
+
end
|
69
|
+
else
|
70
|
+
enabled_maintenance_mode.inject([]) do |a, mode|
|
71
|
+
resource, action = *mode.to_s.split('_').map(&:to_sym)
|
72
|
+
if action == :all
|
73
|
+
a + config.maintenance_group[resource].values
|
74
|
+
else
|
75
|
+
a + config.maintenance_group[resource][action]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
enabled_cfg.flatten!
|
81
|
+
|
82
|
+
applied = enabled_cfg
|
83
|
+
.uniq
|
84
|
+
.select { |c| config_appliable?(c, method, path) }
|
85
|
+
.sort { |a, b| path_length(a[:path]) <=> path_length(b[:path]) }
|
86
|
+
if applied.length > 0
|
87
|
+
return applied[0]
|
88
|
+
else
|
89
|
+
return nil
|
90
|
+
end
|
91
|
+
rescue NoMethodError
|
92
|
+
raise Rack::TrafficSignal::Exceptions::InvalidMaintenanceGroup
|
93
|
+
end
|
94
|
+
|
95
|
+
def config
|
96
|
+
Rack::TrafficSignal.config
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'rack/traffic_signal/version'
|
2
|
+
require 'rack/traffic_signal/config'
|
3
|
+
require 'rack/traffic_signal/exceptions'
|
4
|
+
require 'rack/traffic_signal/middleware'
|
5
|
+
require 'rack/traffic_signal/railtie' if defined? Rails
|
6
|
+
|
7
|
+
module Rack
|
8
|
+
module TrafficSignal
|
9
|
+
def self.setup
|
10
|
+
yield(config)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.config
|
14
|
+
@config ||= Config.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.internal_access?(env)
|
18
|
+
remote_ip = IPAddress(request_from(env))
|
19
|
+
config.internal_ips
|
20
|
+
.map { |internal_ip| IPAddress(internal_ip) }
|
21
|
+
.any? { |internal_ip| internal_ip.include?(remote_ip) if remote_ip.class == internal_ip.class }
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.skip_path?(env)
|
25
|
+
path = env['PATH_INFO']
|
26
|
+
path = path.chop if path[-1] == '/'
|
27
|
+
config.skip_paths.any? do |skip_path|
|
28
|
+
if skip_path.is_a? Regexp
|
29
|
+
path.match(skip_path)
|
30
|
+
elsif skip_path.is_a? String
|
31
|
+
path == skip_path
|
32
|
+
else
|
33
|
+
false
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
def self.request_from(env)
|
40
|
+
return env['REMOTE_ADDR'] unless env['HTTP_X_FORWARDED_FOR']
|
41
|
+
env['HTTP_X_FORWARDED_FOR'].split(/,/)[0].strip
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'rack/traffic_signal'
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'rack/traffic_signal/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "rack-traffic-signal"
|
8
|
+
spec.version = Rack::TrafficSignal::VERSION
|
9
|
+
spec.authors = ["keigo yamamoto"]
|
10
|
+
spec.email = ["k5.trismegistus@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = 'Traffic signal of rack application'
|
13
|
+
spec.description = 'Make your app maintenance mode. You can prohibit all/a part of external access'
|
14
|
+
spec.homepage = "https://github.com/k5trismegistus/rack-traffic-signal"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
|
+
f.match(%r{^(test|spec|features)/})
|
19
|
+
end
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_dependency "ipaddress"
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.14"
|
24
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
25
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
26
|
+
spec.add_development_dependency "pry"
|
27
|
+
spec.add_development_dependency "rack-test"
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rack-traffic-signal
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- keigo yamamoto
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-07-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: ipaddress
|
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: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.14'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.14'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry
|
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: rack-test
|
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
|
+
description: Make your app maintenance mode. You can prohibit all/a part of external
|
98
|
+
access
|
99
|
+
email:
|
100
|
+
- k5.trismegistus@gmail.com
|
101
|
+
executables: []
|
102
|
+
extensions: []
|
103
|
+
extra_rdoc_files: []
|
104
|
+
files:
|
105
|
+
- ".gitignore"
|
106
|
+
- ".rspec"
|
107
|
+
- ".travis.yml"
|
108
|
+
- Gemfile
|
109
|
+
- LICENSE.txt
|
110
|
+
- README.md
|
111
|
+
- Rakefile
|
112
|
+
- lib/generators/rack_traffic_signal/install_generator.rb
|
113
|
+
- lib/generators/templates/503.html
|
114
|
+
- lib/generators/templates/initializer.rb
|
115
|
+
- lib/rack-traffic_signal.rb
|
116
|
+
- lib/rack/traffic_signal.rb
|
117
|
+
- lib/rack/traffic_signal/config.rb
|
118
|
+
- lib/rack/traffic_signal/exceptions.rb
|
119
|
+
- lib/rack/traffic_signal/middleware.rb
|
120
|
+
- lib/rack/traffic_signal/railtie.rb
|
121
|
+
- lib/rack/traffic_signal/version.rb
|
122
|
+
- rack-traffic-signal.gemspec
|
123
|
+
homepage: https://github.com/k5trismegistus/rack-traffic-signal
|
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
|
+
rubyforge_project:
|
143
|
+
rubygems_version: 2.4.5.1
|
144
|
+
signing_key:
|
145
|
+
specification_version: 4
|
146
|
+
summary: Traffic signal of rack application
|
147
|
+
test_files: []
|