add mime types overrides

This commit is contained in:
xfy
2024-05-11 09:26:23 +08:00
parent 38fff15762
commit 16ac65a8cc
6 changed files with 64 additions and 35 deletions

View File

@ -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

View File

@ -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)
} }

View File

@ -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);
}

View File

@ -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

View File

@ -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";

View File

@ -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()