Initial commit
This commit is contained in:
9
crates/cgcx-content-typing/Cargo.toml
Normal file
9
crates/cgcx-content-typing/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "cgcx-content-typing"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
[dependencies]
|
||||
cgcx-core = { path = "../cgcx-core" }
|
||||
infer = "0.16"
|
||||
mime_guess = "2"
|
||||
87
crates/cgcx-content-typing/src/lib.rs
Normal file
87
crates/cgcx-content-typing/src/lib.rs
Normal file
@@ -0,0 +1,87 @@
|
||||
pub const RENDER_IMAGE: u32 = 1 << 0;
|
||||
pub const RENDER_VIDEO: u32 = 1 << 1;
|
||||
pub const RENDER_AUDIO: u32 = 1 << 2;
|
||||
pub const RENDER_MARKDOWN: u32 = 1 << 3;
|
||||
pub const RENDER_TEXT: u32 = 1 << 4;
|
||||
pub const RENDER_DOCUMENT: u32 = 1 << 5;
|
||||
pub const RENDER_EXECUTABLE: u32 = 1 << 6;
|
||||
pub const RENDER_DANGEROUS: u32 = 1 << 7;
|
||||
pub const RENDER_NO_INLINE: u32 = 1 << 8;
|
||||
|
||||
const DANGEROUS_EXTENSIONS: &[&str] = &[
|
||||
"exe", "scr", "bat", "cmd", "sh", "dll", "so", "dylib", "jar", "msi", "com", "app", "apk",
|
||||
];
|
||||
|
||||
const DANGEROUS_MIME_TYPES: &[&str] = &[
|
||||
"text/html",
|
||||
"text/javascript",
|
||||
"text/css",
|
||||
"application/javascript",
|
||||
"application/ecmascript",
|
||||
];
|
||||
|
||||
pub fn detect_mime_type(data: &[u8], file_name: &str) -> String {
|
||||
if let Some(kind) = infer::get(data) {
|
||||
let mime = kind.mime_type();
|
||||
if !mime.is_empty() && mime != "application/octet-stream" {
|
||||
return mime.to_string();
|
||||
}
|
||||
}
|
||||
mime_guess::from_path(file_name)
|
||||
.first_or_octet_stream()
|
||||
.to_string()
|
||||
}
|
||||
|
||||
pub fn compute_render_flags(mime_type: &str, file_name: &str, data: &[u8]) -> u32 {
|
||||
let mut flags = 0u32;
|
||||
|
||||
if mime_type.starts_with("image/") {
|
||||
flags |= RENDER_IMAGE;
|
||||
} else if mime_type.starts_with("video/") {
|
||||
flags |= RENDER_VIDEO;
|
||||
} else if mime_type.starts_with("audio/") {
|
||||
flags |= RENDER_AUDIO;
|
||||
} else if mime_type == "text/markdown"
|
||||
|| file_name.ends_with(".md")
|
||||
|| file_name.ends_with(".markdown")
|
||||
{
|
||||
flags |= RENDER_MARKDOWN | RENDER_TEXT;
|
||||
} else if mime_type.starts_with("text/") {
|
||||
flags |= RENDER_TEXT;
|
||||
} else if mime_type == "application/pdf" || mime_type.starts_with("application/vnd.") {
|
||||
flags |= RENDER_DOCUMENT;
|
||||
}
|
||||
|
||||
if DANGEROUS_MIME_TYPES.contains(&mime_type) {
|
||||
flags |= RENDER_DANGEROUS | RENDER_NO_INLINE;
|
||||
}
|
||||
|
||||
let ext = file_name.rsplit('.').next().unwrap_or("").to_lowercase();
|
||||
if DANGEROUS_EXTENSIONS.contains(&ext.as_str()) {
|
||||
flags |= RENDER_EXECUTABLE | RENDER_DANGEROUS | RENDER_NO_INLINE;
|
||||
}
|
||||
|
||||
if let Some(kind) = infer::get(data) {
|
||||
let mime = kind.mime_type();
|
||||
if mime == "application/x-executable"
|
||||
|| mime == "application/x-msdownload"
|
||||
|| mime == "application/x-pie-executable"
|
||||
{
|
||||
flags |= RENDER_EXECUTABLE | RENDER_DANGEROUS | RENDER_NO_INLINE;
|
||||
}
|
||||
}
|
||||
|
||||
if flags & (RENDER_EXECUTABLE | RENDER_DANGEROUS) != 0 {
|
||||
flags |= RENDER_NO_INLINE;
|
||||
}
|
||||
|
||||
flags
|
||||
}
|
||||
|
||||
pub fn is_dangerous(flags: u32) -> bool {
|
||||
flags & RENDER_DANGEROUS != 0
|
||||
}
|
||||
|
||||
pub fn should_inline(flags: u32) -> bool {
|
||||
flags & RENDER_NO_INLINE == 0
|
||||
}
|
||||
Reference in New Issue
Block a user