Skip to content

Instantly share code, notes, and snippets.

@joshado
Created October 10, 2013 22:07
Show Gist options
  • Save joshado/6926408 to your computer and use it in GitHub Desktop.
Save joshado/6926408 to your computer and use it in GitHub Desktop.
A 10 minute ruby bit-torrent tracker :)
require 'sinatra'
require "sinatra/reloader"
PEER_DICT = Hash.new { |h,k| h[k] = {} }
class Hash
def bencode
[
"d",
map { |k,v| [k.to_s.bencode, v.bencode] },
"e"
].join('')
end
end
class Symbol
def bencode
to_s.bencode
end
end
class String
def bencode
"#{length}:#{to_s}"
end
end
class Fixnum
def bencode
"i#{to_s}e"
end
end
class Array
def bencode
[
"l",
map { |v| v.bencode },
"e"
].flatten.join('')
end
end
# puts "Thomas".bencode
# puts 1234.bencode
# puts [1,2,3,4].bencode
# puts({"a" => 123}.bencode)
# puts({"a" => [1,2,{"b" => :c}, [4,5,6]]}.bencode)
# exit(0)
get '/announce' do
info_hash = params['info_hash']
info_hash_disp = info_hash.unpack("C*")[0,20].map { |i| "%02x" % i }.join(" ")
peer_id = params['peer_id']
peer_id_disp = peer_id.unpack("C*")[0,20].map { |i| "%02x" % i }.join(" ")
port = params['port'].to_i
ip = params['ip'] || request.ip
event = params['event']
if event == 'started'
PEER_DICT[info_hash][peer_id] = [ip, port]
elsif event == 'stopped'
PEER_DICT[info_hash].delete(peer_id)
end
puts "Got annoucement '#{event}'"
puts "Info hash is #{info_hash_disp}"
puts "Peer id is #{peer_id_disp}"
puts "Port is #{port}"
puts "Remote IP is #{ip}"
puts "This info hash has #{PEER_DICT[info_hash].values.size} peers"
content_type 'text/plain'
p response = {
"interval" => 2,
"complete" => 10,
"incomplete" => 20,
"tracker_id" => "tracker-id",
"peers" => PEER_DICT[info_hash].map { |peer_id,params|
ip, port = params
{ "peer_id" => peer_id, "ip" => ip, "port" => port }
}
}.bencode
end
get '/scrape' do
puts "SCRAPE!"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment