-
Notifications
You must be signed in to change notification settings - Fork 375
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Replace contrib Rack::Request and Rack::Response with Gateway::Request and Gateway::Response
- Loading branch information
1 parent
d76de94
commit 9b9987d
Showing
27 changed files
with
298 additions
and
198 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
# typed: false | ||
# frozen_string_literal: true | ||
|
||
require_relative '../../../instrumentation/gateway/argument' | ||
require_relative '../../../../tracing/client_ip' | ||
require_relative '../../../../tracing/contrib/rack/header_collection' | ||
|
||
|
||
module Datadog | ||
module AppSec | ||
module Contrib | ||
module Rack | ||
module Gateway | ||
class Request < Instrumentation::Gateway::Argument | ||
attr_reader :env | ||
|
||
def initialize(env) | ||
@env = env | ||
end | ||
|
||
def request | ||
@request ||= ::Rack::Request.new(env) | ||
end | ||
|
||
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. | ||
request.query_string.split('&').map do |e| | ||
k, v = e.split('=').map { |s| CGI.unescape(s) } | ||
|
||
{ k => v } | ||
end | ||
end | ||
|
||
# Rack < 2.0 does not have :each_header | ||
# TODO: We need access to Rack here. We must make sure we are able to load AppSec without Rack, | ||
# TODO: while still ensure correctness in ths code path. | ||
if defined?(::Rack) && ::Rack::Request.instance_methods.include?(:each_header) | ||
def headers | ||
request.each_header.each_with_object({}) do |(k, v), h| | ||
h[k.gsub(/^HTTP_/, '').downcase.tr('_', '-')] = v if k =~ /^HTTP_/ | ||
end | ||
end | ||
else | ||
def headers | ||
request.env.each_with_object({}) do |(k, v), h| | ||
h[k.gsub(/^HTTP_/, '').downcase.tr('_', '-')] = v if k =~ /^HTTP_/ | ||
end | ||
end | ||
end | ||
|
||
def body | ||
request.body.read.tap { request.body.rewind } | ||
end | ||
|
||
def url | ||
request.url | ||
end | ||
|
||
def cookies | ||
request.cookies | ||
end | ||
|
||
def host | ||
request.host | ||
end | ||
|
||
def user_agent | ||
request.user_agent | ||
end | ||
|
||
def remote_addr | ||
env['REMOTE_ADDR'] | ||
end | ||
|
||
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 | ||
|
||
def client_ip | ||
remote_ip = remote_addr | ||
headers = Datadog::Tracing::Contrib::Rack::Header::RequestHeaderCollection.new(env) | ||
|
||
result = Datadog::Tracing::ClientIp.raw_ip_from_request(headers, remote_ip) | ||
|
||
if result.raw_ip | ||
ip = Datadog::Tracing::ClientIp.strip_decorations(result.raw_ip) | ||
return unless Datadog::Tracing::ClientIp.valid_ip?(ip) | ||
|
||
ip | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# typed: false | ||
# frozen_string_literal: true | ||
|
||
require_relative '../../../instrumentation/gateway/argument' | ||
|
||
module Datadog | ||
module AppSec | ||
module Contrib | ||
module Rack | ||
module Gateway | ||
class Response < Instrumentation::Gateway::Argument | ||
attr_reader :body, :status, :headers | ||
|
||
def initialize(body, status, headers) | ||
@body = body | ||
@status = status | ||
@headers = headers.each_with_object({}) { |(k, v), h| h[k.downcase] = v } | ||
end | ||
|
||
def response | ||
@response ||= ::Rack::Response.new(body, status, headers) | ||
end | ||
|
||
def cookies | ||
response.cookies | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.