class Rack::DetectTor
Public Class Methods
new(app, options={})
click to toggle source
# File lib/rack-detect-tor.rb, line 7 def initialize(app, options={}) @app = app @options = { 'external_ip' => nil, 'external_port' => nil, 'update_frequency' => 60*60 }.merge(options) @identifier = Hash[@options.select{|k,v| k =~ /^external_/}. sort_by{|k,v| k}].values.map{|v| v.to_s == '' ? '*' : v}.join('/') log_message 'Fetching initial list of tor exits...' @tor_exits = fetch_tor_exits || {} start_update_timer unless @options['update_frequency'].to_i == 0 end
Public Instance Methods
call(env)
click to toggle source
# File lib/rack-detect-tor.rb, line 25 def call(env) env['tor_exit_user'] = @tor_exits.include? Rack::Request.new(env).ip unless env['tor_exit_user'] == true @app.call(env) end
Private Instance Methods
fetch_tor_exits()
click to toggle source
# File lib/rack-detect-tor.rb, line 32 def fetch_tor_exits begin if @options.select{|k,v| k =~ /^external_/}.values.map{|v| v.to_s}.include? '' log_message "WARNING: external_ip/external_port not specified. " + "Using list of ALL exits. Results will NOT be accurate" tor_exits = open('https://check.torproject.org/exit-addresses').read. split("\n").select{|i| i =~ /^ExitAddress/}.map{|j| j.split(' ')[1]} else check_url = "https://check.torproject.org/cgi-bin/TorBulkExitList.py?" + "ip=#{@options['external_ip']}&port=#{@options['external_port']}" tor_exits = open(check_url).read.split("\n").select{|i| !(i =~ /^\#/)} end rescue OpenURI::HTTPError => e log_error "Error fetching list of tor exits (#{e})." return nil end log_message "Found #{tor_exits.count} exits." return tor_exits end
log_error(message)
click to toggle source
# File lib/rack-detect-tor.rb, line 72 def log_error(message) $stderr.puts "Rack::DetectTor [#{@identifier}]: ERROR: #{message}" end
log_message(message)
click to toggle source
# File lib/rack-detect-tor.rb, line 68 def log_message(message) $stdout.puts "Rack::DetectTor [#{@identifier}]: #{message}" end
start_update_timer()
click to toggle source
# File lib/rack-detect-tor.rb, line 55 def start_update_timer log_message "Starting update timer... (updating every #{@options['update_frequency']} seconds)" Thread.new do EventMachine.run do @update_timer = EventMachine::PeriodicTimer.new(@options['update_frequency']) do log_message 'Updating list of tor exits...' @tor_exits = fetch_tor_exits || @tor_exits end end end end