(self, html_text, headers)
| 12304 | return out |
| 12305 | |
| 12306 | def _domain_tech_fingerprint(self, html_text, headers): |
| 12307 | out = {} |
| 12308 | if not html_text: |
| 12309 | return out |
| 12310 | text = (html_text or "").lower() |
| 12311 | tech = set() |
| 12312 | markers = { |
| 12313 | "WordPress": ["wp-content", "wordpress"], |
| 12314 | "Drupal": ["drupal-settings-json", "drupal"], |
| 12315 | "Joomla": ["joomla"], |
| 12316 | "Next.js": ["__next", "next/static"], |
| 12317 | "React": ["react", "data-reactroot"], |
| 12318 | "Vue": ["vue.", "__vuerouter"], |
| 12319 | "Angular": ["ng-app", "angular"], |
| 12320 | "Django": ["csrfmiddlewaretoken", "csrf"], |
| 12321 | "Laravel": ["laravel", "csrf-token"], |
| 12322 | "Rails": ["_rails", "rails-ujs"], |
| 12323 | "Shopify": ["shopify"], |
| 12324 | "Cloudflare": ["cloudflare"], |
| 12325 | "Wix": ["wix.com", "static-parastorage.com"] |
| 12326 | } |
| 12327 | for name, checks in markers.items(): |
| 12328 | if any(c in text for c in checks): |
| 12329 | tech.add(name) |
| 12330 | |
| 12331 | gen = re.search(r'<meta[^>]+name=["\']generator["\'][^>]+content=["\']([^"\']+)', html_text, flags=re.IGNORECASE) |
| 12332 | if gen: |
| 12333 | tech.add(gen.group(1).strip()) |
| 12334 | |
| 12335 | server_h = headers.get("server") if isinstance(headers, dict) else None |
| 12336 | if server_h: |
| 12337 | out["Server header"] = str(server_h) |
| 12338 | if "x-powered-by" in {k.lower() for k in (headers.keys() if isinstance(headers, dict) else {})}: |
| 12339 | out["X-Powered-By"] = headers.get("x-powered-by") or headers.get("X-Powered-By") |
| 12340 | |
| 12341 | if tech: |
| 12342 | out["Tech Stack stimato"] = ", ".join(sorted(tech)) |
| 12343 | else: |
| 12344 | out["Tech Stack stimato"] = "Non identificato" |
| 12345 | return out |
| 12346 | |
| 12347 | def _wayback_summary(self, domain): |
| 12348 | out = {} |
no outgoing calls
no test coverage detected