feat: update axum to v0.8.1 (#595)

This commit is contained in:
Valerio Ageno
2025-02-26 19:01:10 +01:00
committed by GitHub
parent 059f3d6476
commit caf1a58a0b
11 changed files with 103 additions and 20 deletions
+1 -1
View File
@@ -362,7 +362,7 @@ mod tests {
("/about", "/about"),
("/posts/index", "/posts"),
("/posts/any-post", "/posts/any-post"),
("/posts/[post]", "/posts/:post"),
("/posts/[post]", "/posts/{post}"),
];
results.into_iter().for_each(|(path, expected_path)| {
+16 -5
View File
@@ -46,6 +46,20 @@ impl AxumInfo {
}
if route.is_dynamic {
let dyn_re = Regex::new(r"\[(.*?)\]").expect("Failed to create dyn regex");
let catch_all_re =
Regex::new(r"\{\.\.\.(.*?)\}").expect("Failed to create catch all regex");
let dyn_result = dyn_re.replace_all(&axum_route, |caps: &regex::Captures| {
format!("{{{}}}", &caps[1])
});
let axum_route = catch_all_re
.replace_all(&dyn_result, |caps: &regex::Captures| {
format!("{{*{}}}", &caps[1])
})
.to_string();
return AxumInfo {
module_import: module
.as_str()
@@ -55,10 +69,7 @@ impl AxumInfo {
.replace('[', "dyn_")
.replace("...", "catch_all_")
.replace(']', ""),
axum_route: axum_route
.replace("[...", "*")
.replace('[', ":")
.replace(']', ""),
axum_route,
};
}
@@ -296,7 +307,7 @@ mod tests {
let dyn_info = AxumInfo::new(&Route::new("/[posts]".to_string()));
assert_eq!(dyn_info.axum_route, "/:posts");
assert_eq!(dyn_info.axum_route, "/{posts}");
assert_eq!(dyn_info.module_import, "dyn_posts");
}
+4 -4
View File
@@ -127,19 +127,19 @@ fn it_successfully_create_catch_all_routes() {
assert!(temp_main_rs_content.contains("mod dyn_catch_all_all_routes;"));
assert!(temp_main_rs_content.contains(
r#".route("/api/*all_apis", post(api_dyn_catch_all_all_apis::post_tuono_internal_api))"#
r#".route("/api/{*all_apis}", post(api_dyn_catch_all_all_apis::post_tuono_internal_api))"#
));
assert!(temp_main_rs_content.contains(
r#".route("/*all_routes", get(dyn_catch_all_all_routes::tuono_internal_route))"#
r#".route("/{*all_routes}", get(dyn_catch_all_all_routes::tuono_internal_route))"#
));
assert!(temp_main_rs_content.contains(
r#".route("/*all_routes", get(dyn_catch_all_all_routes::tuono_internal_route))"#
r#".route("/{*all_routes}", get(dyn_catch_all_all_routes::tuono_internal_route))"#
));
assert!(temp_main_rs_content.contains(
r#".route("/__tuono/data/*all_routes", get(dyn_catch_all_all_routes::tuono_internal_api))"#
r#".route("/__tuono/data/{*all_routes}", get(dyn_catch_all_all_routes::tuono_internal_api))"#
));
}
+4 -4
View File
@@ -18,8 +18,8 @@ include = [
[dependencies]
ssr_rs = "0.8.1"
axum = {version = "0.7.5", features = ["json", "ws"]}
axum-extra = {version = "0.9.6", features = ["cookie"]}
axum = {version = "0.8.1", features = ["json", "ws"]}
axum-extra = {version = "0.10.0", features = ["cookie"]}
tokio = { version = "1.37.0", features = ["full"] }
serde = { version = "1.0.202", features = ["derive"] }
erased-serde = "0.4.5"
@@ -35,9 +35,9 @@ colored = "2.1.0"
tuono_lib_macros = {path = "../tuono_lib_macros", version = "0.17.8"}
tuono_internal = {path = "../tuono_internal", version = "0.17.8"}
# Match the same version used by axum
tokio-tungstenite = "0.24.0"
tokio-tungstenite = "0.26.0"
futures-util = { version = "0.3", default-features = false, features = ["sink", "std"] }
tungstenite = "0.24.0"
tungstenite = "0.26.0"
http = "1.1.0"
pin-project = "1.1.7"
tower = "0.5.1"
+1 -1
View File
@@ -64,7 +64,7 @@ impl Server {
.to_owned()
.layer(LoggerLayer::new())
.route("/vite-server/", get(vite_websocket_proxy))
.route("/vite-server/*path", get(vite_reverse_proxy))
.route("/vite-server/{*path}", get(vite_reverse_proxy))
.fallback_service(
ServeDir::new(DEV_PUBLIC_DIR)
.fallback(get(catch_all).layer(LoggerLayer::new())),
+4 -4
View File
@@ -1,5 +1,5 @@
use crate::config::GLOBAL_CONFIG;
use axum::extract::ws::{self, WebSocket, WebSocketUpgrade};
use axum::extract::ws::{self, Utf8Bytes as AxumUtf8Bytes, WebSocket, WebSocketUpgrade};
use axum::response::IntoResponse;
use futures_util::{SinkExt, StreamExt};
use tokio_tungstenite::connect_async;
@@ -64,7 +64,7 @@ async fn handle_socket(mut tuono_socket: WebSocket) {
while let Some(msg) = tuono_receiver.next().await {
if let Ok(msg) = msg {
let msg_to_vite = match msg.clone() {
ws::Message::Text(str) => Message::Text(str),
ws::Message::Text(str) => Message::Text(str.to_string().into()),
ws::Message::Pong(payload) => Message::Pong(payload),
ws::Message::Ping(payload) => Message::Ping(payload),
ws::Message::Binary(payload) => Message::Binary(payload),
@@ -91,7 +91,7 @@ async fn handle_socket(mut tuono_socket: WebSocket) {
tokio::spawn(async move {
while let Some(Ok(msg)) = vite_receiver.next().await {
let msg_to_browser = match msg {
Message::Text(str) => ws::Message::Text(str),
Message::Text(str) => ws::Message::Text(AxumUtf8Bytes::from(str.to_string())),
Message::Ping(payload) => ws::Message::Ping(payload),
Message::Pong(payload) => ws::Message::Pong(payload),
Message::Binary(payload) => ws::Message::Binary(payload),
@@ -100,7 +100,7 @@ async fn handle_socket(mut tuono_socket: WebSocket) {
Message::Close(_) => ws::Message::Close(None),
_ => {
eprintln!("Unexpected message from the vite WebSocket to the browser: {msg:?}");
ws::Message::Text("Unhandled".to_string())
ws::Message::Text("Unhandled".to_string().into())
}
};
+44
View File
@@ -103,3 +103,47 @@ async fn api_route_route() {
"{\"data\":\"{}\",\"info\":{\"redirect_destination\":null}}"
);
}
#[tokio::test]
#[serial]
async fn it_reads_the_catch_all_path_parameter() {
let app = MockTuonoServer::spawn().await;
let client = reqwest::Client::builder()
.redirect(reqwest::redirect::Policy::none())
.build()
.unwrap();
let server_url = format!("http://{}:{}", &app.address, &app.port);
let response = client
.get(format!("{server_url}/catch_all/url_parameter"))
.send()
.await
.expect("Failed to execute request.");
assert!(response.status().is_success());
assert_eq!(response.text().await.unwrap(), "url_parameter");
}
#[tokio::test]
#[serial]
async fn it_reads_the_path_parameter() {
let app = MockTuonoServer::spawn().await;
let client = reqwest::Client::builder()
.redirect(reqwest::redirect::Policy::none())
.build()
.unwrap();
let server_url = format!("http://{}:{}", &app.address, &app.port);
let response = client
.get(format!("{server_url}/dynamic/url_parameter"))
.send()
.await
.expect("Failed to execute request.");
assert!(response.status().is_success());
assert_eq!(response.text().await.unwrap(), "url_parameter");
}
+11
View File
@@ -0,0 +1,11 @@
use tuono_lib::Request;
#[tuono_lib::api(GET)]
async fn read_catch_all_parameter(req: Request) -> String {
let param = req
.params
.get("catch_all")
.expect("Failed to get the catch_all param");
param.to_string()
}
@@ -0,0 +1,11 @@
use tuono_lib::Request;
#[tuono_lib::api(GET)]
async fn read_dynamic_parameter(req: Request) -> String {
let param = req
.params
.get("parameter")
.expect("Failed to get the catch_all param");
param.to_string()
}
+5 -1
View File
@@ -7,6 +7,8 @@ use tempfile::{tempdir, TempDir};
use tuono_lib::axum::routing::get;
use tuono_lib::{axum::Router, tuono_internal_init_v8_platform, Mode, Server};
use crate::utils::catch_all::get_tuono_internal_api as catch_all;
use crate::utils::dynamic_parameter::get_tuono_internal_api as dynamic_parameter;
use crate::utils::health_check::get_tuono_internal_api as health_check;
use crate::utils::route as html_route;
use crate::utils::route::tuono_internal_api as route_api;
@@ -76,7 +78,9 @@ impl MockTuonoServer {
.route("/", get(html_route::tuono_internal_route))
.route("/tuono/data", get(html_route::tuono_internal_api))
.route("/health_check", get(health_check))
.route("/route-api", get(route_api));
.route("/route-api", get(route_api))
.route("/catch_all/{*catch_all}", get(catch_all))
.route("/dynamic/{parameter}", get(dynamic_parameter));
let server = Server::init(router, Mode::Prod).await;
+2
View File
@@ -1,3 +1,5 @@
pub mod catch_all;
pub mod dynamic_parameter;
pub mod health_check;
pub mod mock_server;
pub mod route;