Skip to content

feat: (1 of 2) Supporting changes for upstream example module. #36

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
}
};
}