[使用PyQt5,我已经成功设置了QWebEngineUrlRequestInterceptor子类,并且可以修改Web请求的标头和数据。我正在为类似VPN的应用程序构建此应用程序,在该应用程序中,请求被转换为数据包(使用scapy的IP()
对象或类似模块发送),加密并发送到另一个地址,该地址将解密并将数据包数据转换回QWebEngine请求。我的问题是如何将用PyQt5拦截的Web请求转换为IP数据包格式,反之亦然?
这里是拦截器代码:
#Custom url interceptor for modifying headers
#and the url before sending it on
class UrlRequestInterceptor(QWebEngineUrlRequestInterceptor):
def __init__(self,parent=None):
super(QWebEngineUrlRequestInterceptor,self).__init__(parent)
def interceptRequest(self,info):
#Modify the actual request here - todo: block the
#request here, packet simulate etc...
info.setHttpHeader(b"Accept-Language",InterClassVariables.languageCode.encode())
问题是,当您需要IP信息(第3层)时,QWebEngineUrlRequestInterceptor
与HTTP(第7层)进行交互。 QWebEngineUrlRequestInfo没有任何IP属性(同样位于第7层)。
虽然可以使用Qt的QHostInfo,但使用香草Python更简单。在这里,我们使用netifaces。尽管alternatives不在标准库中,但它更复杂,与平台有关或需要Internet连接。
import socket
from PyQt5.Qt import QUrl
from PyQt5.Qt import QWebEngineUrlRequestInterceptor
from PyQt5.Qt import QWebEngineUrlRequestInfo
import netifaces
from scapy.all import IP
#Custom url interceptor for modifying headers
#and the url before sending it on
class UrlRequestInterceptor(QWebEngineUrlRequestInterceptor):
def __init__(self,parent=None):
super(QWebEngineUrlRequestInterceptor,self).__init__(parent)
self.info = None
def interceptRequest(self, info: QWebEngineUrlRequestInfo):
#Modify the actual request here - todo: block the
#request here, packet simulate etc...
self.info = info
self.info.setHttpHeader(b"Accept-Language",
InterClassVariables.languageCode.encode())
self.sendPacket()
def getDestIp(self):
qUrl = self.info.requestURL()
url = qUrl.toString()
dest_ip = socket.gethostbyname(url)
return dest_ip
def sendPacket()
src_ip = netifaces.gateways()['default'][netifaces.AF_INET][0]
dest_ip = get_dest_ip(self.info)
ip_layer = IP(src=src_ip, dst=dest_ip)
other_layers = OTHER_PROTOCOLS() # FIXME
pkt = ip_layer/other_layers
send(pkt) # Choose whichever send function is most appropriate here
如果我们打印数据包(没有其他层),我们应该得到类似的内容:
$ python project.py -show-packet # Pseudo cli
###[ IP ]###
version = 4
ihl = None
tos = 0x0
len = None
id = 1
flags =
frag = 0
ttl = 64
proto = ip
chksum = None
src = 172.31.98.1
dst = 151.101.65.69
\options \