This avoids a vulnerability in tokio (#3085). The major version updates of both actix-web and actix-rt required some signficant changes. Chief among those, it turns out we were relying on actix-rt to run the HttpServer in a different thread from the rest of the test, so that we could talk to it from sync code in the test thread. This no longer works, so the sync code is now run in a dedicated thread with `actix_rt::task::spawn_blocking`.
73 lines
2.0 KiB
Rust
73 lines
2.0 KiB
Rust
#![deny(clippy::all)]
|
|
|
|
mod api;
|
|
mod server;
|
|
pub mod storage;
|
|
|
|
use crate::storage::Storage;
|
|
use actix_web::{get, middleware, web, Responder};
|
|
use api::{api_scope, ServerState};
|
|
use std::sync::Arc;
|
|
|
|
pub use server::ServerConfig;
|
|
|
|
#[get("/")]
|
|
async fn index() -> impl Responder {
|
|
format!("TaskChampion sync server v{}", env!("CARGO_PKG_VERSION"))
|
|
}
|
|
|
|
/// A Server represents a sync server.
|
|
#[derive(Clone)]
|
|
pub struct Server {
|
|
server_state: Arc<ServerState>,
|
|
}
|
|
|
|
impl Server {
|
|
/// Create a new sync server with the given storage implementation.
|
|
pub fn new(config: ServerConfig, storage: Box<dyn Storage>) -> Self {
|
|
Self {
|
|
server_state: Arc::new(ServerState { config, storage }),
|
|
}
|
|
}
|
|
|
|
/// Get an Actix-web service for this server.
|
|
pub fn config(&self, cfg: &mut web::ServiceConfig) {
|
|
cfg.service(
|
|
web::scope("")
|
|
.app_data(web::Data::new(self.server_state.clone()))
|
|
.wrap(
|
|
middleware::DefaultHeaders::new().add(("Cache-Control", "no-store, max-age=0")),
|
|
)
|
|
.service(index)
|
|
.service(api_scope()),
|
|
);
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod test {
|
|
use super::*;
|
|
use crate::storage::InMemoryStorage;
|
|
use actix_web::{test, App};
|
|
use pretty_assertions::assert_eq;
|
|
|
|
pub(crate) fn init_logging() {
|
|
let _ = env_logger::builder().is_test(true).try_init();
|
|
}
|
|
|
|
#[actix_rt::test]
|
|
async fn test_cache_control() {
|
|
let server = Server::new(Default::default(), Box::new(InMemoryStorage::new()));
|
|
let app = App::new().configure(|sc| server.config(sc));
|
|
let mut app = test::init_service(app).await;
|
|
|
|
let req = test::TestRequest::get().uri("/").to_request();
|
|
let resp = test::call_service(&mut app, req).await;
|
|
assert!(resp.status().is_success());
|
|
assert_eq!(
|
|
resp.headers().get("Cache-Control").unwrap(),
|
|
&"no-store, max-age=0".to_string()
|
|
)
|
|
}
|
|
}
|