api_valve 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|