Skip to content

Commit 82b683d

Browse files
committed
refactor: use foreign-type for request
1 parent 54b7316 commit 82b683d

File tree

6 files changed

+84
-60
lines changed

6 files changed

+84
-60
lines changed

Cargo.lock

Lines changed: 28 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ targets = []
3939
[dependencies]
4040
allocator-api2 = { version = "0.2.21", default-features = false }
4141
async-task = { version = "4.7.1", optional = true }
42+
foreign-types = "0.5.0"
4243
lock_api = "0.4.13"
4344
nginx-sys = { path = "nginx-sys", version = "0.5.0-beta"}
4445
pin-project-lite = { version = "0.2.16", optional = true }

examples/async.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::sync::atomic::{AtomicBool, AtomicPtr, Ordering};
44
use std::sync::{Arc, OnceLock};
55
use std::time::Instant;
66

7-
use ngx::core;
7+
use ngx::core::{self, ForeignTypeRef};
88
use ngx::ffi::{
99
ngx_array_push, ngx_command_t, ngx_conf_t, ngx_connection_t, ngx_event_t, ngx_http_handler_pt,
1010
ngx_http_module_t, ngx_http_phases_NGX_HTTP_ACCESS_PHASE, ngx_int_t, ngx_module_t,
@@ -171,7 +171,7 @@ http_request_handler!(async_access_handler, |request: &mut http::Request| {
171171
unsafe { ngx_post_event(&mut ctx.event, addr_of_mut!(ngx_posted_next_events)) };
172172

173173
// Request is no longer needed and can be converted to something movable to the async block
174-
let req = AtomicPtr::new(request.into());
174+
let req = AtomicPtr::new(request.as_ptr());
175175
let done_flag = ctx.done.clone();
176176

177177
let rt = ngx_http_async_runtime();

examples/upstream.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
use std::ffi::{c_char, c_void};
1010
use std::mem;
1111

12-
use ngx::core::{Pool, Status};
12+
use ngx::core::{ForeignTypeRef, Pool, Status};
1313
use ngx::ffi::{
1414
ngx_atoi, ngx_command_t, ngx_conf_t, ngx_connection_t, ngx_event_free_peer_pt,
1515
ngx_event_get_peer_pt, ngx_http_module_t, ngx_http_upstream_init_peer_pt,
@@ -133,7 +133,7 @@ http_upstream_init_peer_pt!(
133133
};
134134

135135
let original_init_peer = hccf.original_init_peer.unwrap();
136-
if unsafe { original_init_peer(request.into(), us) != Status::NGX_OK.into() } {
136+
if unsafe { original_init_peer(request.as_ptr(), us) != Status::NGX_OK.into() } {
137137
return Status::NGX_ERROR;
138138
}
139139

src/core/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ pub use slab::SlabPool;
1010
pub use status::*;
1111
pub use string::*;
1212

13+
pub use foreign_types::ForeignTypeRef;
14+
1315
/// Gets an outer object pointer from a pointer to one of its fields.
1416
/// While there is no corresponding C macro, the pattern is common in the NGINX source.
1517
///

src/http/request.rs

Lines changed: 49 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -89,31 +89,10 @@ macro_rules! http_variable_get {
8989
/// requests.
9090
///
9191
/// See <https://nginx.org/en/docs/dev/development_guide.html#http_request>
92-
#[repr(transparent)]
93-
pub struct Request(ngx_http_request_t);
92+
pub struct Request(foreign_types::Opaque);
9493

95-
impl<'a> From<&'a Request> for *const ngx_http_request_t {
96-
fn from(request: &'a Request) -> Self {
97-
&request.0 as *const _
98-
}
99-
}
100-
101-
impl<'a> From<&'a mut Request> for *mut ngx_http_request_t {
102-
fn from(request: &'a mut Request) -> Self {
103-
&request.0 as *const _ as *mut _
104-
}
105-
}
106-
107-
impl AsRef<ngx_http_request_t> for Request {
108-
fn as_ref(&self) -> &ngx_http_request_t {
109-
&self.0
110-
}
111-
}
112-
113-
impl AsMut<ngx_http_request_t> for Request {
114-
fn as_mut(&mut self) -> &mut ngx_http_request_t {
115-
&mut self.0
116-
}
94+
unsafe impl foreign_types::ForeignTypeRef for Request {
95+
type CType = ngx_http_request_t;
11796
}
11897

11998
impl Request {
@@ -123,20 +102,30 @@ impl Request {
123102
///
124103
/// The caller has provided a valid non-null pointer to a valid `ngx_http_request_t`
125104
/// which shares the same representation as `Request`.
105+
#[inline]
126106
pub unsafe fn from_ngx_http_request<'a>(r: *mut ngx_http_request_t) -> &'a mut Request {
127-
&mut *r.cast::<Request>()
107+
ForeignTypeRef::from_ptr_mut(r)
108+
}
109+
110+
#[inline]
111+
fn inner(&self) -> &ngx_http_request_t {
112+
unsafe { &*self.as_ptr() }
113+
}
114+
#[inline]
115+
fn inner_mut(&mut self) -> &mut ngx_http_request_t {
116+
unsafe { &mut *self.as_ptr() }
128117
}
129118

130119
/// Is this the main request (as opposed to a subrequest)?
131120
pub fn is_main(&self) -> bool {
132-
let main = self.0.main.cast();
121+
let main = self.inner().main.cast();
133122
core::ptr::eq(self, main)
134123
}
135124

136125
/// Request pool.
137126
pub fn pool(&self) -> Pool {
138127
// SAFETY: This request is allocated from `pool`, thus must be a valid pool.
139-
unsafe { Pool::from_ngx_pool(self.0.pool) }
128+
unsafe { Pool::from_ngx_pool(self.inner().pool) }
140129
}
141130

142131
/// Returns the result as an `Option` if it exists, otherwise `None`.
@@ -147,17 +136,17 @@ impl Request {
147136
/// [`ngx_http_upstream_t`] is best described in
148137
/// <https://nginx.org/en/docs/dev/development_guide.html#http_load_balancing>
149138
pub fn upstream(&self) -> Option<*mut ngx_http_upstream_t> {
150-
if self.0.upstream.is_null() {
139+
if self.inner().upstream.is_null() {
151140
return None;
152141
}
153-
Some(self.0.upstream)
142+
Some(self.inner().upstream)
154143
}
155144

156145
/// Pointer to a [`ngx_connection_t`] client connection object.
157146
///
158147
/// [`ngx_connection_t`]: https://nginx.org/en/docs/dev/development_guide.html#connection
159148
pub fn connection(&self) -> *mut ngx_connection_t {
160-
self.0.connection
149+
self.inner().connection
161150
}
162151

163152
/// Pointer to a [`ngx_log_t`].
@@ -169,7 +158,7 @@ impl Request {
169158

170159
/// Get Module context pointer
171160
fn get_module_ctx_ptr(&self, module: &ngx_module_t) -> *mut c_void {
172-
unsafe { *self.0.ctx.add(module.ctx_index) }
161+
unsafe { *self.inner().ctx.add(module.ctx_index) }
173162
}
174163

175164
/// Get Module context
@@ -183,9 +172,9 @@ impl Request {
183172
/// Sets the value as the module's context.
184173
///
185174
/// See <https://nginx.org/en/docs/dev/development_guide.html#http_request>
186-
pub fn set_module_ctx(&self, value: *mut c_void, module: &ngx_module_t) {
175+
pub fn set_module_ctx(&mut self, value: *mut c_void, module: &ngx_module_t) {
187176
unsafe {
188-
*self.0.ctx.add(module.ctx_index) = value;
177+
*self.inner_mut().ctx.add(module.ctx_index) = value;
189178
};
190179
}
191180

@@ -210,77 +199,81 @@ impl Request {
210199
///
211200
/// [request body]: https://nginx.org/en/docs/dev/development_guide.html#http_request_body
212201
pub fn discard_request_body(&mut self) -> Status {
213-
unsafe { Status(ngx_http_discard_request_body(&mut self.0)) }
202+
unsafe { Status(ngx_http_discard_request_body(self.as_ptr())) }
214203
}
215204

216205
/// Client HTTP [User-Agent].
217206
///
218207
/// [User-Agent]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent
219208
pub fn user_agent(&self) -> Option<&NgxStr> {
220-
if !self.0.headers_in.user_agent.is_null() {
221-
unsafe { Some(NgxStr::from_ngx_str((*self.0.headers_in.user_agent).value)) }
209+
if !self.inner().headers_in.user_agent.is_null() {
210+
unsafe {
211+
Some(NgxStr::from_ngx_str(
212+
(*self.inner().headers_in.user_agent).value,
213+
))
214+
}
222215
} else {
223216
None
224217
}
225218
}
226219

227220
/// Set HTTP status of response.
228221
pub fn set_status(&mut self, status: HTTPStatus) {
229-
self.0.headers_out.status = status.into();
222+
self.inner_mut().headers_out.status = status.into();
230223
}
231224

232225
/// Add header to the `headers_in` object.
233226
///
234227
/// See <https://nginx.org/en/docs/dev/development_guide.html#http_request>
235228
pub fn add_header_in(&mut self, key: &str, value: &str) -> Option<()> {
236229
let table: *mut ngx_table_elt_t =
237-
unsafe { ngx_list_push(&mut self.0.headers_in.headers) as _ };
238-
unsafe { add_to_ngx_table(table, self.0.pool, key, value) }
230+
unsafe { ngx_list_push(&mut self.inner_mut().headers_in.headers) as _ };
231+
unsafe { add_to_ngx_table(table, self.inner().pool, key, value) }
239232
}
240233

241234
/// Add header to the `headers_out` object.
242235
///
243236
/// See <https://nginx.org/en/docs/dev/development_guide.html#http_request>
244237
pub fn add_header_out(&mut self, key: &str, value: &str) -> Option<()> {
245238
let table: *mut ngx_table_elt_t =
246-
unsafe { ngx_list_push(&mut self.0.headers_out.headers) as _ };
247-
unsafe { add_to_ngx_table(table, self.0.pool, key, value) }
239+
unsafe { ngx_list_push(&mut self.inner_mut().headers_out.headers) as _ };
240+
unsafe { add_to_ngx_table(table, self.inner().pool, key, value) }
248241
}
249242

250243
/// Set response body [Content-Length].
251244
///
252245
/// [Content-Length]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Length
253246
pub fn set_content_length_n(&mut self, n: usize) {
254-
self.0.headers_out.content_length_n = n as off_t;
247+
self.inner_mut().headers_out.content_length_n = n as off_t;
255248
}
256249

257250
/// Send the output header.
258251
///
259252
/// Do not call this function until all output headers are set.
260253
pub fn send_header(&mut self) -> Status {
261-
unsafe { Status(ngx_http_send_header(&mut self.0)) }
254+
unsafe { Status(ngx_http_send_header(self.as_ptr())) }
262255
}
263256

264257
/// Flag indicating that the output does not require a body.
265258
///
266259
/// For example, this flag is used by `HTTP HEAD` requests.
267260
pub fn header_only(&self) -> bool {
268-
self.0.header_only() != 0
261+
self.inner().header_only() != 0
269262
}
270263

271264
/// request method
272265
pub fn method(&self) -> Method {
273-
Method::from_ngx(self.0.method)
266+
Method::from_ngx(self.inner().method)
274267
}
275268

276269
/// path part of request only
277270
pub fn path(&self) -> &NgxStr {
278-
unsafe { NgxStr::from_ngx_str(self.0.uri) }
271+
unsafe { NgxStr::from_ngx_str(self.inner().uri) }
279272
}
280273

281274
/// full uri - containing path and args
282275
pub fn unparsed_uri(&self) -> &NgxStr {
283-
unsafe { NgxStr::from_ngx_str(self.0.unparsed_uri) }
276+
unsafe { NgxStr::from_ngx_str(self.inner().unparsed_uri) }
284277
}
285278

286279
/// Send the [response body].
@@ -290,13 +283,13 @@ impl Request {
290283
///
291284
/// [response body]: https://nginx.org/en/docs/dev/development_guide.html#http_request_body
292285
pub fn output_filter(&mut self, body: &mut ngx_chain_t) -> Status {
293-
unsafe { Status(ngx_http_output_filter(&mut self.0, body)) }
286+
unsafe { Status(ngx_http_output_filter(self.as_ptr(), body)) }
294287
}
295288

296289
/// Perform internal redirect to a location
297290
pub fn internal_redirect(&self, location: &str) -> Status {
298291
assert!(!location.is_empty(), "uri location is empty");
299-
let uri_ptr = unsafe { &mut ngx_str_t::from_str(self.0.pool, location) as *mut _ };
292+
let uri_ptr = unsafe { &mut ngx_str_t::from_str(self.inner().pool, location) as *mut _ };
300293

301294
// FIXME: check status of ngx_http_named_location or ngx_http_internal_redirect
302295
if location.starts_with('@') {
@@ -326,7 +319,7 @@ impl Request {
326319
ngx_int_t,
327320
) -> ngx_int_t,
328321
) -> Status {
329-
let uri_ptr = unsafe { &mut ngx_str_t::from_str(self.0.pool, uri) as *mut _ };
322+
let uri_ptr = unsafe { &mut ngx_str_t::from_str(self.inner().pool, uri) as *mut _ };
330323
// -------------
331324
// allocate memory and set values for ngx_http_post_subrequest_t
332325
let sub_ptr = self
@@ -377,13 +370,13 @@ impl Request {
377370
/// Iterate over headers_in
378371
/// each header item is (&str, &str) (borrowed)
379372
pub fn headers_in_iterator(&self) -> NgxListIterator<'_> {
380-
unsafe { list_iterator(&self.0.headers_in.headers) }
373+
unsafe { list_iterator(&self.inner().headers_in.headers) }
381374
}
382375

383376
/// Iterate over headers_out
384377
/// each header item is (&str, &str) (borrowed)
385378
pub fn headers_out_iterator(&self) -> NgxListIterator<'_> {
386-
unsafe { list_iterator(&self.0.headers_out.headers) }
379+
unsafe { list_iterator(&self.inner().headers_out.headers) }
387380
}
388381
}
389382

@@ -392,21 +385,21 @@ impl crate::http::HttpModuleConfExt for Request {
392385
unsafe fn http_main_conf_unchecked<T>(&self, module: &ngx_module_t) -> Option<NonNull<T>> {
393386
// SAFETY: main_conf[module.ctx_index] is either NULL or allocated with ngx_p(c)alloc and
394387
// explicitly initialized by the module
395-
NonNull::new((*self.0.main_conf.add(module.ctx_index)).cast())
388+
NonNull::new((*self.inner().main_conf.add(module.ctx_index)).cast())
396389
}
397390

398391
#[inline]
399392
unsafe fn http_server_conf_unchecked<T>(&self, module: &ngx_module_t) -> Option<NonNull<T>> {
400393
// SAFETY: srv_conf[module.ctx_index] is either NULL or allocated with ngx_p(c)alloc and
401394
// explicitly initialized by the module
402-
NonNull::new((*self.0.srv_conf.add(module.ctx_index)).cast())
395+
NonNull::new((*self.inner().srv_conf.add(module.ctx_index)).cast())
403396
}
404397

405398
#[inline]
406399
unsafe fn http_location_conf_unchecked<T>(&self, module: &ngx_module_t) -> Option<NonNull<T>> {
407400
// SAFETY: loc_conf[module.ctx_index] is either NULL or allocated with ngx_p(c)alloc and
408401
// explicitly initialized by the module
409-
NonNull::new((*self.0.loc_conf.add(module.ctx_index)).cast())
402+
NonNull::new((*self.inner().loc_conf.add(module.ctx_index)).cast())
410403
}
411404
}
412405

@@ -417,7 +410,7 @@ impl crate::http::HttpModuleConfExt for Request {
417410
impl fmt::Debug for Request {
418411
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
419412
f.debug_struct("Request")
420-
.field("request_", &self.0)
413+
.field("request_", &self.inner())
421414
.finish()
422415
}
423416
}

0 commit comments

Comments
 (0)