前几天初步学了下gevent,不写点东西真是手痒啊,那就写个代理呗。
第一步,接受代理客户端请求
class Server:
def __init__(self, host, port=8000,listenum=5):
self.host = host
self.port = port
self.server = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
self.server.setsockopt ( socket.SOL_SOCKET, socket.SO_REUSEADDR , 1) # no time wait
self.server.bind ( (host, port ) )
self.server.listen (listenum)
self.alive = True
self.header = {}
def run(self):
while self.alive:
conn, addr = self.server.accept()
data = StringIO('')
while True:
res = conn.recv( 8096)
data.write(res)
if len(res) < 8096 :
break
data.flush()
data.seek(0)
if data.len==0: continue
self.parser_header(data)
port = self.header.get('port',80)
pack =Packet (conn = conn , data= data.getvalue() , header= self.header, dest_port=port)
queue.put(pack)
logging.info(u"proxy addr %s ——————> %s "%(addr,self.header['host']))
def parser_header(self,data):
first_line = data.readline()
data.seek( len(first_line))
self.header['method'] , self.header['path'], self.header['version'] = first_line.split()
for line in data.readlines():
if line.startswith('Host'):
line = line.strip('\r\n')
if line.count(':') == 1: line+=':80'
self.header['host'],self.header['port'] = line[6:].split(":")
break
def kill(self):
self.alive = False
第二步proxy代理请求
class FastProxy:
def __init__(self):
pass
def run(self):
while True:
pack = queue.get()
self.request(pack)
@staticmethod
def request(pack):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect(( pack.dest, pack.port ))
#s.settimeout(10)
size = s.sendall( pack.data )
except socket.error as msg:
s.close()
s = None
return
while True:
try:
res = s.recv(4096)
except socket.error:
s.close()
s = None
return
try:
pack.conn.sendall(res)
except socket.error:
pack.conn.close()
pack.conn = None
return
logging.debug("send %d....."%(len(res)))
if len(res) ==0:
pack.conn.close()
s.close()
logging.info("one request has been handled ,still has %d request"%queue.qsize())
break
第三步全局的结构
每一个连接的地址信息和数据都放Packet里,是server和proxy的纽带
class Packet:
def __init__(self, conn, data, header, dest_port = 80):
self.conn = conn
self.header = header
self.dest = socket.gethostbyname( header['host'])
self.port = int(dest_port)
self.data = data
queue = Queue() #all the requests will be put into queue by Server and be got and handled from queue by Proxy. it's safe.
queue用来放packet,server生产,proxy消费
最后,都扔到Pool里去
if __name__ == '__main__':
pool = Pool(50)
pool.spawn(start_server)
for i in range(50):
pool.spawn( start_proxy)
pool.join()
怎么使用
在浏览器里装一个代理插件,我用的是Chrome+SwitchOmega。然后设置下代理的端口号和ip。