api_valve 0.6.0 → 0.6.1
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/api_valve.rb +3 -6
- data/lib/api_valve/middleware.rb +43 -0
- data/lib/api_valve/middleware/error_handling.rb +15 -17
- data/lib/api_valve/middleware/logging.rb +1 -1
- data/lib/api_valve/middleware/router.rb +15 -0
- data/lib/api_valve/proxy.rb +16 -13
- data/lib/api_valve/{router.rb → route_set.rb} +15 -18
- data/lib/api_valve/runner.rb +9 -0
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8f4cba9301dc5313a548d0d0be717b8bbc0af686c5da846bac838547e08dd8e3
|
4
|
+
data.tar.gz: 42d48117b5969d38f5125bfa4fbbde0633fbde1214b738de1efd607007cbb978
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 537cfb673ad5a8eeb6ec9f0871a0a85d6b61206326e0c9f0f4731414f341f60c45b595feab392f86ab4ea00c64819f83c3b7b98c2650a40e318e22bf1e812a64
|
7
|
+
data.tar.gz: f7e6538270b6d444c1bdf4b1fe06f9d86864c61ca1d9738201d21f9eb06c6349888e4141756ef5db7afdc63a9c427985a64d8d7c306d783d9740ad04d8934743
|
data/lib/api_valve.rb
CHANGED
@@ -17,17 +17,14 @@ module ApiValve
|
|
17
17
|
autoload :Error, 'api_valve/error'
|
18
18
|
autoload :ErrorResponder, 'api_valve/error_responder'
|
19
19
|
autoload :Forwarder, 'api_valve/forwarder'
|
20
|
+
autoload :Middleware, 'api_valve/middleware'
|
20
21
|
autoload :Logger, 'api_valve/logger'
|
21
22
|
autoload :Proxy, 'api_valve/proxy'
|
22
|
-
autoload :
|
23
|
+
autoload :RouteSet, 'api_valve/route_set'
|
24
|
+
autoload :Runner, 'api_valve/runner'
|
23
25
|
|
24
26
|
include ActiveSupport::Configurable
|
25
27
|
|
26
|
-
module Middleware
|
27
|
-
autoload :ErrorHandling, 'api_valve/middleware/error_handling'
|
28
|
-
autoload :Logging, 'api_valve/middleware/logging'
|
29
|
-
end
|
30
|
-
|
31
28
|
config_accessor :logger do
|
32
29
|
Logger.new(STDOUT)
|
33
30
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module ApiValve
|
2
|
+
class Middleware
|
3
|
+
autoload :ErrorHandling, 'api_valve/middleware/error_handling'
|
4
|
+
autoload :Logging, 'api_valve/middleware/logging'
|
5
|
+
autoload :Router, 'api_valve/middleware/router'
|
6
|
+
|
7
|
+
Item = Struct.new(:klass, :proc)
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@registry = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def insert_after(other, middleware, *args, &block)
|
14
|
+
@registry.insert position(other) + 1, to_item(middleware, *args, &block)
|
15
|
+
end
|
16
|
+
|
17
|
+
def insert_before(other, middleware, *args, &block)
|
18
|
+
@registry.insert position(other), to_item(middleware, *args, &block)
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_app(root_app)
|
22
|
+
@registry.reverse.inject(root_app) { |memo, obj| obj.proc.call memo }
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_s
|
26
|
+
@registry.map(&:klass).join("\n")
|
27
|
+
end
|
28
|
+
|
29
|
+
def use(middleware, *args, &block)
|
30
|
+
@registry << to_item(middleware, *args, &block)
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def position(klass)
|
36
|
+
@registry.index { |item| item.klass == klass }
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_item(middleware, *args, &block)
|
40
|
+
Item.new(middleware, proc { |app| middleware.new(app, *args, &block) })
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -1,23 +1,21 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
end
|
1
|
+
class ApiValve::Middleware
|
2
|
+
class ErrorHandling
|
3
|
+
def initialize(app)
|
4
|
+
@app = app
|
5
|
+
end
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
7
|
+
def call(env)
|
8
|
+
@app.call(env)
|
9
|
+
rescue Exception => e # rubocop:disable Lint/RescueException
|
10
|
+
log_error e
|
11
|
+
self.class.const_get(ApiValve.error_responder).new(e).call
|
12
|
+
end
|
14
13
|
|
15
|
-
|
14
|
+
private
|
16
15
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end
|
16
|
+
def log_error(error)
|
17
|
+
ApiValve.logger.error { "#{error.class}: #{error.message}" }
|
18
|
+
ApiValve.logger.error { error.backtrace.join("\n") }
|
21
19
|
end
|
22
20
|
end
|
23
21
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class ApiValve::Middleware
|
2
|
+
class Router
|
3
|
+
def initialize(app, routeset)
|
4
|
+
@app = app
|
5
|
+
@routeset = routeset
|
6
|
+
end
|
7
|
+
|
8
|
+
def call(env)
|
9
|
+
route, match_data = @routeset.match env
|
10
|
+
env['api_valve.router.route'] = route
|
11
|
+
env['api_valve.router.match_data'] = match_data
|
12
|
+
@app.call(env)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/api_valve/proxy.rb
CHANGED
@@ -64,22 +64,25 @@ module ApiValve
|
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
67
|
-
attr_reader :request, :forwarder, :
|
67
|
+
attr_reader :request, :forwarder, :middleware, :route_set
|
68
|
+
|
69
|
+
alias router route_set
|
68
70
|
|
69
71
|
def initialize(forwarder)
|
70
72
|
@forwarder = forwarder
|
71
|
-
@
|
72
|
-
@
|
73
|
+
@route_set = RouteSet.new
|
74
|
+
@middleware = Middleware.new
|
75
|
+
use Middleware::Router, route_set
|
73
76
|
end
|
74
77
|
|
75
78
|
def call(env)
|
76
|
-
|
77
|
-
stack.call(env)
|
79
|
+
to_app.call(env)
|
78
80
|
rescue ApiValve::Error::Client, ApiValve::Error::Server => e
|
79
81
|
render_error e
|
80
82
|
end
|
81
83
|
|
82
|
-
delegate :add_route, to: :
|
84
|
+
delegate :add_route, to: :route_set
|
85
|
+
delegate :use, to: :middleware
|
83
86
|
|
84
87
|
def build_routes_from_config(routes_config)
|
85
88
|
return forward_all unless routes_config
|
@@ -97,32 +100,32 @@ module ApiValve
|
|
97
100
|
|
98
101
|
def forward(methods, path_regexp = nil, request_override = {})
|
99
102
|
Array.wrap(methods).each do |method|
|
100
|
-
|
103
|
+
route_set.public_send(method, path_regexp, proc { |request, match_data|
|
101
104
|
forwarder.call request, {'match_data' => match_data}.merge(request_override || {})
|
102
105
|
})
|
103
106
|
end
|
104
107
|
end
|
105
108
|
|
106
109
|
def forward_all
|
107
|
-
|
110
|
+
route_set.any do |request, match_data|
|
108
111
|
forwarder.call request, 'match_data' => match_data
|
109
112
|
end
|
110
113
|
end
|
111
114
|
|
112
115
|
def deny(methods, path_regexp = nil, with: 'Error::Forbidden')
|
113
116
|
Array.wrap(methods).each do |method|
|
114
|
-
|
117
|
+
route_set.public_send(method, path_regexp, ->(*_args) { raise ApiValve.const_get(with) })
|
115
118
|
end
|
116
119
|
end
|
117
120
|
|
118
|
-
def use(middleware, *args, &block)
|
119
|
-
@middlewares << proc { |app| middleware.new(app, *args, &block) }
|
120
|
-
end
|
121
|
-
|
122
121
|
protected
|
123
122
|
|
124
123
|
def render_error(error)
|
125
124
|
self.class.const_get(ApiValve.error_responder).new(error).call
|
126
125
|
end
|
126
|
+
|
127
|
+
def to_app
|
128
|
+
@to_app ||= @middleware.to_app(Runner.new)
|
129
|
+
end
|
127
130
|
end
|
128
131
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module ApiValve
|
2
|
-
class
|
2
|
+
class RouteSet
|
3
3
|
METHODS = %i(get post put patch delete head).freeze
|
4
4
|
|
5
5
|
Route = Struct.new(:regexp, :block) do
|
@@ -16,8 +16,20 @@ module ApiValve
|
|
16
16
|
reset_routes
|
17
17
|
end
|
18
18
|
|
19
|
-
def
|
20
|
-
|
19
|
+
def match(env)
|
20
|
+
request = Rack::Request.new(env)
|
21
|
+
|
22
|
+
# For security reasons do not allow URLs that could break out of the proxy namespace on the
|
23
|
+
# server. Preferably an nxing/apache rewrite will kill these URLs before they hit us
|
24
|
+
raise 'URL not supported' if request.path_info.include?('/../')
|
25
|
+
|
26
|
+
match_data = nil
|
27
|
+
route = @routes && @routes[request.request_method.downcase.to_sym].find do |r|
|
28
|
+
(match_data = r.match(request.path_info))
|
29
|
+
end
|
30
|
+
raise Error::NotRouted, 'Endpoint not found' unless route
|
31
|
+
|
32
|
+
[route, match_data]
|
21
33
|
end
|
22
34
|
|
23
35
|
def delete(path = nil, prok = nil)
|
@@ -65,20 +77,5 @@ module ApiValve
|
|
65
77
|
def reset_routes
|
66
78
|
@routes = Hash[METHODS.map { |v| [v, []] }].freeze
|
67
79
|
end
|
68
|
-
|
69
|
-
private
|
70
|
-
|
71
|
-
def match(request)
|
72
|
-
# For security reasons do not allow URLs that could break out of the proxy namespace on the
|
73
|
-
# server. Preferably an nxing/apache rewrite will kill these URLs before they hit us
|
74
|
-
raise 'URL not supported' if request.path_info.include?('/../')
|
75
|
-
|
76
|
-
@routes && @routes[request.request_method.downcase.to_sym].each do |route|
|
77
|
-
if (match_data = route.match(request.path_info))
|
78
|
-
return route.call request, match_data
|
79
|
-
end
|
80
|
-
end
|
81
|
-
raise Error::NotRouted, 'Endpoint not found'
|
82
|
-
end
|
83
80
|
end
|
84
81
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: api_valve
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- mkon
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-12-
|
11
|
+
date: 2018-12-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -202,10 +202,13 @@ files:
|
|
202
202
|
- lib/api_valve/forwarder/request.rb
|
203
203
|
- lib/api_valve/forwarder/response.rb
|
204
204
|
- lib/api_valve/logger.rb
|
205
|
+
- lib/api_valve/middleware.rb
|
205
206
|
- lib/api_valve/middleware/error_handling.rb
|
206
207
|
- lib/api_valve/middleware/logging.rb
|
208
|
+
- lib/api_valve/middleware/router.rb
|
207
209
|
- lib/api_valve/proxy.rb
|
208
|
-
- lib/api_valve/
|
210
|
+
- lib/api_valve/route_set.rb
|
211
|
+
- lib/api_valve/runner.rb
|
209
212
|
homepage: https://github.com/mkon/api_valve
|
210
213
|
licenses:
|
211
214
|
- MIT
|