api_proxy 0.1.3 → 0.2.3
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/Gemfile.lock +1 -1
- data/README.md +1 -5
- data/lib/api_proxy.rb +3 -2
- data/lib/api_proxy/config.rb +4 -8
- data/lib/api_proxy/headers_filter.rb +22 -0
- data/lib/api_proxy/middleware.rb +4 -13
- data/lib/api_proxy/response_builder.rb +56 -0
- data/lib/api_proxy/signed_request.rb +49 -0
- data/lib/api_proxy/version.rb +1 -1
- metadata +5 -4
- data/lib/api_proxy/request.rb +0 -40
- data/lib/api_proxy/request_options_builder.rb +0 -73
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1d1ac2a1d2b57c66377b1e28d0ae1ab5c0cceff203eae7d23f089df9f5a4b1e2
|
4
|
+
data.tar.gz: 5d03d9c8643879f8d145b63c5704f37e96e9e78564e3b74944edf7f74c9f650a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dfded3b838256acfa4ac94f12ff4d437992accc9fa0bae0248fe5891d366a810d91b585188ba3aeaeaaa58abb4982c97e1b33753fadc66466b71cbd75186d09d
|
7
|
+
data.tar.gz: '08ae6bbb9c9ee7c71929dca3a3b944bdf32ff972a91d379ed86e86f842bd075dd323294fe355eff22958c499e61ea44542fa56e35644aa77b83dcabb1163e559'
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -31,11 +31,7 @@ ApiProxy.configure(:my_namespace) do |config|
|
|
31
31
|
config.api_key = ENV['SERVICE_API_KEY']
|
32
32
|
config.api_secret = ENV['SERVICE_API_SECRET']
|
33
33
|
|
34
|
-
config.
|
35
|
-
config.api_host = 'localhost'
|
36
|
-
config.api_port = 3000
|
37
|
-
|
38
|
-
config.api_prefix = '/api/v1/'
|
34
|
+
config.api_url = 'http://localhost:3002/api/v1'
|
39
35
|
|
40
36
|
config.request_starts_with = '/_some_key'
|
41
37
|
end
|
data/lib/api_proxy.rb
CHANGED
@@ -8,8 +8,9 @@ require 'active_support/core_ext/module'
|
|
8
8
|
module ApiProxy
|
9
9
|
autoload :Config, 'api_proxy/config'
|
10
10
|
autoload :Middleware, 'api_proxy/middleware'
|
11
|
-
autoload :
|
12
|
-
autoload :
|
11
|
+
autoload :HeadersFilter, 'api_proxy/headers_filter'
|
12
|
+
autoload :SignedRequest, 'api_proxy/signed_request'
|
13
|
+
autoload :ResponseBuilder, 'api_proxy/response_builder'
|
13
14
|
|
14
15
|
def self.configuration(namespace)
|
15
16
|
@configuration ||= {}
|
data/lib/api_proxy/config.rb
CHANGED
@@ -4,10 +4,7 @@ module ApiProxy
|
|
4
4
|
class Config
|
5
5
|
attr_accessor :api_key,
|
6
6
|
:api_secret,
|
7
|
-
:
|
8
|
-
:api_host,
|
9
|
-
:api_port,
|
10
|
-
:api_prefix,
|
7
|
+
:api_url,
|
11
8
|
:request_starts_with,
|
12
9
|
:request_allowed,
|
13
10
|
:custom_headers,
|
@@ -17,15 +14,14 @@ module ApiProxy
|
|
17
14
|
load_defaults
|
18
15
|
end
|
19
16
|
|
17
|
+
private
|
18
|
+
|
20
19
|
def load_defaults
|
21
20
|
@api_key = 'key'
|
22
21
|
@api_secret = 'secret'
|
23
22
|
|
24
|
-
@
|
25
|
-
@api_host = 'localhost'
|
26
|
-
@api_port = 3000
|
23
|
+
@api_url = 'http://localhost:3000/api/v1'
|
27
24
|
|
28
|
-
@api_prefix = '/api/v1/'
|
29
25
|
@request_starts_with = '/_ts'
|
30
26
|
|
31
27
|
@request_allowed = ->(_env) { true }
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ApiProxy
|
4
|
+
class HeadersFilter
|
5
|
+
ALLOWED_HEADERS = [
|
6
|
+
'content-type',
|
7
|
+
'etag',
|
8
|
+
'cache-control',
|
9
|
+
'content-length',
|
10
|
+
'content-disposition',
|
11
|
+
'content-transfer-encoding'
|
12
|
+
].freeze
|
13
|
+
|
14
|
+
def initialize(headers)
|
15
|
+
@headers = headers
|
16
|
+
end
|
17
|
+
|
18
|
+
def filter
|
19
|
+
@headers.select { |key, _value| ALLOWED_HEADERS.include?(key) }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/api_proxy/middleware.rb
CHANGED
@@ -4,24 +4,15 @@ module ApiProxy
|
|
4
4
|
class Middleware
|
5
5
|
def initialize(app, namespace = :default)
|
6
6
|
@app = app
|
7
|
-
@
|
7
|
+
@namespace = namespace
|
8
8
|
end
|
9
9
|
|
10
10
|
def call(env)
|
11
|
-
|
11
|
+
builder = ApiProxy::ResponseBuilder.new(env, @namespace)
|
12
12
|
|
13
|
-
|
14
|
-
request = ApiProxy::Request.new(builder)
|
13
|
+
return @app.call(env) unless builder.allow_request?
|
15
14
|
|
16
|
-
response
|
17
|
-
|
18
|
-
Rack::Response.new(response.to_s, response.code, request.headers)
|
19
|
-
end
|
20
|
-
|
21
|
-
def allow_request?(env)
|
22
|
-
return false unless env['REQUEST_PATH'].start_with?(@config.request_starts_with)
|
23
|
-
|
24
|
-
@config.request_allowed.call(env)
|
15
|
+
builder.response
|
25
16
|
end
|
26
17
|
end
|
27
18
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rack'
|
4
|
+
|
5
|
+
module ApiProxy
|
6
|
+
class ResponseBuilder
|
7
|
+
attr_reader :env, :namespace, :config
|
8
|
+
|
9
|
+
def initialize(env, namespace = :default)
|
10
|
+
@env = env
|
11
|
+
@namespace = namespace
|
12
|
+
@config = ApiProxy.configuration(namespace)
|
13
|
+
end
|
14
|
+
|
15
|
+
def allow_request?
|
16
|
+
return false unless request.path.start_with?(config.request_starts_with)
|
17
|
+
|
18
|
+
config.request_allowed.call(@env)
|
19
|
+
end
|
20
|
+
|
21
|
+
def response
|
22
|
+
Rack::Response.new(
|
23
|
+
result.to_s,
|
24
|
+
result.code,
|
25
|
+
ApiProxy::HeadersFilter.new(result.headers).filter
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def request
|
32
|
+
@request ||= Rack::Request.new(@env)
|
33
|
+
end
|
34
|
+
|
35
|
+
def result
|
36
|
+
@result ||= ApiProxy::SignedRequest.new(request.request_method, url, options).perform
|
37
|
+
end
|
38
|
+
|
39
|
+
def url
|
40
|
+
path = request.path.gsub(config.request_starts_with, '')
|
41
|
+
File.join(config.api_url.to_s, path)
|
42
|
+
end
|
43
|
+
|
44
|
+
def options
|
45
|
+
{ namespace: namespace, body: filtered_params, headers: headers }
|
46
|
+
end
|
47
|
+
|
48
|
+
def filtered_params
|
49
|
+
request.params.reject { |key, _value| config.reject_params.include?(key.to_s) }
|
50
|
+
end
|
51
|
+
|
52
|
+
def headers
|
53
|
+
config.custom_headers.call(env)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'httparty'
|
4
|
+
require 'api_signature'
|
5
|
+
|
6
|
+
module ApiProxy
|
7
|
+
class SignedRequest
|
8
|
+
include ::HTTParty
|
9
|
+
|
10
|
+
attr_reader :request_method, :url, :options
|
11
|
+
|
12
|
+
def initialize(request_method, url, options = {})
|
13
|
+
@request_method = request_method.to_s.downcase
|
14
|
+
@url = URI.parse(url)
|
15
|
+
@options = options
|
16
|
+
end
|
17
|
+
|
18
|
+
def perform
|
19
|
+
self.class.send(request_method, url, headers: headers, body: body, format: :json)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def headers
|
25
|
+
(options[:headers] || {}).merge(signature_headers)
|
26
|
+
end
|
27
|
+
|
28
|
+
def body
|
29
|
+
options[:body]
|
30
|
+
end
|
31
|
+
|
32
|
+
def signature_headers
|
33
|
+
ApiSignature::Builder.new(signature_options).headers
|
34
|
+
end
|
35
|
+
|
36
|
+
def signature_options
|
37
|
+
{
|
38
|
+
access_key: config.api_key,
|
39
|
+
secret: config.api_secret,
|
40
|
+
request_method: request_method,
|
41
|
+
path: url.path
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
def config
|
46
|
+
ApiProxy.configuration(options[:namespace]) || :default
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/api_proxy/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: api_proxy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Igor Malinovskiy
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-08-
|
11
|
+
date: 2018-08-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -215,9 +215,10 @@ files:
|
|
215
215
|
- bin/setup
|
216
216
|
- lib/api_proxy.rb
|
217
217
|
- lib/api_proxy/config.rb
|
218
|
+
- lib/api_proxy/headers_filter.rb
|
218
219
|
- lib/api_proxy/middleware.rb
|
219
|
-
- lib/api_proxy/
|
220
|
-
- lib/api_proxy/
|
220
|
+
- lib/api_proxy/response_builder.rb
|
221
|
+
- lib/api_proxy/signed_request.rb
|
221
222
|
- lib/api_proxy/version.rb
|
222
223
|
homepage: https://github.com/psyipm/api_proxy
|
223
224
|
licenses:
|
data/lib/api_proxy/request.rb
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'httparty'
|
4
|
-
|
5
|
-
module ApiProxy
|
6
|
-
class Request
|
7
|
-
include ::HTTParty
|
8
|
-
|
9
|
-
attr_reader :builder
|
10
|
-
|
11
|
-
delegate :url, :options, :request_method, to: :builder
|
12
|
-
|
13
|
-
ALLOWED_HEADERS = [
|
14
|
-
'content-type',
|
15
|
-
'etag',
|
16
|
-
'cache-control',
|
17
|
-
'content-length',
|
18
|
-
'content-disposition',
|
19
|
-
'content-transfer-encoding'
|
20
|
-
].freeze
|
21
|
-
|
22
|
-
def initialize(request_options_builder)
|
23
|
-
@builder = request_options_builder
|
24
|
-
end
|
25
|
-
|
26
|
-
def result
|
27
|
-
@result ||= perform_request
|
28
|
-
end
|
29
|
-
|
30
|
-
def headers
|
31
|
-
result.headers.select { |key, _value| ALLOWED_HEADERS.include?(key) }
|
32
|
-
end
|
33
|
-
|
34
|
-
private
|
35
|
-
|
36
|
-
def perform_request
|
37
|
-
self.class.send(request_method, url, options)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
@@ -1,73 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'api_signature'
|
4
|
-
require 'rack'
|
5
|
-
|
6
|
-
module ApiProxy
|
7
|
-
class RequestOptionsBuilder
|
8
|
-
attr_reader :env, :config
|
9
|
-
|
10
|
-
delegate :api_key,
|
11
|
-
:api_secret,
|
12
|
-
:api_host,
|
13
|
-
:api_port,
|
14
|
-
:api_prefix,
|
15
|
-
:url_scheme,
|
16
|
-
:request_starts_with, to: :config
|
17
|
-
|
18
|
-
def initialize(env, config)
|
19
|
-
@env = env
|
20
|
-
@config = config
|
21
|
-
end
|
22
|
-
|
23
|
-
def options
|
24
|
-
{ headers: headers, body: body, format: :json }
|
25
|
-
end
|
26
|
-
|
27
|
-
def url
|
28
|
-
URI::Generic.build(scheme: url_scheme, host: api_host, port: api_port, path: path)
|
29
|
-
end
|
30
|
-
|
31
|
-
def request_method
|
32
|
-
request.request_method.downcase
|
33
|
-
end
|
34
|
-
|
35
|
-
private
|
36
|
-
|
37
|
-
def body
|
38
|
-
request.params.reject { |key, _value| config.reject_params.include?(key) }
|
39
|
-
end
|
40
|
-
|
41
|
-
def request
|
42
|
-
@request ||= Rack::Request.new(env)
|
43
|
-
end
|
44
|
-
|
45
|
-
def headers
|
46
|
-
custom_headers = config.custom_headers.call(env)
|
47
|
-
|
48
|
-
signature_builder.headers.merge(custom_headers)
|
49
|
-
end
|
50
|
-
|
51
|
-
def signature_builder
|
52
|
-
@signature_builder ||= ApiSignature::Builder.new(request_params)
|
53
|
-
end
|
54
|
-
|
55
|
-
def request_params
|
56
|
-
{
|
57
|
-
access_key: api_key,
|
58
|
-
secret: api_secret,
|
59
|
-
request_method: request_method,
|
60
|
-
scheme: url_scheme,
|
61
|
-
host: api_host,
|
62
|
-
port: api_port,
|
63
|
-
path: path
|
64
|
-
}
|
65
|
-
end
|
66
|
-
|
67
|
-
def path
|
68
|
-
request_path = request.path.gsub(request_starts_with, '')
|
69
|
-
|
70
|
-
File.join(api_prefix, request_path)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|