Class: Aikido::Zen::Request

Inherits:
SimpleDelegator
  • Object
show all
Defined in:
lib/aikido/zen/request.rb

Overview

Wrapper around Rack::Request-like objects to add some behavior.

Defined Under Namespace

Classes: HeuristicRouter, RailsRouter, Schema

Constant Summary collapse

BLESSED_CGI_HEADERS =
%w[CONTENT_TYPE CONTENT_LENGTH]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(delegate, config = Aikido::Zen.config, framework:, router:) ⇒ Request

Returns a new instance of Request.



26
27
28
29
30
31
# File 'lib/aikido/zen/request.rb', line 26

def initialize(delegate, config = Aikido::Zen.config, framework:, router:)
  super(delegate)
  @config = config
  @framework = framework
  @router = router
end

Instance Attribute Details

#actorAikido::Zen::Actor?

The current user, if set by the host app.

Returns:

See Also:



18
19
20
# File 'lib/aikido/zen/request.rb', line 18

def actor
  @actor
end

#frameworkString (readonly)

Returns identifier of the framework handling this HTTP request.

Returns:

  • (String)

    identifier of the framework handling this HTTP request.



9
10
11
# File 'lib/aikido/zen/request.rb', line 9

def framework
  @framework
end

#routerAikido::Zen::Router (readonly)

Returns:

  • (Aikido::Zen::Router)


12
13
14
# File 'lib/aikido/zen/request.rb', line 12

def router
  @router
end

#tenant_idInteger, ...

The current tenant, if set by the host app.

Returns:

  • (Integer, String, nil)

See Also:



24
25
26
# File 'lib/aikido/zen/request.rb', line 24

def tenant_id
  @tenant_id
end

Instance Method Details

#__setobj__(delegate) ⇒ Object

:nodoc:



33
34
35
36
# File 'lib/aikido/zen/request.rb', line 33

def __setobj__(delegate) # :nodoc:
  super
  @route = @normalized_headers = nil
end

#as_jsonObject



88
89
90
91
92
93
94
95
96
97
# File 'lib/aikido/zen/request.rb', line 88

def as_json
  {
    "method" => request_method.upcase,
    "url" => url,
    "ipAddress" => client_ip,
    "userAgent" => user_agent,
    "source" => framework,
    "route" => route&.path
  }
end

#client_ipString

Returns the IP address of the client making the request.

Returns:

  • (String)

    the IP address of the client making the request.



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/aikido/zen/request.rb', line 49

def client_ip
  return @client_ip if @client_ip

  if @config.client_ip_header
    value = env[@config.client_ip_header]

    if value
      if Resolv::AddressRegex.match?(value)
        @client_ip = value
      else
        @config.logger.warn("Invalid IP address in custom client IP header `#{@config.client_ip_header}`: `#{value}`")
      end
    else
      @config.logger.debug("Custom client IP header `#{@config.client_ip_header}` not present in request")
    end
  end

  @client_ip ||= respond_to?(:remote_ip) ? remote_ip : ip
end

#normalized_headersHash<String, String>

Map the CGI-style env Hash into "pretty-looking" headers, preserving the values as-is. For example, HTTP_ACCEPT turns into "Accept", CONTENT_TYPE turns into "Content-Type", and HTTP_X_FORWARDED_FOR turns into "X-Forwarded-For".

Returns:

  • (Hash<String, String>)


75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/aikido/zen/request.rb', line 75

def normalized_headers
  @normalized_headers ||= env.slice(*BLESSED_CGI_HEADERS)
    .merge(env.select { |key, _| key.start_with?("HTTP_") })
    .transform_keys do |header|
      header
        .delete_prefix("HTTP_")
        .downcase
        .split("_")
        .map(&:capitalize)
        .join("-")
    end
end

#routeAikido::Zen::Route

Returns the framework route being requested.

Returns:



39
40
41
# File 'lib/aikido/zen/request.rb', line 39

def route
  @route ||= @router.recognize(self)
end

#schemaAikido::Zen::Request::Schema?



44
45
46
# File 'lib/aikido/zen/request.rb', line 44

def schema
  @schema ||= Aikido::Zen::Request::Schema.build
end