diff --git a/radicle-httpd/Cargo.lock b/radicle-httpd/Cargo.lock index 29dfe7692..7fcc40ccd 100644 --- a/radicle-httpd/Cargo.lock +++ b/radicle-httpd/Cargo.lock @@ -375,6 +375,17 @@ dependencies = [ "shlex", ] +[[package]] +name = "cfb" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f" +dependencies = [ + "byteorder", + "fnv", + "uuid", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -1005,6 +1016,15 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "infer" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc150e5ce2330295b8616ce0e3f53250e53af31759a9dbedad1621ba29151847" +dependencies = [ + "cfb", +] + [[package]] name = "inout" version = "0.1.3" @@ -1683,6 +1703,7 @@ dependencies = [ "chrono", "flate2", "hyper", + "infer", "lexopt", "lru", "nonempty", @@ -2564,6 +2585,12 @@ dependencies = [ "serde", ] +[[package]] +name = "uuid" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3758f5e68192bb96cc8f9b7e2c2cfdabb435499a28499a42f8f984092adad4b" + [[package]] name = "valuable" version = "0.1.0" diff --git a/radicle-httpd/Cargo.toml b/radicle-httpd/Cargo.toml index d4afaab76..f7885396b 100644 --- a/radicle-httpd/Cargo.toml +++ b/radicle-httpd/Cargo.toml @@ -27,6 +27,7 @@ base64 = { version = "0.22.1" } chrono = { version = "0.4.38", default-features = false, features = ["clock"] } flate2 = { version = "1" } hyper = { version = "1.4", default-features = false } +infer = { version = "0.16.0" } lexopt = { version = "0.3.0" } lru = { version = "0.12.4" } nonempty = { version = "0.9.0", features = ["serialize"] } diff --git a/radicle-httpd/src/raw.rs b/radicle-httpd/src/raw.rs index 3fd6d401f..19c1d4fc7 100644 --- a/radicle-httpd/src/raw.rs +++ b/radicle-httpd/src/raw.rs @@ -161,7 +161,7 @@ fn blob_response( async fn file_by_oid_handler( Path((rid, oid)): Path<(RepoId, Oid)>, State(profile): State>, - Query(qs): Query, + Query(_qs): Query, ) -> impl IntoResponse { let storage = &profile.storage; let repo = storage.repository(rid)?; @@ -172,6 +172,8 @@ async fn file_by_oid_handler( } let blob = repo.blob(oid)?; + let content = blob.content(); + let mime = infer::get(content).map(|i| i.mime_type().to_string()); let mut response_headers = HeaderMap::new(); if blob.size() > MAX_BLOB_SIZE { @@ -180,10 +182,10 @@ async fn file_by_oid_handler( response_headers.insert( header::CONTENT_TYPE, - HeaderValue::from_str(&qs.mime.unwrap_or("application/octet-stream".to_string()))?, + HeaderValue::from_str(&mime.unwrap_or("application/octet-stream".to_string()))?, ); - Ok::<_, Error>((StatusCode::OK, response_headers, blob.content().to_vec())) + Ok::<_, Error>((StatusCode::OK, response_headers, content.to_vec())) } #[cfg(test)]