Description
There's a certain unsafe pattern that is repeated in most of the examples:
let co = unsafe { request.get_module_loc_conf::<ModuleConfig>(&*addr_of!(ngx_http_curl_module)) };
let co = co.expect("module config is none");
The problems here are:
ngx_http_curl_module
is a global mutable static, requiringunsafe
for any access.- Nothing guarantees that the type requested matches an actual type allocated for the module config.
Something we can optimize here is to tie config type to a context type and to a module ptr, and hide most of the unsafe details from end user.
E.g.
impl HttpLocationConf for ngx_http_core_module_t {
type ConfType = ngx_http_core_loc_conf_t;
fn module() -> &'static ngx_module_t { unsafe { &*addr_of!(ngx_http_core_module) } }
}
fn get_loc_conf<T: HttpLocationConf>(req) -> <T as HttpLocationConf>::ConfType;
req.get_loc_conf::<ngx_http_core_module_t>().ok_or(...)?;
or with an opposite direction of the mapping
impl HttpModuleConf for ngx_http_core_loc_conf_t {
const CONTEXT: &HttpModuleConfType = HttpModuleConfType::Location;
fn module() -> &'static ngx_module_t { unsafe { &*addr_of!(ngx_http_core_module) } }
}
fn get_conf<T: HttpModuleConf>(req) -> &T;
req.get_conf::<ngx_http_core_loc_conf_t>().ok_or(...)?;
Extending the ngx::http::module::HTTPModule
trait is also a viable option.
An important thing to consider is that the module configs can be obtained from ngx_cycle_t
, ngx_conf_t
, ngx_http_request_t
or ngx_http_upstream_t
objects and all of those should provide safe accessors.