api_valve 0.2.0 → 0.3.0
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/cascade.rb +22 -0
- data/lib/api_valve/error.rb +20 -6
- data/lib/api_valve/error_responder.rb +13 -6
- data/lib/api_valve/forwarder/permission_handler.rb +4 -1
- data/lib/api_valve/forwarder/request.rb +2 -2
- data/lib/api_valve/forwarder.rb +1 -1
- data/lib/api_valve/middleware/error_handling.rb +1 -1
- data/lib/api_valve/middleware/logging.rb +4 -15
- data/lib/api_valve/proxy.rb +9 -3
- data/lib/api_valve/router.rb +1 -1
- data/lib/api_valve.rb +5 -0
- metadata +20 -5
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 3082a9e6ce31e0044de55d718dc95764b9a7bd966b26f2eac1a219b687b1dc90
         | 
| 4 | 
            +
              data.tar.gz: df5e9392bafe22aa847b603b392ea6d386b4736e9af1fcb991a3a5c3989253e5
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 92fcfc205c9da56bc4a565ede28e87cbf4dd0eb5a5f9a0a705e20d3d74699b32015222930bd028dbe592818a03e6988b34d80a4798601a127dd0a2373883a7ed
         | 
| 7 | 
            +
              data.tar.gz: 35402f30d4d8ad53792c77d5cc86893e489bdcf5717dc28b7b6dcee1e09a247aad58d4a939e88d13fbdcaaa82bf7845b81808bbfde9932d71d09eb7c41df142c
         | 
| @@ -0,0 +1,22 @@ | |
| 1 | 
            +
            module ApiValve
         | 
| 2 | 
            +
              class Cascade
         | 
| 3 | 
            +
                def initialize(*proxies)
         | 
| 4 | 
            +
                  @proxies = proxies
         | 
| 5 | 
            +
                end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                def call(env)
         | 
| 8 | 
            +
                  @proxies.each do |proxy|
         | 
| 9 | 
            +
                    return proxy.call env
         | 
| 10 | 
            +
                  rescue Error::NotRouted
         | 
| 11 | 
            +
                    next
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
                  render_error Error::NotFound.new
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                protected
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                def render_error(error)
         | 
| 19 | 
            +
                  self.class.const_get(ApiValve.error_responder).new(error).call
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
            end
         | 
    
        data/lib/api_valve/error.rb
    CHANGED
    
    | @@ -1,13 +1,27 @@ | |
| 1 1 | 
             
            module ApiValve
         | 
| 2 | 
            -
               | 
| 3 | 
            -
                 | 
| 4 | 
            -
             | 
| 5 | 
            -
             | 
| 2 | 
            +
              class Error < RuntimeError
         | 
| 3 | 
            +
                class_attribute :http_status, :code, :title, :default_message
         | 
| 4 | 
            +
                self.http_status = :server_error
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                Client = Class.new(self)
         | 
| 7 | 
            +
                Server = Class.new(self)
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                def initialize(*args)
         | 
| 10 | 
            +
                  @options = args.extract_options!
         | 
| 11 | 
            +
                  super(args.first || default_message)
         | 
| 6 12 | 
             
                end
         | 
| 7 13 |  | 
| 8 14 | 
             
                Rack::Utils::SYMBOL_TO_STATUS_CODE.each do |sym, code|
         | 
| 9 | 
            -
                   | 
| 10 | 
            -
                   | 
| 15 | 
            +
                  case code
         | 
| 16 | 
            +
                  when 400..499
         | 
| 17 | 
            +
                    const_set sym.to_s.camelize, Class.new(Client) { self.http_status = sym }
         | 
| 18 | 
            +
                  when 500..599
         | 
| 19 | 
            +
                    const_set sym.to_s.camelize, Class.new(Server) { self.http_status = sym }
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                NotRouted = Class.new(self) do
         | 
| 24 | 
            +
                  self.http_status = 404
         | 
| 11 25 | 
             
                end
         | 
| 12 26 | 
             
              end
         | 
| 13 27 | 
             
            end
         | 
| @@ -7,7 +7,7 @@ module ApiValve | |
| 7 7 | 
             
                def call
         | 
| 8 8 | 
             
                  [
         | 
| 9 9 | 
             
                    status,
         | 
| 10 | 
            -
                    {'Content-Type' => 'application/json'},
         | 
| 10 | 
            +
                    {'Content-Type' => 'application/vnd.api+json'},
         | 
| 11 11 | 
             
                    [MultiJson.dump({errors: [json_error]}, mode: :compat)]
         | 
| 12 12 | 
             
                  ]
         | 
| 13 13 | 
             
                end
         | 
| @@ -22,19 +22,26 @@ module ApiValve | |
| 22 22 |  | 
| 23 23 | 
             
                def json_error
         | 
| 24 24 | 
             
                  {
         | 
| 25 | 
            -
                    status: status,
         | 
| 26 | 
            -
                    code: | 
| 25 | 
            +
                    status: status.to_s,
         | 
| 26 | 
            +
                    code:   json_code,
         | 
| 27 | 
            +
                    title:  json_title,
         | 
| 27 28 | 
             
                    detail: json_detail,
         | 
| 28 | 
            -
                    meta: | 
| 29 | 
            +
                    meta:   json_meta
         | 
| 29 30 | 
             
                  }.compact
         | 
| 30 31 | 
             
                end
         | 
| 31 32 |  | 
| 32 33 | 
             
                def json_code
         | 
| 33 | 
            -
                  @error.try(:code) ||  | 
| 34 | 
            +
                  @error.try(:code) || @error.class.name.demodulize.underscore
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                def json_title
         | 
| 38 | 
            +
                  @error.try(:title) || Rack::Utils::HTTP_STATUS_CODES[status]
         | 
| 34 39 | 
             
                end
         | 
| 35 40 |  | 
| 36 41 | 
             
                def json_detail
         | 
| 37 | 
            -
                   | 
| 42 | 
            +
                  return if json_title == @error.message
         | 
| 43 | 
            +
                  return if @error.message == @error.class.name
         | 
| 44 | 
            +
                  @error.message
         | 
| 38 45 | 
             
                end
         | 
| 39 46 |  | 
| 40 47 | 
             
                def json_meta
         | 
| @@ -4,6 +4,8 @@ module ApiValve | |
| 4 4 | 
             
              # attributes that can be read or written.
         | 
| 5 5 |  | 
| 6 6 | 
             
              class Forwarder::PermissionHandler
         | 
| 7 | 
            +
                InsufficientPermissions = Class.new(Error::Forbidden)
         | 
| 8 | 
            +
             | 
| 7 9 | 
             
                module RequestIntegration
         | 
| 8 10 | 
             
                  private
         | 
| 9 11 |  | 
| @@ -33,7 +35,8 @@ module ApiValve | |
| 33 35 |  | 
| 34 36 | 
             
                # Tells the request class if the request is allowed
         | 
| 35 37 | 
             
                # Simple implementation is always true. Override in your implementation.
         | 
| 36 | 
            -
                 | 
| 38 | 
            +
                # Should raise InsufficientPermissions when not allowed
         | 
| 39 | 
            +
                def check_permissions!
         | 
| 37 40 | 
             
                  true
         | 
| 38 41 | 
             
                end
         | 
| 39 42 | 
             
              end
         | 
| @@ -26,8 +26,8 @@ module ApiValve | |
| 26 26 | 
             
                end
         | 
| 27 27 |  | 
| 28 28 | 
             
                # Is the request allowed? If it returns false, Forwarder will raise Error::Forbidden
         | 
| 29 | 
            -
                def  | 
| 30 | 
            -
                  permission_handler. | 
| 29 | 
            +
                def check_permissions!
         | 
| 30 | 
            +
                  permission_handler.check_permissions!
         | 
| 31 31 | 
             
                end
         | 
| 32 32 |  | 
| 33 33 | 
             
                # HTTP method to use when forwarding. Must return sym.
         | 
    
        data/lib/api_valve/forwarder.rb
    CHANGED
    
    | @@ -24,7 +24,7 @@ module ApiValve | |
| 24 24 | 
             
                # request and response.
         | 
