Class: Rack::Honeypot

Inherits:
Object
  • Object
show all
Includes:
Unindentable
Defined in:
lib/rack/honeypot.rb

Instance Method Summary collapse

Constructor Details

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

Returns a new instance of Honeypot.



7
8
9
10
11
12
13
14
# File 'lib/rack/honeypot.rb', line 7

def initialize(app, options={})
  @app = app
  @class_name   = options[:class_name] || "phonetoy"
  @label        = options[:label] || "Don't fill in this field"
  @input_name   = options[:input_name] || "email"
  @input_value  = options[:input_value] || ""
  @logger       = options[:logger]
end

Instance Method Details

#build_response_body(response) ⇒ Object



36
37
38
39
40
# File 'lib/rack/honeypot.rb', line 36

def build_response_body(response)
  response_body = ""
  response.each { |part| response_body += part }
  response_body
end

#call(env) ⇒ Object



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

def call(env)
  if spambot_submission?(Rack::Request.new(env).params)
    @logger.warn("[Rack::Honeypot] Spam bot detected; responded with null") unless @logger.nil?
    send_to_dead_end
  else
    status, headers, response = @app.call(env)
    new_body = insert_honeypot(build_response_body(response))
    new_headers = recalculate_body_length(headers, new_body)
    [status, new_headers, new_body]
  end
end

#insert_honeypot(body) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/rack/honeypot.rb', line 48

def insert_honeypot(body)
  css = unindent <<-BLOCK
    <style type='text/css' media='all'>
      div.#{@class_name} {
        display:none;
      }
    </style>
  BLOCK
  div = unindent <<-BLOCK
    <div class='#{@class_name}'>
      <label for='#{@input_name}'>#{@label}</label>
      <input type='text' name='#{@input_name}' value='#{@input_value}'/>
    </div>
  BLOCK
  body.gsub!(/<\/head>/, css + "\n</head>")
  body.gsub!(/<form(.*)>/, '<form\1>' + "\n" + div)
  body
end

#recalculate_body_length(headers, body) ⇒ Object



42
43
44
45
46
# File 'lib/rack/honeypot.rb', line 42

def recalculate_body_length(headers, body)
  new_headers = headers
  new_headers["Content-Length"] = body.length.to_s
  new_headers
end

#send_to_dead_endObject



32
33
34
# File 'lib/rack/honeypot.rb', line 32

def send_to_dead_end
  [200, {'Content-Type' => 'text/html', "Content-Length" => "0"}, []]
end

#spambot_submission?(form_hash) ⇒ Boolean

Returns:

  • (Boolean)


28
29
30
# File 'lib/rack/honeypot.rb', line 28

def spambot_submission?(form_hash)
  form_hash && form_hash[@input_name] && form_hash[@input_name] != @input_value
end