class Raven::Utils::RealIp

Constants

LOCAL_ADDRESSES

Attributes

ip[RW]
ip_addresses[RW]

Public Class Methods

new(ip_addresses) click to toggle source
# File lib/raven/utils/real_ip.rb, line 21
def initialize(ip_addresses)
  self.ip_addresses = ip_addresses
end

Public Instance Methods

calculate_ip() click to toggle source
# File lib/raven/utils/real_ip.rb, line 25
def calculate_ip
  # CGI environment variable set by Rack
  remote_addr = ips_from(ip_addresses[:remote_addr]).last

  # Could be a CSV list and/or repeated headers that were concatenated.
  client_ips    = ips_from(ip_addresses[:client_ip])
  real_ips      = ips_from(ip_addresses[:real_ip])
  forwarded_ips = ips_from(ip_addresses[:forwarded_for])

  ips = [client_ips, real_ips, forwarded_ips, remote_addr].flatten.compact

  # If every single IP option is in the trusted list, just return REMOTE_ADDR
  self.ip = filter_local_addresses(ips).first || remote_addr
end

Protected Instance Methods

filter_local_addresses(ips) click to toggle source
# File lib/raven/utils/real_ip.rb, line 57
def filter_local_addresses(ips)
  ips.reject { |ip| LOCAL_ADDRESSES.any? { |proxy| proxy === ip } }
end
ips_from(header) click to toggle source
# File lib/raven/utils/real_ip.rb, line 42
def ips_from(header)
  # Split the comma-separated list into an array of strings
  ips = header ? header.strip.split(/[,\s]+/) : []
  ips.select do |ip|
    begin
      # Only return IPs that are valid according to the IPAddr#new method
      range = IPAddr.new(ip).to_range
      # we want to make sure nobody is sneaking a netmask in
      range.begin == range.end
    rescue ArgumentError
      nil
    end
  end
end