class Rack::IpAddressRestriction
Constants
- DEFAULT_MAPPING
- VERSION
Public Class Methods
new(app, options = {})
click to toggle source
# File lib/rack/ip_address_restriction.rb, line 11 def initialize(app, options = {}) @app = app options = DEFAULT_MAPPING if options.empty? @mapping = create_mapping(options) end
Public Instance Methods
call(env)
click to toggle source
# File lib/rack/ip_address_restriction.rb, line 17 def call(env) if allow?(env) @app.call(env) else [403, { 'Content-Type' => 'text/html', 'Content-Length' => '0' }, []] end end
Private Instance Methods
allow?(env)
click to toggle source
# File lib/rack/ip_address_restriction.rb, line 49 def allow?(env) return true unless ip_masks = ip_masks_for_current_path(env) request = Request.new(env) ip_masks.any? { |addr| addr.include?(IPAddr.new(request.ip)) } end
create_mapping(config)
click to toggle source
# File lib/rack/ip_address_restriction.rb, line 27 def create_mapping(config) mapping = config.map do |location, ip_masks| host, path = parse_location(location) raise ArgumentError, 'paths need to start with /' if path[0] != '/' path_prefix = Pathname.new(path).cleanpath.to_s.chomp('/') ip_masks = ip_masks.map { |addr| addr.is_a?(IPAddr) ? addr : IPAddr.new(addr) } [host, path_prefix, ip_masks] end mapping.sort_by { |(host, path_prefix, _)| [host ? -host.size : (-1.0 / 0.0), -path_prefix.size] } end
ip_masks_for_current_path(env)
click to toggle source
# File lib/rack/ip_address_restriction.rb, line 56 def ip_masks_for_current_path(env) path = Pathname.new(env["PATH_INFO"].to_s).cleanpath.to_s @mapping.each do |host, path_prefix, ip_masks| next if host && ![env['HTTP_HOST'], env['SERVER_NAME']].include?(host) next if path !~ %r{\A#{Regexp.quote(path_prefix)}(.*)\z}i || !($1.empty? || $1[0] == '/') return ip_masks end nil end
parse_location(location)
click to toggle source
# File lib/rack/ip_address_restriction.rb, line 40 def parse_location(location) uri = URI.parse(location) if uri.host [uri.host, uri.path] else [nil, location] end end