This commit is contained in:
+11
-34
@@ -215,49 +215,25 @@ class Handler(BaseHTTPRequestHandler):
|
|||||||
# ── POST /api/drhider ────────────────────────────────────────────────
|
# ── POST /api/drhider ────────────────────────────────────────────────
|
||||||
|
|
||||||
def _handle_drhider(self):
|
def _handle_drhider(self):
|
||||||
"""Обфускация: multipart files → LLM-NER → ZIP."""
|
"""Обфускация: JSON {files: [{name, data: base64}]} → ZIP."""
|
||||||
from services.drhider import obfuscate_files
|
from services.drhider import obfuscate_files
|
||||||
|
import base64
|
||||||
|
|
||||||
length = int(self.headers.get("Content-Length", 0))
|
length = int(self.headers.get("Content-Length", 0))
|
||||||
raw = self.rfile.read(length)
|
raw = self.rfile.read(length)
|
||||||
ctype = self.headers.get("Content-Type", "")
|
|
||||||
|
|
||||||
# Парсим multipart вручную
|
body = json.loads(raw) if raw else {}
|
||||||
import cgi, re
|
raw_files = body.get("files", [])
|
||||||
_, params = cgi.parse_header(ctype)
|
if not raw_files:
|
||||||
boundary = params.get("boundary", "").encode()
|
self._json({"ok": False, "error": "No files"}, 400)
|
||||||
if not boundary:
|
|
||||||
self._json({"ok": False, "error": "No multipart boundary"}, 400)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
files = []
|
files = []
|
||||||
# Разбиваем по boundary
|
for f in raw_files:
|
||||||
parts = raw.split(b"--" + boundary)
|
name = f.get("name", "unnamed")
|
||||||
for part in parts:
|
data = base64.b64decode(f.get("data", ""))
|
||||||
if b"Content-Disposition" not in part:
|
files.append((name, data, f.get("type", "")))
|
||||||
continue
|
|
||||||
try:
|
|
||||||
header_end = part.index(b"\r\n\r\n")
|
|
||||||
except ValueError:
|
|
||||||
continue
|
|
||||||
headers_raw = part[:header_end].decode("latin-1", errors="replace")
|
|
||||||
content = part[header_end + 4:]
|
|
||||||
if content.endswith(b"\r\n"):
|
|
||||||
content = content[:-2]
|
|
||||||
# Извлечь filename
|
|
||||||
m = re.search(r'filename="([^"]*)"', headers_raw)
|
|
||||||
if not m:
|
|
||||||
continue
|
|
||||||
fname = m.group(1)
|
|
||||||
if not fname:
|
|
||||||
continue
|
|
||||||
files.append((fname, content, ""))
|
|
||||||
|
|
||||||
if not files:
|
|
||||||
self._json({"ok": False, "error": "Нет файлов"}, 400)
|
|
||||||
return
|
|
||||||
|
|
||||||
# LLM-клиент (совместимый с drhider.LLMClient протоколом: complete(prompt)->str)
|
|
||||||
class _VMLLM:
|
class _VMLLM:
|
||||||
def complete(self, prompt):
|
def complete(self, prompt):
|
||||||
import httpx
|
import httpx
|
||||||
@@ -279,6 +255,7 @@ class Handler(BaseHTTPRequestHandler):
|
|||||||
self.send_header("Content-Type", "application/zip")
|
self.send_header("Content-Type", "application/zip")
|
||||||
self.send_header("Content-Disposition", 'attachment; filename="drhider_output.zip"')
|
self.send_header("Content-Disposition", 'attachment; filename="drhider_output.zip"')
|
||||||
self.send_header("Content-Length", str(len(zip_data)))
|
self.send_header("Content-Length", str(len(zip_data)))
|
||||||
|
self.send_header("Access-Control-Allow-Origin", "*")
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
self.wfile.write(zip_data)
|
self.wfile.write(zip_data)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ BTN.onclick = async () => {
|
|||||||
payload.push({name: f.name, data: b64, type: f.type || ''});
|
payload.push({name: f.name, data: b64, type: f.type || ''});
|
||||||
}
|
}
|
||||||
setStatus('progress', '⏳ Обработка...');
|
setStatus('progress', '⏳ Обработка...');
|
||||||
const r = await fetch('/api/drhider', {
|
const r = await fetch('https://contracts.kube5s.ru/api/drhider', {
|
||||||
method:'POST',
|
method:'POST',
|
||||||
headers: {'Content-Type': 'application/json'},
|
headers: {'Content-Type': 'application/json'},
|
||||||
body: JSON.stringify({files: payload})
|
body: JSON.stringify({files: payload})
|
||||||
|
|||||||
Reference in New Issue
Block a user