Hi there, I'm writing a CLI tool to use in the security penetration area, my problem is that I don't know how to pass CLI arg to a function that is calling via tokio::async and concurrent mode.
my code is below:
line 23 is where I got the arg value
line 38 is where I attempt to use its value to pass to the target function
Error is:
args
does not live long enough
borrowed value does not live long enoughrustc(E0597)
main.rs(24, 19): borrowed value does not live long enough
main.rs(44, 35): argument requires that args
is borrowed for 'static
main.rs(57, 1): args
dropped here while still borrowed
use regex::Regex;
use serde::*;
use std::any::Any;
use std::collections::*;
use std::env;
use std::sync::Arc;
use std::thread;
use std::time::Duration;
#[derive(Serialize, Deserialize)]
struct TimeRecord {
timeStamp: String,
url: String,
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let args: Vec<String> = env::args().collect();
if args.len() == 1 {
panic!("Pass the domain name in the parameter!");
}
let domain = &args[1];
let base_url = format!("https://web.archive.org/cdx/search/cdx?url={}/robots.txt&output=json&filter=statuscode:200&fl=timestamp,original&collapse=digest",&domain);
let resp = reqwest::get(base_url).await?.text().await?;
let json: Vec<TimeRecord> = serde_json::from_str(&resp).expect("JSON was not well-formatted");
let mut handles = Vec::new();
let mut result: HashMap<char, usize> = HashMap::new();
for obj in json {
if obj.url == "original" {
continue;
}
let handle = tokio::spawn(async {
get_robot_file(domain, obj.timeStamp, obj.url).await;
});
handles.push(handle);
}
for handle in handles {
let map = handle.await.unwrap();
}
Ok(())
}
async fn get_robot_file(
base_domain: &String,
timestamp: String,
url: String,
) -> Result<String, Box<dyn std::error::Error>> {
let base_url = format!("http://web.archive.org/web/{}if_/{}", timestamp, url);
let resp = reqwest::get(base_url).await?.text().await?;
if resp.is_empty() {
return Ok(String::from("ok"));
}
let items: Vec<&str> = resp.trim().split("\n").collect();
for item in items {
if item.to_lowercase().contains("disallow:") || item.to_lowercase().contains("allow:") {
let sub_item: Vec<&str> = item.split(": ").collect();
if sub_item.capacity() <= 1 {
continue;
}
let temp = &sub_item[1]
.replace("\n", "")
.replace("*", "")
.replace("\r", "");
if !temp.is_empty() {
let mut result = String::new();
result.push_str(base_domain);
result.push_str(temp);
println!("{:#?}", &result);
}
}
}
Ok(String::from("ok"))
}