//! Gestión del servidor y servicios web (con [Actix Web](https://docs.rs/actix-web)). pub use actix_session::Session; pub use actix_web::body::BoxBody; pub use actix_web::dev::Server; pub use actix_web::dev::ServiceFactory as Factory; pub use actix_web::dev::ServiceRequest as Request; pub use actix_web::dev::ServiceResponse as Response; pub use actix_web::{cookie, http, rt, web}; pub use actix_web::{App, Error, HttpMessage, HttpRequest, HttpResponse, HttpServer}; pub use actix_web_files::Files as ActixFiles; pub use pagetop_statics::ResourceFiles; #[doc(hidden)] pub use actix_web::test; /// **Obsoleto desde la versión 0.3.0**: usar [`static_files_service!`](crate::static_files_service) /// en su lugar. #[deprecated(since = "0.3.0", note = "Use `static_files_service!` instead")] #[macro_export] macro_rules! include_files { // Forma 1: incluye un conjunto de recursos por nombre. ( $bundle:ident ) => { $crate::util::paste! { mod [] { include!(concat!(env!("OUT_DIR"), "/", stringify!($bundle), ".rs")); } } }; // Forma 2: asigna a una variable estática $STATIC un conjunto de recursos. ( $STATIC:ident => $bundle:ident ) => { $crate::util::paste! { mod [] { include!(concat!(env!("OUT_DIR"), "/", stringify!($bundle), ".rs")); } pub static $STATIC: std::sync::LazyLock<$crate::StaticResources> = std::sync::LazyLock::new( $crate::StaticResources::new([]::$bundle) ); } }; } /// **Obsoleto desde la versión 0.3.0**: usar [`static_files_service!`](crate::static_files_service) /// en su lugar. #[deprecated(since = "0.3.0", note = "Use `static_files_service!` instead")] #[macro_export] macro_rules! include_files_service { ( $scfg:ident, $bundle:ident => $route:expr $(, [$root:expr, $relative:expr])? ) => {{ $crate::util::paste! { let span = $crate::trace::debug_span!("Configuring static files ", path = $route); let _ = span.in_scope(|| { // Determina si se sirven recursos embebidos (`true`) o desde disco (`false`). #[allow(unused_mut)] let mut serve_embedded:bool = true; $( // Si `$root` y `$relative` no están vacíos, se comprueba la ruta absoluta. if !$root.is_empty() && !$relative.is_empty() { if let Ok(absolute) = $crate::util::absolute_dir($root, $relative) { // Servimos directamente desde el sistema de ficheros. $scfg.service($crate::service::ActixFiles::new( $route, absolute, ).show_files_listing()); serve_embedded = false } } )? // Si no se localiza el directorio, se exponen entonces los recursos embebidos. if serve_embedded { $scfg.service($crate::service::ResourceFiles::new( $route, []::$bundle(), )); } }); } }}; } /// Configura un servicio web para publicar archivos estáticos. /// /// La macro ofrece tres modos para configurar el servicio: /// /// - **Sistema de ficheros o embebido** (`[$path, $bundle]`): trata de servir los archivos desde /// `$path`; y si es una cadena vacía, no existe o no es un directorio, entonces usará el conjunto /// de recursos `$bundle` integrado en el binario. /// - **Sólo embebido** (`[$bundle]`): sirve siempre desde el conjunto de recursos `$bundle` /// integrado en el binario. /// - **Sólo sistema de ficheros** (`$path`): sin usar corchetes, sirve únicamente desde el sistema /// de ficheros si existe; en otro caso no registra el servicio. /// /// # Argumentos /// /// * `$scfg` – Instancia de [`ServiceConfig`](crate::service::web::ServiceConfig) donde aplicar la /// configuración. /// * `$path` – Ruta al directorio local con los archivos estáticos. /// * `$bundle` – Nombre del conjunto de recursos que esta macro integra en el binario. /// * `$route` – Ruta URL base desde la que se servirán los archivos. /// /// # Ejemplos /// /// ```rust,ignore /// use pagetop::prelude::*; /// /// pub struct MyExtension; /// /// impl Extension for MyExtension { /// fn configure_service(&self, scfg: &mut service::web::ServiceConfig) { /// // Forma 1) Sistema de ficheros o embebido. /// static_files_service!(scfg, ["/var/www/static", assets] => "/public"); /// /// // Forma 2) Siempre embebido. /// static_files_service!(scfg, [assets] => "/public"); /// /// // Forma 3) Sólo sistema de ficheros (no requiere `assets`). /// static_files_service!(scfg, "/var/www/static" => "/public"); /// } /// } /// ``` #[macro_export] macro_rules! static_files_service { // Forma 1: primero intenta servir desde el sistema de ficheros; si falla, sirve embebido. ( $scfg:ident, [$path:expr, $bundle:ident] => $route:expr $(,)? ) => {{ let span = $crate::trace::debug_span!( "Configuring static files (file system or embedded)", mode = "fs_or_embedded", route = $route, ); let _ = span.in_scope(|| { let mut serve_embedded: bool = true; if !::std::path::Path::new(&$path).as_os_str().is_empty() { if let Ok(absolute) = $crate::util::resolve_absolute_dir($path) { $scfg.service($crate::service::ActixFiles::new($route, absolute)); serve_embedded = false; } } if serve_embedded { $crate::util::paste! { mod [] { include!(concat!(env!("OUT_DIR"), "/", stringify!($bundle), ".rs")); } $scfg.service($crate::service::ResourceFiles::new( $route, []::$bundle(), )); } } }); }}; // Forma 2: sirve siempre embebido. ( $scfg:ident, [$bundle:ident] => $route:expr $(,)? ) => {{ let span = $crate::trace::debug_span!( "Configuring static files (using embedded only)", mode = "embedded", route = $route, ); let _ = span.in_scope(|| { $crate::util::paste! { mod [] { include!(concat!(env!("OUT_DIR"), "/", stringify!($bundle), ".rs")); } $scfg.service($crate::service::ResourceFiles::new( $route, []::$bundle(), )); } }); }}; // Forma 3: intenta servir desde el sistema de ficheros. ( $scfg:ident, $path:expr => $route:expr $(,)? ) => {{ let span = $crate::trace::debug_span!( "Configuring static files (file system only)", mode = "fs", route = $route, ); let _ = span.in_scope(|| match $crate::util::resolve_absolute_dir($path) { Ok(absolute) => { $scfg.service($crate::service::ActixFiles::new($route, absolute)); } Err(e) => { $crate::trace::warn!( "Static dir not found or invalid for route `{}`: {:?} ({e})", $route, $path, ); } }); }}; }