简单的实现一个HTTP代理
0x00前言
之前一直尝试先个http代理,每次都是败北而归。这次稍微好一点….补上坑吧
0x01如何实现
HTTP代理
request
浏览器->py(代理)->目标
response
目标->py(代理)->浏览器
获取Host头里指向的域名和端口,如果没有指定端口默认为80,处理Proxy-Connection
头部。将Proxy-Connection
修改为Connection: close
。
使用异步来处理请求,否则可能会出现响应跟不上的问题
0x02实现
#@author:九世
#@time:2019/12/2
#@file:test.py
from gevent.monkey import patch_all;patch_all()
from gevent.server import StreamServer
import socket
import re
class Http(object):
def __init__(self,text):
self.yuan=text
self.text=bytes.decode(text).replace('\r','')
self.headers={}
self.TUNNEL_OK = b'HTTP/1.1 200 Connection Established\r\nConnection: close\r\n\r\n'
def proxyconnection(self,text):
self.yuan=re.sub(b"Proxy-Connection",b"Connection",self.yuan)
self.yuan=re.sub(b"keep-alive",b"close",self.yuan)
domain=re.findall("\s.* HTTP",text)[0]
dtm=str(domain).rstrip().lstrip().replace(self.headers['Host'],'').replace('http://',' ').replace('https://',' ')
searchs=str(domain)
self.yuan=re.sub(bytes(searchs,encoding='utf-8'),bytes(dtm,encoding='utf-8'),self.yuan)
def jiexi(self):
try:
data=re.findall('Host[:].*',self.text)
if len(data)>0:
dt=str(data[0]).replace('Host:','').split(':')
if len(dt)==2:
self.headers['Host']=str('{}'.format(dt[0]).strip().rstrip())
self.headers['port']=dt[1]
else:
self.headers['Host']=str('{}'.format(dt[0])).rstrip().lstrip()
self.headers['port']=80
if 'Proxy-Connection' in self.text and not "CONNECT" in self.text:
self.proxyconnection(self.text)
if 'Host' in self.headers:
return self.headers['Host'],self.headers['port'],self.yuan
except:
pass
def send_banners(self,host,port,data):
jg=b''
c=socket.socket()
c.connect((host,int(port)))
c.sendall(data)
while True:
rc=c.recv(4096)
if rc:
jg+=rc
else:
break
return jg
def main(s,address):
try:
while True:
request = s.recv(4096)
print(request)
obj = Http(request)
jg = obj.jiexi()
if b'CONNECT' in request:
s.sendall(obj.TUNNEL_OK)
while True:
rv=s.recv(1024)
if rv:
fb=obj.send_banners(jg[0],jg[1],rv)
print(fb)
s.sendall(fb)
else:
break
else:
fb = obj.send_banners(jg[0], jg[1], jg[2])
s.sendall(fb)
except Exception as r:
if 'not subscriptable' in str(r):
pass
if __name__ == '__main__':
print('[+] 开始监听')
try:
server=StreamServer(("127.0.0.1",4444),main)
server.serve_forever()
except:
pass
'''
s=socket.socket()
s.bind(('127.0.0.1',4444))
s.listen(1)
while True:
accept,adr=s.accept()
request=accept.recv(4096)
print(request)
obj=Http(request)
jg=obj.jiexi()
fb=obj.send_banners(jg[0],jg[1],jg[2])
accept.sendall(fb)
'''
小结:
1.解析HTTP请求获取Host头里请求的内容和端口
2.使用异步来处理,否则会出现响应更不上的问题
3.修改Proxy-Connection头为Connection:close
4.处理HTTPS
0x03缺陷
- 无法转发HTTPS
- 某些隐性BUG
0x04参考链接
python http代理支持 https - 宁次 - 博客园
什么是HTTP隧道,怎么理解HTTP隧道呢? - 知乎
Python HTTPS代理隧道 - 代码日志
python – gevent StreamServer.start()似乎没有做我期望的 - 代码日志
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。
文章标题:简单的实现一个HTTP代理
本文作者:九世
发布时间:2019-12-02, 22:43:58
最后更新:2019-12-02, 23:11:36
原始链接:http://jiushill.github.io/posts/2aaeb1.html版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。