Skip to content

Instantly share code, notes, and snippets.

Created December 14, 2011 19:26
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save anonymous/1478065 to your computer and use it in GitHub Desktop.
Save anonymous/1478065 to your computer and use it in GitHub Desktop.
Grabs a proxy list from spys.ru and programmatically checks for the first one that responds fast enough for your liking.
require 'net/http'
require 'timeout'
$proxies = nil
Net::HTTP.start('spys.ru') do |http|
response, body = http.get('/en/http-proxy-list/')
secret = body.match(/">(.+?);<\/script>/)[1].split(';')
keys, holder = {}, binding
secret.each { |s| keys[s.split('=')[0]] = eval(s, holder) }
finder = %r{4>([0-9.]+)<.+?>"\+(.+?)\)<.+?/anon.+?[12]>(.+?)</f}
$proxies = body.scan(finder)
$proxies.each_with_index do |p, i|
port = '', holder
p[1].split('+').each { |k| port << eval(k, holder) }
$proxies[i] = "#{p[0]}:#{port[2..-1].join}"
end
end
def get_proxy
return nil if $proxies.empty?
Timeout::timeout(1) do
test = $proxies.shift
ip, port = test.split(':')
Net::HTTP::Proxy(ip, port).start('www.google.com') do |http|
response, body = http.get('/')
return get_proxy unless ['200', '302'].include?(response.code)
end
return test
end rescue get_proxy
end
require 'net/http'
require 'timeout'
$proxies = nil
# bad global, but it prevents doing the search again for each new test
Net::HTTP.start('spys.ru') do |http|
response, body = http.get('/en/http-proxy-list/')
secret = body.match(/">(.+?);<\/script>/)[1].split(';')
# ex: g7v2=2677;t0z6=2189;f6e5=1478;q7z6j0=0^g7v2;l2o5e5=1^t0z6;h8n4p6=2^f6e5;
# spys.ru seem like cool people; they offer their service entirely free,
# and most of the proxies are pretty decent, but they do make it slightly
# tougher to programmatically get the list
# rather than just showing the ip:port combination in plain text, they're
# using javascript, secret variables, and a bunch of xor all over the place
# to eventually display the port
# I'm sure they did this for a bit of "security", of course, but I also feel
# like they were issuing it as a playful challenge to fellow programmers
# maybe not, but I enjoyed decrypting them nonetheless
keys, holder = {}, binding
# keys holds the aforementioned variable names, holder is a binding for eval
secret.each { |s| keys[s.split('=')[0]] = eval(s, holder) }
finder = %r{4>([0-9.]+)<.+?>"\+(.+?)\)<.+?/anon.+?[12]>(.+?)</f}
# pretty tame as far as regexes go; pulls out the ip, the javascript for
# writing the xored port and the anonymity of the proxy; non-anonymous proxies
# are silly, so filter them
# ex: ['85.114.132.49', '(y5t0y5^w3t0)+(j0p6j0^g7i9)+(d4c3f6^v2c3)+(b2y5o5^l2d4)', 'ANM']
$proxies = body.scan(finder)
$proxies.each_with_index do |p, i|
port = '', holder # same eval binding, of course
p[1].split('+').each { |k| port << eval(k, holder) }
# the addition in the javascript isn't numeric, so evaling the whole thing
# won't do; that's why port is initialized as an empty string
$proxies[i] = "#{p[0]}:#{port[2..-1].join}"
# mush it all back together, ex: 85.114.132.49:3128
# start from index 2 because 0 is '' and 1 is holder.class (Binding)
end
end
def get_proxy
return nil if $proxies.empty? # bad luck, not a single proxy qualified
Timeout::timeout(3) do
test = $proxies.shift
ip, port = test.split(':')
Net::HTTP::Proxy(ip, port).start('www.google.com') do |http|
response, body = http.get('/')
# the proxy server might have responded quickly, but can you use it?
return get_proxy unless ['200', '302'].include?(response.code)
# 200 for OK, 302 for the redirect Google sends for other countries
end
return test
end rescue get_proxy # timeout expired, try again
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment