Fix ngx 0.5.0 API compatibility
- Update HttpModule trait implementation to match ngx 0.5.0 API - Implement HttpModuleLocationConf as separate unsafe trait - Fix configuration access using Module::location_conf() - Replace ngx_null_command macro with explicit null command - Update imports to use correct constant names - Suppress C FFI naming convention warnings
This commit is contained in:
1
.cursorrules
Normal file
1
.cursorrules
Normal file
@ -0,0 +1 @@
|
||||
- Always use `direnv exec "$PWD"` when invoking cargo and other tools that need access to the nix/direnv environment
|
||||
4
.envrc
4
.envrc
@ -1,5 +1,7 @@
|
||||
use flake
|
||||
unset TMPDIR
|
||||
export NGINX_SOURCE_DIR=$PWD/ngx_src/nginx-1.28.0
|
||||
export NGINX_SOURCE_DIR=$PWD/ngx_src/nginx-1.28.0/
|
||||
export NGINX_BUILD_DIR=$PWD/ngx_src/nginx-1.28.0/objs/
|
||||
export ZLIB_VERSION=1.3.1
|
||||
export NGX_VERSION=1.28.0
|
||||
export CFLAGS='-Wno-unterminated-string-initialization'
|
||||
|
||||
116
.idea/workspace.xml
generated
Normal file
116
.idea/workspace.xml
generated
Normal file
@ -0,0 +1,116 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AutoImportSettings">
|
||||
<option name="autoReloadType" value="SELECTIVE" />
|
||||
</component>
|
||||
<component name="CargoProjects">
|
||||
<cargoProject FILE="$PROJECT_DIR$/Cargo.toml" />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="082e38d9-eb7e-4f8e-b3a3-6d5c499efa60" name="Changes" comment="">
|
||||
<change beforePath="$PROJECT_DIR$/runit" beforeDir="false" afterPath="$PROJECT_DIR$/runit" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="Git.Settings">
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="MacroExpansionManager">
|
||||
<option name="directoryName" value="3nobPjdc" />
|
||||
</component>
|
||||
<component name="ProjectCodeStyleSettingsMigration">
|
||||
<option name="version" value="2" />
|
||||
</component>
|
||||
<component name="ProjectColorInfo">{
|
||||
"associatedIndex": 4
|
||||
}</component>
|
||||
<component name="ProjectId" id="35X1zv6pKATZ3MYZz7k7SnGMlTz" />
|
||||
<component name="ProjectViewState">
|
||||
<option name="autoscrollFromSource" value="true" />
|
||||
<option name="hideEmptyMiddlePackages" value="true" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent"><![CDATA[{
|
||||
"keyToString": {
|
||||
"NIXITCH_NIXPKGS_CONFIG": "",
|
||||
"NIXITCH_NIX_CONF_DIR": "",
|
||||
"NIXITCH_NIX_OTHER_STORES": "",
|
||||
"NIXITCH_NIX_PATH": "",
|
||||
"NIXITCH_NIX_PROFILES": "",
|
||||
"NIXITCH_NIX_REMOTE": "",
|
||||
"NIXITCH_NIX_USER_PROFILE_DIR": "",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"RunOnceActivity.git.unshallow": "true",
|
||||
"kotlin-language-version-configured": "true",
|
||||
"last_opened_file_path": "/Users/edwlan/nginx-test",
|
||||
"node.js.detected.package.eslint": "true",
|
||||
"node.js.detected.package.tslint": "true",
|
||||
"node.js.selected.package.eslint": "(autodetect)",
|
||||
"node.js.selected.package.tslint": "(autodetect)",
|
||||
"nodejs_package_manager_path": "npm",
|
||||
"org.rust.cargo.project.model.PROJECT_DISCOVERY": "true",
|
||||
"org.rust.cargo.project.model.impl.CargoExternalSystemProjectAware.subscribe.first.balloon": "",
|
||||
"project.structure.last.edited": "Artifacts",
|
||||
"project.structure.proportion": "0.15",
|
||||
"project.structure.side.proportion": "0.2",
|
||||
"settings.editor.selected.configurable": "preferences.pluginManager",
|
||||
"vue.rearranger.settings.migration": "true"
|
||||
}
|
||||
}]]></component>
|
||||
<component name="RunManager">
|
||||
<configuration default="true" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
|
||||
<option name="command" value="run" />
|
||||
<envs />
|
||||
<option name="emulateTerminal" value="true" />
|
||||
<option name="channel" value="DEFAULT" />
|
||||
<option name="requiredFeatures" value="true" />
|
||||
<option name="allFeatures" value="false" />
|
||||
<option name="withSudo" value="false" />
|
||||
<option name="buildTarget" value="REMOTE" />
|
||||
<option name="backtrace" value="SHORT" />
|
||||
<option name="isRedirectInput" value="false" />
|
||||
<option name="redirectInputPath" value="" />
|
||||
<method v="2">
|
||||
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
<component name="RustProjectSettings">
|
||||
<option name="toolchainHomeDirectory" value="$PROJECT_DIR$/../.cargo/bin" />
|
||||
</component>
|
||||
<component name="SharedIndexes">
|
||||
<attachedChunks>
|
||||
<set>
|
||||
<option value="bundled-jdk-9823dce3aa75-fdfe4dae3a2d-intellij.indexing.shared.core-IU-243.21565.193" />
|
||||
<option value="bundled-js-predefined-d6986cc7102b-e768b9ed790e-JavaScript-IU-243.21565.193" />
|
||||
</set>
|
||||
</attachedChunks>
|
||||
</component>
|
||||
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
|
||||
<component name="SwiftWorkspaceSettings">
|
||||
<option name="detectedToolchain" value="true" />
|
||||
<option name="toolchainPathValue" value="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain" />
|
||||
</component>
|
||||
<component name="TaskManager">
|
||||
<task active="true" id="Default" summary="Default task">
|
||||
<changelist id="082e38d9-eb7e-4f8e-b3a3-6d5c499efa60" name="Changes" comment="" />
|
||||
<created>1763241867264</created>
|
||||
<option name="number" value="Default" />
|
||||
<option name="presentableId" value="Default" />
|
||||
<updated>1763241867264</updated>
|
||||
<workItem from="1763241868325" duration="59000" />
|
||||
<workItem from="1763241931565" duration="328000" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
<option name="version" value="3" />
|
||||
</component>
|
||||
<component name="XSLT-Support.FileAssociations.UIState">
|
||||
<expand />
|
||||
<select />
|
||||
</component>
|
||||
</project>
|
||||
844
Cargo.lock
generated
844
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -7,7 +7,7 @@ edition = "2024"
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
ngx = "0.4.1"
|
||||
ngx = "0.5.0"
|
||||
rusqlite = "0.37.0"
|
||||
handlebars = "6.3.2"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
# Add the path to your library here.
|
||||
load_module target/debug/libnginx_test.so;
|
||||
load_module target/debug/libnginx_test.dylib;
|
||||
|
||||
worker_processes 1;
|
||||
|
||||
|
||||
2
runit
2
runit
@ -1,4 +1,4 @@
|
||||
/home/edwlan/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/.cache/nginx/1.23.3/linux-x86_64/sbin/nginx \
|
||||
./ngx_src/nginx-1.28.0/objs/nginx \
|
||||
-e /dev/stdout \
|
||||
-p "$PWD" \
|
||||
-c conf/howto.conf \
|
||||
|
||||
71
src/lib.rs
71
src/lib.rs
@ -1,15 +1,16 @@
|
||||
use handlebars::Handlebars;
|
||||
use ngx::core::Buffer;
|
||||
use ngx::ffi::{
|
||||
NGX_CONF_TAKE1, NGX_HTTP_LOC_CONF, NGX_HTTP_MODULE, NGX_RS_HTTP_LOC_CONF_OFFSET,
|
||||
NGX_CONF_TAKE1, NGX_HTTP_LOC_CONF, NGX_HTTP_MODULE, NGX_HTTP_LOC_CONF_OFFSET,
|
||||
NGX_RS_MODULE_SIGNATURE, nginx_version, ngx_array_push, ngx_chain_t, ngx_command_t,
|
||||
ngx_conf_t, ngx_http_core_module, ngx_http_handler_pt,
|
||||
ngx_http_module_t, ngx_http_phases_NGX_HTTP_ACCESS_PHASE, ngx_http_request_t, ngx_int_t,
|
||||
ngx_module_t, ngx_str_t, ngx_uint_t,
|
||||
ngx_conf_t, ngx_http_handler_pt, ngx_http_module_t,
|
||||
ngx_http_phases_NGX_HTTP_ACCESS_PHASE, ngx_int_t, ngx_module_t, ngx_str_t, ngx_uint_t,
|
||||
};
|
||||
use ngx::http::{
|
||||
HttpModule, HttpModuleLocationConf, HttpModuleMainConf, MergeConfigError, NgxHttpCoreModule,
|
||||
};
|
||||
use ngx::http::{HTTPModule, MergeConfigError};
|
||||
use ngx::{core, core::Status, http};
|
||||
use ngx::{http_request_handler, ngx_log_debug_http, ngx_modules, ngx_null_command, ngx_string};
|
||||
use ngx::{http_request_handler, ngx_log_debug_http, ngx_modules, ngx_string};
|
||||
use rusqlite::{Connection, Result};
|
||||
use serde_json::json;
|
||||
use std::os::raw::{c_char, c_void};
|
||||
@ -17,19 +18,20 @@ use std::ptr::addr_of;
|
||||
|
||||
struct Module;
|
||||
|
||||
// Implement our HTTPModule trait, we're creating a postconfiguration method to install our
|
||||
// Implement our HttpModule trait, we're creating a postconfiguration method to install our
|
||||
// handler's Access phase function.
|
||||
impl http::HTTPModule for Module {
|
||||
type MainConf = ();
|
||||
type SrvConf = ();
|
||||
type LocConf = ModuleConfig;
|
||||
impl http::HttpModule for Module {
|
||||
fn module() -> &'static ngx_module_t {
|
||||
unsafe { &*addr_of!(ngx_http_howto_module) }
|
||||
}
|
||||
|
||||
unsafe extern "C" fn postconfiguration(cf: *mut ngx_conf_t) -> ngx_int_t {
|
||||
unsafe {
|
||||
let htcf = http::ngx_http_conf_get_module_main_conf(cf, &*addr_of!(ngx_http_core_module));
|
||||
let htcf =
|
||||
NgxHttpCoreModule::main_conf_mut(&*cf).expect("failed to get core main conf");
|
||||
|
||||
let h = ngx_array_push(
|
||||
&mut (*htcf).phases[ngx_http_phases_NGX_HTTP_ACCESS_PHASE as usize].handlers,
|
||||
&mut htcf.phases[ngx_http_phases_NGX_HTTP_ACCESS_PHASE as usize].handlers,
|
||||
) as *mut ngx_http_handler_pt;
|
||||
if h.is_null() {
|
||||
return core::Status::NGX_ERROR.into();
|
||||
@ -42,6 +44,11 @@ impl http::HTTPModule for Module {
|
||||
}
|
||||
}
|
||||
|
||||
// Implement HttpModuleLocationConf to define our location-specific configuration
|
||||
unsafe impl HttpModuleLocationConf for Module {
|
||||
type LocationConf = ModuleConfig;
|
||||
}
|
||||
|
||||
// Create a ModuleConfig to save our configuration state.
|
||||
#[derive(Debug, Default)]
|
||||
struct ModuleConfig {
|
||||
@ -70,15 +77,16 @@ impl http::Merge for ModuleConfig {
|
||||
}
|
||||
|
||||
// Create our "C" module context with function entrypoints for NGINX event loop. This "binds" our
|
||||
// HTTPModule implementation to functions callable from C.
|
||||
// HttpModule implementation to functions callable from C.
|
||||
#[unsafe(no_mangle)]
|
||||
#[allow(non_upper_case_globals)]
|
||||
static ngx_http_howto_module_ctx: ngx_http_module_t = ngx_http_module_t {
|
||||
preconfiguration: Some(Module::preconfiguration),
|
||||
postconfiguration: Some(Module::postconfiguration),
|
||||
create_main_conf: Some(Module::create_main_conf),
|
||||
init_main_conf: Some(Module::init_main_conf),
|
||||
create_srv_conf: Some(Module::create_srv_conf),
|
||||
merge_srv_conf: Some(Module::merge_srv_conf),
|
||||
create_main_conf: None,
|
||||
init_main_conf: None,
|
||||
create_srv_conf: None,
|
||||
merge_srv_conf: None,
|
||||
create_loc_conf: Some(Module::create_loc_conf),
|
||||
merge_loc_conf: Some(Module::merge_loc_conf),
|
||||
};
|
||||
@ -89,6 +97,7 @@ static ngx_http_howto_module_ctx: ngx_http_module_t = ngx_http_module_t {
|
||||
ngx_modules!(ngx_http_howto_module);
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
#[allow(non_upper_case_globals)]
|
||||
pub static mut ngx_http_howto_module: ngx_module_t = ngx_module_t {
|
||||
ctx_index: ngx_uint_t::max_value(),
|
||||
index: ngx_uint_t::max_value(),
|
||||
@ -121,14 +130,15 @@ pub static mut ngx_http_howto_module: ngx_module_t = ngx_module_t {
|
||||
};
|
||||
|
||||
// Register and allocate our command structures for directive generation and eventual storage. Be
|
||||
// sure to terminate the array with the ngx_null_command! macro.
|
||||
// sure to terminate the array with an empty command.
|
||||
#[unsafe(no_mangle)]
|
||||
#[allow(non_upper_case_globals)]
|
||||
static mut ngx_http_howto_commands: [ngx_command_t; 4] = [
|
||||
ngx_command_t {
|
||||
name: ngx_string!("sqlite_db"),
|
||||
type_: (NGX_HTTP_LOC_CONF | NGX_CONF_TAKE1) as ngx_uint_t,
|
||||
set: Some(ngx_http_howto_commands_set_db_path),
|
||||
conf: NGX_RS_HTTP_LOC_CONF_OFFSET,
|
||||
conf: NGX_HTTP_LOC_CONF_OFFSET,
|
||||
offset: 0,
|
||||
post: std::ptr::null_mut(),
|
||||
},
|
||||
@ -136,7 +146,7 @@ static mut ngx_http_howto_commands: [ngx_command_t; 4] = [
|
||||
name: ngx_string!("sqlite_query"),
|
||||
type_: (NGX_HTTP_LOC_CONF | NGX_CONF_TAKE1) as ngx_uint_t,
|
||||
set: Some(ngx_http_howto_commands_set_query),
|
||||
conf: NGX_RS_HTTP_LOC_CONF_OFFSET,
|
||||
conf: NGX_HTTP_LOC_CONF_OFFSET,
|
||||
offset: 0,
|
||||
post: std::ptr::null_mut(),
|
||||
},
|
||||
@ -144,11 +154,21 @@ static mut ngx_http_howto_commands: [ngx_command_t; 4] = [
|
||||
name: ngx_string!("sqlite_template"),
|
||||
type_: (NGX_HTTP_LOC_CONF | NGX_CONF_TAKE1) as ngx_uint_t,
|
||||
set: Some(ngx_http_howto_commands_set_template_path),
|
||||
conf: NGX_RS_HTTP_LOC_CONF_OFFSET,
|
||||
conf: NGX_HTTP_LOC_CONF_OFFSET,
|
||||
offset: 0,
|
||||
post: std::ptr::null_mut(),
|
||||
},
|
||||
ngx_command_t {
|
||||
name: ngx_str_t {
|
||||
len: 0,
|
||||
data: std::ptr::null_mut(),
|
||||
},
|
||||
type_: 0,
|
||||
set: None,
|
||||
conf: 0,
|
||||
offset: 0,
|
||||
post: std::ptr::null_mut(),
|
||||
},
|
||||
ngx_null_command!(),
|
||||
];
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
@ -242,10 +262,7 @@ fn execute_query(db_path: &str, query: &str) -> Result<Vec<std::collections::Has
|
||||
//
|
||||
// The function body is implemented as a Rust closure.
|
||||
http_request_handler!(howto_access_handler, |request: &mut http::Request| {
|
||||
let co = unsafe {
|
||||
request.get_module_loc_conf::<ModuleConfig>(&*addr_of!(ngx_http_howto_module))
|
||||
};
|
||||
let co = co.expect("module config is none");
|
||||
let co = Module::location_conf(request).expect("module config is none");
|
||||
|
||||
// Check if all required config values are set
|
||||
if co.db_path.is_empty() || co.query.is_empty() || co.template_path.is_empty() {
|
||||
|
||||
Reference in New Issue
Block a user