Class: HttpBL

Inherits:
Object
  • Object
show all
Defined in:
lib/httpbl.rb

Overview

The Httpbl middleware

Instance Method Summary collapse

Constructor Details

#initialize(app, options = {}) ⇒ HttpBL

Returns a new instance of HttpBL.



6
7
8
9
10
11
12
13
14
15
16
17
# File 'lib/httpbl.rb', line 6

def initialize(app, options = {})
  @app = app
  @options = {:blocked_search_engines => [],
              :age_threshold => 10,
              :threat_level_threshold => 2,
              # 8..128 aren't used as of 3/2009, but might be used in the future
              :deny_types => [1, 2, 4, 8, 16, 32, 64, 128],
              # DONT set this to 0
              :dns_timeout => 0.5
              }.merge(options)
  raise "Missing :api_key for Http:BL middleware" unless @options[:api_key]
end

Instance Method Details

#_call(env) ⇒ Object



23
24
25
26
27
28
29
30
31
32
# File 'lib/httpbl.rb', line 23

def _call(env)
  request = Rack::Request.new(env)
  bl_status = resolve(request.ip)
  if bl_status and blocked?(bl_status)
    [403, {"Content-Type" => "text/html"}, "<h1>403 Forbidden</h1> Request IP is listed as suspicious by <a href='http://projecthoneypot.org/ip_#{request.ip}'>Project Honeypot</a>"]
  else
    @app.call(env)
  end
  
end

#blocked?(response) ⇒ Boolean

Returns:

  • (Boolean)


42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/httpbl.rb', line 42

def blocked?(response)
  response = response.split('.').collect!(&:to_i)
  if response[0] == 127 
    if response[3] == 0
      @blocked = true if @options[:blocked_search_engines].include? response[2]
    else 
      @age = true if response[1] < @options[:age_threshold]
      @threat = true if response[2] > @options[:threat_level_threshold]
      @options[:deny_types].each do |key|
        @deny = true if response[3] & key == key  
      end
      @blocked = true if @deny and @threat and @age
    end
  end
  return @blocked
end

#call(env) ⇒ Object



19
20
21
# File 'lib/httpbl.rb', line 19

def call(env)
  dup._call(env)
end

#resolve(ip) ⇒ Object



34
35
36
37
38
39
40
# File 'lib/httpbl.rb', line 34

def resolve(ip)
  query = @options[:api_key] + '.' + ip.split('.').reverse.join('.') + '.dnsbl.httpbl.org'
  Timeout::timeout(@options[:dns_timeout]) do
     Resolv::DNS.new.getaddress(query).to_s rescue nil
  end
  rescue Timeout::Error, Errno::ECONNREFUSED
end