Serving Git Repository using Rust HTTP (Hyper) Server

pub(crate) struct GitServer {}

#[injectable(GitServer, async = true)]
impl GitServer {
    pub fn new() -> Self {
        Self {}
    }

    async fn start(&self) -> anyhow::Result<()> {
        info!("Starting GitServer");
        let addr = SocketAddr::from(([127, 0, 0, 1], 7001));
        let make_service = hyper::service::make_service_fn(|_| {
            let service = service_fn(move |_req| Self::call(_req).map(Ok::<_, http::Error>));

            futures::future::ok::<_, http::Error>(service)
        });
        let server = Server::bind(&addr).serve(make_service);
        info!("GitServer listening on {}", addr);
        if let Err(e) = server.await {
            error!("Error starting GitServer error: {}", e);
        }
        Ok(())
    }

    async fn call(req: hyper::Request<hyper::Body>) -> hyper::Response<hyper::Body> {
        debug!("GitServer request: {:?}", req);
        let mut cmd = tokio::process::Command::new("git");
        cmd.arg("http-backend");
        cmd.env("GIT_PROJECT_ROOT", "/some/git/project");
        cmd.env("GIT_HTTP_EXPORT_ALL", "1");
        cmd.env("PATH_INFO", req.uri().path());
        cmd.current_dir("/data/os-manager/temp/git");
        let resp = hyper_cgi::do_cgi(req, cmd).await.0;
        debug!("GitServer response: {:?}", resp);
        resp
    }
}

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *