You can block requests at the Rack middleware level. You can use the gem ( rack-attack ), or you can create your own Rack middleware.
Option 1: Rack-attack
https://github.com/kickstarter/rack-attack
If you want to go in standby mode, after you installed it, you can use a configuration that looks like this:
class Rack::Attack
blacklist("block referer spam") do |request|
spammers = [/co\.lumb\.co/, /darodar/]
spammers.find { |spammer| request.referer =~ spammer }
end
end
Since we love testing, here is a test that you must write first before implementing the solution (using the RSpec request specification):
require "rails_helper"
describe "Referer blacklist", type: :request do
describe "referer spam" do
it "is blocked" do
spammers = ["http://co.lumb.co/", "http://forum.topic56809347.darodar.com/"]
spammers.each do |spammer|
get root_path, {}, { "HTTP_REFERER" => spammer }
expect(response).to be_forbidden
end
end
end
describe "regular referer" do
it "is not blocked" do
get root_path, {}, { "HTTP_REFERER" => "google.com" }
expect(response).to be_ok
end
end
describe "direct request" do
it "is not blocked" do
get root_path
expect(response).to be_ok
end
end
end
Option 2: Custom Middleware
( -), , Rack, (: ):
class RefererSpamBlocker
SPAMMERS = [/co\.lumb\.co/, /darodar/]
def initialize(app)
@app = app
end
def call(env)
if blacklisted?(env)
forbidden
else
@app.call(env)
end
end
private
def blacklisted?(env)
!SPAMMERS.find { |spammer| env["HTTP_REFERER"] =~ spammer }.empty?
end
def forbidden
[403, {'Content-Type' => 'text/plain'}, ["Forbidden\n"]]
end
end
Rails, , config/application.rb
config.middleware.use RefererSpamBlocker
, Rack :
http://railscasts.com/episodes/151-rack-middleware
Bonus
, , , ENV .