use crate::config::{
models::ConfigModel,
types::{AddressFamily, Uri, WsProtocol},
};
use schemars::JsonSchema;
use serde::Deserialize;
use std::{collections::HashMap, net::IpAddr, path::PathBuf};
use tracing::log;
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, JsonSchema)]
pub struct Serve {
#[serde(default)]
#[deprecated(note = "Use the 'addresses' field instead")]
pub address: Option<IpAddr>,
#[serde(default)]
pub addresses: Vec<IpAddr>,
#[serde(default)]
pub prefer_address_family: Option<AddressFamily>,
#[serde(default)]
pub disable_address_lookup: bool,
#[serde(default = "default::port")]
pub port: u16,
#[serde(default)]
pub aliases: Vec<String>,
#[serde(default)]
pub open: bool,
#[serde(default)]
pub no_autoreload: bool,
#[serde(default)]
pub headers: HashMap<String, String>,
#[serde(default)]
pub no_error_reporting: bool,
#[serde(default)]
pub no_spa: bool,
pub ws_protocol: Option<WsProtocol>,
#[serde(default)]
pub ws_base: Option<String>,
#[serde(default)]
pub tls_key_path: Option<PathBuf>,
#[serde(default)]
pub tls_cert_path: Option<PathBuf>,
#[serde(default)]
pub serve_base: Option<String>,
#[serde(default)]
pub proxy_no_redirect: Option<bool>,
#[deprecated]
pub proxy_backend: Option<Uri>,
#[serde(default)]
#[deprecated]
pub proxy_rewrite: Option<String>,
#[serde(default)]
#[deprecated]
pub proxy_ws: Option<bool>,
#[serde(default)]
#[deprecated]
pub proxy_insecure: Option<bool>,
#[serde(default)]
#[deprecated]
pub proxy_no_system_proxy: Option<bool>,
#[serde(default)]
pub disable_csp: bool,
#[serde(default = "default::csp")]
pub csp: Vec<String>,
}
impl Default for Serve {
#[allow(deprecated)]
fn default() -> Self {
Self {
address: None,
addresses: vec![],
aliases: vec![],
prefer_address_family: None,
port: default::port(),
disable_address_lookup: false,
open: false,
no_autoreload: false,
headers: Default::default(),
no_error_reporting: false,
no_spa: false,
ws_protocol: None,
ws_base: None,
tls_key_path: None,
tls_cert_path: None,
serve_base: None,
proxy_backend: None,
proxy_rewrite: None,
proxy_ws: None,
proxy_insecure: None,
proxy_no_system_proxy: None,
proxy_no_redirect: None,
disable_csp: false,
csp: default::csp(),
}
}
}
mod default {
pub const fn port() -> u16 {
8080
}
pub fn csp() -> Vec<String> {
[
"script-src 'wasm-unsafe-eval' 'nonce-{{NONCE}}'",
"style-src 'nonce-{{NONCE}}'",
]
.map(|s| s.to_string())
.into()
}
}
macro_rules! check_proxy_setting {
($s: expr, $f: ident) => {
if $s.$f.is_some() {
log::warn!(
"Found a setting for single {}, without single proxy_rewrite setting. This has no effect.", stringify!($f)
);
}
};
}
impl ConfigModel for Serve {
#[allow(deprecated)]
fn migrate(&mut self) -> anyhow::Result<()> {
if let Some(address) = self.address.take() {
log::warn!("The field `address` in the configuration is deprecated and will be removed in a future version. Migrate to the `addresses` field, which allows adding more than one.");
self.addresses.push(address);
}
if self.proxy_backend.is_none() {
check_proxy_setting!(self, proxy_rewrite);
check_proxy_setting!(self, proxy_ws);
check_proxy_setting!(self, proxy_insecure);
check_proxy_setting!(self, proxy_no_system_proxy);
}
Ok(())
}
}