Skip to content

Commit 8b3a119

Browse files
f5yacobucciMatthew Yacobucci
andauthored
feat: (1 of 2) Supporting changes for upstream example module. (#36)
* 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]>
1 parent 7972ae7 commit 8b3a119

File tree

4 files changed

+79
-0
lines changed

4 files changed

+79
-0
lines changed

src/http/conf.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,33 @@ pub unsafe fn ngx_http_conf_get_module_loc_conf(
3131
let http_conf_ctx = (*cf).ctx as *mut ngx_http_conf_ctx_t;
3232
*(*http_conf_ctx).loc_conf.add(module.ctx_index) as *mut ngx_http_core_loc_conf_t
3333
}
34+
35+
/// # Safety
36+
///
37+
/// The caller has provided a value `ngx_http_upstream_srv_conf_t. If the `us` argument is null, a
38+
/// None Option is returned; however, if the `us` internal fields are invalid or the module index
39+
/// is out of bounds failures may still occur.
40+
pub unsafe fn ngx_http_conf_upstream_srv_conf_immutable<T>(
41+
us: *const ngx_http_upstream_srv_conf_t,
42+
module: &ngx_module_t,
43+
) -> Option<*const T> {
44+
if us.is_null() {
45+
return None;
46+
}
47+
Some(*(*us).srv_conf.add(module.ctx_index) as *const T)
48+
}
49+
50+
/// # Safety
51+
///
52+
/// The caller has provided a value `ngx_http_upstream_srv_conf_t. If the `us` argument is null, a
53+
/// None Option is returned; however, if the `us` internal fields are invalid or the module index
54+
/// is out of bounds failures may still occur.
55+
pub unsafe fn ngx_http_conf_upstream_srv_conf_mutable<T>(
56+
us: *const ngx_http_upstream_srv_conf_t,
57+
module: &ngx_module_t,
58+
) -> Option<*mut T> {
59+
if us.is_null() {
60+
return None;
61+
}
62+
Some(*(*us).srv_conf.add(module.ctx_index) as *mut T)
63+
}

src/http/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ mod conf;
22
mod module;
33
mod request;
44
mod status;
5+
mod upstream;
56

67
pub use conf::*;
78
pub use module::*;
89
pub use request::*;
910
pub use status::*;
11+
pub use upstream::*;

src/http/request.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,17 @@ macro_rules! http_variable_get {
7979
#[repr(transparent)]
8080
pub struct Request(ngx_http_request_t);
8181

82+
impl<'a> From<&'a Request> for *const ngx_http_request_t {
83+
fn from(request: &'a Request) -> Self {
84+
&request.0 as *const _
85+
}
86+
}
87+
impl<'a> From<&'a mut Request> for *mut ngx_http_request_t {
88+
fn from(request: &'a mut Request) -> Self {
89+
&request.0 as *const _ as *mut _
90+
}
91+
}
92+
8293
impl Request {
8394
/// Create a [`Request`] from an [`ngx_http_request_t`].
8495
///
@@ -104,6 +115,21 @@ impl Request {
104115
unsafe { Pool::from_ngx_pool(self.0.pool) }
105116
}
106117

118+
/// Returns the result as an `Option` if it exists, otherwise `None`.
119+
///
120+
/// The option wraps an ngx_http_upstream_t instance, it will be none when the underlying NGINX request
121+
/// does not have a pointer to a [`ngx_http_upstream_t`] upstream structure.
122+
///
123+
/// [`ngx_http_upstream_t`]: is best described in
124+
/// https://nginx.org/en/docs/dev/development_guide.html#http_request
125+
/// https://nginx.org/en/docs/dev/development_guide.html#http_load_balancing
126+
pub fn upstream(&self) -> Option<*mut ngx_http_upstream_t> {
127+
if self.0.upstream.is_null() {
128+
return None;
129+
}
130+
Some(self.0.upstream)
131+
}
132+
107133
/// Pointer to a [`ngx_connection_t`] client connection object.
108134
///
109135
/// [`ngx_connection_t`]: https://nginx.org/en/docs/dev/development_guide.html#connection

src/http/upstream.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/// Define a static upstream peer initializer
2+
///
3+
/// Initializes the upstream 'get', 'free', and 'session' callbacks and gives the module writer an
4+
/// opportunity to set custom data.
5+
///
6+
/// This macro will define the NGINX callback type:
7+
/// `typedef ngx_int_t (*ngx_http_upstream_init_peer_pt)(ngx_http_request_t *r, ngx_http_upstream_srv_conf_t *us)`,
8+
/// we keep this macro name in-sync with its underlying NGINX type, this callback is required to
9+
/// initialize your peer.
10+
///
11+
/// Load Balancing: <https://nginx.org/en/docs/dev/development_guide.html#http_load_balancing>
12+
#[macro_export]
13+
macro_rules! http_upstream_init_peer_pt {
14+
( $name: ident, $handler: expr ) => {
15+
#[no_mangle]
16+
extern "C" fn $name(r: *mut ngx_http_request_t, us: *mut ngx_http_upstream_srv_conf_t) -> ngx_int_t {
17+
let status: Status = $handler(unsafe { &mut Request::from_ngx_http_request(r) }, us);
18+
status.0
19+
}
20+
};
21+
}

0 commit comments

Comments
 (0)