Support serve_protocols
field on domain settings
This commit is contained in:
parent
5099f79260
commit
7049252787
12
README.md
12
README.md
@ -64,6 +64,12 @@ domain:
|
|||||||
# url: "https://somewhere.com/some/repo.git"
|
# url: "https://somewhere.com/some/repo.git"
|
||||||
# branch_name: main
|
# branch_name: main
|
||||||
# public: false
|
# public: false
|
||||||
|
#
|
||||||
|
# # Which protocols to serve the domain on. The given list overwrites the
|
||||||
|
# # default, which is to serve on all available protocols.
|
||||||
|
# #serve_protocols:
|
||||||
|
# #- protocol: http
|
||||||
|
# #- protocol: https
|
||||||
|
|
||||||
# An example built-in domain backed by a reverse-proxy to some other
|
# An example built-in domain backed by a reverse-proxy to some other
|
||||||
# web-service. Requests to the backing service will automatically have
|
# web-service. Requests to the backing service will automatically have
|
||||||
@ -85,6 +91,12 @@ domain:
|
|||||||
# value: ""
|
# value: ""
|
||||||
#
|
#
|
||||||
# public: false
|
# public: false
|
||||||
|
#
|
||||||
|
# # Which protocols to serve the domain on. The given list overwrites the
|
||||||
|
# # default, which is to serve on all available protocols.
|
||||||
|
# #serve_protocols:
|
||||||
|
# #- protocol: http
|
||||||
|
# #- protocol: https
|
||||||
|
|
||||||
service:
|
service:
|
||||||
|
|
||||||
|
@ -3,30 +3,9 @@ pub mod checker;
|
|||||||
mod config;
|
mod config;
|
||||||
pub mod manager;
|
pub mod manager;
|
||||||
mod name;
|
mod name;
|
||||||
|
mod settings;
|
||||||
pub mod store;
|
pub mod store;
|
||||||
|
|
||||||
pub use config::*;
|
pub use config::*;
|
||||||
pub use name::*;
|
pub use name::*;
|
||||||
|
pub use settings::*;
|
||||||
use crate::error::unexpected::{self, Mappable};
|
|
||||||
use crate::origin;
|
|
||||||
|
|
||||||
use hex::ToHex;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use sha2::{Digest, Sha256};
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
|
|
||||||
/// Defines how a domain will behave when it is accessed. These are configured by the owner of the
|
|
||||||
/// domain during setup.
|
|
||||||
pub struct Settings {
|
|
||||||
#[serde(flatten)]
|
|
||||||
pub origin_descr: origin::Descr,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Settings {
|
|
||||||
pub fn hash(&self) -> Result<String, unexpected::Error> {
|
|
||||||
let mut h = Sha256::new();
|
|
||||||
serde_json::to_writer(&mut h, self).or_unexpected()?;
|
|
||||||
Ok(h.finalize().encode_hex::<String>())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
38
src/domain/settings.rs
Normal file
38
src/domain/settings.rs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
use crate::error::unexpected::{self, Mappable};
|
||||||
|
use crate::origin;
|
||||||
|
|
||||||
|
use hex::ToHex;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use sha2::{Digest, Sha256};
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
|
||||||
|
#[serde(tag = "protocol")]
|
||||||
|
pub enum SettingsServeProtocol {
|
||||||
|
#[serde(rename = "http")]
|
||||||
|
Http,
|
||||||
|
#[serde(rename = "https")]
|
||||||
|
Https,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_serve_protocols() -> Vec<SettingsServeProtocol> {
|
||||||
|
vec![SettingsServeProtocol::Http, SettingsServeProtocol::Https]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
|
||||||
|
/// Defines how a domain will behave when it is accessed. These are configured by the owner of the
|
||||||
|
/// domain during setup.
|
||||||
|
pub struct Settings {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub origin_descr: origin::Descr,
|
||||||
|
|
||||||
|
#[serde(default = "default_serve_protocols")]
|
||||||
|
pub serve_protocols: Vec<SettingsServeProtocol>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Settings {
|
||||||
|
pub fn hash(&self) -> Result<String, unexpected::Error> {
|
||||||
|
let mut h = Sha256::new();
|
||||||
|
serde_json::to_writer(&mut h, self).or_unexpected()?;
|
||||||
|
Ok(h.finalize().encode_hex::<String>())
|
||||||
|
}
|
||||||
|
}
|
@ -165,23 +165,8 @@ impl<'svc> Service {
|
|||||||
req: Request<Body>,
|
req: Request<Body>,
|
||||||
req_is_https: bool,
|
req_is_https: bool,
|
||||||
) -> Response<Body> {
|
) -> Response<Body> {
|
||||||
// first check if the domain is backed by a proxy, and deal with that first
|
let settings = match self.domain_manager.get_settings(&domain) {
|
||||||
match self.domain_manager.get_settings(&domain) {
|
Ok(settings) => settings,
|
||||||
Ok(settings) => {
|
|
||||||
if let origin::Descr::Proxy { .. } = settings.origin_descr {
|
|
||||||
return origin::proxy::serve_http_request(
|
|
||||||
&settings,
|
|
||||||
client_ip,
|
|
||||||
req,
|
|
||||||
req_is_https,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.unwrap_or_else(|e| {
|
|
||||||
self.internal_error(format!("proxying {domain}: {e}").as_str())
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// fall out of match
|
|
||||||
}
|
|
||||||
Err(domain::manager::GetSettingsError::NotFound) => {
|
Err(domain::manager::GetSettingsError::NotFound) => {
|
||||||
return self.render_error_page(404, "Domain not found");
|
return self.render_error_page(404, "Domain not found");
|
||||||
}
|
}
|
||||||
@ -190,8 +175,29 @@ impl<'svc> Service {
|
|||||||
format!("failed to fetch settings for domain {domain}: {e}").as_str(),
|
format!("failed to fetch settings for domain {domain}: {e}").as_str(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let allowed = settings.serve_protocols.iter().any(|p| match p {
|
||||||
|
domain::SettingsServeProtocol::Http => !req_is_https,
|
||||||
|
domain::SettingsServeProtocol::Https => req_is_https,
|
||||||
|
});
|
||||||
|
|
||||||
|
if !allowed {
|
||||||
|
return self.render_error_page(
|
||||||
|
421,
|
||||||
|
"The requested protocol is not supported by this domain",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if the domain is backed by a proxy then that is handled specially.
|
||||||
|
if let origin::Descr::Proxy { .. } = settings.origin_descr {
|
||||||
|
return origin::proxy::serve_http_request(&settings, client_ip, req, req_is_https)
|
||||||
|
.await
|
||||||
|
.unwrap_or_else(|e| {
|
||||||
|
self.internal_error(format!("proxying {domain}: {e}").as_str())
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
let mut path_owned;
|
let mut path_owned;
|
||||||
let path = req.uri().path();
|
let path = req.uri().path();
|
||||||
|
|
||||||
|
@ -6,23 +6,24 @@ use crate::{domain, error::unexpected, origin};
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize, Default)]
|
#[derive(Serialize, Deserialize, Default)]
|
||||||
pub struct FlatDomainSettings {
|
pub struct FlatDomainSettings {
|
||||||
domain_setting_origin_descr_kind: Option<String>,
|
domain_setting_origin_descr_kind: String,
|
||||||
|
|
||||||
domain_setting_origin_descr_git_url: Option<String>,
|
domain_setting_origin_descr_git_url: Option<String>,
|
||||||
domain_setting_origin_descr_git_branch_name: Option<String>,
|
domain_setting_origin_descr_git_branch_name: Option<String>,
|
||||||
|
|
||||||
domain_setting_origin_descr_proxy_url: Option<String>,
|
domain_setting_origin_descr_proxy_url: Option<String>,
|
||||||
|
|
||||||
|
#[serde(default)]
|
||||||
|
domain_setting_serve_protocol_http: bool,
|
||||||
|
#[serde(default)]
|
||||||
|
domain_setting_serve_protocol_https: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<FlatDomainSettings> for domain::Settings {
|
impl TryFrom<FlatDomainSettings> for domain::Settings {
|
||||||
type Error = String;
|
type Error = String;
|
||||||
|
|
||||||
fn try_from(v: FlatDomainSettings) -> Result<Self, Self::Error> {
|
fn try_from(v: FlatDomainSettings) -> Result<Self, Self::Error> {
|
||||||
let origin_descr = match v
|
let origin_descr = match v.domain_setting_origin_descr_kind.as_str() {
|
||||||
.domain_setting_origin_descr_kind
|
|
||||||
.unwrap_or("".to_string())
|
|
||||||
.as_str()
|
|
||||||
{
|
|
||||||
"git" => Ok(origin::Descr::Git {
|
"git" => Ok(origin::Descr::Git {
|
||||||
url: v
|
url: v
|
||||||
.domain_setting_origin_descr_git_url
|
.domain_setting_origin_descr_git_url
|
||||||
@ -35,7 +36,20 @@ impl TryFrom<FlatDomainSettings> for domain::Settings {
|
|||||||
_ => Err("invalid domain_setting_origin_descr_kind".to_string()),
|
_ => Err("invalid domain_setting_origin_descr_kind".to_string()),
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
Ok(Self { origin_descr })
|
let mut serve_protocols = Vec::<domain::SettingsServeProtocol>::default();
|
||||||
|
|
||||||
|
if v.domain_setting_serve_protocol_http {
|
||||||
|
serve_protocols.push(domain::SettingsServeProtocol::Http);
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.domain_setting_serve_protocol_https {
|
||||||
|
serve_protocols.push(domain::SettingsServeProtocol::Https);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
origin_descr,
|
||||||
|
serve_protocols,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,16 +57,32 @@ impl TryFrom<domain::Settings> for FlatDomainSettings {
|
|||||||
type Error = unexpected::Error;
|
type Error = unexpected::Error;
|
||||||
|
|
||||||
fn try_from(v: domain::Settings) -> Result<Self, Self::Error> {
|
fn try_from(v: domain::Settings) -> Result<Self, Self::Error> {
|
||||||
|
let mut res = FlatDomainSettings::default();
|
||||||
|
|
||||||
match v.origin_descr {
|
match v.origin_descr {
|
||||||
origin::Descr::Git { url, branch_name } => Ok(FlatDomainSettings {
|
origin::Descr::Git { url, branch_name } => {
|
||||||
domain_setting_origin_descr_kind: Some("git".to_string()),
|
res.domain_setting_origin_descr_kind = "git".to_string();
|
||||||
domain_setting_origin_descr_git_url: Some(url),
|
res.domain_setting_origin_descr_git_url = Some(url);
|
||||||
domain_setting_origin_descr_git_branch_name: Some(branch_name),
|
res.domain_setting_origin_descr_git_branch_name = Some(branch_name);
|
||||||
..Default::default()
|
}
|
||||||
}),
|
origin::Descr::Proxy { .. } => {
|
||||||
origin::Descr::Proxy { .. } => Err(unexpected::Error::from(
|
return Err(unexpected::Error::from(
|
||||||
"proxy origins not supported for forms",
|
"proxy origins not supported for forms",
|
||||||
)),
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for serve_protocol in v.serve_protocols {
|
||||||
|
match serve_protocol {
|
||||||
|
domain::SettingsServeProtocol::Http => {
|
||||||
|
res.domain_setting_serve_protocol_http = true
|
||||||
|
}
|
||||||
|
domain::SettingsServeProtocol::Https => {
|
||||||
|
res.domain_setting_serve_protocol_https = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user