Domani connects your domain to whatever you want to host on it, all with no account needed
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
domani/src/domain/config/proxied_domain.rs

119 lines
3.1 KiB

use crate::error::unexpected::{self, Mappable};
use serde::{Deserialize, Serialize};
fn addr_from_url(
url: &str,
expected_scheme: &str,
default_port: u16,
) -> unexpected::Result<String> {
let parsed: http::Uri = url.parse().or_unexpected_while("could not parse as url")?;
let scheme = parsed.scheme().or_unexpected_while("scheme is missing")?;
if scheme != expected_scheme {
return Err(unexpected::Error::from(
format!("scheme should be {expected_scheme}").as_str(),
));
}
if let Some(path_and_query) = parsed.path_and_query() {
let path_and_query = path_and_query.as_str();
if !path_and_query.is_empty() && path_and_query != "/" {
return Err(unexpected::Error::from("path must be empty"));
}
}
match parsed.authority() {
None => Err(unexpected::Error::from("host is missing")),
Some(authority) => {
let port = authority.port().map(|p| p.as_u16()).unwrap_or(default_port);
Ok(format!("{}:{port}", authority.host()))
}
}
}
#[derive(Deserialize, Serialize, Clone)]
pub struct GeminiUrl {
pub original_url: String,
pub addr: String,
}
impl TryFrom<String> for GeminiUrl {
type Error = unexpected::Error;
fn try_from(url: String) -> Result<Self, Self::Error> {
let addr = addr_from_url(&url, "gemini", 1965)?;
Ok(Self {
original_url: url,
addr,
})
}
}
impl From<GeminiUrl> for String {
fn from(u: GeminiUrl) -> Self {
u.original_url
}
}
#[derive(Deserialize, Serialize, Clone)]
pub struct HttpUrl {
pub original_url: String,
pub addr: String,
}
impl TryFrom<String> for HttpUrl {
type Error = unexpected::Error;
fn try_from(url: String) -> Result<Self, Self::Error> {
let addr = addr_from_url(&url, "http", 80)?;
Ok(Self {
original_url: url,
addr,
})
}
}
impl From<HttpUrl> for String {
fn from(u: HttpUrl) -> Self {
u.original_url
}
}
#[derive(Deserialize, Serialize, Clone)]
pub struct HttpRequestHeader {
name: String,
value: String,
}
#[derive(Clone, Default)]
pub struct HttpRequestHeaders(pub http::header::HeaderMap);
impl TryFrom<HttpRequestHeaders> for Vec<HttpRequestHeader> {
type Error = http::header::ToStrError;
fn try_from(h: HttpRequestHeaders) -> Result<Self, Self::Error> {
let mut v = vec![];
for (name, value) in &h.0 {
v.push(HttpRequestHeader {
name: name.to_string(),
value: value.to_str()?.to_string(),
})
}
Ok(v)
}
}
impl TryFrom<Vec<HttpRequestHeader>> for HttpRequestHeaders {
type Error = unexpected::Error;
fn try_from(v: Vec<HttpRequestHeader>) -> Result<Self, Self::Error> {
use http::header::{HeaderMap, HeaderName, HeaderValue};
let mut h = HeaderMap::new();
for pair in v {
let name: HeaderName = pair.name.parse().or_unexpected()?;
let value: HeaderValue = pair.value.parse().or_unexpected()?;
h.insert(name, value);
}
Ok(Self(h))
}
}