diff --git a/src/http/conf.rs b/src/http/conf.rs index 4761bb0..a135e9f 100644 --- a/src/http/conf.rs +++ b/src/http/conf.rs @@ -31,3 +31,33 @@ pub unsafe fn ngx_http_conf_get_module_loc_conf( let http_conf_ctx = (*cf).ctx as *mut ngx_http_conf_ctx_t; *(*http_conf_ctx).loc_conf.add(module.ctx_index) as *mut ngx_http_core_loc_conf_t } + +/// # Safety +/// +/// The caller has provided a value `ngx_http_upstream_srv_conf_t. If the `us` argument is null, a +/// None Option is returned; however, if the `us` internal fields are invalid or the module index +/// is out of bounds failures may still occur. +pub unsafe fn ngx_http_conf_upstream_srv_conf_immutable( + us: *const ngx_http_upstream_srv_conf_t, + module: &ngx_module_t, +) -> Option<*const T> { + if us.is_null() { + return None; + } + Some(*(*us).srv_conf.add(module.ctx_index) as *const T) +} + +/// # Safety +/// +/// The caller has provided a value `ngx_http_upstream_srv_conf_t. If the `us` argument is null, a +/// None Option is returned; however, if the `us` internal fields are invalid or the module index +/// is out of bounds failures may still occur. +pub unsafe fn ngx_http_conf_upstream_srv_conf_mutable( + us: *const ngx_http_upstream_srv_conf_t, + module: &ngx_module_t, +) -> Option<*mut T> { + if us.is_null() { + return None; + } + Some(*(*us).srv_conf.add(module.ctx_index) as *mut T) +} diff --git a/src/http/mod.rs b/src/http/mod.rs index 230ce0b..024ad1f 100644 --- a/src/http/mod.rs +++ b/src/http/mod.rs @@ -2,8 +2,10 @@ mod conf; mod module; mod request; mod status; +mod upstream; pub use conf::*; pub use module::*; pub use request::*; pub use status::*; +pub use upstream::*; diff --git a/src/http/request.rs b/src/http/request.rs index 1594f17..be0330f 100644 --- a/src/http/request.rs +++ b/src/http/request.rs @@ -79,6 +79,17 @@ macro_rules! http_variable_get { #[repr(transparent)] pub struct Request(ngx_http_request_t); +impl<'a> From<&'a Request> for *const ngx_http_request_t { + fn from(request: &'a Request) -> Self { + &request.0 as *const _ + } +} +impl<'a> From<&'a mut Request> for *mut ngx_http_request_t { + fn from(request: &'a mut Request) -> Self { + &request.0 as *const _ as *mut _ + } +} + impl Request { /// Create a [`Request`] from an [`ngx_http_request_t`]. /// @@ -104,6 +115,17 @@ impl Request { unsafe { Pool::from_ngx_pool(self.0.pool) } } + /// Returns the result as an `Option` if it exists, otherwise `None`. + /// + /// The option wraps a pointer to a [`ngx_http_upstream_t`] upstream server object. + /// + /// [`ngx_http_upstream_t`]: is best described in + /// https://nginx.org/en/docs/dev/development_guide.html#http_request + /// https://nginx.org/en/docs/dev/development_guide.html#http_load_balancing + pub fn upstream(&self) -> Option<*mut ngx_http_upstream_t> { + Some(self.0.upstream) + } + /// Pointer to a [`ngx_connection_t`] client connection object. /// /// [`ngx_connection_t`]: https://nginx.org/en/docs/dev/development_guide.html#connection diff --git a/src/http/upstream.rs b/src/http/upstream.rs new file mode 100644 index 0000000..99148bb --- /dev/null +++ b/src/http/upstream.rs @@ -0,0 +1,15 @@ +/// Define a static upstream peer initializer +/// +/// Initializes the upstream 'get', 'free', and 'session' callbacks and gives the module writer an +/// opportunity to set custom data. +/// Load Balancing: +#[macro_export] +macro_rules! http_upstream_peer_init { + ( $name: ident, $handler: expr ) => { + #[no_mangle] + extern "C" fn $name(r: *mut ngx_http_request_t, us: *mut ngx_http_upstream_srv_conf_t) -> ngx_int_t { + let status: Status = $handler(unsafe { &mut Request::from_ngx_http_request(r) }, us); + status.0 + } + }; +}