class Sentry::RequestInterface
Constants
- CONTENT_HEADERS
- IP_HEADERS
- MAX_BODY_LIMIT
See
Sentry
server default limits at github.com/getsentry/sentry/blob/master/src/sentry/conf/server.py- REQUEST_ID_HEADERS
Attributes
data[RW]
env[RW]
headers[RW]
method[RW]
query_string[RW]
url[RW]
Public Class Methods
build(env:)
click to toggle source
# File lib/sentry/interfaces/request.rb, line 20 def self.build(env:) env = clean_env(env) request = ::Rack::Request.new(env) self.new(request: request) end
clean_env(env)
click to toggle source
# File lib/sentry/interfaces/request.rb, line 26 def self.clean_env(env) unless Sentry.configuration.send_default_pii # need to completely wipe out ip addresses RequestInterface::IP_HEADERS.each do |header| env.delete(header) end end env end
new(request:)
click to toggle source
# File lib/sentry/interfaces/request.rb, line 37 def initialize(request:) env = request.env if Sentry.configuration.send_default_pii self.data = read_data_from(request) self.cookies = request.cookies self.query_string = request.query_string end self.url = request.scheme && request.url.split('?').first self.method = request.request_method self.headers = filter_and_format_headers(env) self.env = filter_and_format_env(env) end
Private Instance Methods
encode_to_utf_8(value)
click to toggle source
# File lib/sentry/interfaces/request.rb, line 91 def encode_to_utf_8(value) if value.encoding != Encoding::UTF_8 && value.respond_to?(:force_encoding) value = value.dup.force_encoding(Encoding::UTF_8) end if !value.valid_encoding? value = value.scrub end value end
filter_and_format_env(env)
click to toggle source
# File lib/sentry/interfaces/request.rb, line 119 def filter_and_format_env(env) return env if Sentry.configuration.rack_env_whitelist.empty? env.select do |k, _v| Sentry.configuration.rack_env_whitelist.include? k.to_s end end
filter_and_format_headers(env)
click to toggle source
# File lib/sentry/interfaces/request.rb, line 68 def filter_and_format_headers(env) env.each_with_object({}) do |(key, value), memo| begin key = key.to_s # rack env can contain symbols next memo['X-Request-Id'] ||= Utils::RequestId.read_from(env) if Utils::RequestId::REQUEST_ID_HEADERS.include?(key) next if is_server_protocol?(key, value, env["SERVER_PROTOCOL"]) next if is_skippable_header?(key) # Rack stores headers as HTTP_WHAT_EVER, we need What-Ever key = key.sub(/^HTTP_/, "") key = key.split('_').map(&:capitalize).join('-') memo[key] = encode_to_utf_8(value.to_s) rescue StandardError => e # Rails adds objects to the Rack env that can sometimes raise exceptions # when `to_s` is called. # See: https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/middleware/remote_ip.rb#L134 Sentry.logger.warn(LOGGER_PROGNAME) { "Error raised while formatting headers: #{e.message}" } next end end end
is_server_protocol?(key, value, protocol_version)
click to toggle source
Rack
adds in an incorrect HTTP_VERSION key, which causes downstream to think this is a Version header. Instead, this is mapped to env. But we don't want to ignore a valid header if the request has legitimately sent a Version header themselves. See: github.com/rack/rack/blob/028438f/lib/rack/handler/cgi.rb#L29 NOTE: This will be removed in version 3.0+
# File lib/sentry/interfaces/request.rb, line 115 def is_server_protocol?(key, value, protocol_version) key == 'HTTP_VERSION' && value == protocol_version end
is_skippable_header?(key)
click to toggle source
# File lib/sentry/interfaces/request.rb, line 103 def is_skippable_header?(key) key.upcase != key || # lower-case envs aren't real http headers key == "HTTP_COOKIE" || # Cookies don't go here, they go somewhere else !(key.start_with?('HTTP_') || CONTENT_HEADERS.include?(key)) end
read_data_from(request)
click to toggle source
# File lib/sentry/interfaces/request.rb, line 55 def read_data_from(request) if request.form_data? request.POST elsif request.body # JSON requests, etc data = request.body.read(MAX_BODY_LIMIT) data = encode_to_utf_8(data.to_s) request.body.rewind data end rescue IOError => e e.message end