class ApiValve::Forwarder::Request

This class is wraps the original request. It's methods are called by the Forwarder to make the actual request in the target endpoint. So by changing the public methods in this call, we can control how the request is forwarded

Constants

NOT_PREFIXED_HEADERS
WHITELISTED_HEADERS

Attributes

options[R]
original_request[R]

Public Class Methods

new(original_request, options = {}) click to toggle source
# File lib/api_valve/forwarder/request.rb, line 22
def initialize(original_request, options = {})
  @original_request = original_request
  @options = options.with_indifferent_access
end

Public Instance Methods

body() click to toggle source

Returns body to forward to the target endpoint Override to control the payload that is passed through

# File lib/api_valve/forwarder/request.rb, line 55
def body
  return unless %i(put post patch).include? method

  original_request.body.read
end
headers() click to toggle source

Returns a hash of headers to forward to the target endpoint Override to control the HTTP headers that will be passed through

# File lib/api_valve/forwarder/request.rb, line 47
def headers
  whitelisted_headers.each_with_object({}) do |key, h|
    h[key] = header(key)
  end.merge(forwarded_headers).compact
end
method() click to toggle source

HTTP method to use when forwarding. Must return sym. Returns original request method

# File lib/api_valve/forwarder/request.rb, line 29
def method
  @method ||= original_request.request_method.downcase.to_sym
end
path() click to toggle source

URL path to use when forwarding

# File lib/api_valve/forwarder/request.rb, line 34
def path
  path = options['endpoint'] || ''
  if (override = override_path(options))
    path += override
  else
    path += original_request.path_info
  end
  # we remove leading slash so we can use endpoints with deeper folder levels
  path.gsub(%r{^/}, '')
end
url_params() click to toggle source

Returns query params to forward to the target endpoint Override to control the query parameters that can be passed through

# File lib/api_valve/forwarder/request.rb, line 63
def url_params
  return unless original_request.query_string.present?

  @url_params ||= Rack::Utils.parse_nested_query(original_request.query_string)
end

Protected Instance Methods

permission_handler() click to toggle source
# File lib/api_valve/forwarder/request.rb, line 71
def permission_handler
  original_request.env['permission_handler']
end

Private Instance Methods

forwarded_headers() click to toggle source
# File lib/api_valve/forwarder/request.rb, line 77
def forwarded_headers
  {
    'X-Forwarded-For'    => x_forwarded_for,
    'X-Forwarded-Host'   => original_request.host,
    'X-Forwarded-Port'   => original_request.port.to_s,
    'X-Forwarded-Prefix' => original_request.env['SCRIPT_NAME'].presence,
    'X-Forwarded-Proto'  => original_request.scheme
  }.compact
end
header(name) click to toggle source
# File lib/api_valve/forwarder/request.rb, line 100
def header(name)
  name = "HTTP_#{name}" unless NOT_PREFIXED_HEADERS.include? name
  name = name.upcase.tr('-', '_')
  original_request.get_header(name)
end
override_path(options) click to toggle source
# File lib/api_valve/forwarder/request.rb, line 87
def override_path(options)
  return unless (path = options['path'])
  return path unless options['match_data']

  path % options['match_data'].named_captures.symbolize_keys
end
whitelisted_headers() click to toggle source
# File lib/api_valve/forwarder/request.rb, line 106
def whitelisted_headers
  @options[:whitelisted_headers] || WHITELISTED_HEADERS
end
x_forwarded_for() click to toggle source
# File lib/api_valve/forwarder/request.rb, line 94
def x_forwarded_for
  (
    header('X-Forwarded-For').to_s.split(', ') << original_request.env['REMOTE_ADDR']
  ).join(', ')
end