From 80fb5bc30e5f53861e7049707074987a449eebc1 Mon Sep 17 00:00:00 2001 From: Aleksei Bavshin Date: Sat, 26 Oct 2024 00:43:53 -0700 Subject: [PATCH 1/9] test: fix nginx-sys doctests --- nginx-sys/src/lib.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/nginx-sys/src/lib.rs b/nginx-sys/src/lib.rs index d56a3aa2..db9a05e4 100644 --- a/nginx-sys/src/lib.rs +++ b/nginx-sys/src/lib.rs @@ -24,8 +24,7 @@ //! ```rust,no_run //! use nginx_sys::nginx_version; //! -//! let version = unsafe { nginx_version() }; -//! println!("Nginx version: {}", version); +//! println!("Nginx version: {}", nginx_version); //! ``` //! #![warn(missing_docs)] @@ -77,7 +76,7 @@ pub unsafe fn bytes_to_uchar(pool: *mut ngx_pool_t, data: &[u8]) -> Option<*mut /// A raw pointer (`*mut u_char`) to the allocated memory containing the converted string data. /// /// # Example -/// ```rust +/// ```rust,ignore /// 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); @@ -237,11 +236,15 @@ impl TryFrom for &str { /// /// # 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 +/// # use nginx_sys::*; +/// # unsafe fn example(pool: *mut ngx_pool_t, headers: *mut ngx_list_t) { +/// // Obtain a pointer to the nginx table entry +/// let table: *mut ngx_table_elt_t = ngx_list_push(headers).cast(); +/// assert!(!table.is_null()); /// 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, From ae2a3dbad87813a69f63a331eb963caf9878dc9c Mon Sep 17 00:00:00 2001 From: Aleksei Bavshin Date: Sat, 26 Oct 2024 00:54:33 -0700 Subject: [PATCH 2/9] chore: clippy warnings * clippy::legacy_numeric_constants in examples/httporigdst.rs * clippy::single_match in examples/awssig.rs --- examples/awssig.rs | 9 +++------ examples/httporigdst.rs | 4 ++-- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/examples/awssig.rs b/examples/awssig.rs index e235d2ef..dcc1974b 100644 --- a/examples/awssig.rs +++ b/examples/awssig.rs @@ -310,12 +310,9 @@ http_request_handler!(awssigv4_header_handler, |request: &mut Request| { // Copy only headers that will be used to sign the request let mut headers = HeaderMap::new(); for (name, value) in request.headers_in_iterator() { - match name.to_lowercase().as_str() { - "host" => { - headers.insert(http::header::HOST, value.parse().unwrap()); - } - &_ => {} - }; + if name.to_lowercase() == "host" { + headers.insert(http::header::HOST, value.parse().unwrap()); + } } headers.insert("X-Amz-Date", datetime_now.parse().unwrap()); ngx_log_debug_http!(request, "headers {:?}", headers); diff --git a/examples/httporigdst.rs b/examples/httporigdst.rs index 8c3de756..50009bdd 100644 --- a/examples/httporigdst.rs +++ b/examples/httporigdst.rs @@ -96,8 +96,8 @@ ngx::ngx_modules!(ngx_http_orig_dst_module); #[no_mangle] #[used] pub static mut ngx_http_orig_dst_module: ngx_module_t = ngx_module_t { - ctx_index: ngx_uint_t::max_value(), - index: ngx_uint_t::max_value(), + ctx_index: ngx_uint_t::MAX, + index: ngx_uint_t::MAX, name: std::ptr::null_mut(), spare0: 0, spare1: 0, From 0dc05cbc1dc3e7601538ba4e87f33ac6a223da04 Mon Sep 17 00:00:00 2001 From: Aleksei Bavshin Date: Fri, 26 Jul 2024 21:38:23 -0700 Subject: [PATCH 3/9] docs: fix rustdoc warnings and some incorrect references --- src/core/buffer.rs | 2 + src/core/pool.rs | 4 +- src/http/module.rs | 2 +- src/http/request.rs | 24 +++++----- src/log.rs | 110 ++++++++++++++++++++++---------------------- 5 files changed, 73 insertions(+), 69 deletions(-) diff --git a/src/core/buffer.rs b/src/core/buffer.rs index baccd8b0..90862384 100644 --- a/src/core/buffer.rs +++ b/src/core/buffer.rs @@ -3,6 +3,8 @@ use std::slice; use crate::ffi::*; /// The `Buffer` trait provides methods for working with an nginx buffer (`ngx_buf_t`). +/// +/// See pub trait Buffer { /// Returns a raw pointer to the underlying `ngx_buf_t` of the buffer. fn as_ngx_buf(&self) -> *const ngx_buf_t; diff --git a/src/core/pool.rs b/src/core/pool.rs index 2e6c7dd3..4099065f 100644 --- a/src/core/pool.rs +++ b/src/core/pool.rs @@ -4,7 +4,9 @@ use std::{mem, ptr}; use crate::core::buffer::{Buffer, MemoryBuffer, TemporaryBuffer}; use crate::ffi::*; -/// Wrapper struct for an `ngx_pool_t` pointer, providing methods for working with memory pools. +/// Wrapper struct for an [`ngx_pool_t`] pointer, providing methods for working with memory pools. +/// +/// See pub struct Pool(*mut ngx_pool_t); impl Pool { diff --git a/src/http/module.rs b/src/http/module.rs index e372a35b..6a0f587f 100644 --- a/src/http/module.rs +++ b/src/http/module.rs @@ -45,7 +45,7 @@ impl Merge for () { /// These functions allocate structures, initialize them, and merge through the configuration /// layers. /// -/// See https://nginx.org/en/docs/dev/development_guide.html#adding_new_modules for details. +/// See for details. pub trait HTTPModule { /// Configuration in the `http` block. type MainConf: Merge + Default; diff --git a/src/http/request.rs b/src/http/request.rs index 04e19b65..d25d6143 100644 --- a/src/http/request.rs +++ b/src/http/request.rs @@ -88,7 +88,9 @@ macro_rules! http_variable_get { }; } -/// Wrapper struct for an `ngx_http_request_t` pointer, , providing methods for working with HTTP requests. +/// Wrapper struct for an [`ngx_http_request_t`] pointer, providing methods for working with HTTP requests. +/// +/// See #[repr(transparent)] pub struct Request(ngx_http_request_t); @@ -107,8 +109,6 @@ impl<'a> From<&'a mut Request> for *mut ngx_http_request_t { impl Request { /// Create a [`Request`] from an [`ngx_http_request_t`]. /// - /// [`ngx_http_request_t`]: https://nginx.org/en/docs/dev/development_guide.html#http_request - /// /// # Safety /// /// The caller has provided a valid non-null pointer to a valid `ngx_http_request_t` @@ -134,9 +134,8 @@ impl Request { /// The option wraps an ngx_http_upstream_t instance, it will be none when the underlying NGINX request /// does not have a pointer to a [`ngx_http_upstream_t`] upstream structure. /// - /// [`ngx_http_upstream_t`]: is best described in - /// https://nginx.org/en/docs/dev/development_guide.html#http_request - /// https://nginx.org/en/docs/dev/development_guide.html#http_load_balancing + /// [`ngx_http_upstream_t`] is best described in + /// pub fn upstream(&self) -> Option<*mut ngx_http_upstream_t> { if self.0.upstream.is_null() { return None; @@ -218,7 +217,7 @@ impl Request { /// Sets the value as the module's context. /// - /// See https://nginx.org/en/docs/dev/development_guide.html#http_request + /// See pub fn set_module_ctx(&self, value: *mut c_void, module: &ngx_module_t) { unsafe { *self.0.ctx.add(module.ctx_index) = value; @@ -267,7 +266,7 @@ impl Request { /// Add header to the `headers_in` object. /// - /// See https://nginx.org/en/docs/dev/development_guide.html#http_request + /// See pub fn add_header_in(&mut self, key: &str, value: &str) -> Option<()> { let table: *mut ngx_table_elt_t = unsafe { ngx_list_push(&mut self.0.headers_in.headers) as _ }; unsafe { add_to_ngx_table(table, self.0.pool, key, value) } @@ -275,7 +274,7 @@ impl Request { /// Add header to the `headers_out` object. /// - /// See https://nginx.org/en/docs/dev/development_guide.html#http_request + /// See pub fn add_header_out(&mut self, key: &str, value: &str) -> Option<()> { let table: *mut ngx_table_elt_t = unsafe { ngx_list_push(&mut self.0.headers_out.headers) as _ }; unsafe { add_to_ngx_table(table, self.0.pool, key, value) } @@ -425,7 +424,7 @@ impl fmt::Debug for Request { } } -/// Iterator for `ngx_list_t` types. +/// Iterator for [`ngx_list_t`] types. /// /// Implementes the std::iter::Iterator trait. pub struct NgxListIterator { @@ -435,10 +434,11 @@ pub struct NgxListIterator { i: ngx_uint_t, } -// create new http request iterator +/// Creates new HTTP header iterator +/// /// # Safety /// -/// The caller has provided a valid `ngx_str_t` which can be dereferenced validly. +/// The caller has provided a valid [`ngx_str_t`] which can be dereferenced validly. pub unsafe fn list_iterator(list: *const ngx_list_t) -> NgxListIterator { let part: *const ngx_list_part_t = &(*list).part; diff --git a/src/log.rs b/src/log.rs index 03114460..a0f0397e 100644 --- a/src/log.rs +++ b/src/log.rs @@ -38,64 +38,13 @@ macro_rules! ngx_log_debug_http { } } -/// Debug masks for use with ngx_log_debug_mask, these represent the only accepted values for the -/// mask. -#[derive(Debug)] -pub enum DebugMask { - /// Aligns to the NGX_LOG_DEBUG_CORE mask. - Core, - /// Aligns to the NGX_LOG_DEBUG_ALLOC mask. - Alloc, - /// Aligns to the NGX_LOG_DEBUG_MUTEX mask. - Mutex, - /// Aligns to the NGX_LOG_DEBUG_EVENT mask. - Event, - /// Aligns to the NGX_LOG_DEBUG_HTTP mask. - Http, - /// Aligns to the NGX_LOG_DEBUG_MAIL mask. - Mail, - /// Aligns to the NGX_LOG_DEBUG_STREAM mask. - Stream, -} - -impl TryFrom for DebugMask { - type Error = u32; - - fn try_from(value: u32) -> Result { - match value { - crate::ffi::NGX_LOG_DEBUG_CORE => Ok(DebugMask::Core), - crate::ffi::NGX_LOG_DEBUG_ALLOC => Ok(DebugMask::Alloc), - crate::ffi::NGX_LOG_DEBUG_MUTEX => Ok(DebugMask::Mutex), - crate::ffi::NGX_LOG_DEBUG_EVENT => Ok(DebugMask::Event), - crate::ffi::NGX_LOG_DEBUG_HTTP => Ok(DebugMask::Http), - crate::ffi::NGX_LOG_DEBUG_MAIL => Ok(DebugMask::Mail), - crate::ffi::NGX_LOG_DEBUG_STREAM => Ok(DebugMask::Stream), - _ => Err(0), - } - } -} - -impl From for u32 { - fn from(value: DebugMask) -> Self { - match value { - DebugMask::Core => crate::ffi::NGX_LOG_DEBUG_CORE, - DebugMask::Alloc => crate::ffi::NGX_LOG_DEBUG_ALLOC, - DebugMask::Mutex => crate::ffi::NGX_LOG_DEBUG_MUTEX, - DebugMask::Event => crate::ffi::NGX_LOG_DEBUG_EVENT, - DebugMask::Http => crate::ffi::NGX_LOG_DEBUG_HTTP, - DebugMask::Mail => crate::ffi::NGX_LOG_DEBUG_MAIL, - DebugMask::Stream => crate::ffi::NGX_LOG_DEBUG_STREAM, - } - } -} - /// Log with requested debug mask. /// -/// **NOTE:** This macro supports `DebugMask::Http` (`NGX_LOG_DEBUG_HTTP`), however, if you have -/// access to a Request object via an http handler it can be more convenient and readable to use the -/// `ngx_log_debug_http` macro instead. +/// **NOTE:** This macro supports [`DebugMask::Http`] (`NGX_LOG_DEBUG_HTTP`), however, if you have +/// access to a Request object via an http handler it can be more convenient and readable to use +/// the [`ngx_log_debug_http`] macro instead. /// -/// See https://nginx.org/en/docs/dev/development_guide.html#logging for details and available +/// See for details and available /// masks. #[macro_export] macro_rules! ngx_log_debug_mask { @@ -178,6 +127,57 @@ macro_rules! ngx_log_debug_mask { }); } +/// Debug masks for use with [`ngx_log_debug_mask`], these represent the only accepted values for +/// the mask. +#[derive(Debug)] +pub enum DebugMask { + /// Aligns to the NGX_LOG_DEBUG_CORE mask. + Core, + /// Aligns to the NGX_LOG_DEBUG_ALLOC mask. + Alloc, + /// Aligns to the NGX_LOG_DEBUG_MUTEX mask. + Mutex, + /// Aligns to the NGX_LOG_DEBUG_EVENT mask. + Event, + /// Aligns to the NGX_LOG_DEBUG_HTTP mask. + Http, + /// Aligns to the NGX_LOG_DEBUG_MAIL mask. + Mail, + /// Aligns to the NGX_LOG_DEBUG_STREAM mask. + Stream, +} + +impl TryFrom for DebugMask { + type Error = u32; + + fn try_from(value: u32) -> Result { + match value { + crate::ffi::NGX_LOG_DEBUG_CORE => Ok(DebugMask::Core), + crate::ffi::NGX_LOG_DEBUG_ALLOC => Ok(DebugMask::Alloc), + crate::ffi::NGX_LOG_DEBUG_MUTEX => Ok(DebugMask::Mutex), + crate::ffi::NGX_LOG_DEBUG_EVENT => Ok(DebugMask::Event), + crate::ffi::NGX_LOG_DEBUG_HTTP => Ok(DebugMask::Http), + crate::ffi::NGX_LOG_DEBUG_MAIL => Ok(DebugMask::Mail), + crate::ffi::NGX_LOG_DEBUG_STREAM => Ok(DebugMask::Stream), + _ => Err(0), + } + } +} + +impl From for u32 { + fn from(value: DebugMask) -> Self { + match value { + DebugMask::Core => crate::ffi::NGX_LOG_DEBUG_CORE, + DebugMask::Alloc => crate::ffi::NGX_LOG_DEBUG_ALLOC, + DebugMask::Mutex => crate::ffi::NGX_LOG_DEBUG_MUTEX, + DebugMask::Event => crate::ffi::NGX_LOG_DEBUG_EVENT, + DebugMask::Http => crate::ffi::NGX_LOG_DEBUG_HTTP, + DebugMask::Mail => crate::ffi::NGX_LOG_DEBUG_MAIL, + DebugMask::Stream => crate::ffi::NGX_LOG_DEBUG_STREAM, + } + } +} + #[cfg(test)] mod tests { From 0b4b8a875e38c5bf4c6c2cef51aa9ba1011de679 Mon Sep 17 00:00:00 2001 From: Aleksei Bavshin Date: Sat, 26 Oct 2024 00:49:33 -0700 Subject: [PATCH 4/9] ci: run tests and clippy for all workspace crates --- .github/workflows/ci.yaml | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 61563212..03778d04 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -3,7 +3,8 @@ name: Rust on: [ push, pull_request ] env: - CARGO_TERM_COLOR: always + CARGO_TERM_COLOR: 'always' + CARGO_TERM_VERBOSE: 'true' jobs: test-linux: @@ -36,8 +37,10 @@ jobs: .cache/*.tar.sig key: ${{ runner.os }}-deps-${{ hashFiles('**/nginx-sys/build.rs') }} restore-keys: ${{ runner.os }}-deps- + - name: build + run: cargo build --workspace --all-targets --all-features - name: run tests - run: cargo test --verbose + run: cargo test --workspace --all-features examples-linux: name: Examples (Linux) @@ -70,7 +73,7 @@ jobs: key: ${{ runner.os }}-deps-${{ hashFiles('**/nginx-sys/build.rs') }} restore-keys: ${{ runner.os }}-deps- - name: compile examples - run: cargo build --release --package examples --examples --verbose + run: cargo build --release --package examples --examples --all-features test-macos: name: Test (MacOS) @@ -109,9 +112,9 @@ jobs: - name: disable ipv6 for gpg run: echo "disable-ipv6" > .cache/.gnupg/dirmngr.conf - name: build - run: cargo build --verbose + run: cargo build - name: run tests - run: cargo test --verbose + run: cargo test --workspace fmt: name: Rustfmt @@ -124,7 +127,7 @@ jobs: - name: rustfmt version run: rustfmt --version - name: cargo fmt - run: cargo fmt --all --verbose --check || true + run: cargo fmt --all --check clippy: name: Clippy @@ -159,4 +162,4 @@ jobs: with: components: rustfmt, clippy - name: run clippy - run: cargo clippy -- -D warnings \ No newline at end of file + run: cargo clippy --workspace --all-targets --all-features -- -Dwarnings \ No newline at end of file From 6e673a62a89dc037bf45202cedf6bff41d0b53cf Mon Sep 17 00:00:00 2001 From: Aleksei Bavshin Date: Mon, 28 Oct 2024 16:12:26 -0700 Subject: [PATCH 5/9] ci: move clippy check into test-linux There's a lot of duplication between these jobs, so running clippy separately just wastes resources. --- .github/workflows/ci.yaml | 46 ++++++++++----------------------------- 1 file changed, 11 insertions(+), 35 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 03778d04..f6833f15 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -37,9 +37,20 @@ jobs: .cache/*.tar.sig key: ${{ runner.os }}-deps-${{ hashFiles('**/nginx-sys/build.rs') }} restore-keys: ${{ runner.os }}-deps- + - uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt, clippy + - name: build + id: build run: cargo build --workspace --all-targets --all-features + + - name: run clippy + if: ${{ !cancelled() && steps.build.outcome == 'success' }} # always run if build succeeds + run: cargo clippy --workspace --all-targets --all-features -- -Dwarnings + - name: run tests + if: ${{ !cancelled() && steps.build.outcome == 'success' }} # always run if build succeeds run: cargo test --workspace --all-features examples-linux: @@ -128,38 +139,3 @@ jobs: run: rustfmt --version - name: cargo fmt run: cargo fmt --all --check - - clippy: - name: Clippy - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: set up cargo cache - uses: actions/cache@v4 - continue-on-error: false - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - target/ - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - restore-keys: ${{ runner.os }}-cargo- - - name: set up nginx deps source cache - uses: actions/cache@v4 - continue-on-error: false - with: - path: | - .cache/.gnupg - .cache/nginx - .cache/*.tar.gz - .cache/*.tar.asc - .cache/*.tar.sig - key: ${{ runner.os }}-deps-${{ hashFiles('**/nginx-sys/build.rs') }} - restore-keys: ${{ runner.os }}-deps- - - uses: dtolnay/rust-toolchain@stable - with: - components: rustfmt, clippy - - name: run clippy - run: cargo clippy --workspace --all-targets --all-features -- -Dwarnings \ No newline at end of file From d610c0b5ba898a6709d8596af6a6109731c953d4 Mon Sep 17 00:00:00 2001 From: Aleksei Bavshin Date: Mon, 28 Oct 2024 16:34:00 -0700 Subject: [PATCH 6/9] ci: check documentation --- .github/workflows/ci.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index f6833f15..6cafe9af 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -5,6 +5,7 @@ on: [ push, pull_request ] env: CARGO_TERM_COLOR: 'always' CARGO_TERM_VERBOSE: 'true' + RUSTDOCFLAGS: '-Dwarnings' jobs: test-linux: @@ -53,6 +54,10 @@ jobs: if: ${{ !cancelled() && steps.build.outcome == 'success' }} # always run if build succeeds run: cargo test --workspace --all-features + - name: rustdoc + if: ${{ !cancelled() && steps.build.outcome == 'success' }} # always run if build succeeds + run: cargo doc --no-deps + examples-linux: name: Examples (Linux) runs-on: ubuntu-latest From 4e8120a7ef2f11aec1fa80b84173a68e85edd4ee Mon Sep 17 00:00:00 2001 From: Aleksei Bavshin Date: Mon, 28 Oct 2024 14:41:39 -0700 Subject: [PATCH 7/9] fix: minimize deps for building examples with nginx buildsystem --- Cargo.toml | 3 ++- examples/Cargo.toml | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index eb8a53d3..f3a9a2bf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,10 +22,11 @@ keywords = ["nginx", "module", "sys"] nginx-sys = { path = "nginx-sys", version = "0.5.0"} [features] +default = ["vendored"] # Build our own copy of the NGINX by default. # This could be disabled with `--no-default-features` to minimize the dependency tree # when building against an existing copy of the NGINX with the NGX_OBJS variable. -default = ["nginx-sys/vendored"] +vendored = ["nginx-sys/vendored"] [badges] maintenance = { status = "experimental" } diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 87031120..cd27ce02 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -6,11 +6,12 @@ edition = "2021" license = "Apache-2.0" [dev-dependencies] -ngx = { path = "../" } +ngx = { path = "../", default-features = false } aws-sign-v4 = "0.3.0" chrono = "0.4.23" http = "1.1.0" libc = "0.2.140" +tokio = { version = "1.33.0", features = ["full"] } [[example]] name = "curl" @@ -39,10 +40,9 @@ path = "async.rs" crate-type = ["cdylib"] [dependencies] -tokio = { version = "1.33.0", features = ["full"] } [features] -default = ["export-modules"] +default = ["export-modules", "ngx/vendored"] # Generate `ngx_modules` table with module exports # The exports table is required for building loadable modules with --crate-type cdylib # outside of the NGINX buildsystem. However, cargo currently does not detect From 131e3e4dc02244a86addb5eca855e054883109e6 Mon Sep 17 00:00:00 2001 From: Aleksei Bavshin Date: Mon, 28 Oct 2024 15:46:55 -0700 Subject: [PATCH 8/9] test: integration tests for example modules --- .github/workflows/nginx.yaml | 96 ++++++++++++++++++++++++++++++++++++ examples/config | 2 +- examples/t/awssig.t | 73 +++++++++++++++++++++++++++ examples/t/curl.t | 70 ++++++++++++++++++++++++++ examples/t/upstream.t | 79 +++++++++++++++++++++++++++++ 5 files changed, 319 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/nginx.yaml create mode 100644 examples/t/awssig.t create mode 100644 examples/t/curl.t create mode 100644 examples/t/upstream.t diff --git a/.github/workflows/nginx.yaml b/.github/workflows/nginx.yaml new file mode 100644 index 00000000..423ec60b --- /dev/null +++ b/.github/workflows/nginx.yaml @@ -0,0 +1,96 @@ +name: NGINX + +on: + push: + branches: + - master + pull_request: + +env: + CARGO_TERM_COLOR: 'always' + RUST_BACKTRACE: '1' + NGX_CONFIGURE: | + auto/configure + --with-compat + --with-debug + --with-http_realip_module + --with-http_ssl_module + --with-http_v2_module + --with-http_v3_module + --with-stream + --with-stream_realip_module + --with-stream_ssl_module + --with-threads + +jobs: + test: + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + module: + # static + - dynamic + nginx-ref: + # master + - stable-1.26 + + steps: + - uses: actions/checkout@v4 + - uses: actions/checkout@v4 + with: + ref: ${{ matrix.nginx-ref }} + repository: 'nginx/nginx' + path: 'nginx' + - uses: actions/checkout@v4 + with: + repository: 'nginx/nginx-tests' + path: 'nginx/tests' + sparse-checkout: | + lib + + - uses: dtolnay/rust-toolchain@stable + + - uses: actions/cache@v4 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + nginx/objs/ngx_rust_examples + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + restore-keys: ${{ runner.os }}-cargo- + + - name: Configure nginx with static modules + if: matrix.module == 'static' + working-directory: nginx + run: | + ${NGX_CONFIGURE} \ + --add-module=${{ github.workspace }}/examples + + - name: Configure nginx with dynamic modules + if: matrix.module != 'static' + working-directory: nginx + env: + TEST_NGINX_GLOBALS: >- + load_module ${{ github.workspace }}/nginx/objs/ngx_http_awssigv4_module.so; + load_module ${{ github.workspace }}/nginx/objs/ngx_http_curl_module.so; + load_module ${{ github.workspace }}/nginx/objs/ngx_http_upstream_custom_module.so; + run: | + ${NGX_CONFIGURE} \ + --add-dynamic-module=${{ github.workspace }}/examples + echo "TEST_NGINX_GLOBALS=$TEST_NGINX_GLOBALS" >> $GITHUB_ENV + + - name: Build nginx + working-directory: nginx + run: make -j$(nproc) + + - name: Run tests + env: + TEST_NGINX_BINARY: ${{ github.workspace }}/nginx/objs/nginx + TEST_NGINX_MODULES: ${{ github.workspace }}/nginx/objs + run: | + prove -v -j$(nproc) -Inginx/tests/lib --state=save examples/t \ + || prove -v -Inginx/tests/lib --state=failed diff --git a/examples/config b/examples/config index 7de72bec..427423d4 100644 --- a/examples/config +++ b/examples/config @@ -24,7 +24,7 @@ if [ $HTTP = YES ]; then ngx_module_lib=$NGX_OBJS/$ngx_addon_name/$ngx_cargo_profile/examples/lib$ngx_module_lib.a ngx_module_deps=$ngx_module_lib - ngx_module_libs=$ngx_module_lib + ngx_module_libs="$ngx_module_lib -lm" # Module deps are usually added to the object file targets, but we don't have any LINK_DEPS="$LINK_DEPS $ngx_module_lib" diff --git a/examples/t/awssig.t b/examples/t/awssig.t new file mode 100644 index 00000000..ba43cd09 --- /dev/null +++ b/examples/t/awssig.t @@ -0,0 +1,73 @@ +#!/usr/bin/perl + +# (C) Nginx, Inc + +# Tests for ngx-rust example modules. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has(qw/http proxy/)->plan(1) + ->write_file_expand('nginx.conf', <<"EOF"); + +%%TEST_GLOBALS%% + +daemon off; + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + awssigv4_access_key my-access-key; + awssigv4_secret_key my-secret-key; + awssigv4_s3_bucket my-bucket; + awssigv4_s3_endpoint s3.example.com; + + location / { + awssigv4 on; + proxy_pass http://127.0.0.1:8081; + } + } + + server { + listen 127.0.0.1:8081; + server_name localhost; + + add_header x-amz-date \$http_x_amz_date; + add_header x-authorization \$http_authorization; + + location / { } + } +} + +EOF + +$t->write_file('index.html', ''); +$t->run(); + +############################################################################### + +like(http_get('/'), qr/x-authorization: AWS4.*Credential=my-access-key/i, + 'awssig header'); + +############################################################################### diff --git a/examples/t/curl.t b/examples/t/curl.t new file mode 100644 index 00000000..dffe5a08 --- /dev/null +++ b/examples/t/curl.t @@ -0,0 +1,70 @@ +#!/usr/bin/perl + +# (C) Nginx, Inc + +# Tests for ngx-rust example modules. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has(qw/http/)->plan(2) + ->write_file_expand('nginx.conf', <<"EOF"); + +%%TEST_GLOBALS%% + +daemon off; + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location / { + curl on; + } + } +} + +EOF + +$t->write_file('index.html', ''); +$t->run(); + +############################################################################### + +like(get('/', 'curl/1.2.3'), qr/403 Forbidden/, 'curl UA forbidden'); +like(get('/', 'MSIE 6.0'), qr/200 OK/, 'other UA allowed'); + +############################################################################### + +sub get { + my ($url, $ua, $extra) = @_; + return http(<new()->has(qw/http proxy/)->plan(2) + ->write_file_expand('nginx.conf', <<"EOF"); + +%%TEST_GLOBALS%% + +daemon off; + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + upstream u { + server 127.0.0.1:8081; + custom 32; + } + + server { + listen 127.0.0.1:8080; + server_name localhost; + + error_log %%TESTDIR%%/e_debug.log debug; + + location / { + proxy_pass http://u; + } + } + + server { + listen 127.0.0.1:8081; + server_name localhost; + + location / { } + } +} + +EOF + +$t->write_file('index.html', ''); +$t->run(); + +############################################################################### + +like(http_get('/'), qr/200 OK/, 'custom upstream'); + +$t->stop(); + +SKIP: { + skip "no --with-debug", 1 unless $t->has_module('--with-debug'); + + like($t->read_file('e_debug.log'), qr/CUSTOM UPSTREAM request/, + 'log - custom upstream'); +} + +############################################################################### From 6f2d4eb0981c699af13b590ecdc5b9307b0d90df Mon Sep 17 00:00:00 2001 From: Aleksei Bavshin Date: Tue, 29 Oct 2024 21:01:10 -0700 Subject: [PATCH 9/9] fix: exclude "async" example from static builds The example starts a multi-threaded tokio runtime in the master process. --- .github/workflows/nginx.yaml | 2 +- examples/config | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/nginx.yaml b/.github/workflows/nginx.yaml index 423ec60b..fbcbda78 100644 --- a/.github/workflows/nginx.yaml +++ b/.github/workflows/nginx.yaml @@ -30,7 +30,7 @@ jobs: fail-fast: false matrix: module: - # static + - static - dynamic nginx-ref: # master diff --git a/examples/config b/examples/config index 427423d4..c3f4cd45 100644 --- a/examples/config +++ b/examples/config @@ -4,7 +4,7 @@ ngx_cargo_profile=ngx-module if [ $HTTP = YES ]; then ngx_module_type=HTTP - if :; then + if [ "$ngx_module_link" = DYNAMIC ]; then ngx_module_name=ngx_http_async_module ngx_module_lib=async