deploy Nous v22 update
This commit is contained in:
+16
-9
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user