Python入门:python实现http透明代理(二)
2016-08-31 15:33
417 查看
编写此例只是因为个人在学习的过程中遇到了诸多问题,并且没有在网上找到一个比较全面的、浅析的案例,大多案例直接用到了select、queue等等,结构也特别清晰,导致不明白哪些是必要的,业务处理逻辑是什么样,所以在此写出来,作为自己的笔记,同时也可以供初学者参考
浏览器(C)—————-HttpProxy(HP)—————-web服务器(S)
要做http代理,这个代理即要做代理服务端,也要做客户端,要接收两头发来的数据,同时要将两头接收到数据转发至对方
1、C向S发送请求
2、HP拦截(处理)
3、HP处理完拦截的数据转发至S
4、S将返回的数据传递给HP
5、HP再将数据拦截(处理)
6、转交给C
1-6就完成了一次完整的请求
扩展:
Accept a connection. The socket must be bound to an address and listening for connections. The return value is a pair (conn, address) where conn is a new socket object usable to send and receive data on the connection, and address is the address bound to the socket on the other end of the connection.
浏览器(C)—————-HttpProxy(HP)—————-web服务器(S)
要做http代理,这个代理即要做代理服务端,也要做客户端,要接收两头发来的数据,同时要将两头接收到数据转发至对方
1、C向S发送请求
2、HP拦截(处理)
3、HP处理完拦截的数据转发至S
4、S将返回的数据传递给HP
5、HP再将数据拦截(处理)
6、转交给C
1-6就完成了一次完整的请求
''' python3.5.2 ''' import socket import threading import re def proxy(ser): #接收线程传递过来的socket对象 conn,addr = ser.accept() #接收一个connection然后返回新的connection和address data = conn.recv(1024) #接收从conn收到的数据 #print(data) #查看接收到的内容,收到的数据是byte类型 path_num = data.decode().find('\r\n') #解码byte类型数据为字符串,然后查找第一行的末尾数 first_line = data.decode()[:path_num] #获取第一行数据(后续要用来判断请求的方法《method》和相对路径) remain_line = data.decode()[path_num:] #获取http head及data,即除第一行以外的数据(需要了解http协议就知道为什么这样处理) method,path_url,protocol = first_line.split() #http第一行数据中包含三个内容,用空格分割之后就得到三个(后面需要用) #print(method) #查看method print(path_url) #查看path_url(即全url)(后续需要用这个url分割相对路径) #print(protocol) #查看protocol(即http的请求协议,一般就是“http/1.1”) host = re.findall(r'(?<=://).*?(?=/)',path_url)[0] #从全url中分割出host(这个host是用来作为proxy转发到web服务器时的目标地址用) main_url = re.findall(r'.*?://',path_url)[0] + host #从全url中分割出主url(即http://加host) #print(main_url) #查看主url path = path_url[len(main_url):] #相对路径/shopxx-mobile/goods/list/243.jhtml s_data = method + ' ' + path + ' ' + protocol + remain_line#将抓到的包进行处理,然后合并**作为**后续转发到web服务器的数据 print(s_data) #打印要发送的数据 print(host) #打印host try: #判断从抓取到的数据中的host是ip地址类型的,还是域名类型的,然后有不同处理 r_host = socket.gethostbyname(host) #尝试使用域名解析ip地址,如果解析成功就将port赋值80(这里不严谨,没有考虑https) port = '80' except: if ':' in host: #如果host中有“:”说明host就是ip地址,并分割出ip址和port r_host,port = host.split(':') else: port = '80' s_s = socket.socket() #再创建一个sockte对象,用于前面分离出的ip与端口进行转发浏览器接收到的数据 print(r_host,port) s_s.connect((r_host,int(port))) #连接从浏览器接收到的数据中的目标ip与端口 print("############################") print(s_data) #打印要转发的数据 s_s.send(s_data.encode()) #转发要发送的数据 d = s_s.recv(1024) #接收转发到web服务器的返回数据 print(d) #打印从web服务器返回的数据 conn.send(d) #将接收的数据使用最上面socket对象中的conn进行发送 #ser.close() #s_s.close() SER_ADDR = ('', 8088) #因为socket中的bind需要一个地址与端口的tuple类型 ser = socket.socket() #创建一个socket对象 ser.bind(SER_ADDR) #对socket对象绑定地址和端口 ser.listen(5) #设置socket对象同时监听多少个链接 while True: #为开启线程循环 t = threading.Thread(target=proxy(ser)) t.start()
扩展:
Accept a connection. The socket must be bound to an address and listening for connections. The return value is a pair (conn, address) where conn is a new socket object usable to send and receive data on the connection, and address is the address bound to the socket on the other end of the connection.
相关文章推荐
- Python入门:python实现http透明代理
- Python入门:python实现http透明代理(三)
- Python模块学习 ---- httplib HTTP协议客户端实现
- Python入门:类的继承与实现
- [原创]用python检测LVS real server状态实现HTTP高可用
- python多线程http下载实现示例
- 转:Python模块学习 ---- httplib HTTP协议客户端实现
- python中httplib实现长连接
- python入门篇1:基于flask的留言板网站实现
- HTTP长连接实现“服务器推”的技术快速入门及演示示例
- HTTP长连接实现“服务器推”的技术快速入门及演示示例
- 06_android入门_采用HttpURLConnection的POST方式实现登陆案例
- Python模块学习 ---- httplib HTTP协议客户端实现
- Python学习一、 Http协议客户端实现
- Python模块学习 ---- httplib HTTP协议客户端实现
- (转)Python中实现带Cookie的Http的Post请求
- D-Bus入门(四)——QTDBUS代码,实现ofono代码下的python测试文件activite-context的功能
- Python模块学习 ---- httplib HTTP协议客户端实现
- Python:httplib模块用于HTTP协议客户端实现
- Python HTTP客户端如何实现自定义Cookie