From a62fa0ffe14af4e66533e2f7bf3e32e08784cf39 Mon Sep 17 00:00:00 2001 From: Aleksei Bavshin Date: Wed, 12 Feb 2025 15:53:45 -0800 Subject: [PATCH 1/3] refactor!: remove macros for initializing empty `ngx_*_variable_t` There are no nginx core APIs that take a list of variables terminated by an empty entry. Variables are always added from the module code, where we should use Rust iterators. --- examples/httporigdst.rs | 8 ++------ src/core/mod.rs | 38 -------------------------------------- 2 files changed, 2 insertions(+), 44 deletions(-) diff --git a/examples/httporigdst.rs b/examples/httporigdst.rs index 02578cc..314cca1 100644 --- a/examples/httporigdst.rs +++ b/examples/httporigdst.rs @@ -8,7 +8,7 @@ use ngx::ffi::{ sockaddr, sockaddr_storage, INET_ADDRSTRLEN, NGX_HTTP_MODULE, }; use ngx::http::{self, HTTPModule}; -use ngx::{http_variable_get, ngx_http_null_variable, ngx_log_debug_http, ngx_null_string, ngx_string}; +use ngx::{http_variable_get, ngx_log_debug_http, ngx_null_string, ngx_string}; const IPV4_STRLEN: usize = INET_ADDRSTRLEN as usize; @@ -102,7 +102,7 @@ pub static mut ngx_http_orig_dst_module: ngx_module_t = ngx_module_t { ..ngx_module_t::default() }; -static mut NGX_HTTP_ORIG_DST_VARS: [ngx_http_variable_t; 3] = [ +static mut NGX_HTTP_ORIG_DST_VARS: [ngx_http_variable_t; 2] = [ // ngx_str_t name // ngx_http_set_variable_pt set_handler // ngx_http_get_variable_pt get_handler @@ -125,7 +125,6 @@ static mut NGX_HTTP_ORIG_DST_VARS: [ngx_http_variable_t; 3] = [ flags: 0, index: 0, }, - ngx_http_null_variable!(), ]; unsafe fn ngx_get_origdst(request: &mut http::Request) -> Result<(String, in_port_t), core::Status> { @@ -276,9 +275,6 @@ impl HTTPModule for Module { // static ngx_int_t ngx_http_orig_dst_add_variables(ngx_conf_t *cf) unsafe extern "C" fn preconfiguration(cf: *mut ngx_conf_t) -> ngx_int_t { for mut v in NGX_HTTP_ORIG_DST_VARS { - if v.name.len == 0 { - break; - } let var = ngx_http_add_variable(cf, &mut v.name, v.flags); if var.is_null() { return core::Status::NGX_ERROR.into(); diff --git a/src/core/mod.rs b/src/core/mod.rs index 07ef434..7cb7868 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -26,41 +26,3 @@ macro_rules! ngx_null_command { } }; } - -/// Static empty configuration variable initializer for [`ngx_http_variable_t`]. -/// -/// This is typically used to terminate an array of HTTP variable types. -/// -/// [`ngx_http_variable_t`]: https://nginx.org/en/docs/dev/development_guide.html#http_variables -#[macro_export] -macro_rules! ngx_http_null_variable { - () => { - $crate::ffi::ngx_http_variable_t { - name: $crate::ngx_null_string!(), - set_handler: None, - get_handler: None, - data: 0, - flags: 0, - index: 0, - } - }; -} - -/// Static empty configuration variable initializer for [`ngx_stream_variable_t`]. -/// -/// This is typically used to terminate an array of Stream variable types. -/// -/// [`ngx_stream_variable_t`]: https://github.com/nginx/nginx/blob/1a8ef991d92d22eb8aded7f49595dd31a639e8a4/src/stream/ngx_stream_variables.h#L21 -#[macro_export] -macro_rules! ngx_stream_null_variable { - () => { - $crate::ffi::ngx_stream_variable_t { - name: $crate::ngx_null_string!(), - set_handler: None, - get_handler: None, - data: 0, - flags: 0, - index: 0, - } - }; -} From 173587d02c0d61f051a2a744ec4c5ab8e31e7220 Mon Sep 17 00:00:00 2001 From: Aleksei Bavshin Date: Wed, 12 Feb 2025 15:46:08 -0800 Subject: [PATCH 2/3] refactor!: replace `ngx_null_string!` with `ngx_str_t::empty()` --- examples/httporigdst.rs | 13 ++----------- nginx-sys/src/lib.rs | 24 ++++++++++++++++++++---- src/core/mod.rs | 2 +- src/core/string.rs | 19 +++---------------- src/http/request.rs | 3 +-- 5 files changed, 27 insertions(+), 34 deletions(-) diff --git a/examples/httporigdst.rs b/examples/httporigdst.rs index 314cca1..02e6ddb 100644 --- a/examples/httporigdst.rs +++ b/examples/httporigdst.rs @@ -8,25 +8,16 @@ use ngx::ffi::{ sockaddr, sockaddr_storage, INET_ADDRSTRLEN, NGX_HTTP_MODULE, }; use ngx::http::{self, HTTPModule}; -use ngx::{http_variable_get, ngx_log_debug_http, ngx_null_string, ngx_string}; +use ngx::{http_variable_get, ngx_log_debug_http, ngx_string}; const IPV4_STRLEN: usize = INET_ADDRSTRLEN as usize; -#[derive(Debug)] +#[derive(Debug, Default)] struct NgxHttpOrigDstCtx { orig_dst_addr: ngx_str_t, orig_dst_port: ngx_str_t, } -impl Default for NgxHttpOrigDstCtx { - fn default() -> NgxHttpOrigDstCtx { - NgxHttpOrigDstCtx { - orig_dst_addr: ngx_null_string!(), - orig_dst_port: ngx_null_string!(), - } - } -} - impl NgxHttpOrigDstCtx { pub fn save(&mut self, addr: &str, port: in_port_t, pool: &mut core::Pool) -> core::Status { let addr_data = pool.alloc_unaligned(addr.len()); diff --git a/nginx-sys/src/lib.rs b/nginx-sys/src/lib.rs index 50428f8..3b22da8 100644 --- a/nginx-sys/src/lib.rs +++ b/nginx-sys/src/lib.rs @@ -4,7 +4,7 @@ use core::fmt; use core::mem::offset_of; -use core::ptr::copy_nonoverlapping; +use core::ptr::{self, copy_nonoverlapping}; use core::slice; #[doc(hidden)] @@ -124,6 +124,16 @@ impl ngx_str_t { core::str::from_utf8(self.as_bytes()).unwrap() } + /// Creates an empty `ngx_str_t` instance. + /// + /// This method replaces the `ngx_null_string` C macro. + pub const fn empty() -> Self { + ngx_str_t { + len: 0, + data: ptr::null_mut(), + } + } + /// Create an `ngx_str_t` instance from a byte slice. /// /// # Safety @@ -155,6 +165,12 @@ impl ngx_str_t { } } +impl Default for ngx_str_t { + fn default() -> Self { + Self::empty() + } +} + impl From for &[u8] { fn from(s: ngx_str_t) -> Self { if s.len == 0 || s.data.is_null() { @@ -196,13 +212,13 @@ impl ngx_module_t { Self { ctx_index: ngx_uint_t::MAX, index: ngx_uint_t::MAX, - name: core::ptr::null_mut(), + name: ptr::null_mut(), spare0: 0, spare1: 0, version: nginx_version as ngx_uint_t, signature: NGX_RS_MODULE_SIGNATURE.as_ptr(), - ctx: core::ptr::null_mut(), - commands: core::ptr::null_mut(), + ctx: ptr::null_mut(), + commands: ptr::null_mut(), type_: 0, init_master: None, init_module: None, diff --git a/src/core/mod.rs b/src/core/mod.rs index 7cb7868..2537a47 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -17,7 +17,7 @@ pub use string::*; macro_rules! ngx_null_command { () => { $crate::ffi::ngx_command_t { - name: $crate::ngx_null_string!(), + name: $crate::ffi::ngx_str_t::empty(), type_: 0, set: None, conf: 0, diff --git a/src/core/string.rs b/src/core/string.rs index 15e9a71..232e6ee 100644 --- a/src/core/string.rs +++ b/src/core/string.rs @@ -6,7 +6,7 @@ use alloc::{borrow::Cow, string::String}; #[cfg(feature = "std")] use std::{borrow::Cow, string::String}; -use crate::ffi::*; +use crate::ffi::{ngx_str_t, u_char}; /// Static string initializer for [`ngx_str_t`]. /// @@ -23,19 +23,6 @@ macro_rules! ngx_string { }}; } -/// Static empty string initializer for [`ngx_str_t`]. -/// -/// [`ngx_str_t`]: https://nginx.org/en/docs/dev/development_guide.html#string_overview -#[macro_export] -macro_rules! ngx_null_string { - () => { - $crate::ffi::ngx_str_t { - len: 0, - data: ::core::ptr::null_mut(), - } - }; -} - /// Representation of a borrowed [Nginx string]. /// /// [Nginx string]: https://nginx.org/en/docs/dev/development_guide.html#string_overview @@ -100,7 +87,7 @@ impl AsRef<[u8]> for NgxStr { impl Default for &NgxStr { fn default() -> Self { - // SAFETY: The null `ngx_str_t` is always a valid Nginx string. - unsafe { NgxStr::from_ngx_str(ngx_null_string!()) } + // SAFETY: The empty `ngx_str_t` is always a valid Nginx string. + unsafe { NgxStr::from_ngx_str(ngx_str_t::default()) } } } diff --git a/src/http/request.rs b/src/http/request.rs index c9af30c..f80d396 100644 --- a/src/http/request.rs +++ b/src/http/request.rs @@ -6,7 +6,6 @@ use core::str::FromStr; use crate::core::*; use crate::ffi::*; use crate::http::status::*; -use crate::ngx_null_string; /// Define a static request handler. /// @@ -229,7 +228,7 @@ impl Request { // SAFETY: `ngx_http_complex_value` does not mutate `r` or `val` and guarentees that // a valid Nginx string is stored in `value` if it successfully returns. unsafe { - let mut value = ngx_null_string!(); + let mut value = ngx_str_t::default(); if ngx_http_complex_value(r, val, &mut value) != NGX_OK as ngx_int_t { return None; } From fc93062c8c287d16a2ba959f14706352b725fc7c Mon Sep 17 00:00:00 2001 From: Aleksei Bavshin Date: Wed, 12 Feb 2025 16:48:12 -0800 Subject: [PATCH 3/3] refactor!: replace `ngx_null_command!` with `ngx_command_t::empty()` --- examples/async.rs | 4 ++-- examples/awssig.rs | 4 ++-- examples/curl.rs | 4 ++-- examples/upstream.rs | 7 ++----- nginx-sys/src/lib.rs | 19 +++++++++++++++++++ src/core/mod.rs | 19 ------------------- 6 files changed, 27 insertions(+), 30 deletions(-) diff --git a/examples/async.rs b/examples/async.rs index cc3c72c..ae27fec 100644 --- a/examples/async.rs +++ b/examples/async.rs @@ -12,7 +12,7 @@ use ngx::ffi::{ NGX_HTTP_LOC_CONF_OFFSET, NGX_HTTP_MODULE, }; use ngx::http::{self, HTTPModule, MergeConfigError}; -use ngx::{http_request_handler, ngx_log_debug_http, ngx_null_command, ngx_string}; +use ngx::{http_request_handler, ngx_log_debug_http, ngx_string}; use tokio::runtime::Runtime; struct Module; @@ -63,7 +63,7 @@ static mut NGX_HTTP_ASYNC_COMMANDS: [ngx_command_t; 2] = [ offset: 0, post: std::ptr::null_mut(), }, - ngx_null_command!(), + ngx_command_t::empty(), ]; static NGX_HTTP_ASYNC_MODULE_CTX: ngx_http_module_t = ngx_http_module_t { diff --git a/examples/awssig.rs b/examples/awssig.rs index bc99f02..49de0be 100644 --- a/examples/awssig.rs +++ b/examples/awssig.rs @@ -9,7 +9,7 @@ use ngx::ffi::{ NGX_HTTP_LOC_CONF, NGX_HTTP_LOC_CONF_OFFSET, NGX_HTTP_MODULE, NGX_HTTP_SRV_CONF, }; use ngx::http::*; -use ngx::{http_request_handler, ngx_log_debug_http, ngx_null_command, ngx_string}; +use ngx::{http_request_handler, ngx_log_debug_http, ngx_string}; struct Module; @@ -82,7 +82,7 @@ static mut NGX_HTTP_AWSSIGV4_COMMANDS: [ngx_command_t; 6] = [ offset: 0, post: std::ptr::null_mut(), }, - ngx_null_command!(), + ngx_command_t::empty(), ]; static NGX_HTTP_AWSSIGV4_MODULE_CTX: ngx_http_module_t = ngx_http_module_t { diff --git a/examples/curl.rs b/examples/curl.rs index 1e4521b..c3dd07b 100644 --- a/examples/curl.rs +++ b/examples/curl.rs @@ -8,7 +8,7 @@ use ngx::ffi::{ NGX_HTTP_LOC_CONF, NGX_HTTP_LOC_CONF_OFFSET, NGX_HTTP_MODULE, }; use ngx::http::{self, HTTPModule, MergeConfigError}; -use ngx::{http_request_handler, ngx_log_debug_http, ngx_null_command, ngx_string}; +use ngx::{http_request_handler, ngx_log_debug_http, ngx_string}; struct Module; @@ -45,7 +45,7 @@ static mut NGX_HTTP_CURL_COMMANDS: [ngx_command_t; 2] = [ offset: 0, post: std::ptr::null_mut(), }, - ngx_null_command!(), + ngx_command_t::empty(), ]; static NGX_HTTP_CURL_MODULE_CTX: ngx_http_module_t = ngx_http_module_t { diff --git a/examples/upstream.rs b/examples/upstream.rs index 1b701ac..c1a3d91 100644 --- a/examples/upstream.rs +++ b/examples/upstream.rs @@ -23,10 +23,7 @@ use ngx::http::{ ngx_http_conf_get_module_srv_conf, ngx_http_conf_upstream_srv_conf_immutable, ngx_http_conf_upstream_srv_conf_mutable, HTTPModule, Merge, MergeConfigError, Request, }; -use ngx::{ - http_upstream_init_peer_pt, ngx_conf_log_error, ngx_log_debug_http, ngx_log_debug_mask, ngx_null_command, - ngx_string, -}; +use ngx::{http_upstream_init_peer_pt, ngx_conf_log_error, ngx_log_debug_http, ngx_log_debug_mask, ngx_string}; #[derive(Clone, Copy, Debug)] #[repr(C)] @@ -97,7 +94,7 @@ static mut NGX_HTTP_UPSTREAM_CUSTOM_COMMANDS: [ngx_command_t; 2] = [ offset: 0, post: std::ptr::null_mut(), }, - ngx_null_command!(), + ngx_command_t::empty(), ]; // Generate the `ngx_modules` table with exported modules. diff --git a/nginx-sys/src/lib.rs b/nginx-sys/src/lib.rs index 3b22da8..9e2abd4 100644 --- a/nginx-sys/src/lib.rs +++ b/nginx-sys/src/lib.rs @@ -206,6 +206,25 @@ impl TryFrom for &str { } } +impl ngx_command_t { + /// Creates a new empty [`ngx_command_t`] instance. + /// + /// This method replaces the `ngx_null_command` C macro. This is typically used to terminate an + /// array of configuration directives. + /// + /// [`ngx_command_t`]: https://nginx.org/en/docs/dev/development_guide.html#config_directives + pub const fn empty() -> Self { + Self { + name: ngx_str_t::empty(), + type_: 0, + set: None, + conf: 0, + offset: 0, + post: ptr::null_mut(), + } + } +} + impl ngx_module_t { /// Create a new `ngx_module_t` instance with default values. pub const fn default() -> Self { diff --git a/src/core/mod.rs b/src/core/mod.rs index 2537a47..e1683a0 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -7,22 +7,3 @@ pub use buffer::*; pub use pool::*; pub use status::*; pub use string::*; - -/// Static empty configuration directive initializer for [`ngx_command_t`]. -/// -/// This is typically used to terminate an array of configuration directives. -/// -/// [`ngx_command_t`]: https://nginx.org/en/docs/dev/development_guide.html#config_directives -#[macro_export] -macro_rules! ngx_null_command { - () => { - $crate::ffi::ngx_command_t { - name: $crate::ffi::ngx_str_t::empty(), - type_: 0, - set: None, - conf: 0, - offset: 0, - post: ::core::ptr::null_mut(), - } - }; -}