use std::net::IpAddr;
use ureq::http::Uri;
use ureq::http::uri::Scheme;
use crate::error::{Error, Result};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum Metadata {
Document,
Sidecar,
}
impl Metadata {
pub(crate) fn max_len(self) -> u64 {
match self {
Self::Document => 10 * 1024 * 1024,
Self::Sidecar => 1024 * 1024,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(super) enum Transport {
Https,
LoopbackHttp,
}
impl Transport {
pub(super) fn of(url: &str) -> Result<Self> {
let uri: Uri = url
.parse()
.map_err(|e| Error::Http(format!("invalid URL {url}: {e}")))?;
if uri.scheme() == Some(&Scheme::HTTPS) {
Ok(Self::Https)
} else if uri.scheme() == Some(&Scheme::HTTP) && uri.host().is_some_and(is_loopback) {
Ok(Self::LoopbackHttp)
} else {
Err(Error::InsecureUrl(url.to_string()))
}
}
}
fn is_loopback(host: &str) -> bool {
let host = host.trim_start_matches('[').trim_end_matches(']');
host.eq_ignore_ascii_case("localhost")
|| host.parse::<IpAddr>().is_ok_and(|ip| ip.is_loopback())
}
pub(crate) fn ensure_secure(url: &str) -> Result<()> {
Transport::of(url).map(drop)
}