# class Raven::Utils::RealIp

### Constants

LOCAL_ADDRESSES

### Attributes

ip[RW]
ip_addresses[RW]

### Public Class Methods

new(ip_addresses) click to toggle source

    # File sentry-raven/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 sentry-raven/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 sentry-raven/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 sentry-raven/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