almost ready
This commit is contained in:
57
worker/blworker/c2.py
Normal file
57
worker/blworker/c2.py
Normal file
@@ -0,0 +1,57 @@
|
||||
"""HTTP client for the .NET C2's job endpoints.
|
||||
|
||||
Stdlib urllib so the blocking calls run off the asyncio loop via to_thread (the event
|
||||
loop belongs to the browser). Each worker points at one job route group — "/jobs" for
|
||||
cs.money, "/skinland/jobs" for skin.land — set once at construction.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
import logging
|
||||
import urllib.error
|
||||
import urllib.request
|
||||
|
||||
log = logging.getLogger("c2")
|
||||
|
||||
|
||||
class C2Client:
|
||||
def __init__(self, base_url: str, token: str, jobs_path: str):
|
||||
self._base = base_url.rstrip("/")
|
||||
self._token = token
|
||||
self._jobs = jobs_path.strip("/")
|
||||
|
||||
def _get_job_sync(self):
|
||||
req = urllib.request.Request(
|
||||
f"{self._base}/{self._jobs}/next", headers={"X-Worker-Token": self._token})
|
||||
try:
|
||||
with urllib.request.urlopen(req, timeout=15) as r:
|
||||
if r.status == 204:
|
||||
return None
|
||||
return json.loads(r.read() or b"null")
|
||||
except urllib.error.HTTPError as e:
|
||||
log.warning("/%s/next -> HTTP %s", self._jobs, e.code)
|
||||
return None
|
||||
except urllib.error.URLError as e:
|
||||
log.warning("C2 unreachable: %s", e)
|
||||
return None
|
||||
|
||||
def _post_result_sync(self, job_id: str, payload: dict):
|
||||
data = json.dumps(payload).encode()
|
||||
req = urllib.request.Request(
|
||||
f"{self._base}/{self._jobs}/{job_id}/result", data=data, method="POST",
|
||||
headers={"X-Worker-Token": self._token, "Content-Type": "application/json"})
|
||||
try:
|
||||
with urllib.request.urlopen(req, timeout=60) as r:
|
||||
return json.loads(r.read() or b"null")
|
||||
except urllib.error.HTTPError as e:
|
||||
log.warning("result -> HTTP %s: %r", e.code, e.read()[:200])
|
||||
return None
|
||||
except urllib.error.URLError as e:
|
||||
log.warning("C2 unreachable posting result: %s", e)
|
||||
return None
|
||||
|
||||
async def get_job(self):
|
||||
return await asyncio.to_thread(self._get_job_sync)
|
||||
|
||||
async def post_result(self, job_id, payload):
|
||||
return await asyncio.to_thread(self._post_result_sync, job_id, payload)
|
||||
Reference in New Issue
Block a user