feat: serve gemini behind a tls terminator

This commit is contained in:
randogoth 2026-10-04 22:04:46 +03:00
parent dc2114a4d2
commit c29364d8e0
8 changed files with 395 additions and 39 deletions

View file

@ -48,16 +48,6 @@ pub struct SiteSpec {
/// `default_site`.
#[serde(default)]
pub hosts: Vec<String>,
/// Gemini only; unused until that listener exists.
#[serde(default)]
pub tls: Option<TlsSpec>,
}
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct TlsSpec {
pub cert: PathBuf,
pub key: PathBuf,
}
#[derive(Debug, Deserialize)]
@ -125,15 +115,6 @@ impl Protocol {
pub fn negotiates(self) -> bool {
matches!(self, Protocol::Http)
}
/// Whether a listener exists for this protocol.
///
/// Gemini needs a TLS stack and per-host certificate selection, which is its
/// own piece of work; naming it in a configuration is refused here rather
/// than panicking on the first connection.
pub fn is_implemented(self) -> bool {
!matches!(self, Protocol::Gemini)
}
}
/// What validation established, and what `--check` prints.
@ -263,12 +244,6 @@ impl ServerConfig {
fn validate_listeners(&self, available: &[&str]) -> Result<BTreeSet<String>, Error> {
let mut formats = BTreeSet::new();
for (name, spec) in &self.listener {
if !spec.protocol.is_implemented() {
return Err(Error::config(format!(
"listener '{name}': {} is not implemented yet",
spec.protocol.as_str()
)));
}
if spec.formats.is_empty() {
return Err(Error::config(format!("listener '{name}': formats must not be empty")));
}