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::())} 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; }