-
Notifications
You must be signed in to change notification settings - Fork 72
/
Copy pathlib.rs
208 lines (195 loc) · 6.53 KB
/
lib.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
//! # nginx-sys
//!
//! The `nginx-sys` crate provides low-level bindings for the nginx C API, allowing Rust applications to interact with nginx servers and modules.
//!
//! ## Usage
//!
//! Add `nginx-sys` as a dependency in your `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! nginx-sys = "0.1.0"
//! ```
//!
//! ## Features
//!
//! - `build`: Enables the build scripts to compile and link against the nginx C library. This feature is enabled by default.
//!
//! ## Examples
//!
//! ### Get Nginx Version
//!
//! This example demonstrates how to retrieve the version of the nginx server.
//!
//! ```rust,no_run
//! use nginx_sys::nginx_version;
//!
//! fn main() {
//! let version = unsafe { nginx_version() };
//! println!("Nginx version: {}", version);
//! }
//! ```
//!
#![warn(missing_docs)]
use std::fmt;
use std::ptr::copy_nonoverlapping;
use std::slice;
#[doc(hidden)]
mod bindings {
#![allow(missing_docs)]
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(dead_code)]
#![allow(clippy::all)]
#![allow(improper_ctypes)]
#[allow(rustdoc::broken_intra_doc_links)]
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
}
#[doc(no_inline)]
pub use bindings::*;
/// Convert a string slice (`&str`) to a raw pointer (`*mut u_char`) allocated in the given nginx memory pool.
///
/// # Arguments
///
/// * `pool` - A pointer to the nginx memory pool (`ngx_pool_t`).
/// * `data` - The string slice to convert to a raw pointer.
///
/// # Safety
/// This function is marked as unsafe because it involves raw pointer manipulation and direct memory allocation using `ngx_palloc`.
///
/// # Returns
/// A raw pointer (`*mut u_char`) to the allocated memory containing the converted string data.
///
/// # Example
/// ```rust
/// let pool: *mut ngx_pool_t = ...; // Obtain a pointer to the nginx memory pool
/// let data: &str = "example"; // The string to convert
/// let ptr = str_to_uchar(pool, data);
/// ```
pub unsafe fn str_to_uchar(pool: *mut ngx_pool_t, data: &str) -> *mut u_char {
let ptr: *mut u_char = unsafe { ngx_palloc(pool, data.len() as _) as _ };
copy_nonoverlapping(data.as_ptr(), ptr, data.len());
ptr
}
impl ngx_str_t {
/// Convert the nginx string to a string slice (`&str`).
///
/// # Safety
/// This function is marked as unsafe because it involves raw pointer manipulation.
/// It assumes that the underlying `data` pointer is valid and points to a valid UTF-8 encoded string.
///
/// # Returns
/// A string slice (`&str`) representing the nginx string.
pub fn to_str(&self) -> &str {
unsafe {
let slice = slice::from_raw_parts(self.data, self.len as usize);
return std::str::from_utf8(slice).unwrap();
}
}
/// Create an `ngx_str_t` instance from a `String`.
///
/// # Arguments
///
/// * `pool` - A pointer to the nginx memory pool (`ngx_pool_t`).
/// * `data` - The `String` from which to create the nginx string.
///
/// # Safety
/// This function is marked as unsafe because it passes a raw pointer (pool) to another unsafe
/// function which allocates a buffer from the pool.
///
/// # Returns
/// An `ngx_str_t` instance representing the given `String`.
pub unsafe fn from_string(pool: *mut ngx_pool_t, data: String) -> Self {
ngx_str_t {
data: str_to_uchar(pool, data.as_str()),
len: data.len() as _,
}
}
/// Create an `ngx_str_t` instance from a string slice (`&str`).
///
/// # Arguments
///
/// * `pool` - A pointer to the nginx memory pool (`ngx_pool_t`).
/// * `data` - The string slice from which to create the nginx string.
///
/// # Safety
/// This function is marked as unsafe because it passes a raw pointer (pool) to another unsafe
/// function which allocates a buffer from the pool.
///
/// # Returns
/// An `ngx_str_t` instance representing the given string slice.
pub unsafe fn from_str(pool: *mut ngx_pool_t, data: &str) -> Self {
ngx_str_t {
data: str_to_uchar(pool, data),
len: data.len() as _,
}
}
}
impl From<ngx_str_t> for &[u8] {
fn from(s: ngx_str_t) -> Self {
if s.len == 0 || s.data.is_null() {
return Default::default();
}
unsafe { slice::from_raw_parts(s.data, s.len as usize) }
}
}
impl TryFrom<ngx_str_t> for String {
type Error = std::string::FromUtf8Error;
fn try_from(s: ngx_str_t) -> Result<Self, Self::Error> {
let bytes: &[u8] = s.into();
String::from_utf8(bytes.into())
}
}
impl fmt::Display for ngx_str_t {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", String::from_utf8_lossy((*self).into()))
}
}
impl TryFrom<ngx_str_t> for &str {
type Error = std::str::Utf8Error;
fn try_from(s: ngx_str_t) -> Result<Self, Self::Error> {
std::str::from_utf8(s.into())
}
}
/// Add a key-value pair to an nginx table entry (`ngx_table_elt_t`) in the given nginx memory pool.
///
/// # Arguments
///
/// * `table` - A pointer to the nginx table entry (`ngx_table_elt_t`) to modify.
/// * `pool` - A pointer to the nginx memory pool (`ngx_pool_t`) for memory allocation.
/// * `key` - The key string to add to the table entry.
/// * `value` - The value string to add to the table entry.
///
/// # Safety
/// This function is marked as unsafe because it involves raw pointer manipulation and direct memory allocation using `str_to_uchar`.
///
/// # Returns
/// An `Option<()>` representing the result of the operation. `Some(())` indicates success, while `None` indicates a null table pointer.
///
/// # Example
/// ```rust
/// let table: *mut ngx_table_elt_t = ...; // Obtain a pointer to the nginx table entry
/// let pool: *mut ngx_pool_t = ...; // Obtain a pointer to the nginx memory pool
/// let key: &str = "key"; // The key to add
/// let value: &str = "value"; // The value to add
/// let result = add_to_ngx_table(table, pool, key, value);
/// ```
pub unsafe fn add_to_ngx_table(
table: *mut ngx_table_elt_t,
pool: *mut ngx_pool_t,
key: &str,
value: &str,
) -> Option<()> {
if table.is_null() {
return None;
}
table.as_mut().map(|table| {
table.hash = 1;
table.key.len = key.len() as _;
table.key.data = str_to_uchar(pool, key);
table.value.len = value.len() as _;
table.value.data = str_to_uchar(pool, value);
table.lowcase_key = str_to_uchar(pool, String::from(key).to_ascii_lowercase().as_str());
})
}