Class: Datadog::AppSec::Contrib::Rack::Gateway::Request

Inherits:
Instrumentation::Gateway::Argument show all
Defined in:
lib/datadog/appsec/contrib/rack/gateway/request.rb

Overview

Gateway Request argument. Normalized extration of data from Rack::Request

Direct Known Subclasses

Sinatra::Gateway::Request

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(env) ⇒ Request

Returns a new instance of Request.



16
17
18
19
# File 'lib/datadog/appsec/contrib/rack/gateway/request.rb', line 16

def initialize(env)
  super()
  @env = env
end

Instance Attribute Details

#envObject (readonly)

Returns the value of attribute env.



14
15
16
# File 'lib/datadog/appsec/contrib/rack/gateway/request.rb', line 14

def env
  @env
end

Instance Method Details

#client_ipObject



90
91
92
93
94
95
# File 'lib/datadog/appsec/contrib/rack/gateway/request.rb', line 90

def client_ip
  remote_ip = remote_addr
  header_collection = Datadog::Core::HeaderCollection.from_hash(headers)

  Datadog::Tracing::ClientIp.extract_client_ip(header_collection, remote_ip)
end

#cookiesObject



65
66
67
# File 'lib/datadog/appsec/contrib/rack/gateway/request.rb', line 65

def cookies
  request.cookies
end

#form_hashObject



81
82
83
84
85
86
87
88
# File 'lib/datadog/appsec/contrib/rack/gateway/request.rb', line 81

def form_hash
  # force form data processing
  request.POST if request.form_data?

  # usually Hash<String,String> but can be a more complex
  # Hash<String,String||Array||Hash> when e.g coming from JSON
  env['rack.request.form_hash']
end

#fullpathObject



57
58
59
# File 'lib/datadog/appsec/contrib/rack/gateway/request.rb', line 57

def fullpath
  request.fullpath
end

#headersObject



42
43
44
45
46
47
48
49
50
51
# File 'lib/datadog/appsec/contrib/rack/gateway/request.rb', line 42

def headers
  result = request.env.each_with_object({}) do |(k, v), h|
    h[k.delete_prefix('HTTP_').tap(&:downcase!).tap { |s| s.tr!('_', '-') }] = v if k.start_with?('HTTP_')
  end

  result['content-type'] = request.content_type if request.content_type
  # Since Rack 3.1, content-length is nil if the body is empty, but we still want to send it to the WAF.
  result['content-length'] = request.content_length || '0'
  result
end

#hostObject



69
70
71
# File 'lib/datadog/appsec/contrib/rack/gateway/request.rb', line 69

def host
  request.host
end

#methodObject



38
39
40
# File 'lib/datadog/appsec/contrib/rack/gateway/request.rb', line 38

def method
  request.request_method
end

#pathObject



61
62
63
# File 'lib/datadog/appsec/contrib/rack/gateway/request.rb', line 61

def path
  request.path
end

#queryObject



25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/datadog/appsec/contrib/rack/gateway/request.rb', line 25

def query
  # Downstream libddwaf expects keys and values to be extractable
  # separately so we can't use [[k, v], ...]. We also want to allow
  # duplicate keys, so we use {k => [v, ...], ...} instead, taking into
  # account that {k => [v1, v2, ...], ...} is possible for duplicate keys.
  request.query_string.split('&').each.with_object({}) do |e, hash|
    k, v = e.split('=').map { |s| CGI.unescape(s) }
    hash[k] ||= []

    hash[k] << v
  end
end

#remote_addrObject



77
78
79
# File 'lib/datadog/appsec/contrib/rack/gateway/request.rb', line 77

def remote_addr
  env['REMOTE_ADDR']
end

#requestObject



21
22
23
# File 'lib/datadog/appsec/contrib/rack/gateway/request.rb', line 21

def request
  @request ||= ::Rack::Request.new(env)
end

#urlObject



53
54
55
# File 'lib/datadog/appsec/contrib/rack/gateway/request.rb', line 53

def url
  request.url
end

#user_agentObject



73
74
75
# File 'lib/datadog/appsec/contrib/rack/gateway/request.rb', line 73

def user_agent
  request.user_agent
end