diff --git a/leptos/src/hydration/mod.rs b/leptos/src/hydration/mod.rs index 60721459fb..5e4a5eed1f 100644 --- a/leptos/src/hydration/mod.rs +++ b/leptos/src/hydration/mod.rs @@ -26,9 +26,20 @@ pub fn AutoReload( Some(val) => val, None => options.reload_port, }; + let protocol = match options.reload_ws_protocol { + leptos_config::ReloadWSProtocol::Auto => "null", leptos_config::ReloadWSProtocol::WS => "'ws://'", leptos_config::ReloadWSProtocol::WSS => "'wss://'", + + unrecognized => { + leptos::logging::error!( + "Unrecognized live reload protocol option '{}'", + unrecognized, + ); + + "null" + } }; let script = format!( diff --git a/leptos/src/hydration/reload_script.js b/leptos/src/hydration/reload_script.js index edf523eea6..a59cce3f95 100644 --- a/leptos/src/hydration/reload_script.js +++ b/leptos/src/hydration/reload_script.js @@ -1,8 +1,9 @@ -if (window.location.protocol === 'https:') { - protocol = 'wss://'; +let host = window.location.hostname; + +if (protocol === null) { + protocol = window.location.protocol === 'https:' ? 'wss://' : 'ws://'; } -let host = window.location.hostname; let ws = new WebSocket(`${protocol}${host}:${reload_port}/live_reload`); ws.onmessage = (ev) => { let msg = JSON.parse(ev.data); diff --git a/leptos_config/src/lib.rs b/leptos_config/src/lib.rs index f4d560ec50..fd05db164e 100644 --- a/leptos_config/src/lib.rs +++ b/leptos_config/src/lib.rs @@ -6,7 +6,8 @@ use crate::errors::LeptosConfigError; use config::{Case, Config, File, FileFormat}; use regex::Regex; use std::{ - env::VarError, fs, net::SocketAddr, path::Path, str::FromStr, sync::Arc, + env::VarError, fmt::Display, fs, net::SocketAddr, path::Path, str::FromStr, + sync::Arc, }; use typed_builder::TypedBuilder; @@ -153,7 +154,7 @@ impl LeptosOptions { None => None, }, reload_ws_protocol: ws_from_str( - env_w_default("LEPTOS_RELOAD_WS_PROTOCOL", "ws")?.as_str(), + env_w_default("LEPTOS_RELOAD_WS_PROTOCOL", "auto")?.as_str(), )?, not_found_path: env_w_default("LEPTOS_NOT_FOUND_PATH", "/404")? .into(), @@ -222,6 +223,7 @@ fn env_w_default( /// Setting this to the `PROD` variant will not include the WebSocket code for `cargo-leptos` watch mode. /// Defaults to `DEV`. #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq)] +#[non_exhaustive] pub enum Env { PROD, DEV, @@ -280,25 +282,28 @@ impl TryFrom for Env { /// An enum that can be used to define the websocket protocol Leptos uses for hotreloading /// Defaults to `ws`. #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq)] +#[non_exhaustive] pub enum ReloadWSProtocol { WS, WSS, + Auto, } impl Default for ReloadWSProtocol { fn default() -> Self { - Self::WS + Self::Auto } } fn ws_from_str(input: &str) -> Result { let sanitized = input.to_lowercase(); match sanitized.as_ref() { + "auto" => Ok(ReloadWSProtocol::Auto), "ws" | "WS" => Ok(ReloadWSProtocol::WS), "wss" | "WSS" => Ok(ReloadWSProtocol::WSS), _ => Err(LeptosConfigError::EnvVarError(format!( - "{input} is not a supported websocket protocol. Use only `ws` or \ - `wss`.", + "{input} is not a supported websocket protocol. Use only `auto`, \ + `ws` or `wss`.", ))), } } @@ -333,6 +338,16 @@ impl TryFrom for ReloadWSProtocol { } } +impl Display for ReloadWSProtocol { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ReloadWSProtocol::WS => f.write_str("ws"), + ReloadWSProtocol::WSS => f.write_str("wss"), + ReloadWSProtocol::Auto => f.write_str("auto"), + } + } +} + /// Loads [LeptosOptions] from a Cargo.toml text content with layered overrides. /// If an env var is specified, like `LEPTOS_ENV`, it will override a setting in the file. pub fn get_config_from_str( diff --git a/leptos_config/src/tests.rs b/leptos_config/src/tests.rs index 9648f0098d..caa096977f 100644 --- a/leptos_config/src/tests.rs +++ b/leptos_config/src/tests.rs @@ -20,6 +20,11 @@ fn env_from_str_test() { #[test] fn ws_from_str_test() { + assert!(matches!( + ws_from_str("auto").unwrap(), + ReloadWSProtocol::Auto + )); + assert!(matches!(ws_from_str("ws").unwrap(), ReloadWSProtocol::WS)); assert!(matches!(ws_from_str("WS").unwrap(), ReloadWSProtocol::WS)); assert!(matches!(ws_from_str("wss").unwrap(), ReloadWSProtocol::WSS)); @@ -28,6 +33,15 @@ fn ws_from_str_test() { assert!(ws_from_str("?").is_err()); } +#[test] +fn ws_from_to_str_test() { + assert_eq!(ws_from_str("auto").unwrap().to_string(), "auto"); + assert_eq!(ws_from_str("ws").unwrap().to_string(), "ws"); + assert_eq!(ws_from_str("WS").unwrap().to_string(), "ws"); + assert_eq!(ws_from_str("wss").unwrap().to_string(), "wss"); + assert_eq!(ws_from_str("WSS").unwrap().to_string(), "wss"); +} + #[test] fn env_w_default_test() { temp_env::with_var("LEPTOS_CONFIG_ENV_TEST", Some("custom"), || {