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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fd0650e0cecef4ec781e6e8a4386ad05573de8b79174d624c7b08af1dfef02bf
4
- data.tar.gz: a608b1470fdfa950fb23edf5bd05949cff1a3ebf1a89a100994c1f3119999213
3
+ metadata.gz: 4c5ecd7703186bfbcd52c8b50d3a643a5c2af56043e92f00e56b8b1863c38fb7
4
+ data.tar.gz: 95263987cdf177ce4703955572e28f4540a3c32f47fb7b519fd0233b79506160
5
5
  SHA512:
6
- metadata.gz: 62804cac7016ef7ec069e17ccc229fe25356de1702512de74b425de0a07331464a9067750d0243aa618cdab1100fcc96e05a5095c969e289c567d66adc8d914d
7
- data.tar.gz: e36dc22f1603317981cf07e372b0deb1a6c65b3ae18b15894a287adb78c7a682e3c90385566e455b7be1dc44d70d8117b6327b31b592d207b7dbc1b3dbd80130
6
+ metadata.gz: a43f1ff0ea8e795a1676bd918b9d849d2404a14793f6ccf93adac8b70c3aa672729822a1e6d516f38201ae3505023e3d0adc46c0a4257497c6c5aaa577bc97fe
7
+ data.tar.gz: 2db871a83ee2dc02b2639ba0e6c19a795f765e24421ef0aacc8ec2f4adbefd2b682d7746cb8c99cd0e976d5afe89af70abb87cb2680dbce92c9f45d6458ed467
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # ApiValve
2
2
 
3
- Lightweight API reverse proxy written in ruby. Based on rack.
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 create & configure your own
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('X-Request-Id' => Thread.current[:request_id]).compact
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
- h[k] = original_response.headers[k]
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
@@ -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(original_request, run_request(request), response_options).rack_response
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] || {}).merge(@options.slice(:permission_handler) || {})
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.1.1
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-06-04 00:00:00.000000000 Z
11
+ date: 2018-08-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport