From fe2d21cf88c47657a53f5ea8fe047ae68916830a Mon Sep 17 00:00:00 2001 From: Jack Wampler Date: Mon, 17 Feb 2025 09:05:24 -0700 Subject: [PATCH] Add a middleware layer to the nym api allowing for data compression (#5451) --- Cargo.lock | 93 +++++++++++++++++++ nym-api/Cargo.toml | 2 +- nym-api/src/network/handlers.rs | 2 + nym-api/src/nym_nodes/handlers/legacy.rs | 2 + nym-api/src/nym_nodes/handlers/mod.rs | 2 + .../src/nym_nodes/handlers/unstable/mod.rs | 2 + 6 files changed, 102 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index b0b0f29182..57c87dc0f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -128,6 +128,21 @@ dependencies = [ "memchr", ] +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + [[package]] name = "allocator-api2" version = "0.2.18" @@ -283,6 +298,22 @@ dependencies = [ "futures-core", ] +[[package]] +name = "async-compression" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df895a515f70646414f4b45c0b79082783b80552b373a68283012928df56f522" +dependencies = [ + "brotli", + "flate2", + "futures-core", + "memchr", + "pin-project-lite", + "tokio", + "zstd", + "zstd-safe", +] + [[package]] name = "async-lock" version = "3.4.0" @@ -797,6 +828,27 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab9008b6bb9fc80b5277f2fe481c09e828743d9151203e804583eb4c9e15b31d" +[[package]] +name = "brotli" +version = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc97b8f16f944bba54f0433f07e30be199b6dc2bd25937444bbad560bcea29bd" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "4.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74fa05ad7d803d413eb8380983b092cbbaf9a85f151b871360e7b00cd7060b37" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + [[package]] name = "bs58" version = "0.5.1" @@ -914,6 +966,8 @@ version = "1.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b62ac837cdb5cb22e10a256099b4fc502b1dfe560cb282963a974d7abd80e476" dependencies = [ + "jobserver", + "libc", "shlex", ] @@ -3902,6 +3956,15 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + [[package]] name = "js-sys" version = "0.3.76" @@ -10527,8 +10590,10 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" dependencies = [ + "async-compression", "bitflags 2.5.0", "bytes", + "futures-core", "futures-util", "http 1.1.0", "http-body 1.0.0", @@ -12165,3 +12230,31 @@ dependencies = [ "once_cell", "simd-adler32", ] + +[[package]] +name = "zstd" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.13+zstd.1.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/nym-api/Cargo.toml b/nym-api/Cargo.toml index 8ea8d4e1e2..4542c8329c 100644 --- a/nym-api/Cargo.toml +++ b/nym-api/Cargo.toml @@ -65,7 +65,7 @@ zeroize = { workspace = true } # for axum server axum = { workspace = true, features = ["tokio"] } axum-extra = { workspace = true, features = ["typed-header"] } -tower-http = { workspace = true, features = ["cors", "trace"] } +tower-http = { workspace = true, features = ["cors", "trace", "compression-br", "compression-deflate", "compression-gzip", "compression-zstd"] } utoipa = { workspace = true, features = ["axum_extras", "time"] } utoipauto = { workspace = true } utoipa-swagger-ui = { workspace = true, features = ["axum"] } diff --git a/nym-api/src/network/handlers.rs b/nym-api/src/network/handlers.rs index ff398a16cb..708a1cf86f 100644 --- a/nym-api/src/network/handlers.rs +++ b/nym-api/src/network/handlers.rs @@ -6,6 +6,7 @@ use crate::support::http::state::AppState; use axum::{extract, Router}; use nym_contracts_common::ContractBuildInformation; use std::collections::HashMap; +use tower_http::compression::CompressionLayer; use utoipa::ToSchema; pub(crate) fn nym_network_routes() -> Router { @@ -16,6 +17,7 @@ pub(crate) fn nym_network_routes() -> Router { "/nym-contracts-detailed", axum::routing::get(nym_contracts_detailed), ) + .layer(CompressionLayer::new()) } #[utoipa::path( diff --git a/nym-api/src/nym_nodes/handlers/legacy.rs b/nym-api/src/nym_nodes/handlers/legacy.rs index 3262f997c1..adb96f2f76 100644 --- a/nym-api/src/nym_nodes/handlers/legacy.rs +++ b/nym-api/src/nym_nodes/handlers/legacy.rs @@ -7,6 +7,7 @@ use axum::extract::State; use axum::{Json, Router}; use nym_api_requests::legacy::LegacyMixNodeBondWithLayer; use nym_api_requests::models::{LegacyDescribedGateway, LegacyDescribedMixNode}; +use tower_http::compression::CompressionLayer; // we want to mark the routes as deprecated in swagger, but still expose them #[allow(deprecated)] @@ -20,6 +21,7 @@ pub(crate) fn legacy_nym_node_routes() -> Router { "/mixnodes/described", axum::routing::get(get_mixnodes_described), ) + .layer(CompressionLayer::new()) } #[utoipa::path( diff --git a/nym-api/src/nym_nodes/handlers/mod.rs b/nym-api/src/nym_nodes/handlers/mod.rs index 6474088b3b..da6ef82c7b 100644 --- a/nym-api/src/nym_nodes/handlers/mod.rs +++ b/nym-api/src/nym_nodes/handlers/mod.rs @@ -21,6 +21,7 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use std::time::Duration; use time::{Date, OffsetDateTime}; +use tower_http::compression::CompressionLayer; use utoipa::{IntoParams, ToSchema}; pub(crate) mod legacy; @@ -45,6 +46,7 @@ pub(crate) fn nym_node_routes() -> Router { // to make it compatible with all the explorers that were used to using 0-100 values .route("/uptime-history/:node_id", get(get_node_uptime_history)) .route("/rewarded-set", get(rewarded_set)) + .layer(CompressionLayer::new()) } #[utoipa::path( diff --git a/nym-api/src/nym_nodes/handlers/unstable/mod.rs b/nym-api/src/nym_nodes/handlers/unstable/mod.rs index c629834919..1ef533fa9a 100644 --- a/nym-api/src/nym_nodes/handlers/unstable/mod.rs +++ b/nym-api/src/nym_nodes/handlers/unstable/mod.rs @@ -33,6 +33,7 @@ use axum::routing::get; use axum::Router; use nym_api_requests::nym_nodes::NodeRoleQueryParam; use serde::Deserialize; +use tower_http::compression::CompressionLayer; pub(crate) mod full_fat; mod helpers; @@ -73,6 +74,7 @@ pub(crate) fn nym_node_routes_unstable() -> Router { .nest("/full-fat", Router::new().route("/", get(nodes_detailed))) .route("/gateways/skimmed", get(skimmed::deprecated_gateways_basic)) .route("/mixnodes/skimmed", get(skimmed::deprecated_mixnodes_basic)) + .layer(CompressionLayer::new()) } #[derive(Debug, Deserialize, utoipa::IntoParams)]