From 9ff8fd4cfb11b5d19132278d8b76fa9a7e02f0a6 Mon Sep 17 00:00:00 2001 From: Mateusz Matejuk Date: Tue, 23 Jan 2024 09:50:46 +0100 Subject: [PATCH] [FEAT]: additional functions exposed * added `&mut headers_out` getter * added `&mut conf_main` getter * exposed additional HTTP codes * added basic headers and body handling --- Cargo.toml | 8 ++-- examples/simple/Cargo.toml | 17 ++++--- nginx_derive/Cargo.toml | 28 ++++++------ nginx_module/Cargo.toml | 30 ++++++------- nginx_module/src/http_request.rs | 76 +++++++++++++++++++++++++++++--- nginx_module/src/lib.rs | 18 +++++--- 6 files changed, 124 insertions(+), 53 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a5c33ca..3826f2a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,9 +1,7 @@ [workspace] -resolver = "2" + resolver = "2" -members = [ - "examples/simple" -] + members = [ "examples/simple" ] [profile.release] -debug = true \ No newline at end of file + debug = true diff --git a/examples/simple/Cargo.toml b/examples/simple/Cargo.toml index 3fe99e5..9e18970 100644 --- a/examples/simple/Cargo.toml +++ b/examples/simple/Cargo.toml @@ -1,16 +1,15 @@ [package] -name = "simple" -version = "0.1.0" -edition = "2021" + edition = "2021" + name = "simple" + version = "0.1.0" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [lib] -crate-type = ["staticlib"] - + crate-type = [ "staticlib" ] [dependencies] -anyhow = "1.0.71" -nginx_derive = { path = "../../nginx_derive" } -nginx_module = { path = "../../nginx_module" } + anyhow = "1.0.71" + nginx_derive = { path = "../../nginx_derive" } + nginx_module = { path = "../../nginx_module" } diff --git a/nginx_derive/Cargo.toml b/nginx_derive/Cargo.toml index 2db93e4..c5233ee 100644 --- a/nginx_derive/Cargo.toml +++ b/nginx_derive/Cargo.toml @@ -1,20 +1,20 @@ [package] -name = "nginx_derive" -version = "0.1.1" -edition = "2021" -authors = ["Gabriel Oprisan "] -description = "Helper crate for nginx-rust" -homepage = "https://github.com/g-Core/nginx-rust" -repository = "https://github.com/g-Core/nginx-rust" -readme = "README.md" -license = "Apache-2.0" + authors = [ "Gabriel Oprisan " ] + description = "Helper crate for nginx-rust" + edition = "2021" + homepage = "https://github.com/g-Core/nginx-rust" + license = "Apache-2.0" + name = "nginx_derive" + readme = "README.md" + repository = "https://github.com/g-Core/nginx-rust" + version = "0.1.1" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [lib] -proc-macro = true + proc-macro = true [dependencies] -syn = "2.0.18" -quote = "1.0.28" -proc-macro2 = "1.0.59" \ No newline at end of file + proc-macro2 = { version = "1.0.59" } + quote = { version = "1.0.28" } + syn = { version = "2.0.18" } diff --git a/nginx_module/Cargo.toml b/nginx_module/Cargo.toml index 63785e8..16b894e 100644 --- a/nginx_module/Cargo.toml +++ b/nginx_module/Cargo.toml @@ -1,22 +1,22 @@ [package] -name = "nginx_module" -version = "0.1.4" -edition = "2021" -build = "build.rs" -authors = ["Gabriel Oprisan "] -description = "Rust bindings for building Nginx modules" -homepage = "https://github.com/g-Core/nginx-rust" -repository = "https://github.com/g-Core/nginx-rust" -readme = "README.md" -license = "Apache-2.0" + authors = [ "Gabriel Oprisan " ] + build = "build.rs" + description = "Rust bindings for building Nginx modules" + edition = "2021" + homepage = "https://github.com/g-Core/nginx-rust" + license = "Apache-2.0" + name = "nginx_module" + readme = "README.md" + repository = "https://github.com/g-Core/nginx-rust" + version = "0.1.4" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [build-dependencies] -bindgen = "0.66.1" + bindgen = { version = "0.66.1" } [dependencies] -anyhow = "1.0.71" -bitflags = "2.3.1" -libc = "0.2.144" \ No newline at end of file + anyhow = { version = "1.0.71" } + bitflags = { version = "2.3.1" } + libc = { version = "0.2.144" } diff --git a/nginx_module/src/http_request.rs b/nginx_module/src/http_request.rs index dc09ede..e936753 100644 --- a/nginx_module/src/http_request.rs +++ b/nginx_module/src/http_request.rs @@ -2,6 +2,10 @@ * Copyright 2023 G-Core Innovations SARL */ +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] + + use std::{ marker::PhantomData, ops::{Deref, DerefMut}, @@ -9,17 +13,17 @@ use std::{ #[cfg(not(nginx_version_1023000))] use crate::{ - bindings::{ngx_array_push, ngx_array_t, NGX_DECLINED, NGX_OK}, + bindings::{ngx_array_push, ngx_array_t, NGX_DECLINED, NGX_OK, NGX_ERROR}, wrappers::array_init, }; use crate::{ bindings::{ ngx_http_get_indexed_variable, ngx_http_parse_multi_header_lines, ngx_http_request_t, - ngx_list_push, ngx_list_t, ngx_module_t, ngx_table_elt_t, - }, - ngx_str_t, - wrappers::IndexedVar, + ngx_list_push, ngx_list_t, ngx_module_t, ngx_table_elt_t, ngx_http_headers_out_t, ngx_buf_t, + ngx_http_send_header, ngx_str_t, ngx_alloc_chain_link, ngx_pcalloc, ngx_chain_s, ngx_http_output_filter, ngx_http_request_s}, + wrappers::IndexedVar, NGX_ERROR, }; + use crate::{connection::Connection, Log}; use super::{NgxStr, Pool}; @@ -57,6 +61,56 @@ impl<'a, Ctx: Default> HttpRequestAndContext<'a, Ctx> { Ok((req, ctx)) } } + + // get raw pointer to request structure + pub fn get_request_pointer ( + &mut self, + ) -> anyhow::Result<*mut ngx_http_request_t> { + let req = &mut self.0 as *mut ngx_http_request_t; + if req.is_null() { + anyhow::bail!("tried to get request pointer which is null"); + } + Ok(req) + } + + // send prepared headers + // headers should be prepared in headers_out structure + pub fn send_headers(&mut self) -> anyhow::Result<()> { + unsafe { + if 0==ngx_http_send_header(&(self.0) as *const ngx_http_request_t as *mut ngx_http_request_t) { + Ok(()) + } else { + Err(anyhow::anyhow!(NGX_ERROR)) + } + } + } + + // request allocation of chain_link structure from nginx's pool + // returns pointer to allocated structure + pub fn alloc_chain_link(&mut self) -> *mut ngx_chain_s { + unsafe { + let x = ngx_alloc_chain_link(self.0.pool); + x + } + } + + // request allocation of chain_link structure from nginx's pool + // returns pointer to allocated structure + pub fn alloc_buf(&mut self) -> *mut ngx_buf_t { + unsafe { + ngx_pcalloc(self.0.pool, std::mem::size_of::()) as *mut ngx_buf_t + } + } + + // request sending the prepared body + // body have to be prepared in ngx_chain_s structure + pub fn send_body(&mut self, chain: *mut ngx_chain_s) { + unsafe { + let x = ngx_http_output_filter(&mut self.0 as *mut ngx_http_request_s, chain); + println!("ngx_htt p_output_filter returned {}", x); + } + } + } impl<'a, Ctx> Deref for HttpRequestAndContext<'a, Ctx> { @@ -81,6 +135,13 @@ impl<'a> HttpRequest<'a> { } } + pub fn get_main_config<'b, Config>(&self, module: &ngx_module_t) -> Option<&'b Config> { + unsafe { + let conf = (*(*self.0.main).main_conf.add(module.ctx_index)) as *const Config; + conf.as_ref() + } + } + pub fn is_main(&self) -> bool { std::ptr::eq(&self.0, self.0.main) } @@ -183,6 +244,10 @@ impl<'a> HttpRequest<'a> { } } + pub fn get_headers_out_ref(&mut self) -> &mut ngx_http_headers_out_t { + &mut self.0.headers_out + } + pub fn unparsed_uri(&self) -> NgxStr { unsafe { NgxStr::from_raw(self.0.unparsed_uri) } } @@ -279,6 +344,7 @@ impl<'a> HttpRequest<'a> { cc = slice[0]; }; } + #[cfg(nginx_version_1023000)] { cc = self.0.headers_out.cache_control; diff --git a/nginx_module/src/lib.rs b/nginx_module/src/lib.rs index 5dcd2ed..7339477 100644 --- a/nginx_module/src/lib.rs +++ b/nginx_module/src/lib.rs @@ -1,5 +1,5 @@ /* - * Copyright 2023 G-Core Innovations SARL + * Copyright 2024 G-Core Innovations SARL */ mod bindings; @@ -10,12 +10,20 @@ use std::{ }; pub use bindings::{ - nginx_version, ngx_chain_t, ngx_command_t, ngx_conf_t, ngx_cycle_t, ngx_http_conf_ctx_t, + nginx_version, ngx_chain_t, ngx_buf_t, ngx_command_t, ngx_conf_t, ngx_cycle_t, ngx_http_conf_ctx_t, ngx_http_module_t, ngx_http_request_body_filter_pt, ngx_http_request_t, ngx_module_t, - ngx_str_t, NGX_CONF_TAKE1, NGX_DECLINED, NGX_ERROR, NGX_HTTP_FORBIDDEN, NGX_HTTP_LOC_CONF, - NGX_HTTP_MAIN_CONF, NGX_HTTP_MODULE, NGX_HTTP_SRV_CONF, NGX_HTTP_TEMPORARY_REDIRECT, - NGX_LOG_ERR, NGX_OK, NGX_RS_HTTP_LOC_CONF_OFFSET, NGX_RS_MODULE_SIGNATURE, + ngx_str_t, NGX_CONF_TAKE1, NGX_ERROR, NGX_HTTP_LOC_CONF, + NGX_HTTP_MAIN_CONF, NGX_HTTP_MODULE, NGX_HTTP_SRV_CONF, + NGX_LOG_ERR, NGX_OK, NGX_RS_HTTP_LOC_CONF_OFFSET, NGX_RS_MODULE_SIGNATURE, }; + +// add common http return codes +pub use bindings::{ + NGX_HTTP_FORBIDDEN, NGX_HTTP_TEMPORARY_REDIRECT, + NGX_HTTP_OK, NGX_HTTP_INTERNAL_SERVER_ERROR, NGX_DECLINED, NGX_HTTP_ACCEPTED, + NGX_HTTP_BAD_REQUEST, NGX_HTTP_NOT_ALLOWED, NGX_HTTP_NOT_FOUND, NGX_HTTP_NOT_IMPLEMENTED +}; + use bindings::{ ngx_array_push, ngx_cycle, ngx_http_core_main_conf_t, ngx_http_core_module, ngx_http_handler_pt, ngx_http_phases_NGX_HTTP_ACCESS_PHASE, ngx_http_top_request_body_filter,