Update axum (#2713)

# Description of Changes

~~Axum now has what we need out of it for a websocket wrapper, so we no
longer need to duplicate `util/flat_csv.rs` and `util/websocket.rs`,
meaning we have less code to maintain.~~ Nevermind, we know send raw
frames, which axum's wrapper does not support. Makes this PR simpler.

# Expected complexity level and risk

2 - upgrading a dependency is a risk, but looking through the
[changelog](https://github.com/tokio-rs/axum/blob/main/axum/CHANGELOG.md#080)
there isn't anything that should affect us.

# Testing

<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->

- [x] tests pass <!-- maybe a test you want to do -->
- [ ] <!-- maybe a test you want a reviewer to do, so they can check it
off when they're satisfied. -->

Co-authored-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
This commit is contained in:
Noa
2026-04-16 08:08:25 -05:00
committed by GitHub
parent ddba47f76a
commit 21b58ef993
8 changed files with 23 additions and 47 deletions
Generated
+11 -30
View File
@@ -342,13 +342,13 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]] [[package]]
name = "axum" name = "axum"
version = "0.7.9" version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" checksum = "021e862c184ae977658b36c4500f7feac3221ca5da43e3f25bd04ab6c79a29b5"
dependencies = [ dependencies = [
"async-trait",
"axum-core", "axum-core",
"bytes", "bytes",
"form_urlencoded",
"futures-util", "futures-util",
"http 1.3.1", "http 1.3.1",
"http-body 1.0.1", "http-body 1.0.1",
@@ -376,13 +376,12 @@ dependencies = [
[[package]] [[package]]
name = "axum-core" name = "axum-core"
version = "0.4.5" version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" checksum = "68464cd0412f486726fb3373129ef5d2993f90c34bc2bc1c1e9943b2f4fc7ca6"
dependencies = [ dependencies = [
"async-trait",
"bytes", "bytes",
"futures-util", "futures-core",
"http 1.3.1", "http 1.3.1",
"http-body 1.0.1", "http-body 1.0.1",
"http-body-util", "http-body-util",
@@ -397,22 +396,21 @@ dependencies = [
[[package]] [[package]]
name = "axum-extra" name = "axum-extra"
version = "0.9.6" version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c794b30c904f0a1c2fb7740f7df7f7972dfaa14ef6f57cb6178dc63e5dca2f04" checksum = "45bf463831f5131b7d3c756525b305d40f1185b688565648a92e1392ca35713d"
dependencies = [ dependencies = [
"axum", "axum",
"axum-core", "axum-core",
"bytes", "bytes",
"fastrand",
"futures-util", "futures-util",
"headers", "headers",
"http 1.3.1", "http 1.3.1",
"http-body 1.0.1", "http-body 1.0.1",
"http-body-util", "http-body-util",
"mime", "mime",
"multer",
"pin-project-lite", "pin-project-lite",
"rustversion",
"serde", "serde",
"tower", "tower",
"tower-layer", "tower-layer",
@@ -4006,9 +4004,9 @@ dependencies = [
[[package]] [[package]]
name = "matchit" name = "matchit"
version = "0.7.3" version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3"
[[package]] [[package]]
name = "md-5" name = "md-5"
@@ -4114,23 +4112,6 @@ dependencies = [
"spacetimedb 2.1.0", "spacetimedb 2.1.0",
] ]
[[package]]
name = "multer"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b"
dependencies = [
"bytes",
"encoding_rs",
"futures-util",
"http 1.3.1",
"httparse",
"memchr",
"mime",
"spin",
"version_check",
]
[[package]] [[package]]
name = "munge" name = "munge"
version = "0.4.7" version = "0.4.7"
+2 -2
View File
@@ -156,8 +156,8 @@ arrayvec = "0.7.2"
async-channel = "2.5" async-channel = "2.5"
async-stream = "0.3.6" async-stream = "0.3.6"
async-trait = "0.1.68" async-trait = "0.1.68"
axum = { version = "0.7", features = ["tracing"] } axum = { version = "0.8.4", features = ["tracing"] }
axum-extra = { version = "0.9", features = ["typed-header"] } axum-extra = { version = "0.10", features = ["typed-header"] }
backtrace = "0.3.66" backtrace = "0.3.66"
base64 = "0.21.2" base64 = "0.21.2"
bigdecimal = "0.4.7" bigdecimal = "0.4.7"
-2
View File
@@ -385,7 +385,6 @@ pub struct SpacetimeAuthHeader {
auth: Option<SpacetimeAuth>, auth: Option<SpacetimeAuth>,
} }
#[async_trait::async_trait]
impl<S: NodeDelegate + Send + Sync> axum::extract::FromRequestParts<S> for SpacetimeAuthHeader { impl<S: NodeDelegate + Send + Sync> axum::extract::FromRequestParts<S> for SpacetimeAuthHeader {
type Rejection = AuthorizationRejection; type Rejection = AuthorizationRejection;
async fn from_request_parts(parts: &mut request::Parts, state: &S) -> Result<Self, Self::Rejection> { async fn from_request_parts(parts: &mut request::Parts, state: &S) -> Result<Self, Self::Rejection> {
@@ -461,7 +460,6 @@ impl SpacetimeAuthHeader {
pub struct SpacetimeAuthRequired(pub SpacetimeAuth); pub struct SpacetimeAuthRequired(pub SpacetimeAuth);
#[async_trait::async_trait]
impl<S: NodeDelegate + Send + Sync> axum::extract::FromRequestParts<S> for SpacetimeAuthRequired { impl<S: NodeDelegate + Send + Sync> axum::extract::FromRequestParts<S> for SpacetimeAuthRequired {
type Rejection = AuthorizationRejection; type Rejection = AuthorizationRejection;
async fn from_request_parts(parts: &mut request::Parts, state: &S) -> Result<Self, Self::Rejection> { async fn from_request_parts(parts: &mut request::Parts, state: &S) -> Result<Self, Self::Rejection> {
+5 -5
View File
@@ -643,7 +643,7 @@ pub async fn reset<S: NodeDelegate + ControlStateDelegate + Authorization>(
host_type, host_type,
}): Query<ResetDatabaseQueryParams>, }): Query<ResetDatabaseQueryParams>,
Extension(auth): Extension<SpacetimeAuth>, Extension(auth): Extension<SpacetimeAuth>,
program_bytes: Option<Bytes>, program_bytes: Bytes,
) -> axum::response::Result<axum::Json<PublishResult>> { ) -> axum::response::Result<axum::Json<PublishResult>> {
let database_identity = name_or_identity.resolve(&ctx).await?; let database_identity = name_or_identity.resolve(&ctx).await?;
let database = worker_ctx_find_database(&ctx, &database_identity) let database = worker_ctx_find_database(&ctx, &database_identity)
@@ -658,7 +658,7 @@ pub async fn reset<S: NodeDelegate + ControlStateDelegate + Authorization>(
&auth.claims.identity, &auth.claims.identity,
DatabaseResetDef { DatabaseResetDef {
database_identity, database_identity,
program_bytes, program_bytes: Some(program_bytes),
num_replicas, num_replicas,
host_type: Some(host_type), host_type: Some(host_type),
}, },
@@ -743,7 +743,7 @@ pub async fn publish<S: NodeDelegate + ControlStateDelegate + Authorization>(
host_type, host_type,
}), }),
Extension(auth), Extension(auth),
Some(program_bytes), program_bytes,
) )
.await; .await;
} }
@@ -1271,7 +1271,7 @@ where
.route("/names", self.names_put) .route("/names", self.names_put)
.route("/identity", self.identity_get) .route("/identity", self.identity_get)
.route("/subscribe", self.subscribe_get) .route("/subscribe", self.subscribe_get)
.route("/call/:reducer", self.call_reducer_procedure_post) .route("/call/{reducer}", self.call_reducer_procedure_post)
.route("/schema", self.schema_get) .route("/schema", self.schema_get)
.route("/logs", self.logs_get) .route("/logs", self.logs_get)
.route("/sql", self.sql_post) .route("/sql", self.sql_post)
@@ -1281,7 +1281,7 @@ where
axum::Router::new() axum::Router::new()
.route("/", self.root_post) .route("/", self.root_post)
.nest("/:name_or_identity", db_router) .nest("/{name_or_identity}", db_router)
.route_layer(axum::middleware::from_fn_with_state(ctx, anon_auth_middleware::<S>)) .route_layer(axum::middleware::from_fn_with_state(ctx, anon_auth_middleware::<S>))
} }
} }
+1 -1
View File
@@ -131,7 +131,7 @@ where
{ {
use axum::routing::get; use axum::routing::get;
axum::Router::new().route( axum::Router::new().route(
"/:identity", "/{identity}",
get(get_energy_balance::<S>) get(get_energy_balance::<S>)
.put(set_energy_balance::<S>) .put(set_energy_balance::<S>)
.post(add_energy::<S>), .post(add_energy::<S>),
+2 -2
View File
@@ -175,7 +175,7 @@ where
.route("/", self.create_post) .route("/", self.create_post)
.route("/public-key", self.public_key_get) .route("/public-key", self.public_key_get)
.route("/websocket-token", self.websocket_token_post) .route("/websocket-token", self.websocket_token_post)
.route("/:identity/verify", self.verify_get) .route("/{identity}/verify", self.verify_get)
.route("/:identity/databases", self.databases_get) .route("/{identity}/databases", self.databases_get)
} }
} }
+1 -3
View File
@@ -21,7 +21,6 @@ use crate::{log_and_500, ControlStateReadAccess};
pub struct ByteStringBody(pub ByteString); pub struct ByteStringBody(pub ByteString);
#[async_trait::async_trait]
impl<S: Send + Sync> FromRequest<S> for ByteStringBody { impl<S: Send + Sync> FromRequest<S> for ByteStringBody {
type Rejection = axum::response::Response; type Rejection = axum::response::Response;
@@ -165,8 +164,7 @@ impl fmt::Display for NameOrIdentity {
pub struct EmptyBody; pub struct EmptyBody;
#[async_trait::async_trait] impl<S: Sync> FromRequest<S> for EmptyBody {
impl<S> FromRequest<S> for EmptyBody {
type Rejection = axum::response::Response; type Rejection = axum::response::Response;
async fn from_request(req: Request, _state: &S) -> Result<Self, Self::Rejection> { async fn from_request(req: Request, _state: &S) -> Result<Self, Self::Rejection> {
let body = req.into_body(); let body = req.into_body();
+1 -2
View File
@@ -78,8 +78,7 @@ pub enum WebSocketUpgradeRejection {
KeyMissing, KeyMissing,
} }
#[async_trait::async_trait] impl<S: Sync> FromRequestParts<S> for WebSocketUpgrade {
impl<S> FromRequestParts<S> for WebSocketUpgrade {
type Rejection = WebSocketUpgradeRejection; type Rejection = WebSocketUpgradeRejection;
async fn from_request_parts(parts: &mut http::request::Parts, _state: &S) -> Result<Self, Self::Rejection> { async fn from_request_parts(parts: &mut http::request::Parts, _state: &S) -> Result<Self, Self::Rejection> {
use WebSocketUpgradeRejection::*; use WebSocketUpgradeRejection::*;