ngx/http/
module.rs

1use core::ffi::{c_char, c_void};
2use core::fmt;
3use core::ptr;
4
5use crate::core::NGX_CONF_ERROR;
6use crate::core::*;
7use crate::ffi::*;
8
9/// MergeConfigError - configuration cannot be merged with levels above.
10#[derive(Debug)]
11pub enum MergeConfigError {
12    /// No value provided for configuration argument
13    NoValue,
14}
15
16#[cfg(feature = "std")]
17impl std::error::Error for MergeConfigError {}
18
19impl fmt::Display for MergeConfigError {
20    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
21        match self {
22            MergeConfigError::NoValue => "no value".fmt(fmt),
23        }
24    }
25}
26
27/// The `Merge` trait provides a method for merging configuration down through each level.
28///
29/// A module configuration should implement this trait for setting its configuration throughout
30/// each level.
31pub trait Merge {
32    /// Module merge function.
33    ///
34    /// # Returns
35    /// Result, Ok on success or MergeConfigError on failure.
36    fn merge(&mut self, prev: &Self) -> Result<(), MergeConfigError>;
37}
38
39impl Merge for () {
40    fn merge(&mut self, _prev: &Self) -> Result<(), MergeConfigError> {
41        Ok(())
42    }
43}
44
45/// The `HTTPModule` trait provides the NGINX configuration stage interface.
46///
47/// These functions allocate structures, initialize them, and merge through the configuration
48/// layers.
49///
50/// See <https://nginx.org/en/docs/dev/development_guide.html#adding_new_modules> for details.
51pub trait HttpModule {
52    /// Returns reference to a global variable of type [ngx_module_t] created for this module.
53    fn module() -> &'static ngx_module_t;
54
55    /// # Safety
56    ///
57    /// Callers should provide valid non-null `ngx_conf_t` arguments. Implementers must
58    /// guard against null inputs or risk runtime errors.
59    unsafe extern "C" fn preconfiguration(_cf: *mut ngx_conf_t) -> ngx_int_t {
60        Status::NGX_OK.into()
61    }
62
63    /// # Safety
64    ///
65    /// Callers should provide valid non-null `ngx_conf_t` arguments. Implementers must
66    /// guard against null inputs or risk runtime errors.
67    unsafe extern "C" fn postconfiguration(_cf: *mut ngx_conf_t) -> ngx_int_t {
68        Status::NGX_OK.into()
69    }
70
71    /// # Safety
72    ///
73    /// Callers should provide valid non-null `ngx_conf_t` arguments. Implementers must
74    /// guard against null inputs or risk runtime errors.
75    unsafe extern "C" fn create_main_conf(cf: *mut ngx_conf_t) -> *mut c_void
76    where
77        Self: super::HttpModuleMainConf,
78        Self::MainConf: Default,
79    {
80        let mut pool = Pool::from_ngx_pool((*cf).pool);
81        pool.allocate::<Self::MainConf>(Default::default()) as *mut c_void
82    }
83
84    /// # Safety
85    ///
86    /// Callers should provide valid non-null `ngx_conf_t` arguments. Implementers must
87    /// guard against null inputs or risk runtime errors.
88    unsafe extern "C" fn init_main_conf(_cf: *mut ngx_conf_t, _conf: *mut c_void) -> *mut c_char
89    where
90        Self: super::HttpModuleMainConf,
91        Self::MainConf: Default,
92    {
93        ptr::null_mut()
94    }
95
96    /// # Safety
97    ///
98    /// Callers should provide valid non-null `ngx_conf_t` arguments. Implementers must
99    /// guard against null inputs or risk runtime errors.
100    unsafe extern "C" fn create_srv_conf(cf: *mut ngx_conf_t) -> *mut c_void
101    where
102        Self: super::HttpModuleServerConf,
103        Self::ServerConf: Default,
104    {
105        let mut pool = Pool::from_ngx_pool((*cf).pool);
106        pool.allocate::<Self::ServerConf>(Default::default()) as *mut c_void
107    }
108
109    /// # Safety
110    ///
111    /// Callers should provide valid non-null `ngx_conf_t` arguments. Implementers must
112    /// guard against null inputs or risk runtime errors.
113    unsafe extern "C" fn merge_srv_conf(_cf: *mut ngx_conf_t, prev: *mut c_void, conf: *mut c_void) -> *mut c_char
114    where
115        Self: super::HttpModuleServerConf,
116        Self::ServerConf: Merge,
117    {
118        let prev = &mut *(prev as *mut Self::ServerConf);
119        let conf = &mut *(conf as *mut Self::ServerConf);
120        match conf.merge(prev) {
121            Ok(_) => ptr::null_mut(),
122            Err(_) => NGX_CONF_ERROR as _,
123        }
124    }
125
126    /// # Safety
127    ///
128    /// Callers should provide valid non-null `ngx_conf_t` arguments. Implementers must
129    /// guard against null inputs or risk runtime errors.
130    unsafe extern "C" fn create_loc_conf(cf: *mut ngx_conf_t) -> *mut c_void
131    where
132        Self: super::HttpModuleLocationConf,
133        Self::LocationConf: Default,
134    {
135        let mut pool = Pool::from_ngx_pool((*cf).pool);
136        pool.allocate::<Self::LocationConf>(Default::default()) as *mut c_void
137    }
138
139    /// # Safety
140    ///
141    /// Callers should provide valid non-null `ngx_conf_t` arguments. Implementers must
142    /// guard against null inputs or risk runtime errors.
143    unsafe extern "C" fn merge_loc_conf(_cf: *mut ngx_conf_t, prev: *mut c_void, conf: *mut c_void) -> *mut c_char
144    where
145        Self: super::HttpModuleLocationConf,
146        Self::LocationConf: Merge,
147    {
148        let prev = &mut *(prev as *mut Self::LocationConf);
149        let conf = &mut *(conf as *mut Self::LocationConf);
150        match conf.merge(prev) {
151            Ok(_) => ptr::null_mut(),
152            Err(_) => NGX_CONF_ERROR as _,
153        }
154    }
155}