From 96928a28c708f08e2c64047ee314d77016a394ce Mon Sep 17 00:00:00 2001 From: Jordan Doyle Date: Sat, 03 Feb 2024 14:12:43 +0000 Subject: [PATCH] Forward Content-Encoding to git http-backend Fixes #56 --- src/methods/filters.rs | 1 + src/methods/repo/smart_git.rs | 30 +++++++++++++++++++++++------- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/methods/filters.rs b/src/methods/filters.rs index b460102..3ee1329 100644 --- a/src/methods/filters.rs +++ a/src/methods/filters.rs @@ -1,7 +1,8 @@ // sorry clippy, we don't have a choice. askama forces this on us #![allow(clippy::unnecessary_wraps, clippy::trivially_copy_pass_by_ref)] use std::borrow::Borrow; + use time::format_description::well_known::Rfc3339; pub fn format_time(s: impl Borrow) -> Result { diff --git a/src/methods/repo/smart_git.rs b/src/methods/repo/smart_git.rs index 52d8fcb..7d4463c 100644 --- a/src/methods/repo/smart_git.rs +++ a/src/methods/repo/smart_git.rs @@ -1,16 +1,17 @@ use std::{io::ErrorKind, path::Path, process::Stdio, str::FromStr}; use anyhow::{bail, Context}; use axum::{ body::{boxed, Body}, extract::BodyStream, - headers::{ContentType, HeaderName, HeaderValue}, + headers::{HeaderMap, HeaderName, HeaderValue}, http::{Method, Uri}, response::Response, - Extension, TypedHeader, + Extension, }; use futures::TryStreamExt; use httparse::Status; +use tokio::process::Command; use tokio_util::io::StreamReader; use tracing::warn; @@ -25,15 +26,20 @@ Extension(Repository(repository)): Extension, method: Method, uri: Uri, - content_type: Option>, + headers: HeaderMap, body: BodyStream, ) -> Result { let path = extract_path(&uri, &repository)?; - let mut command = tokio::process::Command::new("git"); - - if let Some(content_type) = content_type { - command.env("CONTENT_TYPE", content_type.0.to_string()); + let mut command = Command::new("git"); + + for (header, env) in [ + ("Content-Type", "CONTENT_TYPE"), + ("Content-Length", "CONTENT_LENGTH"), + ("Git-Protocol", "GIT_PROTOCOL"), + ("Content-Encoding", "HTTP_CONTENT_ENCODING"), + ] { + extract_header(&headers, &mut command, header, env)?; } let mut child = command @@ -53,7 +59,7 @@ StreamReader::new(body.map_err(|e| std::io::Error::new(ErrorKind::Other, e))); let mut stdin = child.stdin.take().context("Stdin already taken")?; - tokio::io::copy(&mut body, &mut stdin) + tokio::io::copy_buf(&mut body, &mut stdin) .await .context("Failed to copy bytes from request to command stdin")?; } @@ -72,6 +78,14 @@ } Ok(resp) +} + +fn extract_header(input: &HeaderMap, output: &mut Command, header: &str, env: &str) -> Result<()> { + if let Some(value) = input.get(header) { + output.env(env, value.to_str().context("Invalid header")?); + } + + Ok(()) } fn extract_path<'a>(uri: &'a Uri, repository: &Path) -> Result<&'a str> { -- rgit 0.1.3