Testing
This commit is contained in:
parent
cd593e32d2
commit
4bb36b7735
@ -660,7 +660,7 @@ impl ServiceCollector {
|
||||
return None;
|
||||
}
|
||||
let config = String::from_utf8_lossy(&output.stdout);
|
||||
return self.parse_nginx_config(&config);
|
||||
return self.parse_nginx_config(&config).await;
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::warn!("Failed to execute sudo nginx -T: {}", e);
|
||||
@ -694,7 +694,7 @@ impl ServiceCollector {
|
||||
let config = String::from_utf8_lossy(&output.stdout);
|
||||
tracing::debug!("Got nginx config, {} bytes", config.len());
|
||||
|
||||
self.parse_nginx_config(&config)
|
||||
self.parse_nginx_config(&config).await
|
||||
}
|
||||
|
||||
async fn get_nginx_config_from_systemd(&self) -> Option<String> {
|
||||
@ -730,7 +730,7 @@ impl ServiceCollector {
|
||||
None
|
||||
}
|
||||
|
||||
fn parse_nginx_config(&self, config: &str) -> Option<Vec<String>> {
|
||||
async fn parse_nginx_config(&self, config: &str) -> Option<Vec<String>> {
|
||||
let mut sites = Vec::new();
|
||||
let lines: Vec<&str> = config.lines().collect();
|
||||
let mut i = 0;
|
||||
@ -740,31 +740,39 @@ impl ServiceCollector {
|
||||
|
||||
// Look for server blocks
|
||||
if trimmed == "server {" {
|
||||
if let Some(site_info) = self.parse_server_block(&lines, &mut i) {
|
||||
sites.push(site_info);
|
||||
if let Some(hostname) = self.parse_server_block(&lines, &mut i) {
|
||||
sites.push(hostname);
|
||||
}
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
|
||||
tracing::info!("Extracted {} sites with routing info", sites.len());
|
||||
tracing::info!("Found {} potential sites, checking accessibility", sites.len());
|
||||
|
||||
// Check which sites are actually accessible
|
||||
let mut accessible_sites = Vec::new();
|
||||
for site in sites {
|
||||
if self.check_site_accessibility(&site).await {
|
||||
accessible_sites.push(format!("{} ✓", site));
|
||||
}
|
||||
}
|
||||
|
||||
// Limit to reasonable number
|
||||
sites.truncate(15);
|
||||
accessible_sites.truncate(15);
|
||||
|
||||
tracing::info!("Final nginx sites list: {:?}", sites);
|
||||
tracing::info!("Final accessible nginx sites: {:?}", accessible_sites);
|
||||
|
||||
if sites.is_empty() {
|
||||
tracing::warn!("No nginx sites found");
|
||||
if accessible_sites.is_empty() {
|
||||
tracing::warn!("No accessible nginx sites found");
|
||||
None
|
||||
} else {
|
||||
Some(sites)
|
||||
Some(accessible_sites)
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_server_block(&self, lines: &[&str], start_index: &mut usize) -> Option<String> {
|
||||
let mut server_names = Vec::new();
|
||||
let mut destinations = Vec::new();
|
||||
let mut has_redirect = false;
|
||||
let mut i = *start_index + 1;
|
||||
let mut brace_count = 1;
|
||||
|
||||
@ -788,37 +796,9 @@ impl ServiceCollector {
|
||||
}
|
||||
}
|
||||
|
||||
// Extract routing information
|
||||
// Check if this server block is just a redirect
|
||||
if trimmed.starts_with("return") && trimmed.contains("301") {
|
||||
// Skip simple HTTPS redirects (return 301 https://$host$request_uri)
|
||||
if !trimmed.contains("$host") {
|
||||
// Meaningful redirect: return 301 https://pages.cmtec.se$request_uri;
|
||||
if let Some(url_start) = trimmed.find("https://") {
|
||||
let url_part = &trimmed[url_start + 8..]; // Skip "https://"
|
||||
if let Some(url_end) = url_part.find('$') {
|
||||
let domain = &url_part[..url_end];
|
||||
destinations.push(format!("→ {}", domain));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if trimmed.starts_with("proxy_pass") {
|
||||
// Proxy: proxy_pass http://localhost:8080;
|
||||
if let Some(url_start) = trimmed.find("http") {
|
||||
let url_part = &trimmed[url_start..];
|
||||
if let Some(url_end) = url_part.find(';') {
|
||||
let proxy_url = &url_part[..url_end];
|
||||
destinations.push(format!("← {}", proxy_url));
|
||||
}
|
||||
}
|
||||
} else if trimmed.starts_with("root") {
|
||||
// Static files: root /var/www/example;
|
||||
if let Some(path_start) = trimmed.find('/') {
|
||||
let path_part = &trimmed[path_start..];
|
||||
if let Some(path_end) = path_part.find(';') {
|
||||
let root_path = &path_part[..path_end];
|
||||
destinations.push(format!("static {}", root_path));
|
||||
}
|
||||
}
|
||||
has_redirect = true;
|
||||
}
|
||||
|
||||
i += 1;
|
||||
@ -826,14 +806,47 @@ impl ServiceCollector {
|
||||
|
||||
*start_index = i - 1;
|
||||
|
||||
// Build site info string - only show sites with meaningful routing
|
||||
if !server_names.is_empty() && !destinations.is_empty() {
|
||||
let primary_name = &server_names[0];
|
||||
Some(format!("{} {}", primary_name, destinations[0]))
|
||||
// Only return hostnames that are not redirects and have actual content
|
||||
if !server_names.is_empty() && !has_redirect {
|
||||
Some(server_names[0].clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
async fn check_site_accessibility(&self, hostname: &str) -> bool {
|
||||
// Try HTTPS first, then HTTP
|
||||
for scheme in ["https", "http"] {
|
||||
let url = format!("{}://{}", scheme, hostname);
|
||||
|
||||
match tokio::time::timeout(
|
||||
Duration::from_secs(5),
|
||||
Command::new("curl")
|
||||
.args(["-s", "-I", "--max-time", "3", &url])
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.output()
|
||||
).await {
|
||||
Ok(Ok(output)) if output.status.success() => {
|
||||
let response = String::from_utf8_lossy(&output.stdout);
|
||||
// Check for successful HTTP status codes
|
||||
if response.contains("HTTP/") && (
|
||||
response.contains(" 200 ") ||
|
||||
response.contains(" 301 ") ||
|
||||
response.contains(" 302 ") ||
|
||||
response.contains(" 403 ") // Some sites return 403 but are still "accessible"
|
||||
) {
|
||||
tracing::debug!("Site {} accessible via {}", hostname, scheme);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
_ => continue,
|
||||
}
|
||||
}
|
||||
|
||||
tracing::debug!("Site {} not accessible", hostname);
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user