From d07ea6f52ea93e023eb8cc54aae3490fb64a1a1d Mon Sep 17 00:00:00 2001 From: ty Date: Sat, 8 Jun 2024 22:04:06 +0800 Subject: [PATCH] feat: parse content-type with \"mime\" --- Cargo.lock | 1 + Cargo.toml | 2 ++ src/service/local.rs | 37 ++++++++++++++++++++++++------------- 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c5435d75dd35..06b637551eb3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3047,6 +3047,7 @@ dependencies = [ "log", "log4rs", "mimalloc", + "mime", "num_cpus", "qrcode", "rand", diff --git a/Cargo.toml b/Cargo.toml index f8bb096bf8a5..198242316f98 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -167,6 +167,7 @@ local-fake-dns = ["local", "shadowsocks-service/local-fake-dns"] local-online-config = [ "local", "reqwest", + "mime", "shadowsocks-service/local-online-config", ] @@ -224,6 +225,7 @@ serde = { version = "1.0", features = ["derive"] } json5 = "0.4" thiserror = "1.0" base64 = "0.22" +mime = { version = "0.3", optional = true } clap = { version = "4.5", features = ["wrap_help", "suggestions"] } cfg-if = "1" diff --git a/src/service/local.rs b/src/service/local.rs index dafc6729deee..6af2403d4fbe 100644 --- a/src/service/local.rs +++ b/src/service/local.rs @@ -1097,16 +1097,12 @@ async fn get_online_config_servers( online_config_url: &str, ) -> Result, Box> { use log::warn; + use mime::Mime; use reqwest::{redirect::Policy, Client}; #[inline] async fn get_online_config(online_config_url: &str) -> reqwest::Result { - static SHADOWSOCKS_USER_AGENT: &str = concat!( - env!("CARGO_PKG_NAME"), - "/", - env!("CARGO_PKG_VERSION"), - ); - + static SHADOWSOCKS_USER_AGENT: &str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION")); let client = Client::builder() .user_agent(SHADOWSOCKS_USER_AGENT) @@ -1131,14 +1127,29 @@ async fn get_online_config_servers( // Content-Type: application/json; charset=utf-8 // mandatory in standard SIP008 match response.headers().get("Content-Type") { - Some(h) => { - if h != "application/json; charset=utf-8" { - warn!( - "SIP008 Content-Type must be \"application/json; charset=utf-8\", but found {}", - h.to_str().unwrap_or("[non-utf8-value]") - ); + Some(h) => match h.to_str() { + Ok(hstr) => match hstr.parse::() { + Ok(content_type) => { + if content_type.type_() == mime::APPLICATION + && content_type.subtype() == mime::JSON + && content_type.get_param("charset") == Some(mime::UTF_8) + { + trace!("checked Content-Type: {:?}", h); + } else { + warn!( + "Content-Type is not \"application/json; charset=utf-8\", which is mandatory in standard SIP008. found {:?}", + h + ); + } + } + Err(err) => { + warn!("Content-Type parse failed, value: {:?}, error: {}", h, err); + } + }, + Err(..) => { + warn!("Content-Type is not a UTF-8 string: {:?}", h); } - } + }, None => { warn!("missing Content-Type in SIP008 response from {}", online_config_url); }