Search code examples
rustactix-web

how to fix the second actix web service configuration 404 not found error


I want to limit the upload file size for each api when using actix-web, so I tweak the code like this(the legacy config only contains one service):

pub fn config(cfg: &mut web::ServiceConfig) {
    cfg.service(
        web::scope("/tex/project")
            .route("/list", web::get().to(get_projects))
            .route("/copy", web::post().to(cp_proj)),
    );
    // https://stackoverflow.com/questions/71714621/actix-web-limit-upload-file-size
    cfg.app_data(
        MultipartFormConfig::default()
            .total_limit(1048576) // 1 MB = 1024 * 1024
            .memory_limit(2097152) // 2 MB = 2 * 1024 * 1024
            .error_handler(handle_multipart_error),
    )
    .service(web::scope("/tex/project").route("/upload", web::post().to(upload_full_proj)));
    cfg.app_data(
        MultipartFormConfig::default()
            .total_limit(104857600) // 100 MB = 1024 * 1024
            .memory_limit(209715200) // 200 MB = 200 * 1024 * 1024
            .error_handler(handle_multipart_error),
    )
    .service(web::scope("/tex/project").route("/file/upload", web::post().to(upload_proj_file)));
}

after I split the configuration, it seems only the first service config work, when I upload using the second url, shows 404 not found error. Am I missing something? I have tried to tweak the scope with different name, still did not fixed this issue.

pub fn config(cfg: &mut web::ServiceConfig) {
        cfg.service(
            web::scope("/tex/project")
                .route("/list", web::get().to(get_projects))
                .route("/copy", web::post().to(cp_proj)),
        );
        // https://stackoverflow.com/questions/71714621/actix-web-limit-upload-file-size
        cfg.app_data(
            MultipartFormConfig::default()
                .total_limit(1048576) // 1 MB = 1024 * 1024
                .memory_limit(2097152) // 2 MB = 2 * 1024 * 1024
                .error_handler(handle_multipart_error),
        )
        .service(web::scope("/tex/project/proj").route("/upload", web::post().to(upload_full_proj)));
        cfg.app_data(
            MultipartFormConfig::default()
                .total_limit(104857600) // 100 MB = 1024 * 1024
                .memory_limit(209715200) // 200 MB = 200 * 1024 * 1024
                .error_handler(handle_multipart_error),
        )
        .service(web::scope("/tex/project/file").route("/upload", web::post().to(upload_proj_file)));
    }

Solution

  • You are adding multiple conflicting scopes and you aren't calling .app_data in the right place; you're still adding it on the root and not specific to each route (cfg.app_data will add directly to cfg and not what comes after).

    You need to do something like this:

    pub fn config(cfg: &mut web::ServiceConfig) {
        let proj_upload_config = MultipartFormConfig::default()
            .total_limit(1048576) // 1 MB = 1024 * 1024
            .memory_limit(2097152) // 2 MB = 2 * 1024 * 1024
            .error_handler(handle_multipart_error);
    
        let file_upload_config = MultipartFormConfig::default()
            .total_limit(104857600) // 100 MB = 1024 * 1024
            .memory_limit(209715200) // 200 MB = 200 * 1024 * 1024
            .error_handler(handle_multipart_error);
    
        cfg.service(
            web::scope("/tex/project")
                .route("/list", web::get().to(get_projects))
                .route("/copy", web::post().to(cp_proj))
                .route("/proj/upload", web::post().to(upload_full_proj).app_data(proj_upload_config)),
                .route("/file/upload", web::post().to(upload_proj_file).app_data(file_upload_config)),
        );
    }