Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

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

Extension middleware not added to fallbacks? #3183

Closed
Pranoy1c opened this issue Jan 19, 2025 · 0 comments
Closed

Extension middleware not added to fallbacks? #3183

Pranoy1c opened this issue Jan 19, 2025 · 0 comments

Comments

@Pranoy1c
Copy link

Pranoy1c commented Jan 19, 2025

I have the following simple code:

use std::{net::SocketAddr, path::Path};

use axum::{extract::{ConnectInfo, Request, State}, middleware::Next, response::{Html, IntoResponse, Response}, routing::{get, get_service}, Extension};
use tower_http::services::ServeDir;

#[derive(Clone, Debug)]
struct AppState {
    something: String
}

#[tokio::main]
async fn main() {

    let state = AppState {
        something: "Hello world!".to_string()
    };

    let app = axum::Router::new()
        .route("/", get(home_get))
        .nest_service("/assets", get_service(ServeDir::new(Path::new("assets"))))
        .fallback(get(home_get).with_state(state.clone()))
        .route_layer(axum::middleware::from_fn_with_state(state.clone(),info_middleware))
        .with_state(state);

    let listener = tokio::net::TcpListener::bind(":::7070").await.unwrap();
    axum::serve(listener, app.into_make_service_with_connect_info::<SocketAddr>()).await.unwrap();
}

async fn home_get(state: State<AppState>, connection_info: Extension<MyConnectionInfo>) -> Response {
    Html(format!("{} You called from: {}",state.something,connection_info.ip)).into_response()
}

#[derive(Clone, Debug)]
pub struct MyConnectionInfo {
    pub ip: String
}

pub async fn info_middleware(addr: ConnectInfo<SocketAddr>, mut request: Request, next: Next) -> Response {
    request.extensions_mut().insert(MyConnectionInfo {ip: addr.to_string()});
    next.run(request).await
}

In a real world example, my state would contain the database pool from sqlx and the info_middleware would do things like ensure token is valid, extract IP address, User agent etc. and make it available to all handlers.

For routing, basically:

  1. "/" is to take user to home_get
  2. "/assets/favicon.ico" serves the favicon file in the assets folder, and
  3. any other routes is to fallback to home_get.

1 and 2 work well. 3 does not.

For example, "/submit" fails with below 500 Internal error:

Missing request extension: Extension of type `fallbackdemo::MyConnectionInfo` was not found. Perhaps you forgot to add it? See `axum::Extension`.

I think this is because the Extension middleware isn't accessible to fallbacks?

How to make it work? Or some workaround (other than having to specify every single fallback route manually)?

@tokio-rs tokio-rs locked and limited conversation to collaborators Jan 20, 2025
@jplatte jplatte converted this issue into discussion #3184 Jan 20, 2025

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant