interactsh 0.2.1

Async Rust client for polling out-of-band interaction servers.
Documentation
use crate::config::ClientConfig;
use crate::error::TransportStage;
use std::error::Error as StdError;

pub fn normalized_base_url(config: &ClientConfig) -> String {
    if config.server.starts_with("http://") || config.server.starts_with("https://") {
        config.server.trim_end_matches('/').to_string()
    } else {
        format!(
            "{}://{}",
            config.default_scheme.trim_end_matches("://"),
            config.server.trim_end_matches('/')
        )
    }
}

pub fn transport_stage_for(error: &reqwest::Error, default_stage: TransportStage) -> TransportStage {
    if error.is_timeout() {
        return TransportStage::Timeout;
    }

    let mut src = (error as &dyn StdError).source();
    while let Some(s) = src {
        if let Some(ioerr) = s.downcast_ref::<std::io::Error>() {
            match ioerr.kind() {
                std::io::ErrorKind::TimedOut
                | std::io::ErrorKind::WouldBlock
                | std::io::ErrorKind::ConnectionReset
                | std::io::ErrorKind::ConnectionRefused => {
                    return TransportStage::Timeout;
                }
                _ => {}
            }
        }
        src = s.source();
    }

    default_stage
}

pub fn should_retry_status(status: reqwest::StatusCode) -> bool {
    status.as_u16() == 429 || status.is_server_error()
}

pub fn is_connection_refused(error: &reqwest::Error) -> bool {
    let mut src = (error as &dyn StdError).source();
    while let Some(s) = src {
        if let Some(ioerr) = s.downcast_ref::<std::io::Error>() {
            if ioerr.kind() == std::io::ErrorKind::ConnectionRefused {
                return true;
            }
        }
        src = s.source();
    }
    false
}