Class: Aikido::Zen::Request
- Inherits:
-
SimpleDelegator
- Object
- SimpleDelegator
- Aikido::Zen::Request
- 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
-
#actor ⇒ Aikido::Zen::Actor?
The current user, if set by the host app.
-
#framework ⇒ String
readonly
Identifier of the framework handling this HTTP request.
- #router ⇒ Aikido::Zen::Router readonly
Instance Method Summary collapse
-
#__setobj__(delegate) ⇒ Object
:nodoc:.
- #as_json ⇒ Object
-
#initialize(delegate, framework:, router:) ⇒ Request
constructor
A new instance of Request.
-
#normalized_headers ⇒ Hash<String, String>
Map the CGI-style env Hash into “pretty-looking” headers, preserving the values as-is.
-
#route ⇒ Aikido::Zen::Route
The framework route being requested.
- #schema ⇒ Aikido::Zen::Request::Schema?
-
#truncated_body(max_size: 16384) ⇒ String
private
Reads the first 16KiB of the request body, to include in attack reports back to the Aikido server.
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
#actor ⇒ Aikido::Zen::Actor?
The current user, if set by the host app.
18 19 20 |
# File 'lib/aikido/zen/request.rb', line 18 def actor @actor end |
#framework ⇒ String (readonly)
Returns identifier of the framework handling this HTTP request.
9 10 11 |
# File 'lib/aikido/zen/request.rb', line 9 def framework @framework end |
#router ⇒ Aikido::Zen::Router (readonly)
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_json ⇒ Object
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_headers ⇒ Hash<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”.
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 |
#route ⇒ Aikido::Zen::Route
Returns the framework route being requested.
34 35 36 |
# File 'lib/aikido/zen/request.rb', line 34 def route @route ||= @router.recognize(self) end |
#schema ⇒ Aikido::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.
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 |