Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleanup Rack interface #430

Merged
merged 1 commit into from
Jan 5, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
58 changes: 58 additions & 0 deletions lib/raven/integrations/rack.rb
Expand Up @@ -66,4 +66,62 @@ def call(env)
response
end
end

module RackInterface
def from_rack(env_hash)
req = ::Rack::Request.new(env_hash)

self.url = req.scheme && req.url.split('?').first
self.method = req.request_method
self.query_string = req.query_string
self.data = read_data_from(req)

self.headers = format_headers_for_sentry(env_hash)
self.env = format_env_for_sentry(env_hash)
end

private

def read_data_from(request)
if request.form_data?
request.POST
elsif request.body
data = request.body.read
request.body.rewind
data
end
end

def format_headers_for_sentry(env_hash)
env_hash.each_with_object({}) do |(key, value), memo|
key = key.to_s # rack env can contain symbols
value = value.to_s
next unless key.upcase == key # Non-upper case stuff isn't either
# Rack adds in an incorrect HTTP_VERSION key, which causes downstream
# to think this is a Version header. Instead, this is mapped to
# env['SERVER_PROTOCOL']. But we don't want to ignore a valid header
# if the request has legitimately sent a Version header themselves.
# See: https://github.com/rack/rack/blob/028438f/lib/rack/handler/cgi.rb#L29
next if key == 'HTTP_VERSION' && value == ENV['SERVER_PROTOCOL']

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nateberkopec should this be env_hash?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops! It absolutely should be. Looks like my editor autocorrected 'env' to ENV. Writing a test and fixing.

Since you're here, can you weigh in on rack/rack#970, which is the reason this hack exists?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #628

if key.start_with?('HTTP_')
# Header
http_key = key[5..key.length - 1].split('_').map(&:capitalize).join('-')
memo[http_key] = value
elsif %w(CONTENT_TYPE CONTENT_LENGTH).include? key
memo[key.capitalize] = value
end
end
end

def format_env_for_sentry(env_hash)
trimmed_hash = env_hash.select do |k, _v|
%w(REMOTE_ADDR SERVER_NAME SERVER_PORT).include? k.to_s
end
Hash[trimmed_hash] # select returns an Array in Ruby 1.8
end
end

class HttpInterface
include RackInterface
end
end
37 changes: 0 additions & 37 deletions lib/raven/interfaces/http.rb
Expand Up @@ -17,43 +17,6 @@ def initialize(*arguments)
self.cookies = nil
super(*arguments)
end

def from_rack(env)
req = ::Rack::Request.new(env)
self.url = req.scheme && req.url.split('?').first
self.method = req.request_method
self.query_string = req.query_string
server_protocol = env['SERVER_PROTOCOL']
env.each_pair do |key, value|
key = key.to_s #rack env can contain symbols
next unless key.upcase == key # Non-upper case stuff isn't either
# Rack adds in an incorrect HTTP_VERSION key, which causes downstream
# to think this is a Version header. Instead, this is mapped to
# env['SERVER_PROTOCOL']. But we don't want to ignore a valid header
# if the request has legitimately sent a Version header themselves.
# See: https://github.com/rack/rack/blob/028438f/lib/rack/handler/cgi.rb#L29
next if key == 'HTTP_VERSION' and value == server_protocol
if key.start_with?('HTTP_')
# Header
http_key = key[5..key.length - 1].split('_').map(&:capitalize).join('-')
self.headers[http_key] = value.to_s
elsif %w(CONTENT_TYPE CONTENT_LENGTH).include? key
self.headers[key.capitalize] = value.to_s
elsif %w(REMOTE_ADDR SERVER_NAME SERVER_PORT).include? key
# Environment
self.env[key] = value.to_s
end
end

self.data =
if req.form_data?
req.POST
elsif req.body
data = req.body.read
req.body.rewind
data
end
end
end

register_interface :http => HttpInterface
Expand Down