deploy Nous v22 update

This commit is contained in:
Marco0300
2026-09-05 22:45:12 +02:00
parent aacb71221b
commit 112ab552e9
10 changed files with 265 additions and 52 deletions
+16 -9
View File
@@ -24,7 +24,10 @@ EMAIL_RE = re.compile(r"[A-Z0-9._%+\-]+@[A-Z0-9.\-]+\.[A-Z]{2,63}", re.I)
MAX_BODY_BYTES = 700_000
MAX_REDIRECTS = 2
MAX_PAGES = 2
TIMEOUT_SECONDS = max(2, min(30, int(os.environ.get("WEBSITE_SCAN_TIMEOUT", "8"))))
try:
TIMEOUT_SECONDS = max(2, min(60, int(os.environ.get("WEBSITE_SCAN_TIMEOUT", "8"))))
except (TypeError, ValueError):
TIMEOUT_SECONDS = 8
# getaddrinfo has no per-call timeout parameter on all supported platforms.
# Set a bounded process default so a broken DNS server cannot hold a discovery
# worker forever during website analysis.
@@ -105,7 +108,7 @@ def _same_root(left: str, right: str) -> bool:
return bool(a and b and (a == b or a.endswith("." + b) or b.endswith("." + a)))
def _fetch(url: str) -> dict[str, Any]:
def _fetch(url: str, timeout_seconds: int = TIMEOUT_SECONDS) -> dict[str, Any]:
current = url
redirects = 0
started = time.monotonic()
@@ -117,7 +120,7 @@ def _fetch(url: str) -> dict[str, Any]:
return {"error": "unsafe_or_unresolvable_host", "url": current, "latency_ms": int((time.monotonic() - started) * 1000)}
request = Request(current, headers={"User-Agent": "ProspectOS/1.0 (+public-site-check)", "Accept": "text/html,application/xhtml+xml"})
try:
with _opener.open(request, timeout=TIMEOUT_SECONDS) as response:
with _opener.open(request, timeout=timeout_seconds) as response:
last_status = int(getattr(response, "status", 200) or 200)
last_headers = response.headers
body = response.read(MAX_BODY_BYTES)
@@ -147,13 +150,13 @@ def _fetch(url: str) -> dict[str, Any]:
return {"url": current, "initial_url": url, "status": last_status, "headers": last_headers, "body": body, "latency_ms": int((time.monotonic() - started) * 1000), "redirects": redirects, "error": "redirect_limit"}
def _tls_expiry(url: str) -> str:
def _tls_expiry(url: str, timeout_seconds: int = TIMEOUT_SECONDS) -> str:
parsed = urlparse(url)
if parsed.scheme != "https" or not parsed.hostname:
return ""
try:
context = ssl.create_default_context()
with socket.create_connection((parsed.hostname, parsed.port or 443), timeout=TIMEOUT_SECONDS) as raw:
with socket.create_connection((parsed.hostname, parsed.port or 443), timeout=timeout_seconds) as raw:
with context.wrap_socket(raw, server_hostname=parsed.hostname) as secure:
cert = secure.getpeercert()
value = cert.get("notAfter") if cert else ""
@@ -174,11 +177,15 @@ def _emails(text: str) -> list[str]:
return found[:30]
def scan_website(url: str) -> dict[str, Any]:
def scan_website(url: str, timeout_seconds: int | None = None) -> dict[str, Any]:
"""Return bounded website health, metadata, and public email evidence."""
if not url:
return {"website_status": "no_detected_website", "website_checked_at": datetime.now(timezone.utc).replace(microsecond=0).isoformat(), "website_emails": [], "email_evidence": []}
first = _fetch(url)
try:
timeout = max(2, min(60, int(timeout_seconds if timeout_seconds is not None else TIMEOUT_SECONDS)))
except (TypeError, ValueError):
timeout = TIMEOUT_SECONDS
first = _fetch(url, timeout)
status = int(first.get("status") or 0)
final_url = str(first.get("url") or url)
body = bytes(first.get("body") or b"")
@@ -196,7 +203,7 @@ def scan_website(url: str) -> dict[str, Any]:
candidate = urljoin(final_url, href)
label = (href or "").lower()
if any(token in label for token in ("contact", "about", "get-in-touch")) and _same_root(final_url, candidate) and _safe_url(candidate):
page = _fetch(candidate)
page = _fetch(candidate, timeout)
pages.append(page)
emails.extend(_emails(bytes(page.get("body") or b"").decode("utf-8", "replace")))
break
@@ -230,7 +237,7 @@ def scan_website(url: str) -> dict[str, Any]:
"website_title": title,
"website_technology": technologies,
"website_has_viewport": 1 if "viewport" in parser.meta else 0,
"website_tls_expires_at": _tls_expiry(final_url) if urlparse(final_url).scheme == "https" else "",
"website_tls_expires_at": _tls_expiry(final_url, timeout) if urlparse(final_url).scheme == "https" else "",
"website_checked_at": checked,
"website_error": str(first.get("error") or "")[:300],
"website_emails": emails,