api_valve 0.6.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2fdf08e3fa15d2bb46dc6f85ee53c681b696d574585b6be1e11dc7fc6b6527b1
4
- data.tar.gz: 3cf720502939fe562d385a7347e681927e79519446111410f6ba8c8f1ad7fb52
3
+ metadata.gz: 8f4cba9301dc5313a548d0d0be717b8bbc0af686c5da846bac838547e08dd8e3
4
+ data.tar.gz: 42d48117b5969d38f5125bfa4fbbde0633fbde1214b738de1efd607007cbb978
5
5
  SHA512:
6
- metadata.gz: 7e635bcd48b26f59cb92cd46551eb2b4de46fc23765a80c826c7f65993f52dfd232dceb4538586026c73a7d538a591aec96ffd681362c4f5ce1a3d9fbcf944a9
7
- data.tar.gz: 2543e426f0b25a9a3b0c1970f3e4dfc81e9d01ccc6147888438d28bff60dca3c9768f98b9e98c4aaf49b090206df93616632a1f559e0454511b8dd83e9953fe7
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 :Router, 'api_valve/router'
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
- module ApiValve
2
- module Middleware
3
- class ErrorHandling
4
- def initialize(app)
5
- @app = app
6
- end
1
+ class ApiValve::Middleware
2
+ class ErrorHandling
3
+ def initialize(app)
4
+ @app = app
5
+ end
7
6
 
8
- def call(env)
9
- @app.call(env)
10
- rescue Exception => e # rubocop:disable Lint/RescueException
11
- log_error e
12
- self.class.const_get(ApiValve.error_responder).new(e).call
13
- end
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
- private
14
+ private
16
15
 
17
- def log_error(error)
18
- ApiValve.logger.error { "#{error.class}: #{error.message}" }
19
- ApiValve.logger.error { error.backtrace.join("\n") }
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
@@ -1,4 +1,4 @@
1
- module ApiValve::Middleware
1
+ class ApiValve::Middleware
2
2
  class Logging
3
3
  include ActiveSupport::Configurable
4
4
 
@@ -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
@@ -64,22 +64,25 @@ module ApiValve
64
64
  end
65
65
  end
66
66
 
67
- attr_reader :request, :forwarder, :router
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
- @router = Router.new
72
- @middlewares = []
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
- stack = @middlewares.reverse.inject(@router) { |a, e| e.call a }
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: :router
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
- router.public_send(method, path_regexp, proc { |request, match_data|
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
- router.any do |request, match_data|
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
- router.public_send(method, path_regexp, ->(*_args) { raise ApiValve.const_get(with) })
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 Router
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 call(env)
20
- match Rack::Request.new(env)
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
@@ -0,0 +1,9 @@
1
+ module ApiValve
2
+ class Runner
3
+ def call(env)
4
+ env['api_valve.router.route'].call \
5
+ Rack::Request.new(env),
6
+ env['api_valve.router.match_data']
7
+ end
8
+ end
9
+ 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.0
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-14 00:00:00.000000000 Z
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/router.rb
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