class Rack::Access
Rack
middleware for limiting access based on IP address
Options:¶ ↑
path => ipmasks ipmasks: Array of remote addresses which are allowed to access
Examples:¶ ↑
use Rack::Access, '/backend' => [ '127.0.0.1', '192.168.1.0/24' ]
Attributes
options[R]
Public Class Methods
new(app, options = {})
click to toggle source
# File lib/rack/contrib/access.rb 25 def initialize(app, options = {}) 26 @app = app 27 mapping = options.empty? ? {"/" => ["127.0.0.1"]} : options 28 @mapping = remap(mapping) 29 end
Public Instance Methods
call(env)
click to toggle source
# File lib/rack/contrib/access.rb 52 def call(env) 53 request = Request.new(env) 54 ipmasks = ipmasks_for_path(env) 55 return forbidden! unless ip_authorized?(request, ipmasks) 56 status, headers, body = @app.call(env) 57 [status, headers, body] 58 end
forbidden!()
click to toggle source
# File lib/rack/contrib/access.rb 74 def forbidden! 75 [403, { 'Content-Type' => 'text/html', 'Content-Length' => '0' }, []] 76 end
ipmasks_for_path(env)
click to toggle source
# File lib/rack/contrib/access.rb 60 def ipmasks_for_path(env) 61 path = env["PATH_INFO"].to_s 62 hHost, sName, sPort = env.values_at('HTTP_HOST','SERVER_NAME','SERVER_PORT') 63 @mapping.each do |host, location, match, ipmasks| 64 next unless (hHost == host || sName == host \ 65 || (host.nil? && (hHost == sName || hHost == sName+':'+sPort))) 66 next unless path =~ match && rest = $1 67 next unless rest.empty? || rest[0] == ?/ 68 69 return ipmasks 70 end 71 nil 72 end
remap(mapping)
click to toggle source
# File lib/rack/contrib/access.rb 31 def remap(mapping) 32 mapping.map { |location, ipmasks| 33 if location =~ %r{\Ahttps?://(.*?)(/.*)} 34 host, location = $1, $2 35 else 36 host = nil 37 end 38 39 unless location[0] == ?/ 40 raise ArgumentError, "paths need to start with /" 41 end 42 location = location.chomp('/') 43 match = Regexp.new("^#{Regexp.quote(location).gsub('/', '/+')}(.*)", nil, 'n') 44 45 ipmasks.collect! do |ipmask| 46 ipmask.is_a?(IPAddr) ? ipmask : IPAddr.new(ipmask) 47 end 48 [host, location, match, ipmasks] 49 }.sort_by { |(h, l, m, a)| [h ? -h.size : (-1.0 / 0.0), -l.size] } # Longest path first 50 end