Search code examples
rustactix-web

Actix-Web reports "App data is not configured" when processing a file upload


I'm using the Actix framework to create a simple server and I've implemented a file upload using a simple HTML frontend.

use actix_web::web::Data;
use actix_web::{middleware, web, App, HttpResponse, HttpServer};
use std::cell::Cell;

// file upload functions, the same as you can find it under the 
// actix web documentation:
// https://github.com/actix/examples/blob/master/multipart/src/main.rs :
mod upload; 


fn index() -> HttpResponse {
    let html = r#"<html>
            <head><title>Upload Test</title></head>
            <body>
                <form target="/" method="post" enctype="multipart/form-data">
                    <input type="file" name="file"/>
                    <input type="submit" value="Submit"></button>
                </form>
            </body>
        </html>"#;

    HttpResponse::Ok().body(html)
}

#[derive(Clone)]
pub struct AppState {        
    counter: Cell<usize>,        
}

impl AppState {
    fn new() -> Result<Self, Error> {
        // some stuff
        Ok(AppState {
            counter: Cell::new(0usize),
        })
    }
}
fn main() {

    let app_state = AppState::new().unwrap();

    println!("Started http server: http://127.0.0.1:8000");

    HttpServer::new(move || {
        App::new()
            .wrap(middleware::Logger::default())
            .service(
                web::resource("/")
                    .route(web::get().to(index))
                    .route(web::post().to_async(upload::upload)),
            )
            .data(app_state.clone())
    })
    .bind("127.0.0.1:8000")
    .unwrap()
    .run()
    .unwrap();
}

Running the server works fine, but when I submit the file upload, it says:

App data is not configured, to configure use App::data()

I don't know what to do.


Solution

  • I asked people in the rust-jp community to tell you the correct answer.

    Use Arc outer HttpServer.

    /*
    ~~~Cargo.toml
    [package]
    name = "actix-data-example"
    version = "0.1.0"
    authors = ["ncaq <[email protected]>"]
    edition = "2018"
    
    [dependencies]
    actix-web = "1.0.0-rc"
    env_logger = "0.6.0"
    ~~~
     */
    
    use actix_web::*;
    use std::sync::*;
    
    fn main() -> std::io::Result<()> {
        std::env::set_var("RUST_LOG", "actix_web=trace");
        env_logger::init();
    
        let data = Arc::new(Mutex::new(ActixData::default()));
        HttpServer::new(move || {
            App::new()
                .wrap(middleware::Logger::default())
                .data(data.clone())
                .service(web::resource("/index/").route(web::get().to(index)))
                .service(web::resource("/create/").route(web::get().to(create)))
        })
        .bind("0.0.0.0:3000")?
        .run()
    }
    
    fn index(actix_data: web::Data<Arc<Mutex<ActixData>>>) -> HttpResponse {
        println!("actix_data: {:?}", actix_data);
        HttpResponse::Ok().body(format!("{:?}", actix_data))
    }
    
    fn create(actix_data: web::Data<Arc<Mutex<ActixData>>>) -> HttpResponse {
        println!("actix_data: {:?}", actix_data);
        actix_data.lock().unwrap().counter += 1;
        HttpResponse::Ok().body(format!("{:?}", actix_data))
    }
    
    /// actix-webが保持する状態
    #[derive(Debug, Default)]
    struct ActixData {
        counter: usize,
    }
    

    This post report to upstream. Official document data cause App data is not configured, to configure use App::data() · Issue #874 · actix/actix-web