Skip to content

Commit

Permalink
feat: (1 of 2) Supporting changes for upstream example module. (#36)
Browse files Browse the repository at this point in the history
* feat: Supporting changes for upstream example module.

- functions to get mut and const module context from the ngx_http_upstream_srv_conf_t
- Request from trait
- Request upstream getter
- Request peer init macro

---------

Co-authored-by: Matthew Yacobucci <[email protected]>
  • Loading branch information
f5yacobucci and Matthew Yacobucci authored Sep 1, 2023
1 parent 7972ae7 commit 8b3a119
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 0 deletions.
30 changes: 30 additions & 0 deletions src/http/conf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T>(
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<T>(
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)
}
2 changes: 2 additions & 0 deletions src/http/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
26 changes: 26 additions & 0 deletions src/http/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`].
///
Expand All @@ -104,6 +115,21 @@ impl Request {
unsafe { Pool::from_ngx_pool(self.0.pool) }
}

/// Returns the result as an `Option` if it exists, otherwise `None`.
///
/// The option wraps an ngx_http_upstream_t instance, it will be none when the underlying NGINX request
/// does not have a pointer to a [`ngx_http_upstream_t`] upstream structure.
///
/// [`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> {
if self.0.upstream.is_null() {
return None;
}
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
Expand Down
21 changes: 21 additions & 0 deletions src/http/upstream.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/// 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.
///
/// This macro will define the NGINX callback type:
/// `typedef ngx_int_t (*ngx_http_upstream_init_peer_pt)(ngx_http_request_t *r, ngx_http_upstream_srv_conf_t *us)`,
/// we keep this macro name in-sync with its underlying NGINX type, this callback is required to
/// initialize your peer.
///
/// Load Balancing: <https://nginx.org/en/docs/dev/development_guide.html#http_load_balancing>
#[macro_export]
macro_rules! http_upstream_init_peer_pt {
( $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
}
};
}

0 comments on commit 8b3a119

Please sign in to comment.