| 25 25 | 
             
                def call(original_request, local_options = {})
         | 
| 26 26 | 
             
                  request = request_klass.new(original_request, request_options.deep_merge(local_options))
         | 
| 27 | 
            -
                   | 
| 27 | 
            +
                  request.check_permissions!
         | 
| 28 28 | 
             
                  response_klass.new(
         | 
| 29 29 | 
             
                    original_request,
         | 
| 30 30 | 
             
                    run_request(request),
         | 
| @@ -91,21 +91,10 @@ module ApiValve::Middleware | |
| 91 91 | 
             
                  end
         | 
| 92 92 | 
             
                end
         | 
| 93 93 |  | 
| 94 | 
            -
                config_accessor | 
| 95 | 
            -
             | 
| 96 | 
            -
                 | 
| 97 | 
            -
             | 
| 98 | 
            -
                config_accessor :log_request_body do
         | 
| 99 | 
            -
                  false
         | 
| 100 | 
            -
                end
         | 
| 101 | 
            -
             | 
| 102 | 
            -
                config_accessor :log_response_headers do
         | 
| 103 | 
            -
                  false
         | 
| 104 | 
            -
                end
         | 
| 105 | 
            -
             | 
| 106 | 
            -
                config_accessor :log_response_body do
         | 
| 107 | 
            -
                  false
         | 
| 108 | 
            -
                end
         | 
| 94 | 
            +
                config_accessor(:log_request_headers) { false }
         | 
| 95 | 
            +
                config_accessor(:log_request_body) { false }
         | 
| 96 | 
            +
                config_accessor(:log_response_headers) { false }
         | 
| 97 | 
            +
                config_accessor(:log_response_body) { false }
         | 
| 109 98 |  | 
| 110 99 | 
             
                def initialize(app)
         | 
| 111 100 | 
             
                  @app = app
         | 
    
        data/lib/api_valve/proxy.rb
    CHANGED
    
    | @@ -62,8 +62,8 @@ module ApiValve | |
| 62 62 | 
             
                def call(env)
         | 
| 63 63 | 
             
                  @request = Rack::Request.new(env)
         | 
| 64 64 | 
             
                  run_callbacks(:call) { @router.call(@request) }
         | 
| 65 | 
            -
                rescue ApiValve::Error:: | 
| 66 | 
            -
                   | 
| 65 | 
            +
                rescue ApiValve::Error::Client, ApiValve::Error::Server => e
         | 
| 66 | 
            +
                  render_error e
         | 
| 67 67 | 
             
                end
         | 
| 68 68 |  | 
| 69 69 | 
             
                delegate :add_route, to: :router
         | 
| @@ -78,7 +78,7 @@ module ApiValve | |
| 78 78 | 
             
                      forward method, path_regexp, request_override
         | 
| 79 79 | 
             
                    end
         | 
| 80 80 | 
             
                  end
         | 
| 81 | 
            -
                  forward_all
         | 
| 81 | 
            +
                  forward_all unless config['routes']
         | 
| 82 82 | 
             
                end
         | 
| 83 83 |  | 
| 84 84 | 
             
                def forward(methods, path_regexp = nil, request_override = {})
         | 
| @@ -100,5 +100,11 @@ module ApiValve | |
| 100 100 | 
             
                    router.public_send(method, path_regexp, ->(*_args) { raise ApiValve.const_get(with) })
         | 
| 101 101 | 
             
                  end
         | 
| 102 102 | 
             
                end
         | 
| 103 | 
            +
             | 
| 104 | 
            +
                protected
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                def render_error(error)
         | 
| 107 | 
            +
                  self.class.const_get(ApiValve.error_responder).new(error).call
         | 
| 108 | 
            +
                end
         | 
| 103 109 | 
             
              end
         | 
| 104 110 | 
             
            end
         | 
    
        data/lib/api_valve/router.rb
    CHANGED
    
    
    
        data/lib/api_valve.rb
    CHANGED
    
    | @@ -13,6 +13,7 @@ require 'logger' | |
| 13 13 |  | 
| 14 14 | 
             
            module ApiValve
         | 
| 15 15 | 
             
              autoload :Benchmarking,   'api_valve/benchmarking'
         | 
| 16 | 
            +
              autoload :Cascade,        'api_valve/cascade'
         | 
| 16 17 | 
             
              autoload :Error,          'api_valve/error'
         | 
| 17 18 | 
             
              autoload :ErrorResponder, 'api_valve/error_responder'
         | 
| 18 19 | 
             
              autoload :Forwarder,      'api_valve/forwarder'
         | 
| @@ -31,6 +32,10 @@ module ApiValve | |
| 31 32 | 
             
                Logger.new(STDOUT)
         | 
| 32 33 | 
             
              end
         | 
| 33 34 |  | 
| 35 | 
            +
              config_accessor :error_responder do
         | 
| 36 | 
            +
                'ApiValve::ErrorResponder'
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
             | 
| 34 39 | 
             
              config_accessor :expose_backtraces do
         | 
| 35 40 | 
             
                false
         | 
| 36 41 | 
             
              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. | 
| 4 | 
            +
              version: 0.3.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - mkon
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2018- | 
| 11 | 
            +
            date: 2018-09-15 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: activesupport
         | 
| @@ -72,6 +72,20 @@ dependencies: | |
| 72 72 | 
             
                - - "~>"
         | 
| 73 73 | 
             
                  - !ruby/object:Gem::Version
         | 
| 74 74 | 
             
                    version: '2'
         | 
| 75 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 76 | 
            +
              name: json_spec
         | 
| 77 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 78 | 
            +
                requirements:
         | 
| 79 | 
            +
                - - "~>"
         | 
| 80 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 81 | 
            +
                    version: '1.1'
         | 
| 82 | 
            +
              type: :development
         | 
| 83 | 
            +
              prerelease: false
         | 
| 84 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 85 | 
            +
                requirements:
         | 
| 86 | 
            +
                - - "~>"
         | 
| 87 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 88 | 
            +
                    version: '1.1'
         | 
| 75 89 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 76 90 | 
             
              name: rack-test
         | 
| 77 91 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -106,14 +120,14 @@ dependencies: | |
| 106 120 | 
             
                requirements:
         | 
| 107 121 | 
             
                - - '='
         | 
| 108 122 | 
             
                  - !ruby/object:Gem::Version
         | 
| 109 | 
            -
                    version: 0. | 
| 123 | 
            +
                    version: 0.58.2
         | 
| 110 124 | 
             
              type: :development
         | 
| 111 125 | 
             
              prerelease: false
         | 
| 112 126 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 113 127 | 
             
                requirements:
         | 
| 114 128 | 
             
                - - '='
         | 
| 115 129 | 
             
                  - !ruby/object:Gem::Version
         | 
| 116 | 
            -
                    version: 0. | 
| 130 | 
            +
                    version: 0.58.2
         | 
| 117 131 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 118 132 | 
             
              name: rubocop-rspec
         | 
| 119 133 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -180,6 +194,7 @@ files: | |
| 180 194 | 
             
            - README.md
         | 
| 181 195 | 
             
            - lib/api_valve.rb
         | 
| 182 196 | 
             
            - lib/api_valve/benchmarking.rb
         | 
| 197 | 
            +
            - lib/api_valve/cascade.rb
         | 
| 183 198 | 
             
            - lib/api_valve/error.rb
         | 
| 184 199 | 
             
            - lib/api_valve/error_responder.rb
         | 
| 185 200 | 
             
            - lib/api_valve/forwarder.rb
         | 
| @@ -211,7 +226,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 211 226 | 
             
                  version: '0'
         | 
| 212 227 | 
             
            requirements: []
         | 
| 213 228 | 
             
            rubyforge_project: 
         | 
| 214 | 
            -
            rubygems_version: 2.7. | 
| 229 | 
            +
            rubygems_version: 2.7.7
         | 
| 215 230 | 
             
            signing_key: 
         | 
| 216 231 | 
             
            specification_version: 4
         | 
| 217 232 | 
             
            summary: Lightweight ruby/rack API reverse proxy or gateway
         |