用gevent写个代理呗

前几天初步学了下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。

源代码:https://github.com/cocaer/pyproxy

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值