mirror of
https://github.com/edu4rdshl/fhc.git
synced 2026-07-17 23:24:50 +00:00
Use new arguments handling implementation.
This commit is contained in:
parent
2888858d4e
commit
17ea7f983b
2 changed files with 60 additions and 113 deletions
36
src/args.rs
Normal file
36
src/args.rs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
use clap::Parser;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(version, about, long_about = None)]
|
||||
pub struct Cli {
|
||||
#[clap(short, long, default_value = "50")]
|
||||
/// Number of threads to use
|
||||
pub threads: usize,
|
||||
#[clap(long, default_value = "3")]
|
||||
/// Timeout in seconds
|
||||
pub timeout: u64,
|
||||
#[clap(short, long)]
|
||||
/// Show HTTP status codes
|
||||
pub show_codes: bool,
|
||||
#[clap(short, long)]
|
||||
/// Domain to check - can be omitted if using stdin
|
||||
pub domain: Option<String>,
|
||||
#[clap(short, long, default_value = "1")]
|
||||
/// Number of retries
|
||||
pub retries: usize,
|
||||
#[clap(short = 'L', long, default_value = "10")]
|
||||
/// Maximum number of redirects
|
||||
pub max_redirects: usize,
|
||||
#[clap(short, long)]
|
||||
/// Enable bruteforce mode
|
||||
pub bruteforce: bool,
|
||||
#[clap(short, long)]
|
||||
/// Filter status codes. A comma separated list can be used
|
||||
pub filter_codes: Option<String>,
|
||||
#[clap(short, long)]
|
||||
/// Exclude status codes. A comma separated list can be used
|
||||
pub exclude_codes: Option<String>,
|
||||
#[clap(short, long)]
|
||||
/// Quiet mode. This will suppress all fancy output except for the final results
|
||||
pub quiet: bool,
|
||||
}
|
||||
137
src/main.rs
137
src/main.rs
|
|
@ -1,6 +1,6 @@
|
|||
use {
|
||||
clap::{value_t, App, Arg},
|
||||
fhc::{httplib, structs::LibOptions, utils},
|
||||
clap::Parser,
|
||||
fhc::{args, httplib, structs::LibOptions, utils},
|
||||
std::collections::HashSet,
|
||||
tokio::io::{self, AsyncReadExt},
|
||||
};
|
||||
|
|
@ -8,114 +8,16 @@ use {
|
|||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Eval args
|
||||
let matches = App::new("FHC")
|
||||
.version(clap::crate_version!())
|
||||
.author("Eduard Tolosa <edu4rdshl@protonmail.com>")
|
||||
.about("Fast HTTP Checker.")
|
||||
.arg(
|
||||
Arg::with_name("threads")
|
||||
.short("t")
|
||||
.long("threads")
|
||||
.takes_value(true)
|
||||
.help("Number of threads. Default: 50"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("timeout")
|
||||
.long("timeout")
|
||||
.takes_value(true)
|
||||
.help("Timeout in seconds. Default: 3"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("show-codes")
|
||||
.short("s")
|
||||
.long("show-codes")
|
||||
.takes_value(false)
|
||||
.help("Show status codes for discovered hosts."),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("domain")
|
||||
.short("d")
|
||||
.long("domain")
|
||||
.takes_value(true)
|
||||
.help("Target domain. When it's specified, a wordlist can be used from stdin for bruteforcing."),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("retries")
|
||||
.short("r")
|
||||
.long("retries")
|
||||
.takes_value(true)
|
||||
.help("Max number of http probes per target."),
|
||||
).arg(
|
||||
Arg::with_name("max-redirects")
|
||||
.short("L")
|
||||
.long("max-redirects")
|
||||
.takes_value(true)
|
||||
.help("Max number of redirects. Default: 0"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("bruteforce")
|
||||
.short("b")
|
||||
.long("bruteforce")
|
||||
.takes_value(false)
|
||||
.help("Bruteforce subdomains."),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("1xx")
|
||||
.short("1")
|
||||
.long("1xx")
|
||||
.takes_value(false)
|
||||
.help("Show URLs with 100-199 response codes only."),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("2xx")
|
||||
.short("2")
|
||||
.long("2xx")
|
||||
.takes_value(false)
|
||||
.help("Show URLs with 200-299 response codes only."),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("3xx")
|
||||
.short("3")
|
||||
.long("3xx")
|
||||
.takes_value(false)
|
||||
.help("Show URLs with 300-399 response codes only."),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("4xx")
|
||||
.short("4")
|
||||
.long("4xx")
|
||||
.takes_value(false)
|
||||
.help("Show URLs with 400-499 response codes only."),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("5xx")
|
||||
.short("5")
|
||||
.long("5xx")
|
||||
.takes_value(false)
|
||||
.help("Show URLs with 500-599 response codes only."),
|
||||
)
|
||||
.get_matches();
|
||||
let args = args::Cli::parse();
|
||||
|
||||
// Assign values or use defaults
|
||||
let conditional_response_code = if matches.is_present("1xx") {
|
||||
100
|
||||
} else if matches.is_present("2xx") {
|
||||
200
|
||||
} else if matches.is_present("3xx") {
|
||||
300
|
||||
} else if matches.is_present("4xx") {
|
||||
400
|
||||
} else if matches.is_present("5xx") {
|
||||
500
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let threads = value_t!(matches.value_of("threads"), usize).unwrap_or_else(|_| 50);
|
||||
let retries = value_t!(matches.value_of("retries"), usize).unwrap_or_else(|_| 1);
|
||||
let timeout = value_t!(matches.value_of("timeout"), u64).unwrap_or_else(|_| 3);
|
||||
let max_redirects = value_t!(matches.value_of("max-redirects"), usize).unwrap_or_else(|_| 0);
|
||||
let filter_codes = args.filter_codes;
|
||||
let exclude_codes = args.exclude_codes;
|
||||
let threads = args.threads;
|
||||
let retries = args.retries;
|
||||
let timeout = args.timeout;
|
||||
let max_redirects = args.max_redirects;
|
||||
let user_agents_list = utils::user_agents();
|
||||
let show_status_codes = matches.is_present("show-codes");
|
||||
let show_status_codes = args.show_codes;
|
||||
|
||||
let client = httplib::return_http_client(timeout, max_redirects);
|
||||
|
||||
|
|
@ -123,9 +25,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
|
||||
let mut hosts = HashSet::new();
|
||||
|
||||
if matches.is_present("domain") {
|
||||
let domain = value_t!(matches, "domain", String).unwrap();
|
||||
if matches.is_present("bruteforce") {
|
||||
if args.domain.is_some() {
|
||||
let domain = args.domain.expect("Error getting domain");
|
||||
if args.bruteforce {
|
||||
io::stdin().read_to_string(&mut buffer).await?;
|
||||
hosts = buffer
|
||||
.lines()
|
||||
|
|
@ -145,12 +47,21 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
user_agents: user_agents_list,
|
||||
retries,
|
||||
threads,
|
||||
conditional_response_code,
|
||||
filter_codes,
|
||||
exclude_codes,
|
||||
show_status_codes,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
httplib::return_http_data(&lib_options).await;
|
||||
if !args.quiet {
|
||||
if show_status_codes {
|
||||
println!("DOMAIN,[FINAL_URL],[STATUS_CODE]");
|
||||
} else {
|
||||
println!("DOMAIN,[FINAL_URL]");
|
||||
}
|
||||
}
|
||||
|
||||
let _ = httplib::return_http_data(&lib_options).await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue