Scan for cloud storage assets in parallel
(&self, urls: Vec<String>)
| 418 | pub struct CloudAsset { |
| 419 | pub provider: String, |
| 420 | pub url: String, |
| 421 | pub bucket_name: String, |
| 422 | pub is_public: bool, |
| 423 | pub allows_listing: bool, |
| 424 | pub status_code: u16, |
| 425 | } |
| 426 | |
| 427 | impl ParallelCloudScanner { |
| 428 | pub fn new(config: ParallelConfig) -> Self { |
| 429 | let client = Client::builder() |
| 430 | .timeout(Duration::from_secs(config.timeout_secs)) |
| 431 | .danger_accept_invalid_certs(true) |
| 432 | .build() |
| 433 | .unwrap_or_default(); |
| 434 | |
| 435 | let workers = config.cloud_workers; |
| 436 | Self { |
| 437 | config, |
| 438 | client, |
| 439 | semaphore: Arc::new(Semaphore::new(workers)), |
| 440 | } |
| 441 | } |
| 442 | |
| 443 | /// Scan for cloud storage assets in parallel |
| 444 | pub async fn scan_cloud_assets(&self, urls: Vec<String>) -> Vec<CloudAsset> { |
| 445 | if urls.is_empty() { |
| 446 | return Vec::new(); |
| 447 | } |
| 448 | |
| 449 | println!("{}", format!( |
| 450 | "┌───────────────────────────────────────────────────────────────────────────────┐" |
| 451 | ).cyan().bold()); |
| 452 | println!("{}", format!( |
| 453 | "│ ☁️ PARALLEL CLOUD SCANNER │" |
| 454 | ).cyan().bold()); |
| 455 | println!("{}", format!( |
| 456 | "├───────────────────────────────────────────────────────────────────────────────┤" |
| 457 | ).cyan()); |
| 458 | println!("{}", format!( |
| 459 | "│ 📊 URLs to scan: {:<59}│", urls.len() |
| 460 | ).cyan()); |
| 461 | println!("{}", format!( |
| 462 | "│ 👷 Workers: {:<64}│", self.config.cloud_workers |
| 463 | ).cyan()); |
| 464 | println!("{}", format!( |
| 465 | "└───────────────────────────────────────────────────────────────────────────────┘" |
| 466 | ).cyan().bold()); |
| 467 | println!(); |
| 468 | |
| 469 | // Extract potential cloud storage URLs |
| 470 | let cloud_urls = self.extract_cloud_urls(&urls); |
| 471 | |
| 472 | if cloud_urls.is_empty() { |
| 473 | println!("{}", " ℹ️ No cloud storage URLs found".yellow()); |
| 474 | return Vec::new(); |
| 475 | } |
| 476 | |
| 477 | println!("{}", format!(" 🔍 Found {} potential cloud URLs", cloud_urls.len()).yellow()); |
nothing calls this directly
no test coverage detected