Radish alpha
r
rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5
Radicle web interface
Radicle
Git
httpd: Infer mime type of file blob in remaining raw handlers
Sebastian Martinez committed 11 months ago
commit 978b3de61f42ae130426d9533e33ef665ad42ffe
parent 5f22e1b
1 file changed +10 -87
modified radicle-httpd/src/raw.rs
@@ -24,78 +24,6 @@ const MAX_BLOB_SIZE: usize = 10_485_760;

const ARCHIVE_SUFFIX: &str = ".tar.gz";

-
static MIMES: &[(&str, &str)] = &[
-
    ("3gp", "video/3gpp"),
-
    ("7z", "application/x-7z-compressed"),
-
    ("aac", "audio/aac"),
-
    ("avi", "video/x-msvideo"),
-
    ("bin", "application/octet-stream"),
-
    ("bmp", "image/bmp"),
-
    ("bz", "application/x-bzip"),
-
    ("bz2", "application/x-bzip2"),
-
    ("csh", "application/x-csh"),
-
    ("css", "text/css"),
-
    ("csv", "text/csv"),
-
    ("doc", "application/msword"),
-
    (
-
        "docx",
-
        "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
-
    ),
-
    ("epub", "application/epub+zip"),
-
    ("gz", "application/gzip"),
-
    ("gif", "image/gif"),
-
    ("htm", "text/html"),
-
    ("html", "text/html"),
-
    ("ico", "image/vnd.microsoft.icon"),
-
    ("jar", "application/java-archive"),
-
    ("jpeg", "image/jpeg"),
-
    ("jpg", "image/jpeg"),
-
    ("js", "text/javascript"),
-
    ("json", "application/json"),
-
    ("mjs", "text/javascript"),
-
    ("mp3", "audio/mpeg"),
-
    ("mp4", "video/mp4"),
-
    ("mpeg", "video/mpeg"),
-
    ("odp", "application/vnd.oasis.opendocument.presentation"),
-
    ("ods", "application/vnd.oasis.opendocument.spreadsheet"),
-
    ("odt", "application/vnd.oasis.opendocument.text"),
-
    ("oga", "audio/ogg"),
-
    ("ogv", "video/ogg"),
-
    ("ogx", "application/ogg"),
-
    ("otf", "font/otf"),
-
    ("png", "image/png"),
-
    ("pdf", "application/pdf"),
-
    ("php", "application/x-httpd-php"),
-
    ("ppt", "application/vnd.ms-powerpoint"),
-
    (
-
        "pptx",
-
        "application/vnd.openxmlformats-officedocument.presentationml.presentation",
-
    ),
-
    ("rar", "application/vnd.rar"),
-
    ("rtf", "application/rtf"),
-
    ("sh", "application/x-sh"),
-
    ("svg", "image/svg+xml"),
-
    ("tar", "application/x-tar"),
-
    ("tif", "image/tiff"),
-
    ("tiff", "image/tiff"),
-
    ("ttf", "font/ttf"),
-
    ("txt", "text/plain"),
-
    ("wav", "audio/wav"),
-
    ("weba", "audio/webm"),
-
    ("webm", "video/webm"),
-
    ("webp", "image/webp"),
-
    ("woff", "font/woff"),
-
    ("woff2", "font/woff2"),
-
    ("xhtml", "application/xhtml+xml"),
-
    ("xls", "application/vnd.ms-excel"),
-
    (
-
        "xlsx",
-
        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
-
    ),
-
    ("xml", "application/xml"),
-
    ("zip", "application/zip"),
-
];
-

pub fn router(profile: Arc<Profile>) -> Router {
    Router::new()
        .route("/:rid/:sha", get(commit_handler))
@@ -146,7 +74,7 @@ async fn file_by_commit_handler(
    let repo: Repository = repo.backend.into();
    let blob = repo.blob(sha, &path)?;

-
    blob_response(blob, path)
+
    blob_response(blob)
}

async fn archive_by_refname_handler(
@@ -245,27 +173,22 @@ async fn file_by_canonical_head_handler(
    let repo: Repository = repo.backend.into();
    let blob = repo.blob(sha, &path)?;

-
    blob_response(blob, path)
+
    blob_response(blob)
}

-
fn blob_response(
-
    blob: Blob<BlobRef>,
-
    path: String,
-
) -> Result<(StatusCode, HeaderMap, Vec<u8>), Error> {
+
fn blob_response(blob: Blob<BlobRef>) -> Result<(StatusCode, HeaderMap, Vec<u8>), Error> {
    let mut response_headers = HeaderMap::new();
    if blob.size() > MAX_BLOB_SIZE {
        return Ok::<_, Error>((StatusCode::PAYLOAD_TOO_LARGE, response_headers, vec![]));
    }

-
    let mime = if let Some(ext) = path.split('.').last() {
-
        MIMES
-
            .binary_search_by(|(k, _)| k.cmp(&ext))
-
            .map(|k| MIMES[k].1)
-
            .unwrap_or("text/plain; charset=utf-8")
-
    } else {
-
        "application/octet-stream"
-
    };
-
    response_headers.insert(header::CONTENT_TYPE, HeaderValue::from_str(mime)?);
+
    let content = blob.content();
+
    let mime = infer::get(content).map(|i| i.mime_type().to_string());
+

+
    response_headers.insert(
+
        header::CONTENT_TYPE,
+
        HeaderValue::from_str(&mime.unwrap_or("application/octet-stream".to_string()))?,
+
    );

    Ok::<_, Error>((StatusCode::OK, response_headers, blob.content().to_owned()))
}