Skip to content

Commit 3a1ce42

Browse files
committed
fix: use type-driven branch impl
1 parent 869e0d1 commit 3a1ce42

File tree

7 files changed

+181
-727
lines changed

7 files changed

+181
-727
lines changed

Cargo.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,16 @@ description = "Strict SNI validator for Nginx"
1111
crate-type = ["cdylib"]
1212

1313
[dependencies]
14-
ngx = { git = "https://github.com/JyJyJcr/ngx-rust",branch="integ_test" }
15-
#ngx = { path = "../ngx-rust"}
14+
ngx = { git = "https://github.com/JyJyJcr/ngx-rust",branch="nightly" }
15+
#ngx = { path = "../ngx-rust" , default-features = false, features=["std","vendored"] }
1616
fluent-uri = "0.3.2"
1717
bitflags = "2.6.0"
1818

1919

2020
[dev-dependencies]
2121
curl = "0.4.46"
22-
ngx = { git = "https://github.com/JyJyJcr/ngx-rust",branch="integ_test", features=["test_util"] }
22+
ngx = { git = "https://github.com/JyJyJcr/ngx-rust",branch="nightly", features=["test_util"] }
23+
#ngx = { path = "../ngx-rust" , default-features = false, features=["std","vendored", "test_util"] }
2324

2425
[package.metadata.deb]
2526
name = "libnginx-mod-http-ssl-strict-sni"

src/lib.rs

Lines changed: 139 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//#![no_std]
1+
//#![cfg_attr(not(test), no_std)]
22

33
mod logic;
44

@@ -7,38 +7,67 @@ mod ngx_ext;
77

88
mod util;
99

10-
use core::ptr::addr_of;
10+
use core::ffi::CStr;
1111
use core::ptr::addr_of_mut;
12+
1213
use logic::{Analysis, PostReadHandler, PreaccessHandler};
13-
use ngx::ffi::{ngx_conf_t, ngx_http_module_t, ngx_module_t, ngx_str_t};
14-
use ngx::http::MergeConfigError;
15-
use ngx::{core::Status, http};
16-
use ngx::{ngx_modules, ngx_string};
17-
use ngx_ext::http::variable::GetHook;
18-
use ngx_ext::http::{ngx_http_module_ctx, variable::VariableHook, LocCtx, MainCtx};
19-
use ngx_ext::http::{
20-
ConfInitManager, DefaultConfManager, NgxHttpModule, NgxHttpModuleImpl, SetHttpHandler,
14+
use ngx::ffi::{ngx_conf_t, ngx_str_t};
15+
use ngx::http::{
16+
ConfCreateError, ConfInitError, ConfigurationDelegate, DefaultMerge, HttpLocConf, HttpMainConf,
17+
InitConfSetting, Merge, MergeConfigError, NgxHttpModule, NgxHttpModuleCommands,
18+
NgxHttpModuleCommandsRefMut, SetHttpHandler,
19+
};
20+
use ngx::module::{
21+
Command, CommandArgFlag, CommandArgFlagSet, CommandContextFlag, CommandContextFlagSet,
22+
CommandError, NgxModuleCommandsBuilder,
23+
};
24+
use ngx::util::StaticRefMut;
25+
use ngx::{arg_flags, context_flags, ngx_string};
26+
use ngx::{
27+
exhibit_modules,
28+
http::{HttpModule, HttpModuleSkel},
2129
};
22-
use ngx_ext::{ngx_module, CommandArgFlag, CommandContextFlag, NgxCommand, NgxModule};
30+
use ngx_ext::http::variable::{GetHook, VariableHook};
2331

2432
// module exporter
2533
// this macro uses variable name directly.
26-
ngx_modules!(strict_sni_module);
34+
exhibit_modules!(HttpModuleSkel<StrictSniHttpModule>);
2735

28-
// so here we surpress non_upper_case warning.
29-
#[allow(non_upper_case_globals)]
30-
static mut strict_sni_module: ngx_module_t = ngx_module::<StrictSniModule>(
31-
unsafe { &mut *addr_of_mut!(STRICT_SNI_MODULE_CTX) },
32-
unsafe { (&mut *addr_of_mut!(STRICT_SNI_COMMAND_LIST)).ptr() },
33-
);
36+
struct StrictSniHttpModule;
3437

35-
struct StrictSniModule;
36-
impl NgxModule for StrictSniModule {
37-
type Impl = NgxHttpModule<StrictSniHttpModuleImpl>;
38+
impl HttpModule for StrictSniHttpModule {
39+
const SELF: StaticRefMut<NgxHttpModule<Self>> = {
40+
static mut MODULE: NgxHttpModule<StrictSniHttpModule> = NgxHttpModule::new();
41+
unsafe { StaticRefMut::from_mut(&mut *addr_of_mut!(MODULE)) }
42+
};
3843

39-
fn module() -> &'static ngx_module_t {
40-
unsafe { &*addr_of!(strict_sni_module) }
41-
}
44+
const NAME: &'static CStr = c"strict_sni_module";
45+
46+
const COMMANDS: NgxHttpModuleCommandsRefMut<Self> = {
47+
static mut COMMANDS: NgxHttpModuleCommands<StrictSniHttpModule, 3> =
48+
NgxModuleCommandsBuilder::new()
49+
.add::<StrictSniCommand>()
50+
.add::<DirectFilterCommand>()
51+
.build();
52+
unsafe { NgxHttpModuleCommandsRefMut::from_mut(&mut *addr_of_mut!(COMMANDS)) }
53+
};
54+
55+
type MasterInitializer = ();
56+
57+
type ModuleDelegate = ();
58+
59+
type ProcessDelegate = ();
60+
61+
type ThreadDelegate = ();
62+
63+
type PreConfiguration = ();
64+
65+
type PostConfiguration = StrictSniPostConfig;
66+
67+
type MainConfSetting = StrictSniMainConfManager;
68+
type SrvConfSetting = DefaultMerge<()>;
69+
type LocConfSetting = DefaultMerge<ValidationConfig>;
70+
type Ctx = Analysis;
4271
// fn init_module(cycle: &mut ngx_cycle_t) -> ngx_int_t {
4372
// ngx_log_debug!(cycle.log, "strict_sni module init_master called");
4473
// if !cycle.modules.is_null() {
@@ -67,55 +96,9 @@ impl NgxModule for StrictSniModule {
6796
// }
6897
}
6998

70-
command_list!(
71-
static mut STRICT_SNI_COMMAND_LIST: CommandList<StrictSniModule> =
72-
[StrictSniCommand, DirectFilterCommand];
73-
);
74-
75-
static mut STRICT_SNI_MODULE_CTX: ngx_http_module_t =
76-
ngx_http_module_ctx::<StrictSniHttpModuleImpl>();
77-
78-
#[derive(Debug)]
79-
struct StrictSniCommon {
80-
host: VariableHook,
81-
scheme: VariableHook,
82-
sni: VariableHook,
83-
}
84-
85-
//static MODULE_DATA: OnceLock<StrictSniCommon> = OnceLock::new();
86-
87-
struct StrictSniMainConfManager;
88-
impl ConfInitManager for StrictSniMainConfManager {
89-
type Conf = (Option<StrictSniCommon>, ValidationConfig);
90-
91-
fn create(_: &mut ngx_conf_t) -> Result<Self::Conf, ()> {
92-
Ok(Default::default())
93-
}
94-
95-
fn init(cf: &mut ngx_conf_t, (common, _): &mut Self::Conf) -> Result<(), ()> {
96-
let vr_host = cf.hook(&ngx_string!("host")).map_err(|_| ())?;
97-
let vr_scheme = cf.hook(&ngx_string!("scheme")).map_err(|_| ())?;
98-
let vr_sni = cf.hook(&ngx_string!("ssl_server_name")).map_err(|_| ())?;
99-
*common = Some(StrictSniCommon {
100-
host: vr_host,
101-
scheme: vr_scheme,
102-
sni: vr_sni,
103-
});
104-
Ok(())
105-
}
106-
}
107-
108-
struct StrictSniHttpModuleImpl;
109-
impl NgxHttpModuleImpl for StrictSniHttpModuleImpl {
110-
type Module = StrictSniModule;
111-
type MainConf = (Option<StrictSniCommon>, ValidationConfig);
112-
type SrvConf = ();
113-
type LocConf = ValidationConfig;
114-
type MainConfManager = StrictSniMainConfManager;
115-
type SrvConfManager = DefaultConfManager<()>;
116-
type LocConfManager = DefaultConfManager<Self::LocConf>;
117-
type Ctx = Analysis;
118-
fn postconfiguration(cf: &mut ngx_conf_t) -> Result<(), Status> {
99+
struct StrictSniPostConfig;
100+
impl ConfigurationDelegate for StrictSniPostConfig {
101+
fn configuration(cf: &mut ngx_conf_t) -> Result<(), ngx::core::Status> {
119102
// if let Some(log) = unsafe { cf.log.as_mut() } {
120103
// ngx_log_debug!(log, "strict_sni check pool");
121104
// if let Some(cy) = unsafe { cf.cycle.as_ref() } {
@@ -141,6 +124,36 @@ impl NgxHttpModuleImpl for StrictSniHttpModuleImpl {
141124
}
142125
}
143126

127+
#[derive(Debug)]
128+
struct StrictSniCommon {
129+
host: VariableHook,
130+
scheme: VariableHook,
131+
sni: VariableHook,
132+
}
133+
134+
struct StrictSniMainConfManager;
135+
impl InitConfSetting for StrictSniMainConfManager {
136+
type Conf = (Option<StrictSniCommon>, ValidationConfig);
137+
138+
fn create(_: &mut ngx_conf_t) -> Result<Self::Conf, ConfCreateError> {
139+
Ok(Default::default())
140+
}
141+
142+
fn init(cf: &mut ngx_conf_t, (common, _): &mut Self::Conf) -> Result<(), ConfInitError> {
143+
let vr_host = cf.hook(&ngx_string!("host")).map_err(|_| ConfInitError)?;
144+
let vr_scheme = cf.hook(&ngx_string!("scheme")).map_err(|_| ConfInitError)?;
145+
let vr_sni = cf
146+
.hook(&ngx_string!("ssl_server_name"))
147+
.map_err(|_| ConfInitError)?;
148+
*common = Some(StrictSniCommon {
149+
host: vr_host,
150+
scheme: vr_scheme,
151+
sni: vr_sni,
152+
});
153+
Ok(())
154+
}
155+
}
156+
144157
#[derive(Debug, Default)]
145158
struct ValidationConfig {
146159
rfc_mode: CheckSwitch<()>,
@@ -173,7 +186,7 @@ enum HostCheckRigor {
173186

174187
// }
175188

176-
impl http::Merge for ValidationConfig {
189+
impl Merge for ValidationConfig {
177190
fn merge(&mut self, prev: &ValidationConfig) -> Result<(), MergeConfigError> {
178191
if let CheckSwitch::Unset = self.rfc_mode {
179192
self.rfc_mode = prev.rfc_mode.clone();
@@ -189,19 +202,19 @@ impl http::Merge for ValidationConfig {
189202
}
190203

191204
struct StrictSniCommand;
192-
impl NgxCommand for StrictSniCommand {
193-
type Ctx = LocCtx<StrictSniHttpModuleImpl>;
205+
impl Command for StrictSniCommand {
206+
type CallRule = HttpLocConf<ValidationConfig>;
194207
const NAME: ngx_str_t = ngx_string!("strict_sni");
195208

196-
const CONTEXT_FLAG: ngx_ext::CommandContextFlag = {
197-
CommandContextFlag::Main
198-
.union(CommandContextFlag::Srv)
199-
.union(CommandContextFlag::Loc)
200-
};
209+
const CONTEXT_FLAG: CommandContextFlagSet = context_flags!(
210+
CommandContextFlag::HttpMain,
211+
CommandContextFlag::HttpSrv,
212+
CommandContextFlag::HttpLoc
213+
);
201214

202-
const ARG_FLAG: ngx_ext::CommandArgFlag = CommandArgFlag::Take1;
215+
const ARG_FLAG: CommandArgFlagSet = arg_flags!(CommandArgFlag::Take1);
203216

204-
fn handler(cf: &ngx_conf_t, conf: &mut ValidationConfig) -> Result<(), ()> {
217+
fn handler(cf: &mut ngx_conf_t, conf: &mut ValidationConfig) -> Result<(), CommandError> {
205218
if let Some(args) = unsafe { cf.args.as_ref() } {
206219
if let Some(ngx_arg) = unsafe { (args.elts as *mut ngx_str_t).add(1).as_ref() } {
207220
let arg = ngx_arg.to_str();
@@ -233,23 +246,23 @@ impl NgxCommand for StrictSniCommand {
233246
return Ok(());
234247
};
235248
}
236-
Err(())
249+
Err(CommandError)
237250
}
238251
}
239252

240253
struct DirectFilterCommand;
241-
impl NgxCommand for DirectFilterCommand {
242-
type Ctx = MainCtx<StrictSniHttpModuleImpl>;
254+
impl Command for DirectFilterCommand {
255+
type CallRule = HttpMainConf<(Option<StrictSniCommon>, ValidationConfig)>;
243256
const NAME: ngx_str_t = ngx_string!("strict_sni_direct_filter");
244257

245-
const CONTEXT_FLAG: ngx_ext::CommandContextFlag = { CommandContextFlag::Main };
258+
const CONTEXT_FLAG: CommandContextFlagSet = context_flags!(CommandContextFlag::HttpMain);
246259

247-
const ARG_FLAG: ngx_ext::CommandArgFlag = CommandArgFlag::Take1;
260+
const ARG_FLAG: CommandArgFlagSet = arg_flags!(CommandArgFlag::Take1);
248261

249262
fn handler(
250-
cf: &ngx_conf_t,
263+
cf: &mut ngx_conf_t,
251264
(_, conf): &mut (Option<StrictSniCommon>, ValidationConfig),
252-
) -> Result<(), ()> {
265+
) -> Result<(), CommandError> {
253266
if let Some(args) = unsafe { cf.args.as_ref() } {
254267
if let Some(ngx_arg) = unsafe { (args.elts as *mut ngx_str_t).add(1).as_ref() } {
255268
let arg = ngx_arg.to_str();
@@ -281,7 +294,7 @@ impl NgxCommand for DirectFilterCommand {
281294
return Ok(());
282295
};
283296
}
284-
Err(())
297+
Err(CommandError)
285298
}
286299
}
287300

@@ -299,3 +312,38 @@ impl NgxCommand for DirectFilterCommand {
299312
// unsafe { &*addr_of!(client_certificate_filter_module) }
300313
// }
301314
// }
315+
316+
// #[cfg(test)]
317+
// mod test {
318+
// use core::ptr::null_mut;
319+
320+
// struct A {
321+
// x: u32,
322+
// p: *mut u32,
323+
// }
324+
// const fn a() -> A {
325+
// let mut a = A {
326+
// x: 1,
327+
// p: null_mut(),
328+
// };
329+
// let p = unsafe { &raw mut AGLBL.x };
330+
// a.p = p;
331+
// a
332+
// }
333+
// static mut AGLBL: A = a();
334+
// #[test]
335+
// fn global_self_pointer_test() {
336+
// let a = &raw mut AGLBL;
337+
// let x = unsafe { &mut *a }.x;
338+
// let p = unsafe { &mut *a }.p;
339+
// println!("golbal mem {:?} self pointer {:?}", a, p);
340+
// println!("direct {:} indirect {:}", x, unsafe { *p });
341+
// }
342+
343+
// trait TT<X: 'static> {
344+
// const PTR: &'static mut X;
345+
// }
346+
// const fn resolve<X: 'static, T: TT<X>>() -> &'static mut X {
347+
// T::PTR
348+
// }
349+
// }

src/logic.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ use core::str::from_utf8;
1616

1717
use ngx::{
1818
core::Status,
19-
http::{HTTPStatus, Request},
19+
http::{HTTPStatus, HttpHandler, Phase, Request},
2020
ngx_log_debug_http,
2121
};
2222

2323
use crate::{
24-
ngx_ext::http::{request::RequestExt, variable::VariableHook, HttpHandler, Phase},
24+
ngx_ext::http::{request::RequestExt, variable::VariableHook},
2525
util::{parse_host_header, parse_request_line},
26-
CheckSwitch, HostCheckRigor, StrictSniCommon, StrictSniHttpModuleImpl, ValidationConfig,
26+
CheckSwitch, HostCheckRigor, StrictSniCommon, StrictSniHttpModule, ValidationConfig,
2727
};
2828

2929
pub(crate) struct PostReadHandler;
@@ -32,7 +32,7 @@ impl HttpHandler for PostReadHandler {
3232

3333
fn handle(request: &mut Request) -> Status {
3434
ngx_log_debug_http!(request, "strict_sni post_read_handler called");
35-
if let Some((common, main)) = request.main_conf::<StrictSniHttpModuleImpl>() {
35+
if let Some((common, main)) = request.main_conf::<StrictSniHttpModule>() {
3636
ngx_log_debug_http!(request, "strict_sni main config: {:?}", main);
3737
if let Some(common) = common {
3838
ngx_log_debug_http!(request, "strict_sni common: {:?}", common);
@@ -43,7 +43,7 @@ impl HttpHandler for PostReadHandler {
4343
let po = pool.allocate(analysis);
4444
if let Some(analysis) = unsafe { po.as_ref() } {
4545
ngx_log_debug_http!(request, "strict_sni pool alloc succ");
46-
request.set_ctx::<StrictSniHttpModuleImpl>(analysis);
46+
request.set_ctx::<StrictSniHttpModule>(analysis);
4747
let val: Validator = main.into();
4848
return match val.validate(request, analysis) {
4949
Ok(()) => Status::NGX_DECLINED,
@@ -73,9 +73,9 @@ impl HttpHandler for PreaccessHandler {
7373
fn handle(request: &mut Request) -> Status {
7474
ngx_log_debug_http!(request, "strict_sni preaccess_handler called");
7575

76-
if let Some(config) = request.loc_conf::<StrictSniHttpModuleImpl>() {
76+
if let Some(config) = request.loc_conf::<StrictSniHttpModule>() {
7777
ngx_log_debug_http!(request, "strict_sni config: {:?}", config);
78-
if let Some(analysis) = request.get_ctx::<StrictSniHttpModuleImpl>() {
78+
if let Some(analysis) = request.get_ctx::<StrictSniHttpModule>() {
7979
ngx_log_debug_http!(request, "strict_sni analysis: {:?}", analysis);
8080
//request.set_ctx::<StrictSniHttpModule>(an);
8181

0 commit comments

Comments
 (0)