Files
VPSMaster/proxydoctor/worker.py
T
griffinmx 2400c16ea9 Add all: bounded live diagnostics for Beta.1
Reviewed source snapshot: 70a56fe37dd527e68823bddceb0c10d2f64f32dc
Default compact display and repository layout from the prior accepted local baseline are included.
2026-11-02 00:26:12 -08:00

130 lines
4.5 KiB
Python

"""CLI-only hard boundaries for network operations, including blocking DNS."""
import json
import os
import subprocess
import sys
from pathlib import Path
import threading
_active=set()
_lock=threading.Lock()
_cancelled=threading.Event()
def cancel_all():
_cancelled.set()
with _lock:
for process in tuple(_active):
if process.poll() is None:
try:process.kill()
except OSError:pass
def reset():
_cancelled.clear()
def enabled():
return os.environ.get('PROXYDOCTOR_NETWORK_WORKERS','1')=='1'
def local_command(argv, timeout=4):
"""Bound a caller-validated local probe and register it for cancellation."""
if _cancelled.is_set():
return None, '', 'CANCELLED'
with subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
text=True, encoding='utf-8', errors='replace',
env={**os.environ, 'LC_ALL':'C'}) as process:
with _lock:
_active.add(process)
if _cancelled.is_set():process.kill()
try:
output, errors = process.communicate(timeout=timeout)
except subprocess.TimeoutExpired:
process.kill();process.communicate()
return None, '', 'COMMAND_TIMEOUT'
except BaseException:
process.kill();process.communicate()
raise
finally:
with _lock:_active.discard(process)
if len(output)>16384:
return None, '', 'COMMAND_OUTPUT_LIMIT'
message=errors.lower()
error=None
if process.returncode:
if any(token in message for token in ('operation not permitted','permission denied','not enough privileges')):
error='PERMISSION_DENIED'
elif any(token in message for token in ('network is unreachable','network unreachable','no route to host')):
error='NETWORK_UNREACHABLE'
elif 'not supported' in message:
error='PROTOCOL_UNSUPPORTED'
return process.returncode, output, error
def invoke(action,options,timeout=20):
if action not in ('json','page','transfer','carrier_probe','resolve_public'):
raise ValueError('Unsupported network action')
if _cancelled.is_set():
return None
try:
bootstrap='import sys;sys.path.insert(0,sys.argv.pop(1));from proxydoctor.worker import main;sys.exit(main())'
with subprocess.Popen([sys.executable,'-I','-B','-c',bootstrap,str(Path(__file__).resolve().parent.parent),action],
stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.DEVNULL,
text=True,encoding='utf-8') as process:
with _lock:
_active.add(process)
if _cancelled.is_set():process.kill()
try:
output,_=process.communicate(json.dumps(options),timeout=timeout)
except subprocess.TimeoutExpired:
process.kill();process.communicate()
return None
except KeyboardInterrupt:
cancel_all();process.communicate()
raise
except BaseException:
process.kill();process.communicate()
raise
finally:
with _lock:_active.discard(process)
if process.returncode or len(output)>2*1024**2:
return None
return json.loads(output)
except (OSError,ValueError,subprocess.TimeoutExpired):
return None
def main():
os.environ['PROXYDOCTOR_NETWORK_WORKERS']='0'
options=json.loads(sys.stdin.read(65537))
action=sys.argv[1]
if action=='json':
from .net import request_json
result=request_json(**options)
elif action=='page':
from dataclasses import asdict
from .media import fetch_page
result=asdict(fetch_page(**options))
elif action=='transfer':
from dataclasses import asdict
from .bandwidth import transfer
result=asdict(transfer(**options))
elif action=='carrier_probe':
from .carriers import probe_node
result=probe_node(**options)
elif action=='resolve_public':
from .carriers import resolve_public
result=resolve_public(**options)
else:
return 2
print(json.dumps(result))
return 0
if __name__=='__main__':
try:
sys.exit(main())
except (Exception,KeyboardInterrupt):
sys.exit(1) # Never print provider exceptions/credentials.