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, framework:, router:) ⇒ Request

Returns a new instance of Request.



20
21
22
23
24
25
# File 'lib/aikido/zen/request.rb', line 20

def initialize(delegate, framework:, router:)
  super(delegate)
  @framework = framework
  @router = router
  @body_read = false
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

Instance Method Details

#__setobj__(delegate) ⇒ Object

:nodoc:



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

def __setobj__(delegate) # :nodoc:
  super
  @body_read = false
  @route = @normalized_header = @truncated_body = nil
end

#as_jsonObject



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

def as_json
  {
    method: request_method.downcase,
    url: url,
    ipAddress: ip,
    userAgent: user_agent,
    headers: normalized_headers.reject { |_, val| val.to_s.empty? },
    body: truncated_body,
    source: framework,
    route: route&.path
  }
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>)


49
50
51
52
53
54
55
56
# File 'lib/aikido/zen/request.rb', line 49

def normalized_headers
  @normalized_headers ||= env.slice(*BLESSED_CGI_HEADERS)
    .merge(env.select { |key, _| key.start_with?("HTTP_") })
    .transform_keys { |header|
      name = header.sub(/^HTTP_/, "").downcase
      name.split("_").map { |part| part[0].upcase + part[1..] }.join("-")
    }
end

#routeAikido::Zen::Route

Returns the framework route being requested.

Returns:



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

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

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



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

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

#truncated_body(max_size: 16384) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Reads the first 16KiB of the request body, to include in attack reports back to the Aikido server. This method should only be called if an attack is detected during the current request.

If the underlying IO object has been partially (or fully) read before, this will attempt to restore the previous cursor position after reading it if possible, or leave if rewund if not.

Parameters:

  • max_size (Integer) (defaults to: 16384)

    number of bytes to read at most.

Returns:

  • (String)


71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/aikido/zen/request.rb', line 71

def truncated_body(max_size: 16384)
  return @truncated_body if @body_read
  return nil if body.nil?

  begin
    initial_pos = body.pos if body.respond_to?(:pos)
    body.rewind
    @truncated_body = body.read(max_size)
  ensure
    @body_read = true
    body.rewind
    body.seek(initial_pos) if initial_pos && body.respond_to?(:seek)
  end
end