* refactor(tauri-build): make better use of OsString

Co-authored-by: Tony <68118705+Legend-Master@users.noreply.github.com>

* refactor(tauri-build): dont wrap const value in function

* refactor(tauri-build): None codepath is never used, replace Option<Vec> with Vec

* refactor(tauri): use blocking apis where it makes sense

* refactor(tauri): better use of std::fs API

* refactor(tauri): rewind to start

* refactor(tauri): fmt

* add change file
This commit is contained in:
sftse
2026-03-20 11:18:29 +01:00
committed by GitHub
parent 80c1425af8
commit d730770bb9
4 changed files with 59 additions and 82 deletions

View File

@@ -0,0 +1,6 @@
---
"tauri-build": patch:enhance
"tauri": patch:enhance
---
Simplify async-sync code boundaries, no externally visible changes

View File

@@ -411,7 +411,8 @@ impl Attributes {
}
pub fn is_dev() -> bool {
env::var("DEP_TAURI_DEV").expect("missing `cargo:dev` instruction, please update tauri to latest")
env::var_os("DEP_TAURI_DEV")
.expect("missing `cargo:dev` instruction, please update tauri to latest")
== "true"
}
@@ -458,7 +459,7 @@ pub fn try_build(attributes: Attributes) -> Result<()> {
println!("cargo:rerun-if-env-changed=TAURI_CONFIG");
let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
let target_os = env::var_os("CARGO_CFG_TARGET_OS").unwrap();
let mobile = target_os == "ios" || target_os == "android";
cfg_alias("desktop", !mobile);
cfg_alias("mobile", mobile);
@@ -503,7 +504,7 @@ pub fn try_build(attributes: Attributes) -> Result<()> {
let cargo_toml_path = Path::new("Cargo.toml").canonicalize()?;
let mut manifest = Manifest::<cargo_toml::Value>::from_path_with_metadata(cargo_toml_path)?;
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
manifest::check(&config, &mut manifest)?;
@@ -538,7 +539,7 @@ pub fn try_build(attributes: Attributes) -> Result<()> {
.bundle
.resources
.clone()
.unwrap_or_else(|| BundleResources::List(Vec::new()));
.unwrap_or(BundleResources::List(Vec::new()));
if target_triple.contains("windows") {
if let Some(fixed_webview2_runtime_path) = match &config.bundle.windows.webview_install_mode {
WebviewInstallMode::FixedRuntime { path } => Some(path),
@@ -682,7 +683,7 @@ pub fn try_build(attributes: Attributes) -> Result<()> {
}
}
"msvc" => {
if env::var("STATIC_VCRUNTIME").is_ok_and(|v| v == "true") {
if env::var_os("STATIC_VCRUNTIME").is_some_and(|v| v == "true") {
static_vcruntime::build();
}
}

View File

@@ -23,7 +23,7 @@ struct AllowlistedDependency {
name: String,
alias: Option<String>,
kind: DependencyKind,
all_cli_managed_features: Option<Vec<&'static str>>,
all_cli_managed_features: Vec<&'static str>,
expected_features: Vec<String>,
}
@@ -33,7 +33,7 @@ pub fn check(config: &Config, manifest: &mut Manifest) -> Result<()> {
name: "tauri-build".into(),
alias: None,
kind: DependencyKind::Build,
all_cli_managed_features: Some(vec!["isolation"]),
all_cli_managed_features: vec!["isolation"],
expected_features: match config.app.security.pattern {
PatternKind::Isolation { .. } => vec!["isolation".to_string()],
_ => vec![],
@@ -43,12 +43,10 @@ pub fn check(config: &Config, manifest: &mut Manifest) -> Result<()> {
name: "tauri".into(),
alias: None,
kind: DependencyKind::Normal,
all_cli_managed_features: Some(
AppConfig::all_features()
.into_iter()
.filter(|f| f != &"tray-icon")
.collect(),
),
all_cli_managed_features: AppConfig::all_features()
.into_iter()
.filter(|f| f != &"tray-icon")
.collect(),
expected_features: config
.app
.features()
@@ -129,23 +127,13 @@ fn check_features(dependency: Dependency, metadata: &AllowlistedDependency) -> R
Dependency::Inherited(dep) => dep.features,
};
let diff = if let Some(all_cli_managed_features) = &metadata.all_cli_managed_features {
features_diff(
&features
.into_iter()
.filter(|f| all_cli_managed_features.contains(&f.as_str()))
.collect::<Vec<String>>(),
&metadata.expected_features,
)
} else {
features_diff(
&features
.into_iter()
.filter(|f| f.starts_with("allow-"))
.collect::<Vec<String>>(),
&metadata.expected_features,
)
};
let diff = features_diff(
&features
.into_iter()
.filter(|f| metadata.all_cli_managed_features.contains(&f.as_str()))
.collect::<Vec<String>>(),
&metadata.expected_features,
);
let mut error_message = String::new();
if !diff.remove.is_empty() {

View File

@@ -5,10 +5,10 @@
use crate::{path::SafePathBuf, scope, webview::UriSchemeProtocolHandler};
use http::{header::*, status::StatusCode, Request, Response};
use http_range::HttpRange;
use std::fs::File;
use std::io::{Read, Seek, Write};
use std::{borrow::Cow, io::SeekFrom};
use tauri_utils::mime_type::MimeType;
use tokio::fs::File;
use tokio::io::{AsyncReadExt, AsyncSeekExt, AsyncWriteExt};
pub fn get(scope: scope::fs::Scope, window_origin: String) -> UriSchemeProtocolHandler {
Box::new(
@@ -49,7 +49,7 @@ fn get_response(
}
// Separate block for easier error handling
let mut file = match crate::async_runtime::safe_block_on(File::open(path.clone())) {
let mut file = match File::open(path.clone()) {
Ok(file) => file,
Err(e) => {
#[cfg(target_os = "android")]
@@ -70,32 +70,20 @@ fn get_response(
}
};
let (mut file, len, mime_type, read_bytes) = crate::async_runtime::safe_block_on(async move {
// get file length
let len = {
let old_pos = file.stream_position().await?;
let len = file.seek(SeekFrom::End(0)).await?;
file.seek(SeekFrom::Start(old_pos)).await?;
len
};
let len = file.metadata()?.len();
let (mime_type, read_bytes) = {
// get file mime type
let (mime_type, read_bytes) = {
let nbytes = len.min(8192);
let mut magic_buf = Vec::with_capacity(nbytes as usize);
let old_pos = file.stream_position().await?;
(&mut file).take(nbytes).read_to_end(&mut magic_buf).await?;
file.seek(SeekFrom::Start(old_pos)).await?;
(
MimeType::parse(&magic_buf, &path),
// return the `magic_bytes` if we read the whole file
// to avoid reading it again later if this is not a range request
if len < 8192 { Some(magic_buf) } else { None },
)
};
Ok::<(File, u64, String, Option<Vec<u8>>), anyhow::Error>((file, len, mime_type, read_bytes))
})?;
let nbytes = len.min(8192);
let mut magic_buf = Vec::with_capacity(nbytes as usize);
(&mut file).take(nbytes).read_to_end(&mut magic_buf)?;
file.rewind()?;
(
MimeType::parse(&magic_buf, &path),
// return the `magic_bytes` if we read the whole file
// to avoid reading it again later if this is not a range request
if len < 8192 { Some(magic_buf) } else { None },
)
};
resp = resp.header(CONTENT_TYPE, &mime_type);
@@ -148,12 +136,12 @@ fn get_response(
// calculate number of bytes needed to be read
let nbytes = end + 1 - start;
let buf = crate::async_runtime::safe_block_on(async move {
let buf = {
let mut buf = Vec::with_capacity(nbytes as usize);
file.seek(SeekFrom::Start(start)).await?;
file.take(nbytes).read_to_end(&mut buf).await?;
Ok::<Vec<u8>, anyhow::Error>(buf)
})?;
file.seek(SeekFrom::Start(start))?;
file.take(nbytes).read_to_end(&mut buf)?;
buf
};
resp = resp.header(CONTENT_RANGE, format!("bytes {start}-{end}/{len}"));
resp = resp.header(CONTENT_LENGTH, end + 1 - start);
@@ -186,38 +174,34 @@ fn get_response(
format!("multipart/byteranges; boundary={boundary}"),
);
let buf = crate::async_runtime::safe_block_on(async move {
let buf = {
// multi-part range header
let mut buf = Vec::new();
for (start, end) in ranges {
// a new range is being written, write the range boundary
buf.write_all(boundary_sep.as_bytes()).await?;
buf.write_all(boundary_sep.as_bytes())?;
// write the needed headers `Content-Type` and `Content-Range`
buf
.write_all(format!("{CONTENT_TYPE}: {mime_type}\r\n").as_bytes())
.await?;
buf
.write_all(format!("{CONTENT_RANGE}: bytes {start}-{end}/{len}\r\n").as_bytes())
.await?;
buf.write_all(format!("{CONTENT_TYPE}: {mime_type}\r\n").as_bytes())?;
buf.write_all(format!("{CONTENT_RANGE}: bytes {start}-{end}/{len}\r\n").as_bytes())?;
// write the separator to indicate the start of the range body
buf.write_all("\r\n".as_bytes()).await?;
buf.write_all("\r\n".as_bytes())?;
// calculate number of bytes needed to be read
let nbytes = end + 1 - start;
let mut local_buf = Vec::with_capacity(nbytes as usize);
file.seek(SeekFrom::Start(start)).await?;
(&mut file).take(nbytes).read_to_end(&mut local_buf).await?;
file.seek(SeekFrom::Start(start))?;
(&mut file).take(nbytes).read_to_end(&mut local_buf)?;
buf.extend_from_slice(&local_buf);
}
// all ranges have been written, write the closing boundary
buf.write_all(boundary_closer.as_bytes()).await?;
buf.write_all(boundary_closer.as_bytes())?;
Ok::<Vec<u8>, anyhow::Error>(buf)
})?;
buf
};
resp.body(buf.into())
}
} else if request.method() == http::Method::HEAD {
@@ -230,11 +214,9 @@ fn get_response(
let buf = if let Some(b) = read_bytes {
b
} else {
crate::async_runtime::safe_block_on(async move {
let mut local_buf = Vec::with_capacity(len as usize);
file.read_to_end(&mut local_buf).await?;
Ok::<Vec<u8>, anyhow::Error>(local_buf)
})?
let mut local_buf = Vec::with_capacity(len as usize);
file.read_to_end(&mut local_buf)?;
local_buf
};
resp = resp.header(CONTENT_LENGTH, len);
resp.body(buf.into())