mirror of
https://github.com/Flowseal/tg-ws-proxy.git
synced 2026-10-31 04:50:25 +03:00
some ai powered fixes for #1473
This commit is contained in:
+8
-4
@@ -284,17 +284,21 @@ async def probe_appdata_len(domain: str, port: int = 443,
|
|||||||
pass
|
pass
|
||||||
client_hello = outgoing.read()
|
client_hello = outgoing.read()
|
||||||
|
|
||||||
|
# Share one deadline across connecting, sending, and reading the flight.
|
||||||
|
loop = asyncio.get_running_loop()
|
||||||
|
deadline = loop.time() + timeout
|
||||||
reader, writer = await asyncio.wait_for(
|
reader, writer = await asyncio.wait_for(
|
||||||
asyncio.open_connection(domain, port), timeout=timeout)
|
asyncio.open_connection(domain, port), timeout=timeout)
|
||||||
writer.write(client_hello)
|
writer.write(client_hello)
|
||||||
await writer.drain()
|
await asyncio.wait_for(writer.drain(), timeout=deadline - loop.time())
|
||||||
|
|
||||||
flight = bytearray()
|
flight = bytearray()
|
||||||
loop = asyncio.get_running_loop()
|
|
||||||
deadline = loop.time() + timeout
|
|
||||||
while True:
|
while True:
|
||||||
|
remaining = deadline - loop.time()
|
||||||
|
if remaining <= 0:
|
||||||
|
raise asyncio.TimeoutError
|
||||||
chunk = await asyncio.wait_for(
|
chunk = await asyncio.wait_for(
|
||||||
reader.read(16384), timeout=max(0.1, deadline - loop.time()))
|
reader.read(16384), timeout=remaining)
|
||||||
if not chunk:
|
if not chunk:
|
||||||
return None
|
return None
|
||||||
flight.extend(chunk)
|
flight.extend(chunk)
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import struct
|
|||||||
import tempfile
|
import tempfile
|
||||||
import time
|
import time
|
||||||
import unittest
|
import unittest
|
||||||
|
from unittest.mock import AsyncMock, Mock, patch
|
||||||
|
|
||||||
from proxy import fake_tls
|
from proxy import fake_tls
|
||||||
from proxy.fake_tls import (
|
from proxy.fake_tls import (
|
||||||
@@ -337,6 +338,38 @@ def _self_signed_context() -> ssl.SSLContext:
|
|||||||
|
|
||||||
@unittest.skipUnless(getattr(ssl, 'HAS_TLSv1_3', False), 'needs TLS 1.3 in ssl')
|
@unittest.skipUnless(getattr(ssl, 'HAS_TLSv1_3', False), 'needs TLS 1.3 in ssl')
|
||||||
class ProbeAppdataLenTest(unittest.TestCase):
|
class ProbeAppdataLenTest(unittest.TestCase):
|
||||||
|
def test_continuous_records_do_not_extend_probe_timeout(self):
|
||||||
|
async def scenario():
|
||||||
|
async def read(_size):
|
||||||
|
await asyncio.sleep(0.01)
|
||||||
|
return _record(TLS_RECORD_CCS, 1)
|
||||||
|
|
||||||
|
reader = Mock(read=AsyncMock(side_effect=read))
|
||||||
|
writer = Mock(drain=AsyncMock())
|
||||||
|
with patch.object(fake_tls.asyncio, 'open_connection',
|
||||||
|
AsyncMock(return_value=(reader, writer))):
|
||||||
|
result = await asyncio.wait_for(
|
||||||
|
probe_appdata_len('localhost', timeout=0.1), timeout=2)
|
||||||
|
self.assertIsNone(result)
|
||||||
|
self.assertGreater(reader.read.await_count, 1)
|
||||||
|
writer.close.assert_called_once()
|
||||||
|
|
||||||
|
asyncio.run(scenario())
|
||||||
|
|
||||||
|
def test_blocked_drain_obeys_probe_timeout(self):
|
||||||
|
async def scenario():
|
||||||
|
reader = Mock(read=AsyncMock())
|
||||||
|
writer = Mock(drain=AsyncMock(side_effect=asyncio.Event().wait))
|
||||||
|
with patch.object(fake_tls.asyncio, 'open_connection',
|
||||||
|
AsyncMock(return_value=(reader, writer))):
|
||||||
|
result = await asyncio.wait_for(
|
||||||
|
probe_appdata_len('localhost', timeout=0.1), timeout=2)
|
||||||
|
self.assertIsNone(result)
|
||||||
|
reader.read.assert_not_called()
|
||||||
|
writer.close.assert_called_once()
|
||||||
|
|
||||||
|
asyncio.run(scenario())
|
||||||
|
|
||||||
def test_measures_first_encrypted_record_of_real_tls13_server(self):
|
def test_measures_first_encrypted_record_of_real_tls13_server(self):
|
||||||
async def scenario():
|
async def scenario():
|
||||||
server = await asyncio.start_server(
|
server = await asyncio.start_server(
|
||||||
|
|||||||
Reference in New Issue
Block a user