mod manager; use axum::extract::{BodyStream, Path, State}; use axum::http::StatusCode; use axum::response::IntoResponse; use axum::routing::{get_service, post}; use axum::Router; use futures::StreamExt; use futures::TryFutureExt; use futures::TryStreamExt; use libarchive::archive::Entry; use libarchive::read::Archive; use libarchive::read::Builder; use std::io::Read; use tokio::{fs, io, io::AsyncWriteExt}; use tower_http::services::ServeDir; use uuid::Uuid; pub fn router(config: &crate::Config) -> Router { // Try to serve packages by default, and try the database files instead if not found let serve_repos = get_service(ServeDir::new(&config.pkg_dir).fallback(ServeDir::new(&config.repo_dir))); Router::new() .route( "/:repo", post(post_package_archive).get(serve_repos.clone()), ) .fallback(serve_repos) .with_state(config.clone()) } async fn post_package_archive( State(config): State, Path(repo): Path, body: BodyStream, ) -> Result<(), StatusCode> { // let mut body_reader = tokio_util::io::StreamReader::new( // body.map_err(|err| io::Error::new(io::ErrorKind::Other, err)), // ); let mut body = body.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR); // We first stream the uploaded file to disk let uuid: uuid::fmt::Simple = Uuid::new_v4().into(); let path = config.pkg_dir.join(uuid.to_string()); let mut f = fs::File::create(&path) .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR) .await?; while let Some(chunk) = body.next().await { f.write_all(&chunk?) .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR) .await?; } let mut builder = Builder::new(); builder .support_format(libarchive::archive::ReadFormat::Tar) .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; builder .support_filter(libarchive::archive::ReadFilter::All) .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; let mut ar = builder .open_file(&path) .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; for entry in ar.entries() { let mut entry = entry.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; if entry.pathname() == ".PKGINFO" { let mut buffer = String::new(); entry.read_to_string(&mut buffer); println!("{}", buffer); } } Ok(()) }