ngx/lib.rs
1//! # Rust bindings for NGINX
2//!
3//! The `ngx` crate provides a high-level Rust interface for the [NGINX] C APIs,
4//! allowing creation of NGINX dynamic modules completely in Rust.
5//!
6//! [NGINX]: https://nginx.org/
7//!
8//! ## Project status
9//!
10//! This project is in active development. It is stable enough to be used in our
11//! own products, but the APIs are not stabilized and breaking changes are expected.
12//!
13//! ## Build
14//!
15//! NGINX modules can be built against a particular version of NGINX. The following
16//! environment variables can be used to specify the NGINX build to use:
17//!
18//! - `NGINX_BUILD_DIR` - absolute path to the NGINX build directory.
19//! Usually it's `objs` under the source directory, but can be changed with the
20//! `--builddir=` argument of the configure script.
21//!
22//! - `NGINX_SOURCE_DIR` - absolute path to the NGINX source directory, configured
23//! with the [`configure`](https://nginx.org/en/docs/configure.html) command.
24//!
25//! Only the `./configure` step of the NGINX build is mandatory because bindings
26//! generator don't depend on any of the artifacts generated by `make`.
27//!
28//! For example, this is how you would compile the [examples](#examples) using a
29//! specific version of NGINX:
30//!
31//! ```sh
32//! NGINX_BUILD_DIR=/path/to/nginx-1.28.0/objs cargo build --package=examples --examples
33//! ```
34//!
35//! ### Building with the NGINX build script
36//!
37//! You can build your Rust-based module as a part of the NGINX build process by
38//! providing a `config` script implementation and passing the `--add-module`/
39//! `--add-dynamic-module` options to the configure script.
40//!
41//! See the following example integration scripts: [`examples/config`] and
42//! [`examples/config.make`].
43//!
44//! [`examples/config`]: https://github.com/bavshin-f5/ngx-rust/blob/main/examples/config
45//! [`examples/config.make`]: https://github.com/bavshin-f5/ngx-rust/blob/main/examples/config.make
46//!
47//! ### Building with vendored NGINX sources
48//!
49//! It is possible to build module with a vendored copy of the NGINX sources
50//! provided in the `nginx-src` crate by enabling feature `vendored`:
51//!
52//! By default, this will use the latest stable release of NGINX and require
53//! system-wide installation of build dependencies (OpenSSL, PCRE2, Zlib).
54//!
55//! The behavior of vendored builds can be customized with environment variables,
56//! as documented in the [nginx-src] crate README.
57//!
58//! **NOTE**: We recommend to build the module binaries against the exact source and
59//! configuration of the NGINX build that you are planning to use in production,
60//! and that is unlikely to be possible with the vendored source.
61//!
62//! `configure` arguments alter the APIs and the symbols visible to the Rust code,
63//! and some OS distributions are known to ship nginx packages with API-breaking
64//! patches applied.
65//!
66//! [nginx-src]: https://docs.rs/nginx-src/
67//!
68//! ## Cargo features
69//!
70//! - `alloc` - **Enabled** by default. This provides APIs that require allocations
71//! via the `alloc` crate.
72//! - `async` - Enables a minimal async runtime built on top of the NGINX event loop.
73//! - `serde` - Enables serialization support for some of the provided and
74//! re-exported types.
75//! - `std` - **Enabled** by default. This provides APIs that require the standard
76//! library.
77//! - `vendored`: Enables the build scripts to build a copy of nginx source and link
78//! against it. See the [nginx-src] crate documentation for additional details.
79//!
80//! ## Dependencies
81//!
82//! The following dependencies are required to build a Rust NGINX module on Linux
83//! or BSD platform:
84//!
85//! - NGINX build dependencies: C compiler, make, OpenSSL, PCRE2, and Zlib.
86//! - Rust toolchain (1.81.0 or later)
87//! - [libclang] for rust-bindgen
88//!
89//! The installation process and the package names are system-dependent. Please,
90//! consult the documentation for your distribution.
91//!
92//! Note that on some systems you will need `-devel` or `-dev` versions of the
93//! packages.
94//!
95//! For example, [Dockerfile] contains the installation commands for Debian Linux.
96//!
97//! [Dockerfile]: https://github.com/nginx/ngx-rust/blob/main/Dockerfile
98//! [libclang]: https://rust-lang.github.io/rust-bindgen/requirements.html
99//!
100//! ### macOS dependencies
101//!
102//! In order to use the optional GNU make build process on macOS, you will need
103//! to install additional tools. This can be done via [homebrew](https://brew.sh/)
104//! with the following command:
105//!
106//! ```sh
107//! brew install make openssl grep
108//! ```
109//!
110//! Additionally, you may need to set up LLVM and clang. Typically, this is done
111//! as follows:
112//!
113//! ```sh
114//! # make sure xcode tools are installed
115//! xcode-select --install
116//! # instal llvm
117//! brew install --with-toolchain llvm
118//! ```
119#![warn(missing_docs)]
120// support both std and no_std
121#![no_std]
122#[cfg(all(not(feature = "std"), feature = "alloc"))]
123extern crate alloc;
124#[cfg(feature = "std")]
125extern crate std;
126
127pub mod allocator;
128#[cfg(feature = "async")]
129pub mod async_;
130pub mod collections;
131
132/// The core module.
133///
134/// This module provides fundamental utilities needed to interface with many NGINX primitives.
135/// String conversions, the pool (memory interface) object, and buffer APIs are covered here. These
136/// utilities will generally align with the NGINX 'core' files and APIs.
137pub mod core;
138
139/// The ffi module.
140///
141/// This module provides scoped FFI bindings for NGINX symbols.
142pub mod ffi;
143
144/// The http module.
145///
146/// This modules provides wrappers and utilities to NGINX http APIs, such as requests,
147/// configuration access, and statuses.
148pub mod http;
149
150/// The log module.
151///
152/// This module provides an interface into the NGINX logger framework.
153pub mod log;
154
155pub mod sync;
156
157/// Define modules exported by this library.
158///
159/// These are normally generated by the Nginx module system, but need to be
160/// defined when building modules outside of it.
161#[macro_export]
162macro_rules! ngx_modules {
163 ($( $mod:ident ),+) => {
164 #[no_mangle]
165 #[allow(non_upper_case_globals)]
166 pub static mut ngx_modules: [*const $crate::ffi::ngx_module_t; $crate::count!($( $mod, )+) + 1] = [
167 $( unsafe { &$mod } as *const $crate::ffi::ngx_module_t, )+
168 ::core::ptr::null()
169 ];
170
171 #[no_mangle]
172 #[allow(non_upper_case_globals)]
173 pub static mut ngx_module_names: [*const ::core::ffi::c_char; $crate::count!($( $mod, )+) + 1] = [
174 $( concat!(stringify!($mod), "\0").as_ptr() as *const ::core::ffi::c_char, )+
175 ::core::ptr::null()
176 ];
177
178 #[no_mangle]
179 #[allow(non_upper_case_globals)]
180 pub static mut ngx_module_order: [*const ::core::ffi::c_char; 1] = [
181 ::core::ptr::null()
182 ];
183 };
184}
185
186/// Count number of arguments
187#[macro_export]
188macro_rules! count {
189 () => { 0usize };
190 ($x:tt, $( $xs:tt ),*) => { 1usize + $crate::count!($( $xs, )*) };
191}