api_valve 0.1.1 → 0.2.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/README.md +3 -3
- data/lib/api_valve/forwarder/request.rb +18 -6
- data/lib/api_valve/forwarder/response.rb +10 -1
- data/lib/api_valve/forwarder.rb +12 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4c5ecd7703186bfbcd52c8b50d3a643a5c2af56043e92f00e56b8b1863c38fb7
|
4
|
+
data.tar.gz: 95263987cdf177ce4703955572e28f4540a3c32f47fb7b519fd0233b79506160
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a43f1ff0ea8e795a1676bd918b9d849d2404a14793f6ccf93adac8b70c3aa672729822a1e6d516f38201ae3505023e3d0adc46c0a4257497c6c5aaa577bc97fe
|
7
|
+
data.tar.gz: 2db871a83ee2dc02b2639ba0e6c19a795f765e24421ef0aacc8ec2f4adbefd2b682d7746cb8c99cd0e976d5afe89af70abb87cb2680dbce92c9f45d6458ed467
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# ApiValve
|
2
2
|
|
3
|
-
|
3
|
+
Extensible rack application that serves as lightweight API reverse proxy.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -10,5 +10,5 @@ Just add the gem
|
|
10
10
|
gem 'api_valve'
|
11
11
|
```
|
12
12
|
|
13
|
-
See the [examples](https://github.com/mkon/api_valve/tree/master/examples) section on how to
|
14
|
-
proxy using this gem.
|
13
|
+
See the [examples](https://github.com/mkon/api_valve/tree/master/examples) section on how to
|
14
|
+
create & configure your own proxy using this gem.
|
@@ -12,12 +12,7 @@ module ApiValve
|
|
12
12
|
WHITELISTED_HEADERS = %w(
|
13
13
|
Accept
|
14
14
|
Content-Type
|
15
|
-
Forwarded
|
16
15
|
User-Agent
|
17
|
-
X-Forwarded-For
|
18
|
-
X-Forwarded-Host
|
19
|
-
X-Forwarded-Port
|
20
|
-
X-Forwarded-Proto
|
21
16
|
X-Real-IP
|
22
17
|
).freeze
|
23
18
|
NOT_PREFIXED_HEADERS = %w(
|
@@ -58,7 +53,9 @@ module ApiValve
|
|
58
53
|
def headers
|
59
54
|
whitelisted_headers.each_with_object({}) do |key, h|
|
60
55
|
h[key] = header(key)
|
61
|
-
end.merge(
|
56
|
+
end.merge(forwarded_headers).merge(
|
57
|
+
'X-Request-Id' => Thread.current[:request_id]
|
58
|
+
).compact
|
62
59
|
end
|
63
60
|
|
64
61
|
# Returns body to forward to the target endpoint
|
@@ -77,6 +74,21 @@ module ApiValve
|
|
77
74
|
|
78
75
|
private
|
79
76
|
|
77
|
+
def forwarded_headers
|
78
|
+
{
|
79
|
+
'X-Forwarded-For' => x_forwarded_for,
|
80
|
+
'X-Forwarded-Host' => original_request.host,
|
81
|
+
'X-Forwarded-Port' => original_request.port.to_s,
|
82
|
+
'X-Forwarded-Proto' => original_request.scheme
|
83
|
+
}
|
84
|
+
end
|
85
|
+
|
86
|
+
def x_forwarded_for
|
87
|
+
(
|
88
|
+
header('X-Forwarded-For').to_s.split(', ') << original_request.env['REMOTE_ADDR']
|
89
|
+
).join(', ')
|
90
|
+
end
|
91
|
+
|
80
92
|
def header(name)
|
81
93
|
name = "HTTP_#{name}" unless NOT_PREFIXED_HEADERS.include? name
|
82
94
|
name = name.upcase.tr('-', '_')
|
@@ -39,7 +39,11 @@ module ApiValve
|
|
39
39
|
|
40
40
|
def headers
|
41
41
|
whitelisted_headers.each_with_object({}) do |k, h|
|
42
|
-
|
42
|
+
if k == 'Location'
|
43
|
+
h[k] = adjust_location(original_response.headers[k])
|
44
|
+
else
|
45
|
+
h[k] = original_response.headers[k]
|
46
|
+
end
|
43
47
|
end.compact
|
44
48
|
end
|
45
49
|
|
@@ -47,6 +51,11 @@ module ApiValve
|
|
47
51
|
@options[:whitelisted_headers] || WHITELISTED_HEADERS
|
48
52
|
end
|
49
53
|
|
54
|
+
def adjust_location(location)
|
55
|
+
return location if @options[:target_prefix] == @options[:local_prefix]
|
56
|
+
location&.gsub(/^#{@options[:target_prefix]}/, @options[:local_prefix])
|
57
|
+
end
|
58
|
+
|
50
59
|
def body
|
51
60
|
original_response.body.to_s
|
52
61
|
end
|
data/lib/api_valve/forwarder.rb
CHANGED
@@ -15,6 +15,8 @@ module ApiValve
|
|
15
15
|
# response: Options for the response wrapper. See Response#new
|
16
16
|
def initialize(options = {})
|
17
17
|
@options = options.with_indifferent_access
|
18
|
+
uri = URI(options[:endpoint])
|
19
|
+
@target_prefix = uri.path
|
18
20
|
end
|
19
21
|
|
20
22
|
# Takes the original rack request with optional options and returns a rack response
|
@@ -23,7 +25,14 @@ module ApiValve
|
|
23
25
|
def call(original_request, local_options = {})
|
24
26
|
request = request_klass.new(original_request, request_options.deep_merge(local_options))
|
25
27
|
raise Error::Forbidden unless request.allowed?
|
26
|
-
response_klass.new(
|
28
|
+
response_klass.new(
|
29
|
+
original_request,
|
30
|
+
run_request(request),
|
31
|
+
response_options.merge(
|
32
|
+
target_prefix: @target_prefix,
|
33
|
+
local_prefix: original_request.env['SCRIPT_NAME']
|
34
|
+
)
|
35
|
+
).rack_response
|
27
36
|
end
|
28
37
|
|
29
38
|
private
|
@@ -43,7 +52,8 @@ module ApiValve
|
|
43
52
|
|
44
53
|
def response_options
|
45
54
|
# integrate permission handler options as it is instantiated in the response
|
46
|
-
(@options[:response] || {})
|
55
|
+
(@options[:response] || {})
|
56
|
+
.merge(@options.slice(:permission_handler) || {})
|
47
57
|
end
|
48
58
|
|
49
59
|
def run_request(request)
|
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.2.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-08-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|