ferron_common/
modules.rs

1use std::collections::HashSet;
2use std::error::Error;
3use std::net::SocketAddr;
4use std::sync::Arc;
5
6use async_trait::async_trait;
7use bytes::Bytes;
8use http_body_util::combinators::BoxBody;
9use hyper::{HeaderMap, Request, Response, StatusCode, Uri};
10
11use crate::config::ServerConfiguration;
12use crate::logging::ErrorLogger;
13use crate::observability::MetricsMultiSender;
14
15/// A trait that defines a module loader
16pub trait ModuleLoader {
17  /// Loads a module according to specific configuration
18  fn load_module(
19    &mut self,
20    config: &ServerConfiguration,
21    global_config: Option<&ServerConfiguration>,
22    secondary_runtime: &tokio::runtime::Runtime,
23  ) -> Result<Arc<dyn Module + Send + Sync>, Box<dyn Error + Send + Sync>>;
24
25  /// Determines configuration properties required to load a module
26  fn get_requirements(&self) -> Vec<&'static str> {
27    vec![]
28  }
29
30  /// Validates the server configuration
31  #[allow(unused_variables)]
32  fn validate_configuration(
33    &self,
34    config: &ServerConfiguration,
35    used_properties: &mut HashSet<String>,
36  ) -> Result<(), Box<dyn Error + Send + Sync>> {
37    Ok(())
38  }
39}
40
41/// A trait that defines a module
42pub trait Module {
43  /// Obtains the module handlers
44  fn get_module_handlers(&self) -> Box<dyn ModuleHandlers>;
45}
46
47/// A trait that defines handlers for a module
48#[async_trait(?Send)]
49pub trait ModuleHandlers {
50  /// Handles the incoming request
51  async fn request_handler(
52    &mut self,
53    request: Request<BoxBody<Bytes, std::io::Error>>,
54    config: &ServerConfiguration,
55    socket_data: &SocketData,
56    error_logger: &ErrorLogger,
57  ) -> Result<ResponseData, Box<dyn Error + Send + Sync>>;
58
59  /// Modifies the outgoing response
60  async fn response_modifying_handler(
61    &mut self,
62    response: Response<BoxBody<Bytes, std::io::Error>>,
63  ) -> Result<Response<BoxBody<Bytes, std::io::Error>>, Box<dyn Error>> {
64    Ok(response)
65  }
66
67  /// Sends metric data before handling the request
68  #[allow(unused_variables)]
69  async fn metric_data_before_handler(
70    &mut self,
71    request: &Request<BoxBody<Bytes, std::io::Error>>,
72    socket_data: &SocketData,
73    metrics_sender: &MetricsMultiSender,
74  ) {
75  }
76
77  /// Sends metric data after modifying the response
78  #[allow(unused_variables)]
79  async fn metric_data_after_handler(&mut self, metrics_sender: &MetricsMultiSender) {}
80
81  /// Gets the module handlers' type name
82  fn get_name(&self) -> &'static str {
83    std::any::type_name::<Self>()
84  }
85}
86
87/// Contains information about a network socket, including remote and local addresses,
88/// and whether the connection is encrypted.
89pub struct SocketData {
90  /// The remote address of the socket.
91  pub remote_addr: SocketAddr,
92
93  /// The local address of the socket.
94  pub local_addr: SocketAddr,
95
96  /// Indicates if the connection is encrypted.
97  pub encrypted: bool,
98}
99
100/// Data related to an HTTP request
101#[derive(Clone)]
102pub struct RequestData {
103  /// The authenticated username
104  pub auth_user: Option<String>,
105
106  /// The original URL (before URL rewriting)
107  pub original_url: Option<Uri>,
108
109  /// The error status code, when the error handler is executed
110  #[allow(dead_code)]
111  pub error_status_code: Option<StatusCode>,
112}
113
114/// Data related to an HTTP response
115pub struct ResponseData {
116  /// The passed HTTP request
117  pub request: Option<Request<BoxBody<Bytes, std::io::Error>>>,
118
119  /// The HTTP response with a body
120  pub response: Option<Response<BoxBody<Bytes, std::io::Error>>>,
121
122  /// The HTTP response status code (when the response with a body isn't set)
123  pub response_status: Option<StatusCode>,
124
125  /// The HTTP response headers
126  pub response_headers: Option<HeaderMap>,
127
128  /// The new client address
129  pub new_remote_address: Option<SocketAddr>,
130}