86 lines
2.6 KiB
Python
86 lines
2.6 KiB
Python
import asyncio, json, urllib.request, sys
|
|
|
|
async def recv_one(reader):
|
|
b1 = await reader.readexactly(2)
|
|
fin_opcode = b1[0]
|
|
masked_len = b1[1]
|
|
length = masked_len & 0x7F
|
|
if length == 126:
|
|
ext = await reader.readexactly(2)
|
|
length = int.from_bytes(ext, 'big')
|
|
elif length == 127:
|
|
ext = await reader.readexactly(8)
|
|
length = int.from_bytes(ext, 'big')
|
|
masked = (masked_len & 0x80) != 0
|
|
if masked:
|
|
mask = await reader.readexactly(4)
|
|
payload = await reader.readexactly(length) if length else b''
|
|
if masked:
|
|
payload = bytes(b ^ mask[i % 4] for i, b in enumerate(payload))
|
|
return fin_opcode & 0x0F, payload
|
|
|
|
async def send_text(writer, text):
|
|
data = text.encode('utf-8')
|
|
frame = bytearray()
|
|
frame.append(0x81)
|
|
n = len(data)
|
|
mask = b'ABCD'
|
|
if n < 126:
|
|
frame.append(0x80 | n)
|
|
elif n < (1<<16):
|
|
frame.append(0x80 | 126)
|
|
frame += n.to_bytes(2, 'big')
|
|
else:
|
|
frame.append(0x80 | 127)
|
|
frame += n.to_bytes(8, 'big')
|
|
frame += mask
|
|
frame += bytes(b ^ mask[i % 4] for i, b in enumerate(data))
|
|
writer.write(frame)
|
|
await writer.drain()
|
|
|
|
async def main():
|
|
version = json.load(urllib.request.urlopen('http://127.0.0.1:9222/json/version'))
|
|
ws = version['webSocketDebuggerUrl']
|
|
assert ws.startswith('ws://')
|
|
hostportpath = ws[len('ws://'):]
|
|
hostport, _, path = hostportpath.partition('/')
|
|
host, port = hostport.split(':')
|
|
port = int(port)
|
|
path = '/' + path
|
|
reader, writer = await asyncio.open_connection(host, port)
|
|
key = 'dGhlIHNhbXBsZSBub25jZQ=='
|
|
req = (
|
|
f'GET {path} HTTP/1.1\r\n'
|
|
f'Host: {host}:{port}\r\n'
|
|
'Upgrade: websocket\r\n'
|
|
'Connection: Upgrade\r\n'
|
|
f'Sec-WebSocket-Key: {key}\r\n'
|
|
'Sec-WebSocket-Version: 13\r\n\r\n'
|
|
)
|
|
writer.write(req.encode())
|
|
await writer.drain()
|
|
resp = await reader.readuntil(b'\r\n\r\n')
|
|
print('HANDSHAKE_OK' if b'101' in resp else resp.decode(errors='ignore'))
|
|
|
|
msgs = [
|
|
{"id":1,"method":"Browser.getVersion"},
|
|
{"id":2,"method":"Target.getTargets"},
|
|
{"id":3,"method":"Target.createTarget","params":{"url":"https://example.com"}},
|
|
]
|
|
for m in msgs:
|
|
await send_text(writer, json.dumps(m))
|
|
|
|
for _ in range(10):
|
|
opcode, payload = await recv_one(reader)
|
|
if opcode == 1:
|
|
txt = payload.decode('utf-8', errors='ignore')
|
|
print(txt)
|
|
elif opcode == 8:
|
|
print('CLOSE')
|
|
break
|
|
|
|
writer.close()
|
|
await writer.wait_closed()
|
|
|
|
asyncio.run(main())
|