Python入门:python实现http透明代理

本文介绍了一个简单的HTTP代理服务器实现,该服务器使用Python的socket模块完成客户端请求到目标服务器的转发。文章展示了如何解析HTTP请求、建立连接并进行非阻塞的数据传输。
#-*- coding: UTF-8 -*-
import socket,select
import sys
import threading
from multiprocessing import Process
class Proxy:
    def __init__(self,soc):
        self.client,_=soc.accept()
        self.target=None
        self.request_url=None
        self.BUFSIZE=4096
        self.method=None
        self.targetHost=None
    def getClientRequest(self):
        request=self.client.recv(self.BUFSIZE).decode()
        if not request:
            return None
        cn=request.find('\n')
        firstLine=request[:cn]
        print(firstLine[:len(firstLine)-9])
        line=firstLine.split()
        self.method=line[0]
        self.targetHost=line[1]
        return request

    def  getHeader(self,request):
        cn = request.find('\n')
        done = request[cn + 1:]
        #print(done)
        headers = {}
        print('!!!!!!!!!!!!!!!')
        for i in done.split('\r\n\r\n')[0].split('\r\n'):
            #print(i)

            if i != '':
                k, v = i.split(': ')
                headers[k] = v
        print(headers)
        data = {}
        for i in done.split('\r\n\r\n')[1].split('&'):
            if i != '':
                k,v = i.split('=')
                data[k] = v
        print(data)
        return [headers,data]
        
    def commonMethod(self,request):
        tmp=self.targetHost.split('/')
        net=tmp[0]+'//'+tmp[2]
        request=request.replace(net,'')
        targetAddr=self.getTargetInfo(tmp[2])
        try:
            (fam,_,_,_,addr)=socket.getaddrinfo(targetAddr[0],targetAddr[1])[0]
        except Exception as e:
            print(e)
            return
        self.target=socket.socket(fam)
        self.target.connect(addr)
        self.target.send(request.encode())
        self.nonblocking()
    def connectMethod(self,request): #对于CONNECT处理可以添加在这里
        pass
    def run(self):
        request=self.getClientRequest()
        self.getHeader(request)
        if request:
            if self.method in ['GET','POST','PUT',"DELETE",'HAVE']:
                self.commonMethod(request)
            elif self.method=='CONNECT':
                self.connectMethod(request)
    def nonblocking(self):
        inputs=[self.client,self.target]
        while True:
            readable,writeable,errs=select.select(inputs,[],inputs,3)
            if errs:
                break
            for soc in readable:
                data=soc.recv(self.BUFSIZE)
                if data:
                    if soc is self.client:
                        self.target.send(data)
                    elif soc is self.target:
                        self.client.send(data)
                else:
                    break
        self.client.close()
        self.target.close()
    def getTargetInfo(self,host):
        port=0
        site=None
        if ':' in host:
            tmp=host.split(':')
            site=tmp[0]
            port=int(tmp[1])
        else:
            site=host
            port=80
        return site,port
if __name__=='__main__':     
    host = '0.0.0.0'
    port = 8088
    backlog = 5
    server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
    server.bind((host,port))
    server.listen(5)
    while True:
        t = threading.Thread(target=Proxy(server).run)
        t.start()
        # p=Process(target=Proxy(server).run, args=()) #多进程
        # p.start()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值