From 157ade1c85d746584baf9ca7c0ac184b6a8600dd Mon Sep 17 00:00:00 2001 From: Jose Quintana Date: Mon, 12 Jul 2021 23:40:15 +0200 Subject: [PATCH] refactor: decrease allocations during 404/50x error page responses --- Cargo.lock | 40 +++++++++++++++------------------------- Cargo.toml | 1 - src/error_page.rs | 47 ++++++++++++++++++++--------------------------- src/handler.rs | 18 ++++++++++++++++-- src/server.rs | 12 +++++------- 5 files changed, 56 insertions(+), 62 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2c68a75..5c13a4a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -34,9 +34,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.41" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15af2628f6890fe2609a3b91bef4c83450512802e59489f9c1cb1fa5df064a61" +checksum = "595d3cfa7a60d4555cb5067b99f07142a08ea778de5cf993f7b75c7d8fabc486" [[package]] name = "async-compression" @@ -114,15 +114,9 @@ checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" [[package]] name = "cc" -version = "1.0.68" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787" - -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" [[package]] name = "cfg-if" @@ -168,7 +162,7 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -202,7 +196,7 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd3aec53de10fe96d7d8c565eb17f2c687bb5518a2ec453b5b1252964526abe0" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "crc32fast", "libc", "miniz_oxide", @@ -492,9 +486,9 @@ checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790" [[package]] name = "listenfd" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "492158e732f2e2de81c592f0a2427e57e12cd3d59877378fe7af624b6bbe0ca1" +checksum = "809e514e2cb8a9624701346ea3e694c1766d76778e343e537d873c1c366e79a7" dependencies = [ "libc", "uuid", @@ -507,7 +501,7 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -581,7 +575,7 @@ checksum = "fa9b4819da1bc61c0ea48b63b7bc8604064dd43013e7cc325df098d49cd7c18a" dependencies = [ "bitflags", "cc", - "cfg-if 1.0.0", + "cfg-if", "libc", ] @@ -807,7 +801,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c4cfa741c5832d0ef7fab46cabed29c2aae926db0b11bb2069edd8db5e64e16" dependencies = [ "block-buffer", - "cfg-if 1.0.0", + "cfg-if", "cpufeatures", "digest", "opaque-debug", @@ -867,7 +861,6 @@ dependencies = [ "listenfd", "mime_guess", "num_cpus", - "once_cell", "percent-encoding", "pin-project", "structopt", @@ -1008,7 +1001,7 @@ version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -1124,12 +1117,9 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "uuid" -version = "0.6.5" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1436e58182935dcd9ce0add9ea0b558e8a87befe01c1a301e6020aeb0876363" -dependencies = [ - "cfg-if 0.1.10", -] +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" [[package]] name = "version_check" @@ -1159,7 +1149,7 @@ version = "0.2.74" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "wasm-bindgen-macro", ] diff --git a/Cargo.toml b/Cargo.toml index 45e40a6..5603020 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,7 +40,6 @@ bytes = "1.0" percent-encoding = "2.1" structopt = { version = "0.3", default-features = false } num_cpus = { version = "1.13" } -once_cell = "1.7" pin-project = "1.0" tokio-rustls = { version = "0.22" } humansize = "1.1" diff --git a/src/error_page.rs b/src/error_page.rs index b3853ec..193bec3 100644 --- a/src/error_page.rs +++ b/src/error_page.rs @@ -1,15 +1,16 @@ use headers::{AcceptRanges, ContentLength, ContentType, HeaderMapExt, HeaderValue}; use http::header::CONTENT_TYPE; use hyper::{Body, Method, Response, StatusCode}; -use once_cell::sync::OnceCell; use crate::Result; -pub static PAGE_404: OnceCell = OnceCell::new(); -pub static PAGE_50X: OnceCell = OnceCell::new(); - /// It returns a HTTP error response which also handles available `404` or `50x` HTML content. -pub fn error_response(method: &Method, status_code: &StatusCode) -> Result> { +pub fn error_response( + method: &Method, + status_code: &StatusCode, + page404: &str, + page50x: &str, +) -> Result> { tracing::warn!(method = ?method, status = status_code.as_u16(), error = ?status_code.to_owned()); // Check for 4xx/50x status codes and handle their corresponding HTML content @@ -36,15 +37,7 @@ pub fn error_response(method: &Method, status_code: &StatusCode) -> Result { // Extra check for 404 status code and its HTML content if status_code == &StatusCode::NOT_FOUND { - error_page_content = match PAGE_404.get() { - Some(s) => s.to_owned(), - None => { - tracing::error!( - "404 error page content is not accessible or `PAGE_404` uninitialized" - ); - String::new() - } - }; + error_page_content = page404.to_owned(); } status_code } @@ -59,15 +52,7 @@ pub fn error_response(method: &Method, status_code: &StatusCode) -> Result { // HTML content check for status codes 50x - error_page_content = match PAGE_50X.get() { - Some(s) => s.to_owned(), - None => { - tracing::error!( - "50x error page content is not accessible or `PAGE_50X` uninitialized" - ); - String::new() - } - }; + error_page_content = page50x.to_owned(); status_code } // other status codes @@ -75,10 +60,18 @@ pub fn error_response(method: &Method, status_code: &StatusCode) -> Result{}

{}

", - status_code, status_code - ); + error_page_content = [ + "", + status_code.as_str(), + " ", + status_code.canonical_reason().unwrap_or_default(), + "

", + status_code.as_str(), + " ", + status_code.canonical_reason().unwrap_or_default(), + "

", + ] + .concat(); } let mut body = Body::empty(); diff --git a/src/handler.rs b/src/handler.rs index f182e10..c0282bb 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -12,6 +12,8 @@ pub struct RequestHandlerOpts { pub dir_listing: bool, pub cors: Option>, pub security_headers: bool, + pub page404: Arc, + pub page50x: Arc, } /// It defines the main request handler used by the Hyper service request. @@ -42,7 +44,12 @@ impl RequestHandler { } Err(e) => { tracing::debug!("cors error kind: {:?}", e); - return error_page::error_response(method, &StatusCode::FORBIDDEN); + return error_page::error_response( + method, + &StatusCode::FORBIDDEN, + self.opts.page404.as_ref(), + self.opts.page50x.as_ref(), + ); } }; } @@ -59,6 +66,8 @@ impl RequestHandler { return error_page::error_response( method, &StatusCode::INTERNAL_SERVER_ERROR, + self.opts.page404.as_ref(), + self.opts.page50x.as_ref(), ); } }; @@ -75,7 +84,12 @@ impl RequestHandler { Ok(resp) } - Err(status) => error_page::error_response(method, &status), + Err(status) => error_page::error_response( + method, + &status, + self.opts.page404.as_ref(), + self.opts.page50x.as_ref(), + ), } } } diff --git a/src/server.rs b/src/server.rs index 01a1f1f..b3950af 100644 --- a/src/server.rs +++ b/src/server.rs @@ -8,7 +8,7 @@ use structopt::StructOpt; use crate::handler::{RequestHandler, RequestHandlerOpts}; use crate::tls::{TlsAcceptor, TlsConfigBuilder}; use crate::{config::Config, service::RouterService, Result}; -use crate::{cors, error_page, helpers, logger, signals}; +use crate::{cors, helpers, logger, signals}; /// Define a multi-thread HTTP or HTTP/2 web server. pub struct Server { @@ -81,12 +81,8 @@ impl Server { let root_dir = Arc::new(helpers::get_valid_dirpath(&opts.root)?); // Custom error pages content - error_page::PAGE_404 - .set(helpers::read_file_content(opts.page404.as_ref())) - .expect("page 404 is not initialized"); - error_page::PAGE_50X - .set(helpers::read_file_content(opts.page50x.as_ref())) - .expect("page 50x is not initialized"); + let page404 = Arc::from(helpers::read_file_content(opts.page404.as_ref()).as_str()); + let page50x = Arc::from(helpers::read_file_content(opts.page50x.as_ref()).as_str()); // Number of worker threads option let threads = self.threads; @@ -115,6 +111,8 @@ impl Server { dir_listing, cors, security_headers, + page404, + page50x, }, }); -- libgit2 1.7.2