Skip to content

Instantly share code, notes, and snippets.

@byingyang
Created July 15, 2011 17:08
Show Gist options
  • Save byingyang/1085078 to your computer and use it in GitHub Desktop.
Save byingyang/1085078 to your computer and use it in GitHub Desktop.
An old script I whipped together that downloads every song that plays on pandora
#!/usr/bin/env ruby
# this line imports the libpcap ruby bindings
require 'rubygems'
require 'pcap'
require 'pcaplet'
require 'socket'
# thread safe... but we're counting on the fact that the sniffer won't begin again until we're at least
# partially requesting the song (the GET keyword has already been written by the time the network listener is listening again)
def ProcessRequest(host, req, filename)
# connect to the host that we found and grab the file
s = TCPSocket.open(host, 80)
s.print(req)
f = File.new("music/#{filename}.m4a", 'w+')
10.times { s.gets }
while line = s.gets
f.write(line)
end
f.close
s.close
end
def GetSong
# pandora's host for grabbing the audio
pand_audio_host = /(audio.+\.pandora\.com)/
# create packet sniffer on the wireless card
network = Pcaplet.new('-s 1500 -i en1')
# we only need to look at web packets
www_filter = Pcap::Filter.new('tcp and dst port 80', network.capture)
network.add_filter(www_filter)
request = nil
match = nil
# only process the request if it's new
network.each_packet do |pkt|
# make sure that the request is valid GET request (threading issues)
puts pkt
if !pkt.tcp_data.nil? and !pkt.tcp_data.match('GET').nil?
# find the audio host they're using
match = pkt.tcp_data.match(pand_audio_host)
if !match.nil?
request = pkt.tcp_data
break
end
end
end
network.close
return request, match[0]
end
i = 1
while true
req, host = GetSong()
puts req
Thread.new(host, req, i) do |thehost, thereq, thenum|
ProcessRequest(thehost, thereq, (0..8).map{('a'..'z').to_a[rand(26)]}.join)
puts "Song #{thenum} downloaded"
end
i += 1
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment