feat: route plugin HTTP traffic through SOCKS5 proxy

Add PySocks dependency and shared src/derp/http.py module providing
proxy-aware urlopen() and build_opener() that route through
socks5h://127.0.0.1:1080. Subclassed SocksiPyHandler passes SSL
context through to HTTPS connections.

Swapped 14 external-facing plugins to use the proxied helpers.
Local-only traffic (SearXNG, raw DNS/TLS sockets) stays direct.
Updated test mocks in test_twitch and test_alert accordingly.
This commit is contained in:
user
2026-02-15 15:53:49 +01:00
parent 10f62631be
commit 97bbc6a825
19 changed files with 151 additions and 47 deletions

View File

@@ -5,10 +5,10 @@ from __future__ import annotations
import asyncio
import json
import re
import ssl
import urllib.request
from datetime import datetime, timezone
from derp.http import urlopen as _urlopen
from derp.plugin import command, event
# -- Constants ---------------------------------------------------------------
@@ -106,8 +106,7 @@ def _search_youtube(keyword: str) -> list[dict]:
req = urllib.request.Request(_YT_SEARCH_URL, data=payload, method="POST")
req.add_header("Content-Type", "application/json")
ctx = ssl.create_default_context()
resp = urllib.request.urlopen(req, timeout=_FETCH_TIMEOUT, context=ctx)
resp = _urlopen(req, timeout=_FETCH_TIMEOUT)
raw = resp.read()
resp.close()
@@ -141,8 +140,7 @@ def _search_twitch(keyword: str) -> list[dict]:
req.add_header("Client-Id", _GQL_CLIENT_ID)
req.add_header("Content-Type", "application/json")
ctx = ssl.create_default_context()
resp = urllib.request.urlopen(req, timeout=_FETCH_TIMEOUT, context=ctx)
resp = _urlopen(req, timeout=_FETCH_TIMEOUT)
raw = resp.read()
resp.close()