split output streams; closes #44

This commit is contained in:
epi
2020-09-29 06:39:14 -05:00
parent 4a465521c7
commit 6e02a801a1
6 changed files with 42 additions and 21 deletions

View File

@@ -18,6 +18,7 @@ serde = { version = "1.0", features = ["derive"] }
uuid = { version = "0.8", features = ["v4"] }
ansi_term = "0.12"
indicatif = "0.15"
console = "0.12"
[dev-dependencies]
tempfile = "3.1"

View File

@@ -2,7 +2,7 @@ use crate::utils::status_colorizer;
use crate::{client, parser, progress};
use crate::{DEFAULT_CONFIG_NAME, DEFAULT_STATUS_CODES, DEFAULT_WORDLIST, VERSION};
use clap::value_t;
use indicatif::{MultiProgress, ProgressBar};
use indicatif::{MultiProgress, ProgressBar, ProgressDrawTarget};
use lazy_static::lazy_static;
use reqwest::{Client, StatusCode};
use serde::Deserialize;
@@ -17,7 +17,7 @@ lazy_static! {
pub static ref CONFIGURATION: Configuration = Configuration::new();
/// Global progress bar that houses other progress bars
pub static ref PROGRESS_BAR: MultiProgress = MultiProgress::new();
pub static ref PROGRESS_BAR: MultiProgress = MultiProgress::with_draw_target(ProgressDrawTarget::stdout());
/// Global progress bar that is only used for printing messages that don't jack up other bars
pub static ref PROGRESS_PRINTER: ProgressBar = progress::add_bar("", 0, true);

View File

@@ -1,6 +1,6 @@
use crate::config::{CONFIGURATION, PROGRESS_PRINTER};
use crate::scanner::{format_url, make_request};
use crate::utils::{get_url_path_length, status_colorizer};
use crate::utils::{get_url_path_length, status_colorizer, ferox_print};
use ansi_term::Color::{Cyan, Yellow};
use indicatif::ProgressBar;
use reqwest::Response;
@@ -81,29 +81,29 @@ pub async fn wildcard_test(target_url: &str, bar: ProgressBar) -> Option<Wildcar
let url_len = get_url_path_length(&resp_one.url());
if !CONFIGURATION.quiet {
PROGRESS_PRINTER.println(
format!(
ferox_print(
&format!(
"{} {:>10} Wildcard response is dynamic; {} ({} + url length) responses; toggle this behavior by using {}",
status_colorizer("WLD"),
wc_length - url_len,
Yellow.paint("auto-filtering"),
Cyan.paint(format!("{}", wc_length - url_len)),
Yellow.paint("--dontfilter")
)
), &PROGRESS_PRINTER
);
}
wildcard.dynamic = wc_length - url_len;
} else if wc_length == wc2_length {
if !CONFIGURATION.quiet {
PROGRESS_PRINTER.println(format!(
ferox_print(&format!(
"{} {:>10} Wildcard response is static; {} {} responses; toggle this behavior by using {}",
status_colorizer("WLD"),
wc_length,
Yellow.paint("auto-filtering"),
Cyan.paint(format!("{}", wc_length)),
Yellow.paint("--dontfilter")
));
), &PROGRESS_PRINTER);
}
wildcard.size = wc_length;
}
@@ -158,37 +158,37 @@ async fn make_wildcard_request(target_url: &str, length: usize) -> Option<Respon
let content_len = response.content_length().unwrap_or(0);
if !CONFIGURATION.quiet {
PROGRESS_PRINTER.println(format!(
ferox_print(&format!(
"{} {:>10} Got {} for {} (url length: {})",
wildcard,
content_len,
status_colorizer(&response.status().as_str()),
response.url(),
url_len
));
), &PROGRESS_PRINTER);
}
if response.status().is_redirection() {
// show where it goes, if possible
if let Some(next_loc) = response.headers().get("Location") {
if let Ok(next_loc_str) = next_loc.to_str() {
if !CONFIGURATION.quiet {
PROGRESS_PRINTER.println(format!(
ferox_print(&format!(
"{} {:>10} {} redirects to => {}",
wildcard,
content_len,
response.url(),
next_loc_str
));
), &PROGRESS_PRINTER);
}
} else {
if !CONFIGURATION.quiet {
PROGRESS_PRINTER.println(format!(
ferox_print(&format!(
"{} {:>10} {} redirects to => {:?}",
wildcard,
content_len,
response.url(),
next_loc
));
), &PROGRESS_PRINTER);
}
}
}
@@ -238,8 +238,7 @@ pub async fn connectivity_test(target_urls: &[String]) -> Vec<String> {
}
Err(e) => {
if !CONFIGURATION.quiet {
PROGRESS_PRINTER
.println(format!("Could not connect to {}, skipping...", target_url));
ferox_print(&format!("Could not connect to {}, skipping...", target_url), &PROGRESS_PRINTER);
}
log::error!("{}", e);
}

View File

@@ -1,5 +1,5 @@
use crate::config::{PROGRESS_BAR, CONFIGURATION};
use indicatif::{ProgressBar, ProgressStyle};
use indicatif::{ProgressBar, ProgressStyle, ProgressDrawTarget};
pub fn add_bar(prefix: &str, length: u64, hidden: bool) -> ProgressBar {
let style = if hidden || CONFIGURATION.quiet {

View File

@@ -1,6 +1,6 @@
use crate::config::{CONFIGURATION, PROGRESS_BAR, PROGRESS_PRINTER};
use crate::heuristics::WildcardFilter;
use crate::utils::{get_current_depth, get_url_path_length, status_colorizer};
use crate::utils::{get_current_depth, get_url_path_length, status_colorizer, ferox_print};
use crate::{heuristics, progress, FeroxResult};
use futures::future::{BoxFuture, FutureExt};
use futures::{stream, StreamExt};
@@ -189,17 +189,17 @@ async fn spawn_terminal_reporter(mut report_channel: UnboundedReceiver<Response>
if CONFIGURATION.statuscodes.contains(&resp.status().as_u16()) {
if CONFIGURATION.quiet {
PROGRESS_PRINTER.println(format!("{}", resp.url()));
ferox_print(&format!("{}", resp.url()), &PROGRESS_PRINTER);
} else {
let status = status_colorizer(&resp.status().as_str());
PROGRESS_PRINTER.println(format!(
ferox_print(&format!(
// example output
// 200 3280 https://localhost.com/FAQ
"{} {:>10} {}",
status,
resp.content_length().unwrap_or(0),
resp.url()
));
), &PROGRESS_PRINTER);
}
}
log::debug!("report complete: {}", resp.url());

View File

@@ -1,6 +1,8 @@
use ansi_term::Color::{Blue, Cyan, Green, Red, Yellow};
use reqwest::Url;
use std::convert::TryInto;
use console::{user_attended, strip_ansi_codes};
use indicatif::ProgressBar;
/// Helper function that determines the current depth of a given url
///
@@ -105,6 +107,25 @@ pub fn get_url_path_length(url: &Url) -> u64 {
0
}
/// Simple helper to abstract away the check for an attached terminal.
///
/// If a terminal is attached, progress bars are visible and the progress bar is used to print
/// to stderr. The progress bar must be used when bars are visible in order to not jack up any
/// progress bar output (the bar knows how to print above itself)
///
/// If a terminal is not attached, `msg` is printed to stdout, with its ansi
/// color codes stripped.
///
/// additionally, provides a location for future printing options (no color, etc) to be handled
pub fn ferox_print(msg: &str, bar: &ProgressBar) {
if user_attended() {
bar.println(msg);
} else {
let stripped = strip_ansi_codes(msg);
println!("{}", stripped);
}
}
#[cfg(test)]
mod tests {
use super::*;