mesozoa/apache/src/lib.rs

76 lines
2.5 KiB
Rust

extern crate apache_rs;
use apache_rs::ffi::bindgen::{
APR_HOOK_MIDDLE, DECLINED, MODULE_MAGIC_COOKIE, MODULE_MAGIC_NUMBER_MAJOR, MODULE_MAGIC_NUMBER_MINOR, OK, ap_get_module_config, ap_hook_handler, ap_malloc, ap_rprintf, ap_set_content_type, apr_dbm_store, apr_palloc, apr_pool_t, command_struct, module, request_rec, server_rec, strcmp
};
use std::{
convert::TryInto, ffi::{CStr, CString}, os::raw::{c_int, c_void}, str::FromStr, sync::atomic::AtomicU64
};
#[unsafe(no_mangle)]
pub static mut mesozoa_module: module = module {
version: MODULE_MAGIC_NUMBER_MAJOR,
minor_version: MODULE_MAGIC_NUMBER_MINOR,
module_index: -1,
name: c"mod_mesozoa".as_ptr(),
dynamic_load_handle: 0 as *mut c_void,
next: 0 as *mut module,
magic: MODULE_MAGIC_COOKIE as u64,
rewrite_args: None,
create_dir_config: None,
merge_dir_config: None,
create_server_config: Some(c_mesozoa_create_server_config),
merge_server_config: None,
flags: 0,
cmds: 0 as *mut command_struct,
register_hooks: Some(c_mesozoa_hooks),
};
extern "C" fn c_mesozoa_hooks(_: *mut apr_pool_t) {
unsafe {
ap_hook_handler(
Some(c_mesozoa_handler),
std::ptr::null(),
std::ptr::null(),
APR_HOOK_MIDDLE.try_into().unwrap(),
);
};
}
struct ServerConfig {
counter: AtomicU64
}
unsafe extern "C" fn c_mesozoa_create_server_config(pool: *mut apr_pool_t, rec: *mut server_rec) -> *mut c_void {
println!("Create server config");
//let config = Box::leak(Box::new(ServerConfig{}));
let config = unsafe {apr_palloc(pool, core::mem::size_of::<ServerConfig>())} as *mut ServerConfig;
unsafe {&mut *config}.counter = AtomicU64::new(100);
/*Box::into_raw(Box::new(ServerConfig{
counter: AtomicU64::new(100),
})) as *mut c_void*/
config as *mut c_void
}
unsafe extern "C" fn c_mesozoa_handler(r: *mut request_rec) -> c_int {
if (unsafe {*r}).handler == std::ptr::null() || unsafe {strcmp((*r).handler, c"mesozoa-handler".as_ptr())} != 0 {
return DECLINED;
}
let config = unsafe {&*(ap_get_module_config((*(*r).server).module_config, &raw const mesozoa_module) as *const ServerConfig)};
let uri = unsafe{CStr::from_ptr((*r).uri)};
// problème : la mémoire est reset aléatoirement !
// trouver comment avoir une mémoire persistante. (mmap ?)
let content = CString::from_str(&format!("Count: {}\nURI: {:?}", config.counter.fetch_add(1, std::sync::atomic::Ordering::Relaxed), uri)).unwrap();
unsafe {
ap_set_content_type(r, c"text/html; charset=utf-8".as_ptr());
ap_rprintf(r, content.as_ptr());
}
return OK;
}