Class: Rack::AllowedHosts

Inherits:
Object
  • Object
show all
Defined in:
lib/rack/allowed_hosts.rb,
lib/rack/allowed_hosts/version.rb

Constant Summary collapse

VERSION =
'0.0.1'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app, &block) ⇒ AllowedHosts

Returns a new instance of AllowedHosts.



9
10
11
12
13
14
15
# File 'lib/rack/allowed_hosts.rb', line 9

def initialize(app, &block)
  @app = app
  @allowed_hosts = []

  # Call the block
  instance_eval(&block)
end

Instance Attribute Details

#allowed_hostsObject (readonly)

Returns the value of attribute allowed_hosts.



7
8
9
# File 'lib/rack/allowed_hosts.rb', line 7

def allowed_hosts
  @allowed_hosts
end

Instance Method Details

#allow(*hosts) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
# File 'lib/rack/allowed_hosts.rb', line 17

def allow(*hosts)
  # Also allow the for `allow ['host-a.com', 'host-b.com']` etc.
  if hosts.size == 1 && hosts[0].is_a?(Array)
    hosts = hosts[0]
  end

  hosts.each do |host|
    matcher = matcher_for(host)
    @allowed_hosts << matcher unless @allowed_hosts.include? matcher
  end
end

#call(env) ⇒ Object



29
30
31
32
33
34
35
36
37
# File 'lib/rack/allowed_hosts.rb', line 29

def call(env)
  host = env['HTTP_HOST'].split(':').first
  unless host_allowed?(host)
    return [403, {'Content-Type' => 'text/html'}, ['<h1>403 Forbidden</h1>']]
  end

  # Fetch the result
  @app.call(env)
end

#host_allowed?(host) ⇒ Boolean

Returns:

  • (Boolean)


39
40
41
42
43
44
45
46
47
# File 'lib/rack/allowed_hosts.rb', line 39

def host_allowed?(host)
  return false if host.nil?

  @allowed_hosts.each do |pattern|
    return true if pattern.match host
  end

  false
end

#matcher_for(host) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/rack/allowed_hosts.rb', line 49

def matcher_for(host)
  host = host.gsub(/\.\Z/, '')
  parts = host.split('.')
  pattern = nil
  parts.each do |part|
    if pattern.nil?
      pattern = prepared_part(part)
    else
      pattern = /#{pattern}\.#{prepared_part(part)}/
    end
  end
  /\A#{pattern}\Z/
end

#prepared_part(part) ⇒ Object



63
64
65
66
67
68
69
# File 'lib/rack/allowed_hosts.rb', line 63

def prepared_part(part)
  if part == '*'
    /.*/
  else
    Regexp.quote(part)
  end
end