(
self,
target: str,
recon_types: List[ReconType],
timeout: int = DEFAULT_ENGINE_TIMEOUT,
)
| 161 | logger.warning(f"{tool} not found in PATH; CONTENT_DISCOVERY will report status=error") |
| 162 | |
| 163 | def start_scan( |
| 164 | self, |
| 165 | target: str, |
| 166 | recon_types: List[ReconType], |
| 167 | timeout: int = DEFAULT_ENGINE_TIMEOUT, |
| 168 | ) -> str: |
| 169 | if not self.is_available(): |
| 170 | raise RuntimeError("Recon engine requires server mode") |
| 171 | if not recon_types: |
| 172 | raise ValueError("recon_types must not be empty") |
| 173 | |
| 174 | scan_id = f"RECON-{uuid.uuid4().hex[:12]}-{int(time.time())}" |
| 175 | state = ReconScanState(scan_id=scan_id, target=target, recon_types=list(recon_types)) |
| 176 | with self._lock: |
| 177 | self.active_scans[scan_id] = state |
| 178 | |
| 179 | threading.Thread( |
| 180 | target=self._run_scan, |
| 181 | args=(scan_id, target, recon_types, timeout), |
| 182 | name=f"recon-{scan_id}", |
| 183 | daemon=True, |
| 184 | ).start() |
| 185 | |
| 186 | logger.info(f"Started recon scan {scan_id} against {target} ({[r.value for r in recon_types]})") |
| 187 | return scan_id |
| 188 | |
| 189 | def get_scan_state(self, scan_id: str) -> Optional[ReconScanState]: |
| 190 | with self._lock: |
no test coverage detected