mirror of
https://github.com/DefectingCat/candy
synced 2025-07-15 16:51:34 +00:00
add mime types overrides
This commit is contained in:
@ -1,5 +1,8 @@
|
||||
# mime
|
||||
default-type = "application/octet-stream"
|
||||
# add mime types
|
||||
[types]
|
||||
wasm = "application/wasm"
|
||||
[[host]]
|
||||
ip = "0.0.0.0"
|
||||
port = 4000
|
||||
|
@ -1,5 +1,8 @@
|
||||
use crate::{
|
||||
consts::{host_index, keep_alive_timeoutd_efault, mime_default, process_timeout},
|
||||
consts::{
|
||||
host_index, insert_default_mimes, keep_alive_timeoutd_efault, mime_default,
|
||||
process_timeout, types_default,
|
||||
},
|
||||
error::Result,
|
||||
};
|
||||
use std::{collections::BTreeMap, fs};
|
||||
@ -38,6 +41,8 @@ pub struct SettingHost {
|
||||
pub struct Settings {
|
||||
#[serde(default = "mime_default")]
|
||||
pub default_type: String,
|
||||
#[serde(default = "types_default")]
|
||||
pub types: BTreeMap<String, String>,
|
||||
pub host: Vec<SettingHost>,
|
||||
}
|
||||
|
||||
@ -45,6 +50,7 @@ pub fn init_config() -> Result<Settings> {
|
||||
let file = fs::read_to_string("./config.toml")?;
|
||||
let mut settings: Settings = toml::from_str(&file)?;
|
||||
|
||||
// convert route map
|
||||
settings.host.iter_mut().for_each(|host| {
|
||||
let routes = &mut host.route;
|
||||
for route in routes.iter_mut() {
|
||||
@ -56,5 +62,8 @@ pub fn init_config() -> Result<Settings> {
|
||||
}
|
||||
});
|
||||
|
||||
// combine mime types
|
||||
insert_default_mimes(&mut settings.types);
|
||||
|
||||
Ok(settings)
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use std::env;
|
||||
use std::{collections::BTreeMap, env};
|
||||
|
||||
pub const NAME: &str = env!("CARGO_PKG_NAME");
|
||||
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
@ -25,3 +25,33 @@ pub const MIME_DEFAULT: &str = "application/octet-stream";
|
||||
pub fn mime_default() -> String {
|
||||
MIME_DEFAULT.to_string()
|
||||
}
|
||||
|
||||
pub fn types_default() -> BTreeMap<String, String> {
|
||||
BTreeMap::new()
|
||||
}
|
||||
macro_rules! insert_mime {
|
||||
($name:literal, $mime:ident, $map:ident) => {
|
||||
$map.entry($name.to_string()).or_insert($mime.to_string());
|
||||
};
|
||||
}
|
||||
pub fn insert_default_mimes(map: &mut BTreeMap<String, String>) {
|
||||
use crate::http::mime::*;
|
||||
|
||||
insert_mime!("html", TEXT_HTML, map);
|
||||
insert_mime!("htm", TEXT_HTML, map);
|
||||
insert_mime!("shtml", TEXT_HTML, map);
|
||||
insert_mime!("css", TEXT_CSS, map);
|
||||
insert_mime!("xml", TEXT_XML, map);
|
||||
insert_mime!("rss", TEXT_XML, map);
|
||||
insert_mime!("txt", TEXT_PLAIN, map);
|
||||
|
||||
insert_mime!("gif", IMAGE_GIF, map);
|
||||
insert_mime!("jpg", IMAGE_JPEG, map);
|
||||
insert_mime!("jpeg", IMAGE_JPEG, map);
|
||||
insert_mime!("png", IMAGE_PNG, map);
|
||||
insert_mime!("ico", IMAGE_ICON, map);
|
||||
insert_mime!("jng", IMAGE_JNG, map);
|
||||
insert_mime!("wbmp", IMAGE_WBMP, map);
|
||||
|
||||
insert_mime!("js", APPLICATION_JAVASCRIPT, map);
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
|
||||
#![allow(dead_code)]
|
||||
|
||||
macro_rules! mime {
|
||||
($a:ident, $b:literal) => {
|
||||
@ -27,6 +28,9 @@ mime!(TEXT_VCARD, "text/vcard");
|
||||
mime!(IMAGE_JPEG, "image/jpeg");
|
||||
mime!(IMAGE_GIF, "image/gif");
|
||||
mime!(IMAGE_PNG, "image/png");
|
||||
mime!(IMAGE_ICON, "image/x-icon");
|
||||
mime!(IMAGE_JNG, "image/x-jng");
|
||||
mime!(IMAGE_WBMP, "image/vnd.wap.wbmp ");
|
||||
mime!(IMAGE_BMP, "image/bmp");
|
||||
mime!(IMAGE_SVG, "image/svg+xml");
|
||||
|
||||
@ -53,19 +57,3 @@ mime!(TEXT_STAR, "text/*");
|
||||
mime!(IMAGE_STAR, "image/*");
|
||||
mime!(VIDEO_STAR, "video/*");
|
||||
mime!(AUDIO_STAR, "audio/*");
|
||||
|
||||
// #[macro_export]
|
||||
// macro_rules! match_mime {
|
||||
// ($a:ident) => {
|
||||
// match $a {
|
||||
// _ => AUDIO_STAR,
|
||||
// }
|
||||
// };
|
||||
// }
|
||||
|
||||
// fn parse(extension: &str) -> &'static str {
|
||||
// match extension {
|
||||
// _ => AUDIO_STAR,
|
||||
// }
|
||||
// }
|
||||
// impl From<OsStr> for
|
||||
|
@ -1,6 +1,7 @@
|
||||
use std::{path::PathBuf, str::FromStr, time::UNIX_EPOCH};
|
||||
|
||||
use crate::{
|
||||
config::SettingHost,
|
||||
error::{Error, Result},
|
||||
utils::compress::{compress, CompressType},
|
||||
};
|
||||
@ -57,15 +58,15 @@ pub async fn open_file(path: &str) -> Result<File> {
|
||||
|
||||
/// Open then use `ReaderStream` to stream to client.
|
||||
/// Stream a file more suitable for large file, but its slower than read file to memory.
|
||||
pub async fn stream_file(file: File) -> Result<CandyBody<Bytes>> {
|
||||
// Wrap to a tokio_util::io::ReaderStream
|
||||
let reader_stream = ReaderStream::new(file);
|
||||
// Convert to http_body_util::BoxBody
|
||||
let stream_body = StreamBody::new(reader_stream.map_ok(Frame::data));
|
||||
// let boxed_body = stream_body.map_err(|e| Error::IoError(e)).boxed();
|
||||
let boxed_body = BodyExt::map_err(stream_body, Error::Io).boxed();
|
||||
Ok(boxed_body)
|
||||
}
|
||||
// pub async fn stream_file(file: File) -> Result<CandyBody<Bytes>> {
|
||||
// // Wrap to a tokio_util::io::ReaderStream
|
||||
// let reader_stream = ReaderStream::new(file);
|
||||
// // Convert to http_body_util::BoxBody
|
||||
// let stream_body = StreamBody::new(reader_stream.map_ok(Frame::data));
|
||||
// // let boxed_body = stream_body.map_err(|e| Error::IoError(e)).boxed();
|
||||
// let boxed_body = BodyExt::map_err(stream_body, Error::Io).boxed();
|
||||
// Ok(boxed_body)
|
||||
// }
|
||||
|
||||
pub async fn read_file_bytes(file: &mut File, size: u64) -> Result<Vec<u8>> {
|
||||
let mut buffer = vec![0u8; size.try_into()?];
|
||||
@ -73,12 +74,12 @@ pub async fn read_file_bytes(file: &mut File, size: u64) -> Result<Vec<u8>> {
|
||||
Ok(buffer)
|
||||
}
|
||||
|
||||
/// Open local file to memory
|
||||
pub async fn read_file(file: &mut File, size: u64) -> Result<CandyBody<Bytes>> {
|
||||
let bytes = read_file_bytes(file, size).await?;
|
||||
let body = Full::new(bytes.into()).map_err(|e| match e {}).boxed();
|
||||
Ok(body)
|
||||
}
|
||||
// Open local file to memory
|
||||
// pub async fn read_file(file: &mut File, size: u64) -> Result<CandyBody<Bytes>> {
|
||||
// let bytes = read_file_bytes(file, size).await?;
|
||||
// let body = Full::new(bytes.into()).map_err(|e| match e {}).boxed();
|
||||
// Ok(body)
|
||||
// }
|
||||
|
||||
// HTTP status code 404
|
||||
static NOT_FOUND: &[u8] = b"Not Found";
|
||||
|
@ -27,8 +27,6 @@ async fn main() -> Result<()> {
|
||||
info!("{}/{}", NAME, VERSION);
|
||||
info!("OS: {} {}", OS, ARCH);
|
||||
|
||||
// global cache
|
||||
|
||||
let mut servers = settings
|
||||
.host
|
||||
.iter()
|
||||
|
Reference in New Issue
Block a user