Skip to main content

post3_server/s3/
mod.rs

1pub mod extractors;
2pub mod handlers;
3pub mod responses;
4pub mod router;
5
6use std::net::SocketAddr;
7
8use notmad::{Component, ComponentInfo, MadError};
9use post3::StorageBackend;
10use tokio::net::TcpListener;
11use tokio_util::sync::CancellationToken;
12
13use crate::state::State;
14
15pub struct S3Server<B: StorageBackend> {
16    pub host: SocketAddr,
17    pub state: State<B>,
18}
19
20impl<B: StorageBackend> Component for S3Server<B> {
21    fn info(&self) -> ComponentInfo {
22        "post3/s3".into()
23    }
24
25    async fn run(&self, cancellation_token: CancellationToken) -> Result<(), MadError> {
26        let app = router::build_router(self.state.clone());
27
28        tracing::info!("post3 s3-compatible server listening on {}", self.host);
29        let listener = TcpListener::bind(&self.host).await.map_err(|e| {
30            MadError::Inner(anyhow::anyhow!("failed to bind: {e}"))
31        })?;
32
33        axum::serve(listener, app.into_make_service())
34            .with_graceful_shutdown(async move {
35                cancellation_token.cancelled().await;
36            })
37            .await
38            .map_err(|e| MadError::Inner(anyhow::anyhow!("server error: {e}")))?;
39
40        Ok(())
41    }
42}