-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bug with / in nest #2267
Comments
Hello. axum/axum/src/routing/tests/mod.rs Lines 319 to 330 in 8854e66
Or axum/axum/src/routing/path_router.rs Lines 479 to 490 in 8854e66
it would seem that this behaviour is actually deliberate. |
what the RFC says is that if a route with the / at the end is not clearly defined (implicit rule added by the crawler if I understood correctly) |
I encountered this same behavior while testing my server; though, I don't use any nested routers. From what I could find in other issues and discussions was that this behavior is intended. As a work-around in my implementation, I have used tower_http's |
I find this behaviour odd, if its a route with only a slash it ignores that slash for the route, but if it has has use axum::{routing::get, Router};
#[tokio::main]
async fn main() {
let nest_routes = Router::new()
.route("/", get(|| async { "http://127.0.0.1/nest/\n" })) // both http://127.0.0.1/nest (only works without a trailing slash)
.route("/test/", get(|| async { "http://127.0.0.1/nest/test/\n" })); // both http://127.0.0.1/nest/test/ (only works with a traling slash)
let app = Router::new()
.route("/", get(|| async { "http://127.0.0.1/\n" })) // both http://127.0.0.1 and http://127.0.0.1/
.route("/test/", get(|| async { "http://127.0.0.1/test/\n" })) // http://127.0.0.1/test/ (only works with a trailing slash)
.nest("/nest", nest_routes);
axum::Server::bind(&"127.0.0.1:8080".parse().unwrap())
.serve(app.into_make_service())
.await
.unwrap();
} |
I just came across the same issue as well. I thought that by nesting |
Hey everyone, fn rewrite_request_uri<B>(mut req: Request<B>) -> Request<B> {
let uri = req.uri().clone();
let path = uri.path();
if path.ends_with('/') && !path.ends_with("//") && path.len() > 1 {
let new_path = path.trim_end_matches('/');
let new_uri = format!(
"{}{}",
new_path,
uri.query().map_or(String::from(""), |q| format!("?{}", q))
);
*req.uri_mut() = new_uri.parse().expect("Failed to parse new URI");
}
req
} Note !path.ends_with("//") condition which prevents rewriting urls with multiple slashes. If you need to strip away all trailing slashes remove this part. I'm not entirely sure if this is the best approach, but it's been working well for me. If anyone has suggestions for improvement or alternative methods, I'd love to hear them. |
It took me a while to understand this bug report. It is actually intended behavior, there's some previous discussion about this here. I'm going to close this as it's framed as a bug report while the behavior is actually intentional, but have created #2659 as a point of discussion about changing this behavior. |
First, there is There used to be automatic redirects in axum but they were removed in 0.6 #1119 RFC 3386 was mentioned, but I read it as saying that the two paths with and without a trailing slash should be considered equivalent only if the server hints that by e.g. redirecting from one to the other. RFC excerpt
So I think what axum does now is correct and it should not create multiple paths on its own unless instructed to do so. |
Bug Report
Version
Platform
Linux mortifia 6.5.5-1-MANJARO #1 SMP PREEMPT_DYNAMIC Sat Sep 23 12:48:15 UTC 2023 x86_64 GNU/Linux
Description
GET
http://localhost:3000/advertisement
->.route("/", get(advertisement))
GET
http://localhost:3000/advertisement/xxxx
->.route("/:id", get(advertisement_id))
GET
http://localhost:3000/advertisement/
->HTTP ERROR 404
// is the bugbut is the same path
expected
GET
http://localhost:3000/advertisement/
->.route("/", get(advertisement))
The text was updated successfully, but these errors were encountered: