Skip to main content

product_os_server/
lib.rs

1//! Product OS Server
2//!
3//! A comprehensive, feature-rich server library supporting HTTP/HTTPS, TLS, WebSockets,
4//! Server-Sent Events (SSE), and command-and-control distributed networking.
5//!
6//! # Features
7//!
8//! - **HTTP/HTTPS Servers**: Full-featured web servers with TLS support
9//! - **Dual Protocol Support**: Serve both HTTP and HTTPS simultaneously
10//! - **Security**: Built-in CSP, CSRF protection, security headers
11//! - **Compression**: Gzip, Deflate, and Brotli compression support
12//! - **WebSockets**: Native WebSocket handler support
13//! - **SSE**: Server-Sent Events for real-time updates
14//! - **CORS**: Configurable Cross-Origin Resource Sharing
15//! - **Command & Control**: Distributed network capabilities with authentication
16//! - **Flexible Executors**: Support for Tokio and custom executors
17//! - **no_std Support**: Can be used in embedded environments with appropriate features
18//!
19//! # Example
20//!
21//! ```no_run
22//! use product_os_server::{ProductOSServer, StatusCode, Response, Body};
23//! use product_os_server::ServerConfig;
24//! use product_os_async_executor::TokioExecutor;
25//!
26//! # #[cfg(feature = "executor_tokio")]
27//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
28//! // Create server with default configuration
29//! let config = ServerConfig::new();
30//! let mut server: ProductOSServer<(), TokioExecutor, _> = 
31//!     ProductOSServer::new_with_config(config);
32//!
33//! // Add a simple GET handler
34//! async fn hello_handler() -> Result<Response<Body>, StatusCode> {
35//!     Ok(Response::new(Body::empty()))
36//! }
37//!
38//! server.add_get("/hello", hello_handler);
39//!
40//! // Start the server (non-blocking)
41//! // server.start(false).await?;
42//! # Ok(())
43//! # }
44//! ```
45//!
46//! # Feature Flags
47//!
48//! - `core`: Core server functionality (hyper, axum, tracing)
49//! - `executor_tokio`: Tokio executor support
50//! - `tls`: HTTPS/TLS support via rustls
51//! - `dual_server`: Dual HTTP/HTTPS protocol support
52//! - `cors`: CORS middleware
53//! - `ws`: WebSocket support
54//! - `sse`: Server-Sent Events support
55//! - `compression`: Response compression (gzip, deflate, brotli)
56//! - `cspolicy`: Content Security Policy headers
57//! - `csrf`: CSRF protection
58//! - `controller`: Command and control distributed networking
59//! - `middleware`: Extended middleware support
60//! - `extract_headers`: Typed header extraction
61//!
62//! # Safety and Security
63//!
64//! This crate provides security features including:
65//! - TLS/HTTPS with rustls
66//! - Content Security Policy configuration
67//! - CSRF token validation
68//! - Security headers (HSTS, X-Frame-Options, etc.)
69//! - Authentication for command-and-control operations
70//!
71//! Always review your configuration for your specific security requirements.
72
73#![no_std]
74#![warn(missing_docs)]
75#![warn(clippy::unwrap_used)]
76#![warn(clippy::expect_used)]
77#![warn(clippy::panic)]
78
79extern crate no_std_compat as std;
80extern crate alloc;
81
82use core::marker::PhantomData;
83use core::str::FromStr;
84use std::prelude::v1::*;
85
86/// Error types for server operations.
87pub mod error;
88pub use error::{ProductOSServerError, Result as ServerResult};
89
90/// Server configuration types (Network, Certificate, Compression, ServerConfig)
91pub mod config;
92pub use config::{ServerConfig, Network, Certificate, CertificateFiles, CertificateFilesKind, Compression};
93
94#[cfg(feature = "tls")]
95mod https_server;
96
97mod certificates;
98
99mod logging;
100mod http_server;
101
102#[cfg(feature = "cspolicy")]
103mod csp;
104
105#[cfg(feature = "controller")]
106mod command_handler;
107
108#[cfg(feature = "controller")]
109mod feature_handler;
110#[cfg(feature = "dual_server")]
111mod dual_server;
112
113mod server_executor;
114
115#[cfg(any(feature = "oidc", feature = "authentication", feature = "content", feature = "service_handler"))]
116mod features_services;
117
118use std::collections::BTreeMap;
119
120use std::sync::Arc;
121
122#[cfg(feature = "controller")]
123use parking_lot::Mutex;
124
125
126#[cfg(feature = "core")]
127pub use axum::{
128    BoxError,
129    http::uri::Scheme,
130    response::IntoResponse
131};
132
133
134#[cfg(feature = "extract_headers")]
135pub use axum_extra::typed_header::TypedHeader;
136
137#[cfg(feature = "core")]
138pub use hyper::{
139    upgrade,
140    client::conn
141};
142
143pub use product_os_router::{
144    Layer, Service, ServiceExt, service_fn,
145    Router, Method, ProductOSRouter, ServiceBuilder,
146    Json,
147    Form,
148    Body, BodyBytes, Bytes, HttpBody,
149    Request, StatusCode, Response, IntoResponse as RouterIntoResponse,
150    Handler, Uri
151};
152
153#[cfg(feature = "core")]
154pub use axum::extract::Extension;
155
156
157#[cfg(feature = "middleware")]
158pub use product_os_router::*;
159
160#[cfg(feature = "controller")]
161use product_os_command_control::ProductOSController;
162
163#[cfg(feature = "controller")]
164use product_os_store::{ ProductOSKeyValueStore, ProductOSRelationalStore };
165
166
167#[cfg(feature = "core")]
168pub use axum::{
169    extract::*,
170};
171
172#[cfg(feature = "sse")]
173pub use axum::response::sse::{Event, Sse};
174
175#[cfg(feature = "core")]
176use axum::routing::Route;
177
178
179#[cfg(feature = "compression")]
180use tower_http::{
181    compression::CompressionLayer,
182    decompression::DecompressionLayer
183};
184
185#[cfg(feature = "csrf")]
186use axum_csrf::{CsrfConfig, CsrfLayer};
187
188
189
190#[cfg(feature = "executor_tokio")]
191use product_os_async_executor::TokioExecutor;
192
193use product_os_async_executor::Executor;
194use crate::certificates::ProductOSServerCertificates;
195
196/// Default HSTS max-age in seconds (24 hours).
197const DEFAULT_HSTS_MAX_AGE: u32 = 86400;
198
199/// Default timeout for controller lock acquisition (10 seconds).
200#[cfg(feature = "controller")]
201pub(crate) const CONTROLLER_LOCK_TIMEOUT: core::time::Duration = core::time::Duration::from_secs(10);
202
203/// Applies security headers and optional CSRF/CSP middleware to a router.
204///
205/// This helper is used by both the constructor and `set_security` to avoid duplication.
206fn apply_security_headers<S: Clone + Send + Sync + 'static>(
207    router: &mut ProductOSRouter<S>,
208    host: &str,
209    security: &product_os_security::Security,
210) {
211    if !security.enable {
212        return;
213    }
214
215    #[cfg(feature = "cspolicy")]
216    {
217        let csp_config = security
218            .csp
219            .as_ref()
220            .map_or_else(product_os_security::CSPConfig::new, Clone::clone);
221        let csp_value = csp::ContentSecurityPolicy::from_csp_config(&csp_config).get_csp();
222        router.add_default_header("content-security-policy", &csp_value);
223    }
224
225    router.add_default_header("cross-origin-embedder-policy", "require-corp");
226    router.add_default_header("cross-origin-opener-policy", "same-origin");
227    router.add_default_header("referrer-policy", "strict-origin-when-cross-origin");
228    let hsts_value = alloc::format!("max-age={}; includeSubDomains; preload", DEFAULT_HSTS_MAX_AGE);
229    router.add_default_header("strict-transport-security", &hsts_value);
230    router.add_default_header("x-Content-type-options", "nosniff");
231    router.add_default_header("x-powered-by", host);
232
233    #[cfg(feature = "csrf")]
234    {
235        if security.csrf {
236            router.add_middleware(CsrfLayer::new(CsrfConfig::default()));
237            #[cfg(feature = "core")]
238            tracing::info!("CSRF added as extension middleware");
239        }
240    }
241}
242
243/// Applies compression and decompression middleware layers to a router.
244///
245/// This helper is used by both the constructor and `set_compression` to avoid duplication.
246#[cfg(feature = "compression")]
247fn apply_compression<S: Clone + Send + Sync + 'static>(
248    router: &mut ProductOSRouter<S>,
249    compression_config: &crate::config::Compression,
250) {
251    if !compression_config.enable {
252        return;
253    }
254    let mut compression = CompressionLayer::new();
255    if compression_config.gzip { compression = compression.gzip(true); }
256    if compression_config.deflate { compression = compression.deflate(true); }
257    if compression_config.brotli { compression = compression.br(true); }
258    router.add_middleware(compression);
259
260    let mut decompression = DecompressionLayer::new();
261    if compression_config.gzip { decompression = decompression.gzip(true); }
262    if compression_config.deflate { decompression = decompression.deflate(true); }
263    if compression_config.brotli { decompression = decompression.br(true); }
264    router.add_middleware(decompression);
265}
266
267/// Specifies which async executor implementation to use for the server.
268///
269/// Currently, only Tokio is fully supported. Embassy is reserved for future
270/// embedded system support.
271pub enum ExecutorType {
272    /// Use the Tokio async runtime. This is the recommended and fully-supported executor.
273    Tokio,
274    /// Use the Embassy async runtime (for embedded / no_std environments).
275    /// **Note:** Embassy support is experimental and not yet fully implemented.
276    Embassy,
277}
278
279
280
281
282/// The main server struct for Product OS Server
283///
284/// `ProductOSServer` provides a complete web server implementation with support for:
285/// - HTTP and HTTPS protocols
286/// - Routing and middleware
287/// - TLS/SSL via rustls
288/// - WebSockets and Server-Sent Events
289/// - Command-and-control distributed networking (with `controller` feature)
290/// - Compression, CORS, CSRF, and security headers
291///
292/// # Type Parameters
293///
294/// - `S`: The shared state type (must be `Clone + Send + Sync + 'static`)
295/// - `E`: The executor type implementing `Executor` traits
296/// - `X`: The underlying executor context type
297///
298/// # Examples
299///
300/// ## Basic HTTP Server
301///
302/// ```no_run
303/// use product_os_server::{ProductOSServer, StatusCode, Response, Body};
304/// use product_os_server::ServerConfig;
305/// use product_os_async_executor::TokioExecutor;
306///
307/// # #[cfg(feature = "executor_tokio")]
308/// # async fn example() {
309/// let config = ServerConfig::new();
310/// let mut server: ProductOSServer<(), TokioExecutor, _> = 
311///     ProductOSServer::new_with_config(config);
312///
313/// async fn handler() -> Result<Response<Body>, StatusCode> {
314///     Ok(Response::new(Body::empty()))
315/// }
316///
317/// server.add_get("/", handler);
318/// # }
319/// ```
320///
321/// ## Server with Shared State
322///
323/// ```no_run
324/// use product_os_server::{ProductOSServer, StatusCode, Response};
325/// use product_os_server::ServerConfig;
326/// use product_os_async_executor::TokioExecutor;
327///
328/// # #[cfg(feature = "executor_tokio")]
329/// # async fn example() {
330/// #[derive(Clone)]
331/// struct AppState {
332///     counter: std::sync::Arc<parking_lot::Mutex<i32>>,
333/// }
334///
335/// let state = AppState {
336///     counter: std::sync::Arc::new(parking_lot::Mutex::new(0)),
337/// };
338///
339/// let config = ServerConfig::new();
340/// let mut server: ProductOSServer<AppState, TokioExecutor, _> = 
341///     ProductOSServer::new_with_state_with_config(config, state);
342/// # }
343/// ```
344pub struct ProductOSServer<S, E, X>
345where
346    E: product_os_async_executor::Executor<X> + product_os_async_executor::ExecutorPerform<X> + product_os_async_executor::Timer
347{
348    router: ProductOSRouter<S>,
349
350    config: crate::config::ServerConfig,
351    certificates:  product_os_security::certificates::Certificates,
352
353    #[cfg(feature = "controller")]
354    controller: Option<Arc<Mutex<ProductOSController>>>,
355
356    executor: Arc<E>,
357    executor_underlying: PhantomData<X>
358}
359
360#[cfg(feature = "executor_tokio")]
361impl<X> ProductOSServer<(), TokioExecutor, X>
362where
363    TokioExecutor: product_os_async_executor::Executor<X>, TokioExecutor: product_os_async_executor::ExecutorPerform<X>
364{
365    /// Creates a new server with the given configuration and no shared state.
366    ///
367    /// This is a convenience constructor for Tokio-based servers that automatically
368    /// creates and initializes the Tokio executor.
369    ///
370    /// # Arguments
371    ///
372    /// * `config` - Server configuration including network settings, security options, etc.
373    ///
374    /// # Examples
375    ///
376    /// ```no_run
377    /// use product_os_server::ProductOSServer;
378    /// use product_os_server::ServerConfig;
379    /// use product_os_async_executor::TokioExecutor;
380    ///
381    /// # #[cfg(feature = "executor_tokio")]
382    /// # fn example() {
383    /// let config = ServerConfig::new();
384    /// let server: ProductOSServer<(), TokioExecutor, _> = 
385    ///     ProductOSServer::new_with_config(config);
386    /// # }
387    /// ```
388    pub fn new_with_config(config: crate::config::ServerConfig) -> Self {
389        let executor = match TokioExecutor::context_sync() {
390            Ok(exec) => Arc::new(exec),
391            Err(e) => panic!("Failed to create Tokio executor context: {:?}. Ensure a Tokio runtime is active.", e),
392        };
393        ProductOSServer::new_with_executor_with_state_with_config(Some(executor), config, ())
394    }
395
396    /// Creates a new server with default configuration and no shared state.
397    ///
398    /// This constructor uses default configuration settings and creates a Tokio executor.
399    ///
400    /// # Arguments
401    ///
402    /// * `executor` - Optional executor Arc. If None, a new executor will be created.
403    ///
404    /// # Examples
405    ///
406    /// ```no_run
407    /// use product_os_server::ProductOSServer;
408    /// use product_os_async_executor::TokioExecutor;
409    ///
410    /// # #[cfg(feature = "executor_tokio")]
411    /// # fn example() {
412    /// let server: ProductOSServer<(), TokioExecutor, _> = 
413    ///     ProductOSServer::new(None);
414    /// # }
415    /// ```
416    pub fn new(_executor: Option<Arc<TokioExecutor>>) -> Self {
417        let executor = match TokioExecutor::context_sync() {
418            Ok(exec) => Arc::new(exec),
419            Err(e) => panic!("Failed to create Tokio executor context: {:?}. Ensure a Tokio runtime is active.", e),
420        };
421        ProductOSServer::new_with_executor_with_state(Some(executor), ())
422    }
423}
424
425
426
427impl<E, X> ProductOSServer<(), E, X>
428where
429    E: product_os_async_executor::Executor<X> + product_os_async_executor::ExecutorPerform<X> + product_os_async_executor::Timer + 'static
430{
431    /// Creates a new server with a custom executor and configuration.
432    ///
433    /// This constructor allows specifying a custom executor for handling async operations.
434    ///
435    /// # Arguments
436    ///
437    /// * `executor` - Optional executor Arc. If None, will panic.
438    /// * `config` - Server configuration
439    pub fn new_with_executor_with_config(executor: Option<Arc<E>>, config: crate::config::ServerConfig) -> Self {
440        ProductOSServer::new_with_executor_with_state_with_config(executor, config, ())
441    }
442
443    /// Creates a new server with a custom executor and default configuration.
444    ///
445    /// # Arguments
446    ///
447    /// * `executor` - Optional executor Arc. If None, will panic.
448    pub fn new_with_executor(executor: Option<Arc<E>>) -> Self {
449        ProductOSServer::new_with_executor_with_state(executor, ())
450    }
451
452    #[cfg(feature = "controller")]
453    /// Adds a feature to the server.
454    ///
455    /// # Panics
456    ///
457    /// Panics if no controller is configured. Use `try_add_feature` for a non-panicking alternative.
458    #[deprecated(since = "0.0.53", note = "Use try_add_feature which returns Result instead of panicking")]
459    pub async fn add_feature(&mut self, feature_arc: Arc<dyn product_os_capabilities::Feature>, base_path: Option<String>) {
460        self.try_add_feature(feature_arc, base_path).await
461            .unwrap_or_else(|e| panic!("{}", e));
462    }
463
464    #[cfg(feature = "controller")]
465    /// Adds a feature to the server, returning an error if no controller is configured.
466    ///
467    /// Features provide modular functionality that can be dynamically added to the server.
468    /// This method requires the `controller` feature to be enabled.
469    ///
470    /// # Arguments
471    ///
472    /// * `feature_arc` - Arc-wrapped feature implementation
473    /// * `base_path` - Optional base path for mounting the feature's routes
474    ///
475    /// # Errors
476    ///
477    /// Returns `ControllerError` if no controller is configured on the server.
478    pub async fn try_add_feature(&mut self, feature_arc: Arc<dyn product_os_capabilities::Feature>, base_path: Option<String>) -> crate::error::Result<()> {
479        match &self.controller {
480            None => {
481                Err(ProductOSServerError::ControllerError {
482                    operation: "add_feature".to_string(),
483                    message: alloc::format!("Feature {} failed to add to server: no controller", feature_arc.identifier()),
484                })
485            }
486            Some(c) => {
487                let controller_unlocked = c.clone();
488                let mut controller = controller_unlocked.lock();
489
490                let feature_base_path = base_path.unwrap_or_default();
491
492                controller.add_feature(feature_arc.clone(), feature_base_path, &mut self.router).await;
493                #[cfg(feature = "core")]
494                tracing::info!("Feature {} successfully added to server", feature_arc.identifier());
495                Ok(())
496            }
497        }
498    }
499
500    #[cfg(feature = "controller")]
501    /// Adds a mutable feature to the server.
502    ///
503    /// # Panics
504    ///
505    /// Panics if no controller is configured. Use `try_add_feature_mut` for a non-panicking alternative.
506    #[deprecated(since = "0.0.53", note = "Use try_add_feature_mut which returns Result instead of panicking")]
507    pub async fn add_feature_mut(&mut self, feature_arc_mut: Arc<Mutex<dyn product_os_capabilities::Feature>>, base_path: Option<String>) {
508        self.try_add_feature_mut(feature_arc_mut, base_path).await
509            .unwrap_or_else(|e| panic!("{}", e));
510    }
511
512    #[cfg(feature = "controller")]
513    /// Adds a mutable feature to the server, returning an error if no controller is configured.
514    ///
515    /// Similar to `try_add_feature`, but accepts a mutable feature wrapped in an `Arc<Mutex>`.
516    ///
517    /// # Arguments
518    ///
519    /// * `feature_arc_mut` - Arc-wrapped mutex containing the feature implementation
520    /// * `base_path` - Optional base path for mounting the feature's routes
521    ///
522    /// # Errors
523    ///
524    /// Returns `ControllerError` if no controller is configured on the server.
525    pub async fn try_add_feature_mut(&mut self, feature_arc_mut: Arc<Mutex<dyn product_os_capabilities::Feature>>, base_path: Option<String>) -> crate::error::Result<()> {
526        match &self.controller {
527            None => {
528                let feature_locked = feature_arc_mut.lock();
529                Err(ProductOSServerError::ControllerError {
530                    operation: "add_feature_mut".to_string(),
531                    message: alloc::format!("Feature {} failed to add to server: no controller", feature_locked.identifier()),
532                })
533            }
534            Some(c) => {
535                let controller_unlocked = c.clone();
536                let mut controller = controller_unlocked.lock();
537
538                let feature_base_path = base_path.unwrap_or_default();
539
540                controller.add_feature_mut(feature_arc_mut.clone(), feature_base_path, &mut self.router).await;
541                let feature_locked = feature_arc_mut.lock();
542                #[cfg(feature = "core")]
543                tracing::info!("Feature {} successfully added to server", feature_locked.identifier());
544                Ok(())
545            }
546        }
547    }
548}
549
550
551#[cfg(feature = "executor_tokio")]
552impl<S, X> ProductOSServer<S, TokioExecutor, X>
553where
554    S: Clone + Send + Sync + 'static,
555    TokioExecutor: product_os_async_executor::Executor<X>, TokioExecutor: product_os_async_executor::ExecutorPerform<X>
556{
557    /// Creates a new server with state and configuration (Tokio executor).
558    ///
559    /// # Arguments
560    ///
561    /// * `config` - Server configuration
562    /// * `state` - Shared state available to all handlers
563    pub fn new_with_state_with_config(config: crate::config::ServerConfig, state: S) -> Self {
564        let executor = match TokioExecutor::context_sync() {
565            Ok(exec) => Arc::new(exec),
566            Err(e) => panic!("Failed to create Tokio executor context: {:?}. Ensure a Tokio runtime is active.", e),
567        };
568        ProductOSServer::new_with_executor_with_state_with_config(Some(executor), config, state)
569    }
570
571    /// Creates a new server with state and default configuration (Tokio executor).
572    ///
573    /// # Arguments
574    ///
575    /// * `state` - Shared state available to all handlers
576    pub fn new_with_state(state: S) -> Self {
577        let executor = match TokioExecutor::context_sync() {
578            Ok(exec) => Arc::new(exec),
579            Err(e) => panic!("Failed to create Tokio executor context: {:?}. Ensure a Tokio runtime is active.", e),
580        };
581        ProductOSServer::new_with_executor_with_state(Some(executor), state)
582    }
583}
584
585
586impl<S, E, X> ProductOSServer<S, E, X>
587where
588    S: Clone + Send + Sync + 'static,
589    E: product_os_async_executor::Executor<X> + product_os_async_executor::ExecutorPerform<X> + product_os_async_executor::Timer + 'static
590{
591    /// Creates a new server with custom executor, state, and configuration.
592    ///
593    /// This is the most flexible constructor, allowing full customization of executor,
594    /// state, and configuration.
595    ///
596    /// # Arguments
597    ///
598    /// * `executor` - Optional executor Arc. If None, will panic.
599    /// * `config` - Server configuration including network, security, compression settings
600    /// * `state` - Shared state that will be available to all handlers
601    pub fn new_with_executor_with_state_with_config(executor: Option<Arc<E>>, config: crate::config::ServerConfig, state: S) -> Self {
602        #[cfg(feature = "core")]
603        let _ = logging::set_global_logger(logging::define_logging(config.log_level()));
604        #[cfg(feature = "core")]
605        tracing::info!("Log Level: {}", config.log_level());
606
607        let mut router = ProductOSRouter::new_with_state(state);
608
609        // Setup certificates
610        let certificates = ProductOSServerCertificates::setup_certificates(&config.certificate);
611
612        // Parse security config from raw JSON
613        let security_config: Option<product_os_security::Security> = config.security.as_ref()
614            .and_then(|v| {
615                serde_json::from_value(v.clone()).map_err(|e| {
616                    #[cfg(feature = "core")]
617                    tracing::warn!("Failed to parse security config: {}", e);
618                    e
619                }).ok()
620            });
621        if let Some(ref security) = security_config {
622            apply_security_headers(&mut router, &config.network.host, security);
623        }
624
625        #[cfg(feature = "compression")]
626        {
627            if let Some(ref compress) = config.compression {
628                apply_compression(&mut router, compress);
629            }
630        }
631
632        #[cfg(feature = "controller")]
633            let mut option_controller_mutex = None;
634
635        #[cfg(feature = "controller")]
636        {
637            // Parse command_control and store configs from raw JSON
638            let cc_config: Option<product_os_command_control::CommandControl> = config.command_control.as_ref()
639                .and_then(|v| serde_json::from_value(v.clone()).map_err(|e| {
640                    #[cfg(feature = "core")]
641                    tracing::warn!("Failed to parse command_control config: {}", e);
642                    e
643                }).ok());
644            let store_config: Option<product_os_store::Stores> = config.store.as_ref()
645                .and_then(|v| serde_json::from_value(v.clone()).map_err(|e| {
646                    #[cfg(feature = "core")]
647                    tracing::warn!("Failed to parse store config: {}", e);
648                    e
649                }).ok());
650
651            match &cc_config {
652                None => {}
653                Some(command_control) => {
654                    if command_control.enable {
655                        // Setup stores
656                        match &store_config {
657                            None => {}
658                            Some(store) => {
659                                match &store.key_value {
660                                    None => {}
661                                    Some(key_value_config) => {
662                                        let mut key_value = ProductOSKeyValueStore::new(key_value_config);
663                                        match key_value.connect() {
664                                            Ok(_) => {
665                                                #[cfg(feature = "core")]
666                                                tracing::info!("Successfully connected to key value database: {:?}", key_value_config.kind);
667                                            }
668                                            Err(e) => {
669                                                #[cfg(feature = "core")]
670                                                tracing::error!("Connect to key value database error: {:?}", e);
671                                            }
672                                        } // Explicit connection required
673                                        key_value.set_group("product-os-node");
674
675                                        let key_value_store = Arc::new(key_value);
676
677                                        match &store.relational {
678                                            None => {}
679                                            Some(relational_config) => {
680                                                let mut relational = ProductOSRelationalStore::new(relational_config);
681                                                match relational.connect_sync() {
682                                                    Ok(_) => {
683                                                        #[cfg(feature = "core")]
684                                                        tracing::info!("Successfully connected to relational database: {:?}", relational_config.kind);
685                                                    }
686                                                    Err(e) => {
687                                                        #[cfg(feature = "core")]
688                                                        tracing::error!("Connect to relational database error: {:?}", e);
689                                                    }
690                                                };
691
692                                                // ----- Add Route Handlers
693
694                                                command_handler::command_responder(&mut router);
695                                                feature_handler::feature_responder(&mut router, None);
696
697
698                                                // ----- Add Middleware
699
700                                                #[cfg(any(feature = "postgres_store", feature = "sqlite_store"))]
701                                                let controller = ProductOSController::new(command_control.clone(), certificates.clone(), Some(key_value_store.clone()), Some(Arc::new(relational)));
702                                                #[cfg(not(any(feature = "postgres_store", feature = "sqlite_store")))]
703                                                let controller = {
704                                                    // Silence unused variable warning when postgres/sqlite stores are not enabled
705                                                    let _ = relational;
706                                                    ProductOSController::new(command_control.clone(), certificates.clone(), Some(key_value_store.clone()), None)
707                                                };
708                                                let controller_mutex = Arc::new(Mutex::new(controller));
709
710                                                router.add_middleware(Extension(controller_mutex.clone()));
711                                                #[cfg(feature = "core")]
712                                                tracing::info!("Controller added as extension middleware");
713                                                option_controller_mutex = Some(controller_mutex);
714                                            }
715                                        }
716                                    }
717                                }
718                            }
719                        }
720                    }
721                }
722            }
723        }
724
725        let executor = match executor {
726            Some(exec) => exec,
727            None => {
728                #[cfg(feature = "core")]
729                tracing::error!("Unable to create executor context - no executor available");
730                match E::context_sync() {
731                    Ok(exec) => Arc::new(exec),
732                    Err(e) => panic!("Failed to create default executor context: {:?}. An executor must be available.", e),
733                }
734            }
735        };
736
737        // Return Server
738        Self {
739            router,
740
741            config,
742            certificates,
743
744            #[cfg(feature = "controller")]
745            controller: option_controller_mutex,
746
747            executor,
748            executor_underlying: PhantomData
749        }
750    }
751
752    /// Creates a new server with custom executor and state.
753    ///
754    /// Uses default configuration.
755    ///
756    /// # Arguments
757    ///
758    /// * `executor` - Optional executor Arc. If None, will panic.
759    /// * `state` - Shared state available to all handlers
760    pub fn new_with_executor_with_state(executor: Option<Arc<E>>, state: S) -> Self {
761        let config = crate::config::ServerConfig::new();
762
763        let router = ProductOSRouter::new_with_state(state);
764
765        #[cfg(feature = "core")]
766        {
767            let log_level = config.log_level();
768            let _ = logging::set_global_logger(logging::define_logging(log_level));
769            tracing::info!("Log Level: {}", config.log_level());
770        }
771
772        // Setup certificates
773        let certificates = ProductOSServerCertificates::setup_certificates(&config.certificate);
774
775        let executor = match executor {
776            Some(exec) => exec,
777            None => {
778                #[cfg(feature = "core")]
779                tracing::error!("Unable to create executor context - no executor available");
780                match E::context_sync() {
781                    Ok(exec) => Arc::new(exec),
782                    Err(e) => panic!("Failed to create default executor context: {:?}. An executor must be available.", e),
783                }
784            }
785        };
786
787        // Return Server
788        Self {
789            router,
790
791            config,
792            certificates,
793
794            #[cfg(feature = "controller")]
795            controller: None,
796
797            executor,
798            executor_underlying: PhantomData
799        }
800    }
801
802    /// Sets the logging level.
803    ///
804    /// # Arguments
805    ///
806    /// * `log_level` - The tracing level (TRACE, DEBUG, INFO, WARN, ERROR)
807    ///
808    /// # Examples
809    ///
810    /// ```no_run
811    /// # use product_os_server::ProductOSServer;
812    /// # use product_os_server::ServerConfig;
813    /// # use product_os_async_executor::TokioExecutor;
814    /// # #[cfg(feature = "executor_tokio")]
815    /// # fn example() {
816    /// # let config = ServerConfig::new();
817    /// # let mut server: ProductOSServer<(), TokioExecutor, _> = 
818    /// #     ProductOSServer::new_with_config(config);
819    /// server.set_logging(tracing::Level::DEBUG);
820    /// # }
821    /// ```
822    #[cfg(feature = "core")]
823    pub fn set_logging(&mut self, log_level: tracing::Level) {
824        let _ = logging::set_global_logger(logging::define_logging(log_level));
825        tracing::info!("Log Level: {}", self.config.log_level());
826    }
827
828    /// Sets or updates the TLS certificate configuration.
829    ///
830    /// # Arguments
831    ///
832    /// * `certificate_config` - Optional certificate configuration. If None, will generate self-signed.
833    pub fn set_certificate(&mut self, certificate_config: &Option<crate::config::Certificate>) {
834        self.certificates = ProductOSServerCertificates::setup_certificates(certificate_config);
835    }
836
837    /// Sets or updates the security configuration.
838    ///
839    /// This includes settings for security headers, CSRF protection, etc.
840    ///
841    /// # Arguments
842    ///
843    /// * `security` - Optional security configuration. If None, security features are disabled.
844    pub fn set_security(&mut self, security: Option<product_os_security::Security>) {
845        if let Some(security) = security {
846            apply_security_headers(&mut self.router, &self.config.network.host, &security);
847        }
848    }
849
850    /// Sets or updates the compression configuration.
851    ///
852    /// This configures the compression middleware for HTTP responses.
853    /// Supports gzip, deflate, and brotli compression.
854    ///
855    /// # Arguments
856    ///
857    /// * `compression_config` - Optional compression configuration. If None, compression is disabled.
858    #[cfg(feature = "compression")]
859    pub fn set_compression(&mut self, compression_config: Option<crate::config::Compression>) {
860        if let Some(ref compress) = compression_config {
861            apply_compression(&mut self.router, compress);
862        }
863    }
864
865    /// Sets or replaces the controller.
866    ///
867    /// # Arguments
868    ///
869    /// * `controller` - Optional controller mutex. If None, removes the controller.
870    #[cfg(feature = "controller")]
871    pub fn set_controller(&mut self, controller: Option<Arc<Mutex<ProductOSController>>>) {
872        self.controller = controller;
873    }
874
875    /// Adds a service to the server.
876    ///
877    /// Services are background tasks that run alongside the server.
878    ///
879    /// # Arguments
880    ///
881    /// * `service_arc` - Arc-wrapped service implementation
882    #[cfg(feature = "controller")]
883    pub async fn add_service(&mut self, service_arc: Arc<dyn product_os_capabilities::Service>) {
884        match &self.controller {
885            None => {
886                panic!("Service {} failed to add to server: no controller", service_arc.identifier());
887            }
888            Some(c) => {
889                let controller_unlocked = c.clone();
890                let mut controller = controller_unlocked.lock();
891
892                controller.add_service(service_arc.clone()).await;
893                #[cfg(feature = "core")]
894                tracing::info!("Service {} successfully added to server", service_arc.identifier());
895            }
896        }
897    }
898
899    /// Adds a mutable service to the server.
900    ///
901    /// Similar to `add_service`, but accepts a mutable service wrapped in an Arc<Mutex>.
902    ///
903    /// # Arguments
904    ///
905    /// * `service_arc_mut` - Arc-wrapped mutex containing the service implementation
906    #[cfg(feature = "controller")]
907    pub async fn add_service_mut(&mut self, service_arc_mut: Arc<Mutex<dyn product_os_capabilities::Service>>) {
908        match &self.controller {
909            None => {
910                let service_locked = service_arc_mut.lock();
911                panic!("Service {} failed to add to server: no controller", service_locked.identifier());
912            }
913            Some(c) => {
914                let controller_unlocked = c.clone();
915                let mut controller = controller_unlocked.lock();
916
917                controller.add_service_mut(service_arc_mut.clone()).await;
918                let service_locked = service_arc_mut.lock();
919                #[cfg(feature = "core")]
920                tracing::info!("Service {} successfully added to server", service_locked.identifier());
921            }
922        }
923    }
924
925    /*
926    #[cfg(all(feature = "controller", feature = "support_feature_service"))]
927    pub async fn add_feature_service(&mut self, feature_service_arc: Arc<dyn product_os_capabilities::FeatureService>, base_path: Option<String>) {
928        self.add_feature(feature_service_arc.clone(), base_path);
929        self.add_service(feature_service_arc);
930    }
931
932    #[cfg(all(feature = "controller", feature = "support_feature_service"))]
933    pub async fn add_feature_service_mut(&mut self, feature_service_arc_mut: Arc<Mutex<dyn product_os_capabilities::FeatureService>>, base_path: Option<String>) {
934        self.add_feature_mut(feature_service_arc_mut.clone(), base_path);
935        self.add_service_mut(feature_service_arc_mut);
936    }
937    */
938
939    /// Gets the controller.
940    ///
941    /// # Panics
942    ///
943    /// Panics if no controller is configured. Use `try_get_controller` for a non-panicking alternative.
944    #[cfg(feature = "controller")]
945    #[deprecated(since = "0.0.53", note = "Use try_get_controller which returns Result instead of panicking")]
946    pub fn get_controller(&self) -> Arc<Mutex<ProductOSController>> {
947        self.try_get_controller()
948            .unwrap_or_else(|e| panic!("{}", e))
949    }
950
951    /// Gets the controller, returning an error if none is configured.
952    ///
953    /// # Returns
954    ///
955    /// An `Arc<Mutex<ProductOSController>>` if a controller is configured.
956    ///
957    /// # Errors
958    ///
959    /// Returns `ControllerError` if no controller is configured.
960    #[cfg(feature = "controller")]
961    pub fn try_get_controller(&self) -> crate::error::Result<Arc<Mutex<ProductOSController>>> {
962        match &self.controller {
963            None => Err(ProductOSServerError::ControllerError {
964                operation: "get_controller".to_string(),
965                message: "No controller configured on this server".to_string(),
966            }),
967            Some(c) => Ok(c.clone()),
968        }
969    }
970
971    /// Retrieves a mutable reference to the router.
972    ///
973    /// This allows direct manipulation of the underlying router for advanced use cases.
974    ///
975    /// # Returns
976    ///
977    /// A mutable reference to the `ProductOSRouter`.
978    ///
979    /// # Examples
980    ///
981    /// ```no_run
982    /// # use product_os_server::ProductOSServer;
983    /// # use product_os_server::ServerConfig;
984    /// # use product_os_async_executor::TokioExecutor;
985    /// # #[cfg(feature = "executor_tokio")]
986    /// # fn example() {
987    /// # let config = ServerConfig::new();
988    /// # let mut server: ProductOSServer<(), TokioExecutor, _> = 
989    /// #     ProductOSServer::new_with_config(config);
990    /// let router = server.get_router();
991    /// // Perform advanced router operations
992    /// # }
993    /// ```
994    pub fn get_router(&mut self) -> &mut ProductOSRouter<S> {
995        &mut self.router
996    }
997
998    /// Adds a route with a method router.
999    ///
1000    /// # Arguments
1001    ///
1002    /// * `path` - The URL path for the route (e.g., "/api/users")
1003    /// * `service_handler` - The method router handling the route
1004    ///
1005    /// # Examples
1006    ///
1007    /// ```no_run
1008    /// # use product_os_server::{ProductOSServer, Response, StatusCode, Body};
1009    /// # use product_os_server::ServerConfig;
1010    /// # use product_os_async_executor::TokioExecutor;
1011    /// # #[cfg(feature = "executor_tokio")]
1012    /// # fn example() {
1013    /// # let config = ServerConfig::new();
1014    /// # let mut server: ProductOSServer<(), TokioExecutor, _> = 
1015    /// #     ProductOSServer::new_with_config(config);
1016    /// use product_os_router::MethodRouter;
1017    ///
1018    /// async fn handler() -> Result<Response<Body>, StatusCode> {
1019    ///     Ok(Response::new(Body::empty()))
1020    /// }
1021    ///
1022    /// let method_router = MethodRouter::new().get(handler);
1023    /// server.add_route("/test", method_router);
1024    /// # }
1025    /// ```
1026    pub fn add_route(&mut self, path: &str, service_handler: product_os_router::MethodRouter<S>) {
1027        self.router.add_route(path, service_handler);
1028    }
1029
1030    /// Sets a fallback handler for unmatched routes.
1031    ///
1032    /// The fallback handler is called when no route matches the incoming request.
1033    /// This is typically used to return a 404 Not Found response.
1034    ///
1035    /// # Arguments
1036    ///
1037    /// * `service_handler` - The method router for handling unmatched routes
1038    ///
1039    /// # Examples
1040    ///
1041    /// ```no_run
1042    /// # use product_os_server::{ProductOSServer, Response, StatusCode, Body};
1043    /// # use product_os_server::ServerConfig;
1044    /// # use product_os_async_executor::TokioExecutor;
1045    /// # #[cfg(feature = "executor_tokio")]
1046    /// # fn example() {
1047    /// # let config = ServerConfig::new();
1048    /// # let mut server: ProductOSServer<(), TokioExecutor, _> = 
1049    /// #     ProductOSServer::new_with_config(config);
1050    /// use product_os_router::MethodRouter;
1051    ///
1052    /// async fn not_found() -> Result<Response<Body>, StatusCode> {
1053    ///     Err(StatusCode::NOT_FOUND)
1054    /// }
1055    ///
1056    /// let fallback = MethodRouter::new().fallback(not_found);
1057    /// server.set_fallback(fallback);
1058    /// # }
1059    /// ```
1060    pub fn set_fallback(&mut self, service_handler: product_os_router::MethodRouter<S>) {
1061        self.router.set_fallback(service_handler);
1062    }
1063
1064    /// Adds a GET request handler.
1065    ///
1066    /// Convenience method for adding a handler that responds to GET requests.
1067    ///
1068    /// # Arguments
1069    ///
1070    /// * `path` - The URL path (e.g., "/api/users")
1071    /// * `handler` - The async function handling the request
1072    ///
1073    /// # Examples
1074    ///
1075    /// ```no_run
1076    /// # use product_os_server::{ProductOSServer, Response, StatusCode, Body};
1077    /// # use product_os_server::ServerConfig;
1078    /// # use product_os_async_executor::TokioExecutor;
1079    /// # #[cfg(feature = "executor_tokio")]
1080    /// # fn example() {
1081    /// # let config = ServerConfig::new();
1082    /// # let mut server: ProductOSServer<(), TokioExecutor, _> = 
1083    /// #     ProductOSServer::new_with_config(config);
1084    /// async fn get_users() -> Result<Response<Body>, StatusCode> {
1085    ///     Ok(Response::new(Body::empty()))
1086    /// }
1087    ///
1088    /// server.add_get("/api/users", get_users);
1089    /// # }
1090    /// ```
1091    pub fn add_get<H, T>(&mut self, path: &str, handler: H)
1092        where
1093            H: Handler<T, S>,
1094            T: 'static
1095    {
1096        self.router.add_get(path, handler);
1097    }
1098
1099    /// Adds a POST request handler.
1100    ///
1101    /// Convenience method for adding a handler that responds to POST requests.
1102    ///
1103    /// # Arguments
1104    ///
1105    /// * `path` - The URL path (e.g., "/api/users")
1106    /// * `handler` - The async function handling the request
1107    ///
1108    /// # Examples
1109    ///
1110    /// ```no_run
1111    /// # use product_os_server::{ProductOSServer, Response, StatusCode, Json, Body};
1112    /// # use product_os_server::ServerConfig;
1113    /// # use product_os_async_executor::TokioExecutor;
1114    /// # use serde::{Deserialize, Serialize};
1115    /// # #[cfg(feature = "executor_tokio")]
1116    /// # fn example() {
1117    /// # let config = ServerConfig::new();
1118    /// # let mut server: ProductOSServer<(), TokioExecutor, _> = 
1119    /// #     ProductOSServer::new_with_config(config);
1120    /// # #[derive(Deserialize, Serialize)]
1121    /// # struct User { name: String }
1122    /// async fn create_user(Json(user): Json<User>) -> Result<Response<Body>, StatusCode> {
1123    ///     Ok(Response::new(Body::empty()))
1124    /// }
1125    ///
1126    /// server.add_post("/api/users", create_user);
1127    /// # }
1128    /// ```
1129    pub fn add_post<H, T>(&mut self, path: &str, handler: H)
1130        where
1131            H: Handler<T, S>,
1132            T: 'static
1133    {
1134        self.router.add_post(path, handler);
1135    }
1136
1137    /// Adds a handler for a specific HTTP method and path.
1138    ///
1139    /// # Arguments
1140    ///
1141    /// * `path` - The URL path
1142    /// * `method` - The HTTP method (GET, POST, PUT, DELETE, etc.)
1143    /// * `handler` - The async function to handle the request
1144    ///
1145    /// # Examples
1146    ///
1147    /// ```no_run
1148    /// # use product_os_server::{ProductOSServer, Response, StatusCode, Method};
1149    /// # use product_os_server::ServerConfig;
1150    /// # use product_os_async_executor::TokioExecutor;
1151    /// # #[cfg(feature = "executor_tokio")]
1152    /// # fn example() {
1153    /// # let config = ServerConfig::new();
1154    /// # let mut server: ProductOSServer<(), TokioExecutor, _> = 
1155    /// #     ProductOSServer::new_with_config(config);
1156    /// async fn patch_handler() -> Result<Response<product_os_server::Body>, StatusCode> {
1157    ///     Ok(Response::new(product_os_server::Body::empty()))
1158    /// }
1159    /// server.add_handler("/resource", Method::PATCH, patch_handler);
1160    /// # }
1161    /// ```
1162    pub fn add_handler<H, T>(&mut self, path: &str, method: Method, handler: H)
1163        where
1164            H: Handler<T, S>,
1165            T: 'static
1166    {
1167        self.router.add_handler(path, method, handler);
1168    }
1169
1170    /// Sets a fallback handler that will be called for unmatched routes.
1171    ///
1172    /// # Arguments
1173    ///
1174    /// * `handler` - The async function to handle unmatched requests
1175    ///
1176    /// # Examples
1177    ///
1178    /// ```no_run
1179    /// # use product_os_server::{ProductOSServer, Response, StatusCode};
1180    /// # use product_os_server::ServerConfig;
1181    /// # use product_os_async_executor::TokioExecutor;
1182    /// # #[cfg(feature = "executor_tokio")]
1183    /// # fn example() {
1184    /// # let config = ServerConfig::new();
1185    /// # let mut server: ProductOSServer<(), TokioExecutor, _> = 
1186    /// #     ProductOSServer::new_with_config(config);
1187    /// async fn not_found() -> Result<Response<product_os_server::Body>, StatusCode> {
1188    ///     Err(StatusCode::NOT_FOUND)
1189    /// }
1190    /// server.set_fallback_handler(not_found);
1191    /// # }
1192    /// ```
1193    pub fn set_fallback_handler<H, T>(&mut self, handler: H)
1194        where
1195            H: Handler<T, S>,
1196            T: 'static
1197    {
1198        self.router.set_fallback_handler(handler);
1199    }
1200
1201    /// Adds a CORS-enabled handler for a specific HTTP method and path.
1202    ///
1203    /// This method wraps the handler with CORS middleware.
1204    ///
1205    /// # Arguments
1206    ///
1207    /// * `path` - The URL path
1208    /// * `method` - The HTTP method
1209    /// * `handler` - The async function handling the request
1210    #[cfg(feature = "cors")]
1211    pub fn add_cors_handler<H, T>(&mut self, path: &str, method: Method, handler: H)
1212        where
1213            H: Handler<T, S>,
1214            T: 'static
1215    {
1216        self.router.add_cors_handler(path, method, handler);
1217    }
1218
1219    /// Adds a WebSocket handler for the specified path.
1220    ///
1221    /// # Arguments
1222    ///
1223    /// * `path` - The URL path for WebSocket connections
1224    /// * `ws_handler` - The handler for WebSocket upgrades
1225    #[cfg(feature = "ws")]
1226    pub fn add_ws_handler<H, T>(&mut self, path: &str, ws_handler: H)
1227        where
1228            H: Handler<T, S>,
1229            T: 'static
1230    {
1231        self.router.add_ws_handler(path, ws_handler);
1232    }
1233
1234    /// Adds a Server-Sent Events (SSE) handler for the specified path.
1235    ///
1236    /// SSE handlers are added as GET routes since SSE uses HTTP GET requests.
1237    ///
1238    /// # Arguments
1239    ///
1240    /// * `path` - The URL path for SSE connections
1241    /// * `sse_handler` - The handler producing SSE events
1242    #[cfg(feature = "sse")]
1243    pub fn add_sse_handler<H, T>(&mut self, path: &str, sse_handler: H)
1244        where
1245            H: Handler<T, S>,
1246            T: 'static
1247    {
1248        self.add_get(path, sse_handler);
1249    }
1250
1251    /// Adds multiple handlers for different HTTP methods on the same path.
1252    ///
1253    /// # Arguments
1254    ///
1255    /// * `path` - The URL path
1256    /// * `handlers` - A map of HTTP methods to their handlers
1257    ///
1258    /// # Examples
1259    ///
1260    /// ```ignore
1261    /// // Note: This API requires handlers of the same type. In practice,
1262    /// // use add_get, add_post, etc. for different handler implementations.
1263    /// # use product_os_server::{ProductOSServer, Response, StatusCode, Method, Body};
1264    /// # use product_os_server::ServerConfig;
1265    /// # use product_os_async_executor::TokioExecutor;
1266    /// # use std::collections::BTreeMap;
1267    /// # #[cfg(feature = "executor_tokio")]
1268    /// # fn example() {
1269    /// # let config = ServerConfig::new();
1270    /// # let mut server: ProductOSServer<(), TokioExecutor, _> = 
1271    /// #     ProductOSServer::new_with_config(config);
1272    /// async fn handler() -> Result<Response<Body>, StatusCode> {
1273    ///     Ok(Response::new(Body::empty()))
1274    /// }
1275    /// 
1276    /// // Use add_handler for each method instead:
1277    /// server.add_handler("/resource", Method::GET, handler);
1278    /// server.add_handler("/resource", Method::POST, handler);
1279    /// # }
1280    /// ```
1281    pub fn add_handlers<H, T>(&mut self, path: &str, handlers: BTreeMap<Method, H>)
1282        where
1283            H: Handler<T, S>,
1284            T: 'static
1285    {
1286        self.router.add_handlers(path, handlers);
1287    }
1288
1289    /// Adds multiple CORS-enabled handlers for different HTTP methods on the same path.
1290    ///
1291    /// # Arguments
1292    ///
1293    /// * `path` - The URL path
1294    /// * `handlers` - A map of HTTP methods to their handlers
1295    #[cfg(feature = "cors")]
1296    pub fn add_cors_handlers<H, T>(&mut self, path: &str, handlers: BTreeMap<Method, H>)
1297        where
1298            H: Handler<T, S>,
1299            T: 'static
1300    {
1301        self.router.add_cors_handlers(path, handlers);
1302    }
1303
1304    /// Adds a global CORS middleware layer that applies to all routes.
1305    ///
1306    /// This permits any origin, any HTTP method, and any request header,
1307    /// making it suitable for development servers and APIs consumed by
1308    /// third-party front-ends.  For production you may want to use
1309    /// [`add_middleware`] with a more restrictive `CorsLayer` instead.
1310    ///
1311    /// # Examples
1312    ///
1313    /// ```ignore
1314    /// # use product_os_server::ProductOSServer;
1315    /// # use product_os_async_executor::TokioExecutor;
1316    /// // Enable permissive CORS on all routes
1317    /// server.add_cors_middleware();
1318    /// ```
1319    #[cfg(feature = "cors")]
1320    pub fn add_cors_middleware(&mut self) {
1321        self.router.add_cors_middleware();
1322    }
1323
1324    /// Adds middleware to the server.
1325    ///
1326    /// Middleware layers are applied to all routes and can handle cross-cutting concerns
1327    /// like logging, authentication, rate limiting, etc.
1328    ///
1329    /// # Type Parameters
1330    ///
1331    /// * `L` - The middleware layer type
1332    ///
1333    /// # Examples
1334    ///
1335    /// ```no_run
1336    /// # use product_os_server::ProductOSServer;
1337    /// # use product_os_server::ServerConfig;
1338    /// # use product_os_async_executor::TokioExecutor;
1339    /// # #[cfg(feature = "executor_tokio")]
1340    /// # fn example() {
1341    /// # let config = ServerConfig::new();
1342    /// # let mut server: ProductOSServer<(), TokioExecutor, _> = 
1343    /// #     ProductOSServer::new_with_config(config);
1344    /// // Add middleware (example with tower-http)
1345    /// // use tower_http::trace::TraceLayer;
1346    /// // server.add_middleware(TraceLayer::new_for_http());
1347    /// # }
1348    /// ```
1349    #[cfg(feature = "core")]
1350    pub fn add_middleware<L, ResBody>(&mut self, middleware: L)
1351        where
1352            L: Layer<Route> + Clone + Send + Sync + 'static,
1353            L::Service: Service<Request<Body>, Response = Response<ResBody>> + Clone + Send + Sync + 'static,
1354            <L::Service as Service<Request<Body>>>::Future: Send + 'static,
1355            <L::Service as Service<Request<Body>>>::Error: Into<BoxError> + 'static,
1356            ResBody: HttpBody<Data = Bytes> + Send + 'static,
1357            ResBody::Error: Into<BoxError>,
1358    {
1359        self.router.add_middleware(middleware);
1360    }
1361
1362    /// Sets the entire router, replacing the existing one.
1363    ///
1364    /// # Arguments
1365    ///
1366    /// * `router` - The new router to use
1367    ///
1368    /// # Examples
1369    ///
1370    /// ```no_run
1371    /// # use product_os_server::{ProductOSServer, ProductOSRouter};
1372    /// # use product_os_server::ServerConfig;
1373    /// # use product_os_async_executor::TokioExecutor;
1374    /// # #[cfg(feature = "executor_tokio")]
1375    /// # fn example() {
1376    /// # let config = ServerConfig::new();
1377    /// # let mut server: ProductOSServer<(), TokioExecutor, _> = 
1378    /// #     ProductOSServer::new_with_config(config);
1379    /// let new_router = ProductOSRouter::new();
1380    /// server.set_router(new_router);
1381    /// # }
1382    /// ```
1383    pub fn set_router(&mut self, router: ProductOSRouter<S>)
1384    where
1385        S: Clone + Send + Sync + 'static
1386    {
1387        self.router = router;
1388    }
1389
1390
1391    /// Creates and starts a dual protocol (HTTP/HTTPS) server.
1392    ///
1393    /// This server can handle both HTTP and HTTPS connections on the same port,
1394    /// automatically detecting the protocol from the incoming connection.
1395    ///
1396    /// # Arguments
1397    ///
1398    /// * `serve_on_main_thread` - Whether to block the main thread
1399    /// * `listen_all_interfaces` - Whether to listen on all network interfaces
1400    /// * `custom_port` - Optional custom port number
1401    /// * `custom_router` - Optional custom router to use
1402    /// * `with_connect_info` - Whether to extract connection info
1403    /// * `_force_secure` - Reserved for future use (force redirect HTTP to HTTPS)
1404    #[cfg(feature = "dual_server")]
1405    pub async fn create_dual_service_server(&mut self, serve_on_main_thread: bool, listen_all_interfaces: bool, custom_port: Option<u16>, custom_router: Option<Router>, with_connect_info: bool, _force_secure: bool) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
1406        #[cfg(feature = "tls")]
1407        {
1408            let certificates = Some(self.certificates.to_owned());
1409
1410            let router: Router = match custom_router {
1411                None => self.router.get_router(),
1412                Some(r) => r
1413            };
1414
1415            let address = self.config.socket_address(custom_port, listen_all_interfaces);
1416
1417            if serve_on_main_thread {
1418                dual_server::create_dual_tokio_service(address, certificates, router, with_connect_info).await?;
1419            }
1420            else {
1421                if let Err(e) = server_executor::ServerExecutor::spawn(self.executor.clone(), async move {
1422                    match dual_server::create_dual_tokio_service(address, certificates, router, with_connect_info).await {
1423                        Ok(_) => {}
1424                        Err(e) => tracing::error!("Error starting HTTPS server: {}", e)
1425                    }
1426                }) {
1427                    tracing::error!("Failed to spawn dual server task: {}", e);
1428                }
1429            }
1430        }
1431
1432        #[cfg(not(feature = "tls"))]
1433        {
1434            tracing::info!("TLS feature is not enabled - please include the \"tls\" feature in your toml config file");
1435        }
1436
1437        Ok(())
1438    }
1439
1440
1441    /// Creates and starts an HTTPS server.
1442    ///
1443    /// Internal method for creating HTTPS servers with TLS support.
1444    /// Use `start()` instead for normal server initialization.
1445    ///
1446    /// # Arguments
1447    ///
1448    /// * `_serve_on_main_thread` - Whether to block the main thread
1449    /// * `_listen_all_interfaces` - Whether to listen on all network interfaces
1450    /// * `_custom_port` - Optional custom port number
1451    /// * `_custom_router` - Optional custom router to use
1452    /// * `_with_connect_info` - Whether to extract connection info
1453    pub async fn create_https_server(&mut self, serve_on_main_thread: bool, listen_all_interfaces: bool, custom_port: Option<u16>, custom_router: Option<Router>, with_connect_info: bool) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
1454        #[cfg(all(feature = "tls", feature = "executor_tokio"))]
1455        {
1456            let certificates = Some(self.certificates.to_owned());
1457
1458            let router: Router = match custom_router {
1459                None => self.router.get_router(),
1460                Some(r) => r
1461            };
1462
1463            let address = self.config.socket_address(custom_port, listen_all_interfaces);
1464
1465            if serve_on_main_thread {
1466                https_server::create_https_tokio_service(address, certificates, router, with_connect_info).await?;
1467            }
1468            else {
1469                if let Err(e) = server_executor::ServerExecutor::spawn(self.executor.clone(), async move {
1470                    match https_server::create_https_tokio_service(address, certificates, router, with_connect_info).await {
1471                        Ok(_) => {}
1472                        Err(e) => tracing::error!("Error starting HTTPS server: {}", e)
1473                    }
1474                }) {
1475                    tracing::error!("Failed to spawn HTTPS server task: {}", e);
1476                }
1477            }
1478        }
1479        #[cfg(not(feature = "tls"))]
1480        {
1481            // Mark parameters as used to avoid warnings when tls feature is disabled
1482            let _ = (serve_on_main_thread, listen_all_interfaces, custom_port, custom_router, with_connect_info);
1483            #[cfg(feature = "core")]
1484            tracing::info!("TLS feature is not enabled - please include the \"tls\" feature in your toml config file");
1485        }
1486
1487        Ok(())
1488    }
1489
1490    /// Creates and starts an HTTP server.
1491    ///
1492    /// Internal method for creating HTTP servers.
1493    /// Use `start()` instead for normal server initialization.
1494    ///
1495    /// # Arguments
1496    ///
1497    /// * `serve_on_main_thread` - Whether to block the main thread
1498    /// * `listen_all_interfaces` - Whether to listen on all network interfaces
1499    /// * `custom_port` - Optional custom port number
1500    /// * `custom_router` - Optional custom router to use
1501    /// * `with_connect_info` - Whether to extract connection info
1502    pub async fn create_http_server(&mut self, serve_on_main_thread: bool, listen_all_interfaces: bool, custom_port: Option<u16>, custom_router: Option<Router>, with_connect_info: bool) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
1503        #[cfg(feature = "executor_tokio")]
1504        {
1505            let router: Router = match custom_router {
1506                None => self.router.get_router(),
1507                Some(r) => r
1508            };
1509
1510            let address = self.config.socket_address(custom_port, listen_all_interfaces);
1511
1512            if serve_on_main_thread {
1513                http_server::create_http_tokio_service(address, router, with_connect_info).await?;
1514            }
1515            else {
1516                if let Err(e) = server_executor::ServerExecutor::spawn(self.executor.clone(), async move {
1517                    match http_server::create_http_tokio_service(address, router, with_connect_info).await {
1518                        Ok(_) => {}
1519                        Err(e) => tracing::error!("Error starting HTTP server: {}", e)
1520                    }
1521                }) {
1522                    tracing::error!("Failed to spawn HTTP server task: {}", e);
1523                }
1524            }
1525        }
1526        #[cfg(not(feature = "executor_tokio"))]
1527        {
1528            let _ = (serve_on_main_thread, listen_all_interfaces, custom_port, custom_router, with_connect_info);
1529            #[cfg(feature = "core")]
1530            tracing::info!("executor_tokio feature is not enabled for HTTP server");
1531        }
1532
1533        Ok(())
1534    }
1535
1536
1537    /// Initializes data stores.
1538    ///
1539    /// Internal method for store initialization. Currently a no-op but reserved
1540    /// for future store initialization logic.
1541    pub async fn init_stores(&mut self) {
1542        // Do nothing for now
1543    }
1544
1545    /// Gets the relational store.
1546    ///
1547    /// # Returns
1548    ///
1549    /// The relational store wrapped in an Arc, or an error if the controller couldn't be locked.
1550    ///
1551    /// # Panics
1552    ///
1553    /// Panics if no controller is configured.
1554    #[cfg(feature = "controller")]
1555    pub fn get_relational_store(&mut self) -> Result<Arc<ProductOSRelationalStore>, ()> {
1556        match &self.controller {
1557            None => {
1558                panic!("No controller");
1559            }
1560            Some(c) => {
1561                let controller_unlocked = c.clone();
1562                let controller_locked = controller_unlocked.try_lock();
1563                match controller_locked {
1564                    Some(mut controller) => Ok(controller.get_relational_store()),
1565                    None => Err(())
1566                }
1567            }
1568        }
1569    }
1570
1571    /// Gets the key-value store.
1572    ///
1573    /// # Returns
1574    ///
1575    /// The key-value store wrapped in an Arc, or an error if the controller couldn't be locked.
1576    ///
1577    /// # Panics
1578    ///
1579    /// Panics if no controller is configured.
1580    #[cfg(feature = "controller")]
1581    pub fn get_key_value_store(&mut self) -> Result<Arc<ProductOSKeyValueStore>, ()> {
1582        match &self.controller {
1583            None => {
1584                panic!("No controller");
1585            }
1586            Some(c) => {
1587                let controller_unlocked = c.clone();
1588                let controller_locked = controller_unlocked.try_lock();
1589                match controller_locked {
1590                    Some(mut controller) => Ok(controller.get_key_value_store()),
1591                    None => Err(())
1592                }
1593            }
1594        }
1595    }
1596
1597    /// Gets the server configuration.
1598    ///
1599    /// # Returns
1600    ///
1601    /// A clone of the current server configuration.
1602    ///
1603    /// # Examples
1604    ///
1605    /// ```no_run
1606    /// # use product_os_server::ProductOSServer;
1607    /// # use product_os_server::ServerConfig;
1608    /// # use product_os_async_executor::TokioExecutor;
1609    /// # #[cfg(feature = "executor_tokio")]
1610    /// # fn example() {
1611    /// # let config = ServerConfig::new();
1612    /// # let server: ProductOSServer<(), TokioExecutor, _> = 
1613    /// #     ProductOSServer::new_with_config(config);
1614    /// let current_config = server.get_config();
1615    /// println!("Server port: {}", current_config.network.port);
1616    /// # }
1617    /// ```
1618    pub fn get_config(&self) -> crate::config::ServerConfig {
1619        self.config.clone()
1620    }
1621
1622    /// Updates the server configuration.
1623    ///
1624    /// # Arguments
1625    ///
1626    /// * `config` - The new configuration to apply
1627    ///
1628    /// # Examples
1629    ///
1630    /// ```no_run
1631    /// # use product_os_server::ProductOSServer;
1632    /// # use product_os_server::ServerConfig;
1633    /// # use product_os_async_executor::TokioExecutor;
1634    /// # #[cfg(feature = "executor_tokio")]
1635    /// # fn example() {
1636    /// # let config = ServerConfig::new();
1637    /// # let mut server: ProductOSServer<(), TokioExecutor, _> = 
1638    /// #     ProductOSServer::new_with_config(config);
1639    /// let mut new_config = ServerConfig::new();
1640    /// new_config.network.port = 8080;
1641    /// server.update_config(new_config);
1642    /// # }
1643    /// ```
1644    pub fn update_config(&mut self, config: crate::config::ServerConfig) {
1645        self.config = config;
1646    }
1647
1648    /// Gets the base URL of the server.
1649    ///
1650    /// Returns the URL where the server is accessible, constructed from the
1651    /// configuration's host and port settings.
1652    ///
1653    /// # Returns
1654    ///
1655    /// A `Uri` representing the server's base URL.
1656    ///
1657    /// # Examples
1658    ///
1659    /// ```no_run
1660    /// # use product_os_server::ProductOSServer;
1661    /// # use product_os_server::ServerConfig;
1662    /// # use product_os_async_executor::TokioExecutor;
1663    /// # #[cfg(feature = "executor_tokio")]
1664    /// # fn example() {
1665    /// # let config = ServerConfig::new();
1666    /// # let server: ProductOSServer<(), TokioExecutor, _> = 
1667    /// #     ProductOSServer::new_with_config(config);
1668    /// let base_url = server.get_base_url();
1669    /// println!("Server available at: {}", base_url);
1670    /// # }
1671    /// ```
1672    #[deprecated(since = "0.0.53", note = "Use try_get_base_url() which returns Result instead of panicking")]
1673    pub fn get_base_url(&self) -> Uri {
1674        self.try_get_base_url()
1675            .unwrap_or_else(|e| panic!("Failed to parse base URL: {:?}", e))
1676    }
1677
1678    /// Returns the base URL as a `Uri`, or an error if URL parsing fails.
1679    ///
1680    /// This is the non-panicking version of `get_base_url`.
1681    pub fn try_get_base_url(&self) -> crate::error::Result<Uri> {
1682        let url = self.config.try_url_address()?;
1683        Uri::from_str(url.as_str())
1684            .map_err(|e| ProductOSServerError::ConfigurationError {
1685                component: "base_url".to_string(),
1686                message: alloc::format!("Failed to parse URL as URI: {}", e),
1687            })
1688    }
1689
1690
1691    /// Starts the server.
1692    ///
1693    /// This method initializes and starts the HTTP/HTTPS server(s) based on the configuration.
1694    /// It handles:
1695    /// - Starting HTTPS server if TLS is configured
1696    /// - Starting HTTP server for insecure connections (if allowed)
1697    /// - Setting up dual protocol servers
1698    /// - Initializing the command-and-control system (if controller feature is enabled)
1699    ///
1700    /// # Arguments
1701    ///
1702    /// * `serve_on_main_thread` - If true, blocks the main thread; if false, spawns background tasks
1703    ///
1704    /// # Returns
1705    ///
1706    /// Returns `Ok(())` if the server starts successfully, or an error if initialization fails.
1707    ///
1708    /// # Examples
1709    ///
1710    /// ```no_run
1711    /// # use product_os_server::ProductOSServer;
1712    /// # use product_os_server::ServerConfig;
1713    /// # use product_os_async_executor::TokioExecutor;
1714    /// # #[cfg(feature = "executor_tokio")]
1715    /// # async fn example() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
1716    /// # let config = ServerConfig::new();
1717    /// # let mut server: ProductOSServer<(), TokioExecutor, _> = 
1718    /// #     ProductOSServer::new_with_config(config);
1719    /// // Start server in background
1720    /// server.start(false).await?;
1721    /// # Ok(())
1722    /// # }
1723    /// ```
1724    ///
1725    /// # Note
1726    ///
1727    /// When `serve_on_main_thread` is true and the controller feature is enabled,
1728    /// this method will block indefinitely after starting the controller.
1729    #[cfg(feature = "core")]
1730    pub async fn start(&mut self, serve_on_main_thread: bool) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
1731        // ----- Start Server
1732        if self.config.is_secure() {
1733            #[cfg(feature = "controller")]
1734            {
1735                if self.config.network.allow_insecure {
1736                    if !&self.config.network.insecure_use_different_port {
1737                        #[cfg(feature = "dual_server")]
1738                        self.create_dual_service_server(false, self.config.network.listen_all_interfaces.to_owned(), Some(self.config.insecure_port()), None, false, self.config.network.insecure_force_secure.to_owned()).await?;
1739                    }
1740                    else {
1741                        if self.config.network.insecure_force_secure {
1742                            let secure_cfg = ForceSecureConfig {
1743                                host: self.config.network.host.clone(),
1744                                port: self.config.network.port,
1745                            };
1746                            let mut router = Router::new();
1747                            router = router
1748                                .fallback(product_os_router::MethodRouter::new()
1749                                    .get(force_secure_handler)
1750                                    .post(force_secure_handler)
1751                                    .put(force_secure_handler)
1752                                    .patch(force_secure_handler)
1753                                    .delete(force_secure_handler)
1754                                    .trace(force_secure_handler)
1755                                    .head(force_secure_handler)
1756                                    .options(force_secure_handler))
1757                                .layer(axum::extract::Extension(secure_cfg));
1758
1759                            self.create_http_server(false, self.config.network.listen_all_interfaces.to_owned(), Some(self.config.insecure_port()), Some(router), false).await?;
1760                        }
1761                        else {
1762                            self.create_http_server(false, self.config.network.listen_all_interfaces.to_owned(), Some(self.config.insecure_port()), None, false).await?;
1763                        }
1764                    }
1765                }
1766
1767                self.create_https_server(false, self.config.network.listen_all_interfaces.to_owned(), None, None, false).await?;
1768            }
1769            #[cfg(not(feature = "controller"))]
1770            {
1771                if self.config.network.allow_insecure {
1772                    if self.config.network.insecure_force_secure {
1773                        let secure_cfg = ForceSecureConfig {
1774                            host: self.config.network.host.clone(),
1775                            port: self.config.network.port,
1776                        };
1777                        let mut router = Router::new();
1778                        router = router
1779                            .fallback(product_os_router::MethodRouter::new()
1780                                .get(force_secure_handler)
1781                                .post(force_secure_handler)
1782                                .put(force_secure_handler)
1783                                .patch(force_secure_handler)
1784                                .delete(force_secure_handler)
1785                                .trace(force_secure_handler)
1786                                .head(force_secure_handler)
1787                                .options(force_secure_handler))
1788                            .layer(axum::extract::Extension(secure_cfg));
1789
1790                        self.create_http_server(serve_on_main_thread, self.config.network.listen_all_interfaces.to_owned(), Some(self.config.network.insecure_port), Some(router), false).await?;
1791                    }
1792                    else {
1793                        self.create_http_server(serve_on_main_thread, self.config.network.listen_all_interfaces.to_owned(), Some(self.config.network.insecure_port), None, false).await?;
1794                    }
1795                }
1796
1797                self.create_https_server(serve_on_main_thread, self.config.network.listen_all_interfaces.to_owned(), None, None, false).await?;
1798            }
1799        }
1800        else {
1801            #[cfg(feature = "controller")]
1802            {
1803                self.create_http_server(false, self.config.network.listen_all_interfaces.to_owned(), None, None, false).await?;
1804            }
1805            #[cfg(not(feature = "controller"))]
1806            {
1807                self.create_http_server(serve_on_main_thread, self.config.network.listen_all_interfaces.to_owned(), None, None, false).await?;
1808            }
1809        };
1810
1811        #[cfg(feature = "controller")]
1812        {
1813            self.init_stores().await;
1814
1815            let cc_cfg: Option<product_os_command_control::CommandControl> = self.config.command_control.as_ref()
1816                .and_then(|v| serde_json::from_value(v.clone()).ok());
1817            match &cc_cfg {
1818                None => {
1819                    panic!("No controller config");
1820                }
1821                Some(command_control_config) => {
1822                    if command_control_config.enable {
1823                        match &self.controller {
1824                            None => {
1825                                panic!("No controller");
1826                            }
1827                            Some(c) => {
1828                                let controller_unlocked = c.clone();
1829                                let executor = self.executor.clone();
1830
1831                                if serve_on_main_thread {
1832                                    product_os_command_control::run_controller(controller_unlocked, executor).await;
1833                                    // Wait for shutdown signal (Ctrl+C / SIGINT)
1834                                    match tokio::signal::ctrl_c().await {
1835                                        Ok(()) => {
1836                                            #[cfg(feature = "core")]
1837                                            tracing::info!("Shutdown signal received, stopping server...");
1838                                        }
1839                                        Err(e) => {
1840                                            #[cfg(feature = "core")]
1841                                            tracing::error!("Failed to listen for shutdown signal: {:?}", e);
1842                                        }
1843                                    }
1844                                }
1845                                else {
1846                                    if let Err(e) = server_executor::ServerExecutor::spawn(self.executor.clone(), async move {
1847                                        product_os_command_control::run_controller(controller_unlocked, executor).await;
1848                                    }) {
1849                                        #[cfg(feature = "core")]
1850                                        tracing::error!("Failed to spawn controller task: {}", e);
1851                                    }
1852                                }
1853                            }
1854                        }
1855                    }
1856                }
1857            }
1858        }
1859
1860        Ok(())
1861    }
1862
1863    /// Starts all registered services.
1864    ///
1865    /// # Errors
1866    ///
1867    /// Returns `ControllerError` if the controller is not configured, not enabled,
1868    /// cannot be locked, or if starting services fails.
1869    #[cfg(feature = "controller")]
1870    pub async fn start_services(&mut self) -> Result<(), ProductOSServerError> {
1871        let cc_cfg: Option<product_os_command_control::CommandControl> = self.config.command_control.as_ref()
1872            .and_then(|v| serde_json::from_value(v.clone()).map_err(|e| {
1873                #[cfg(feature = "core")]
1874                tracing::warn!("Failed to parse command_control config: {}", e);
1875                e
1876            }).ok());
1877        let command_control_config = cc_cfg.ok_or_else(|| ProductOSServerError::ControllerError {
1878            operation: "start_services".to_string(),
1879            message: "No controller config".to_string(),
1880        })?;
1881        if !command_control_config.enable {
1882            return Err(ProductOSServerError::ControllerError {
1883                operation: "start_services".to_string(),
1884                message: "Controller not enabled".to_string(),
1885            });
1886        }
1887        let controller_arc = self.try_get_controller()?;
1888        let mut controller = controller_arc.try_lock_for(CONTROLLER_LOCK_TIMEOUT)
1889            .ok_or_else(|| ProductOSServerError::LockError { resource: "controller".to_string() })?;
1890        controller.start_services().await
1891            .map_err(|e| ProductOSServerError::ControllerError {
1892                operation: "start_services".to_string(),
1893                message: alloc::format!("Failed to start services: {:?}", e),
1894            })
1895    }
1896
1897    /// Starts a specific service by its identifier.
1898    ///
1899    /// # Arguments
1900    ///
1901    /// * `identifier` - The unique identifier of the service to start
1902    ///
1903    /// # Errors
1904    ///
1905    /// Returns `ControllerError` if the controller is not configured, not enabled,
1906    /// cannot be locked, or if starting the service fails.
1907    #[cfg(feature = "controller")]
1908    pub async fn start_service(&mut self, identifier: &str) -> Result<(), ProductOSServerError> {
1909        let cc_cfg: Option<product_os_command_control::CommandControl> = self.config.command_control.as_ref()
1910            .and_then(|v| serde_json::from_value(v.clone()).map_err(|e| {
1911                #[cfg(feature = "core")]
1912                tracing::warn!("Failed to parse command_control config: {}", e);
1913                e
1914            }).ok());
1915        let command_control_config = cc_cfg.ok_or_else(|| ProductOSServerError::ControllerError {
1916            operation: "start_service".to_string(),
1917            message: "No controller config".to_string(),
1918        })?;
1919        if !command_control_config.enable {
1920            return Err(ProductOSServerError::ControllerError {
1921                operation: "start_service".to_string(),
1922                message: "Controller not enabled".to_string(),
1923            });
1924        }
1925        let controller_arc = self.try_get_controller()?;
1926        let mut controller = controller_arc.try_lock_for(CONTROLLER_LOCK_TIMEOUT)
1927            .ok_or_else(|| ProductOSServerError::LockError { resource: "controller".to_string() })?;
1928        controller.start_service(identifier).await
1929            .map_err(|e| ProductOSServerError::ControllerError {
1930                operation: "start_service".to_string(),
1931                message: alloc::format!("Failed to start service '{}': {:?}", identifier, e),
1932            })
1933    }
1934
1935    /// Stops a specific service by its identifier.
1936    ///
1937    /// # Arguments
1938    ///
1939    /// * `identifier` - The unique identifier of the service to stop
1940    ///
1941    /// # Errors
1942    ///
1943    /// Returns `ControllerError` if the controller is not configured, not enabled,
1944    /// cannot be locked, or if stopping the service fails.
1945    #[cfg(feature = "controller")]
1946    pub async fn stop_service(&mut self, identifier: &str) -> Result<(), ProductOSServerError> {
1947        let cc_cfg: Option<product_os_command_control::CommandControl> = self.config.command_control.as_ref()
1948            .and_then(|v| serde_json::from_value(v.clone()).map_err(|e| {
1949                #[cfg(feature = "core")]
1950                tracing::warn!("Failed to parse command_control config: {}", e);
1951                e
1952            }).ok());
1953        let command_control_config = cc_cfg.ok_or_else(|| ProductOSServerError::ControllerError {
1954            operation: "stop_service".to_string(),
1955            message: "No controller config".to_string(),
1956        })?;
1957        if !command_control_config.enable {
1958            return Err(ProductOSServerError::ControllerError {
1959                operation: "stop_service".to_string(),
1960                message: "Controller not enabled".to_string(),
1961            });
1962        }
1963        let controller_arc = self.try_get_controller()?;
1964        let mut controller = controller_arc.try_lock_for(CONTROLLER_LOCK_TIMEOUT)
1965            .ok_or_else(|| ProductOSServerError::LockError { resource: "controller".to_string() })?;
1966        controller.stop_service(identifier).await
1967            .map_err(|e| ProductOSServerError::ControllerError {
1968                operation: "stop_service".to_string(),
1969                message: alloc::format!("Failed to stop service '{}': {:?}", identifier, e),
1970            })
1971    }
1972}
1973
1974
1975
1976
1977/// Configuration passed to the force-secure redirect handler via an axum `Extension`.
1978#[cfg(feature = "core")]
1979#[derive(Clone, Debug)]
1980struct ForceSecureConfig {
1981    host: String,
1982    port: u16,
1983}
1984
1985/// Redirects HTTP requests to their HTTPS equivalent using the configured host and port.
1986///
1987/// Builds a full `https://host:port/path?query` URL and issues a 301 Permanent Redirect.
1988#[cfg(feature = "core")]
1989async fn force_secure_handler(
1990    Extension(secure_cfg): Extension<ForceSecureConfig>,
1991    request: Request<Body>,
1992) -> Response<BodyBytes> {
1993    let uri = request.uri();
1994    let path = uri.path();
1995    let query = uri.query().map(|q| alloc::format!("?{}", q)).unwrap_or_default();
1996
1997    let https_url = if secure_cfg.port == 443 {
1998        alloc::format!("https://{}{}{}", secure_cfg.host, path, query)
1999    } else {
2000        alloc::format!("https://{}:{}{}{}", secure_cfg.host, secure_cfg.port, path, query)
2001    };
2002
2003    let (parts, _) = axum::response::Redirect::permanent(https_url.as_str()).into_response().into_parts();
2004
2005    let mut response_builder = Response::builder().status(parts.status);
2006    for (key, value) in parts.headers.iter() {
2007        response_builder = response_builder.header(key.to_owned(), value.to_owned());
2008    }
2009
2010    response_builder.body(BodyBytes::empty()).unwrap_or_else(|_e| Response::new(BodyBytes::empty()))
2011}
2012
2013/// Deprecated: Old force-secure handler that redirects to the same path without building a proper HTTPS URL.
2014///
2015/// This handler is broken -- it does not include the scheme, host, or port in the redirect Location header.
2016/// Use `force_secure_handler` instead, which builds a correct `https://host:port/path` redirect.
2017#[cfg(feature = "core")]
2018#[deprecated(since = "0.0.53", note = "Use force_secure_handler which builds correct HTTPS redirect URLs")]
2019#[allow(dead_code)]
2020async fn force_secure_handler_deprecated(request: Request<Body>) -> Response<BodyBytes> {
2021    let uri_path = request.uri().path();
2022
2023    let mut url: String = String::new();
2024    url.push_str(uri_path);
2025
2026    let (parts, _) = axum::response::Redirect::permanent(url.as_str()).into_response().into_parts();
2027
2028    let mut response_builder = Response::builder().status(parts.status);
2029    for (key, value) in parts.headers.iter() {
2030        response_builder = response_builder.header(key.to_owned(), value.to_owned());
2031    }
2032
2033    response_builder.body(BodyBytes::empty()).unwrap_or_else(|_e| Response::new(BodyBytes::empty()))
2034}
2035