MCPcopy Create free account
hub / github.com/cppla/moto / socks5_http_get

Function socks5_http_get

test/bench.py:39–132  ·  view source on GitHub ↗
(timeout: float, phase: str)

Source from the content-addressed store, hash-verified

37 self.phase = phase
38
39async def socks5_http_get(timeout: float, phase: str) -> Result:
40 start = time.monotonic()
41 reader = writer = None
42 try:
43 # 连接到本地 SOCKS5
44 conn_begin = time.monotonic()
45 reader, writer = await asyncio.wait_for(
46 asyncio.open_connection(PROXY_HOST, PROXY_PORT),
47 timeout=timeout
48 )
49 # SOCKS5 greeting
50 writer.write(b"\x05\x01\x00") # VER=5, NMETHODS=1, METHOD=0(no auth)
51 await writer.drain()
52 resp = await asyncio.wait_for(reader.readexactly(2), timeout=timeout)
53 if resp != b"\x05\x00":
54 raise RuntimeError(f"socks5 greet resp invalid: {resp!r}")
55
56 # CONNECT 请求
57 host_bytes = TARGET_HOST.encode()
58 pkt = bytearray()
59 pkt += b"\x05" # VER
60 pkt += b"\x01" # CMD=CONNECT
61 pkt += b"\x00" # RSV
62 pkt += b"\x03" # ATYP=DOMAIN
63 pkt += bytes([len(host_bytes)])
64 pkt += host_bytes
65 pkt += TARGET_PORT.to_bytes(2, "big")
66 writer.write(pkt)
67 await writer.drain()
68 # 应答:VER REP RSV ATYP ... 最少 10 字节 (域名长度可能不同)
69 ver_rep = await asyncio.wait_for(reader.readexactly(4), timeout=timeout)
70 if len(ver_rep) != 4 or ver_rep[1] != 0x00:
71 raise RuntimeError(f"socks5 connect failed: {ver_rep!r}")
72 atyp = ver_rep[3]
73 if atyp == 1: # IPv4
74 await asyncio.wait_for(reader.readexactly(4+2), timeout=timeout)
75 elif atyp == 3:
76 ln = await asyncio.wait_for(reader.readexactly(1), timeout=timeout)
77 await asyncio.wait_for(reader.readexactly(ln[0] + 2), timeout=timeout)
78 elif atyp == 4: # IPv6
79 await asyncio.wait_for(reader.readexactly(16+2), timeout=timeout)
80 else:
81 raise RuntimeError(f"socks5 atyp unsupported: {atyp}")
82
83 connect_done = time.monotonic()
84 connect_ms = (connect_done - conn_begin) * 1000.0
85
86 # 发起 HTTP 请求
87 writer.write(HTTP_REQ_TEMPLATE.replace(b"{host}", TARGET_HOST.encode()))
88 await writer.drain()
89
90 # 首字节
91 first_chunk = await asyncio.wait_for(reader.read(1), timeout=timeout)
92 if not first_chunk:
93 raise RuntimeError("empty first byte")
94 first_byte_ms = (time.monotonic() - start) * 1000.0
95
96 # 读剩余响应(简单读取到 EOF)

Callers 1

workerFunction · 0.85

Calls 1

ResultClass · 0.85

Tested by

no test coverage detected