Module: Contrast::Utils::RequestUtils

Included in:
Agent::Request, Agent::RequestContext
Defined in:
lib/contrast/utils/request_utils.rb

Overview

used in Contrast::Agent::Request

Constant Summary collapse

NUM_ =

TOKENS:

'/{n}/'
ID_ =
'{ID}'
NUM_PATTERN =

PATTERNS:

%r{/\d+/}.cs__freeze
END_PATTERN =
%r{/\d+$}.cs__freeze
STATIC_SUFFIXES =
/\.(?:js|css|jpeg|jpg|gif|png|ico|woff|svg|pdf|eot|ttf|jar)$/i.cs__freeze
UUID_PATTERN =

rubocop:disable Layout/LineLength

Regexp.new('[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}').cs__freeze
HASH_PATTERN =

Regular expression to match any type of hash pattern that is 16 bytes like uuid with no slashes, md5, sha1, sha256, etc

Regexp.new('([a-fA-F0-9]{2}){16,}').cs__freeze
WIN_PATTERN =
Regexp.new('S-1-5-((32-\d+)|(21-\d+-\d+-\d+-\d+))').cs__freeze
MEDIA_TYPE_MARKERS =
%w[image/ text/css text/javascript].cs__freeze

Instance Method Summary collapse

Instance Method Details

#normalize_params(val, prefix: nil) ⇒ Object

Return a flattened hash of params with realized paths for keys, in addition to a separate, valueless, entry for each nest key. See RUBY-621 for more details. { key : { nested_key : [‘x’,‘y’,‘z’ ] } } becomes

key[nested_key][0] : 'x'
key[nested_key][1] : 'y'
key[nested_key][2] : 'z'
key :                ''
nested_key :         ''



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/contrast/utils/request_utils.rb', line 35

def normalize_params val, prefix: nil
  # In non-recursive invocations, val should always be a Hash
  # (rather than breaking this out into two methods)
  case val
  when Tempfile
    # Skip if it's the auto-generated value from rails when it handles
    # file uploads. The file name will still be sent to SR for analysis.
    {}
  when Hash
    res = val.each_with_object({}) do |(k, v), hash|
      k = Contrast::Utils::StringUtils.force_utf8(k)
      nested_prefix = prefix.nil? ? k : "#{ prefix }[#{ k }]"
      hash[k] = Contrast::Utils::ObjectShare::EMPTY_STRING
      hash.merge!(normalize_params(v, prefix: nested_prefix))
    end
    res[prefix] = Contrast::Utils::ObjectShare::EMPTY_STRING if prefix
    res
  when Enumerable
    idx = 0
    res = {}
    while idx < val.length
      res.merge!(normalize_params(val[idx], prefix: "#{ prefix }[#{ idx }]"))
      idx += 1
    end
    res[prefix] = Contrast::Utils::ObjectShare::EMPTY_STRING if prefix
    res
  else
    { prefix => Contrast::Utils::StringUtils.force_utf8(val) }
  end
end

#read_body(body) ⇒ Object

Read the response body and rewind. A well behaved middleware would read the IO object and then rewind.



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/contrast/utils/request_utils.rb', line 70

def read_body body
  return body if body.is_a?(String)

  begin
    can_rewind = Contrast::Utils::DuckUtils.quacks_to?(body, :rewind)
    # if we are after a middleware that failed to rewind
    body.rewind if can_rewind
    body.read
  rescue StandardError => e
    logger.error('Error in attempt to read body', message: e.message)
    logger.trace('With Stack', e)
    body.to_s
  ensure
    # be a good citizen and rewind
    body.rewind if can_rewind
  end
end

#traverse_parsed_multipart(multipart_data, current_names) ⇒ Object

Parameters:



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/contrast/utils/request_utils.rb', line 91

def traverse_parsed_multipart multipart_data, current_names
  return current_names unless multipart_data

  multipart_data.each_value do |data_value|
    next unless data_value.is_a?(Hash)

    tempfile = data_value[:tempfile]
    if tempfile.nil?
      traverse_parsed_multipart(data_value, current_names)
    else
      name = data_value[:name].to_s
      file_name = data_value[:filename].to_s
      current_names[name] = file_name
    end
  end
  current_names
end