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
|
# mime
|
||||||
default-type = "application/octet-stream"
|
default-type = "application/octet-stream"
|
||||||
|
# add mime types
|
||||||
|
[types]
|
||||||
|
wasm = "application/wasm"
|
||||||
[[host]]
|
[[host]]
|
||||||
ip = "0.0.0.0"
|
ip = "0.0.0.0"
|
||||||
port = 4000
|
port = 4000
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
use crate::{
|
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,
|
error::Result,
|
||||||
};
|
};
|
||||||
use std::{collections::BTreeMap, fs};
|
use std::{collections::BTreeMap, fs};
|
||||||
@ -38,6 +41,8 @@ pub struct SettingHost {
|
|||||||
pub struct Settings {
|
pub struct Settings {
|
||||||
#[serde(default = "mime_default")]
|
#[serde(default = "mime_default")]
|
||||||
pub default_type: String,
|
pub default_type: String,
|
||||||
|
#[serde(default = "types_default")]
|
||||||
|
pub types: BTreeMap<String, String>,
|
||||||
pub host: Vec<SettingHost>,
|
pub host: Vec<SettingHost>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,6 +50,7 @@ pub fn init_config() -> Result<Settings> {
|
|||||||
let file = fs::read_to_string("./config.toml")?;
|
let file = fs::read_to_string("./config.toml")?;
|
||||||
let mut settings: Settings = toml::from_str(&file)?;
|
let mut settings: Settings = toml::from_str(&file)?;
|
||||||
|
|
||||||
|
// convert route map
|
||||||
settings.host.iter_mut().for_each(|host| {
|
settings.host.iter_mut().for_each(|host| {
|
||||||
let routes = &mut host.route;
|
let routes = &mut host.route;
|
||||||
for route in routes.iter_mut() {
|
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)
|
Ok(settings)
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::env;
|
use std::{collections::BTreeMap, env};
|
||||||
|
|
||||||
pub const NAME: &str = env!("CARGO_PKG_NAME");
|
pub const NAME: &str = env!("CARGO_PKG_NAME");
|
||||||
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
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 {
|
pub fn mime_default() -> String {
|
||||||
MIME_DEFAULT.to_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
|
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
macro_rules! mime {
|
macro_rules! mime {
|
||||||
($a:ident, $b:literal) => {
|
($a:ident, $b:literal) => {
|
||||||
@ -27,6 +28,9 @@ mime!(TEXT_VCARD, "text/vcard");
|
|||||||
mime!(IMAGE_JPEG, "image/jpeg");
|
mime!(IMAGE_JPEG, "image/jpeg");
|
||||||
mime!(IMAGE_GIF, "image/gif");
|
mime!(IMAGE_GIF, "image/gif");
|
||||||
mime!(IMAGE_PNG, "image/png");
|
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_BMP, "image/bmp");
|
||||||
mime!(IMAGE_SVG, "image/svg+xml");
|
mime!(IMAGE_SVG, "image/svg+xml");
|
||||||
|
|
||||||
@ -53,19 +57,3 @@ mime!(TEXT_STAR, "text/*");
|
|||||||
mime!(IMAGE_STAR, "image/*");
|
mime!(IMAGE_STAR, "image/*");
|
||||||
mime!(VIDEO_STAR, "video/*");
|
mime!(VIDEO_STAR, "video/*");
|
||||||
mime!(AUDIO_STAR, "audio/*");
|
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 std::{path::PathBuf, str::FromStr, time::UNIX_EPOCH};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
config::SettingHost,
|
||||||
error::{Error, Result},
|
error::{Error, Result},
|
||||||
utils::compress::{compress, CompressType},
|
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.
|
/// Open then use `ReaderStream` to stream to client.
|
||||||
/// Stream a file more suitable for large file, but its slower than read file to memory.
|
/// 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>> {
|
// pub async fn stream_file(file: File) -> Result<CandyBody<Bytes>> {
|
||||||
// Wrap to a tokio_util::io::ReaderStream
|
// // Wrap to a tokio_util::io::ReaderStream
|
||||||
let reader_stream = ReaderStream::new(file);
|
// let reader_stream = ReaderStream::new(file);
|
||||||
// Convert to http_body_util::BoxBody
|
// // Convert to http_body_util::BoxBody
|
||||||
let stream_body = StreamBody::new(reader_stream.map_ok(Frame::data));
|
// 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 = stream_body.map_err(|e| Error::IoError(e)).boxed();
|
||||||
let boxed_body = BodyExt::map_err(stream_body, Error::Io).boxed();
|
// let boxed_body = BodyExt::map_err(stream_body, Error::Io).boxed();
|
||||||
Ok(boxed_body)
|
// Ok(boxed_body)
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub async fn read_file_bytes(file: &mut File, size: u64) -> Result<Vec<u8>> {
|
pub async fn read_file_bytes(file: &mut File, size: u64) -> Result<Vec<u8>> {
|
||||||
let mut buffer = vec![0u8; size.try_into()?];
|
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)
|
Ok(buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Open local file to memory
|
// Open local file to memory
|
||||||
pub async fn read_file(file: &mut File, size: u64) -> Result<CandyBody<Bytes>> {
|
// pub async fn read_file(file: &mut File, size: u64) -> Result<CandyBody<Bytes>> {
|
||||||
let bytes = read_file_bytes(file, size).await?;
|
// let bytes = read_file_bytes(file, size).await?;
|
||||||
let body = Full::new(bytes.into()).map_err(|e| match e {}).boxed();
|
// let body = Full::new(bytes.into()).map_err(|e| match e {}).boxed();
|
||||||
Ok(body)
|
// Ok(body)
|
||||||
}
|
// }
|
||||||
|
|
||||||
// HTTP status code 404
|
// HTTP status code 404
|
||||||
static NOT_FOUND: &[u8] = b"Not Found";
|
static NOT_FOUND: &[u8] = b"Not Found";
|
||||||
|
@ -27,8 +27,6 @@ async fn main() -> Result<()> {
|
|||||||
info!("{}/{}", NAME, VERSION);
|
info!("{}/{}", NAME, VERSION);
|
||||||
info!("OS: {} {}", OS, ARCH);
|
info!("OS: {} {}", OS, ARCH);
|
||||||
|
|
||||||
// global cache
|
|
||||||
|
|
||||||
let mut servers = settings
|
let mut servers = settings
|
||||||
.host
|
.host
|
||||||
.iter()
|
.iter()
|
||||||
|
Reference in New Issue
Block a user