mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-04-15 10:58:54 +02:00
Compare commits
1 Commits
clear-stat
...
feat/refer
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af64de041b |
27
Cargo.lock
generated
27
Cargo.lock
generated
@@ -1319,7 +1319,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1641,12 +1641,6 @@ dependencies = [
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ct-codecs"
|
||||
version = "1.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b10589d1a5e400d61f9f38f12f884cfd080ff345de8f17efda36fe0e4a02aa8"
|
||||
|
||||
[[package]]
|
||||
name = "ctor"
|
||||
version = "0.2.9"
|
||||
@@ -2866,11 +2860,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
"libc",
|
||||
"r-efi",
|
||||
"wasi 0.14.2+wasi-0.2.4",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4319,7 +4311,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets 0.52.6",
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4600,12 +4592,11 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "minisign"
|
||||
version = "0.8.0"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6bf96cef396a17a96f7600281aa4da9229860b7a082601b1f6db6eaa5f99ee5"
|
||||
checksum = "b23ef13ff1d745b1e52397daaa247e333c607f3cff96d4df2b798dc252db974b"
|
||||
dependencies = [
|
||||
"ct-codecs",
|
||||
"getrandom 0.3.3",
|
||||
"getrandom 0.2.15",
|
||||
"rpassword",
|
||||
"scrypt",
|
||||
]
|
||||
@@ -6985,13 +6976,13 @@ checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97"
|
||||
|
||||
[[package]]
|
||||
name = "rpassword"
|
||||
version = "7.4.0"
|
||||
version = "7.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "66d4c8b64f049c6721ec8ccec37ddfc3d641c4a7fca57e8f2a89de509c73df39"
|
||||
checksum = "80472be3c897911d0137b2d2b9055faf6eeac5b14e324073d83bc17b191d7e3f"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rtoolbox",
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -10324,7 +10315,7 @@ version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||
dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -70,7 +70,7 @@ jsonschema = "0.33"
|
||||
handlebars = "6"
|
||||
include_dir = "0.7"
|
||||
dirs = "6"
|
||||
minisign = "0.8"
|
||||
minisign = "=0.7.3"
|
||||
base64 = "0.22"
|
||||
ureq = { version = "3", default-features = false, features = ["gzip"] }
|
||||
os_info = "3"
|
||||
|
||||
@@ -1767,6 +1767,17 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"Referer": {
|
||||
"description": "TODO: docs",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/HeaderSource"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"Tauri-Custom-Header": {
|
||||
"description": "A custom header field Tauri-Custom-Header, don't use it.\n Remember to set Access-Control-Expose-Headers accordingly\n\n **NOT INTENDED FOR PRODUCTION USE**",
|
||||
"anyOf": [
|
||||
|
||||
@@ -203,7 +203,7 @@ where
|
||||
mod tests {
|
||||
const PRIVATE_KEY: &str = "dW50cnVzdGVkIGNvbW1lbnQ6IHJzaWduIGVuY3J5cHRlZCBzZWNyZXQga2V5ClJXUlRZMEl5dkpDN09RZm5GeVAzc2RuYlNzWVVJelJRQnNIV2JUcGVXZUplWXZXYXpqUUFBQkFBQUFBQUFBQUFBQUlBQUFBQTZrN2RnWGh5dURxSzZiL1ZQSDdNcktiaHRxczQwMXdQelRHbjRNcGVlY1BLMTBxR2dpa3I3dDE1UTVDRDE4MXR4WlQwa1BQaXdxKy9UU2J2QmVSNXhOQWFDeG1GSVllbUNpTGJQRkhhTnROR3I5RmdUZi90OGtvaGhJS1ZTcjdZU0NyYzhQWlQ5cGM9Cg==";
|
||||
|
||||
// minisign >=0.7.4,<0.8.0 couldn't handle empty passwords.
|
||||
// we use minisign=0.7.3 to prevent a breaking change
|
||||
#[test]
|
||||
fn empty_password_is_valid() {
|
||||
let path = std::env::temp_dir().join("minisign-password-text.txt");
|
||||
|
||||
@@ -65,23 +65,28 @@ impl FromStr for ConfigValue {
|
||||
let path = PathBuf::from(config);
|
||||
let raw =
|
||||
read_to_string(&path).fs_context("failed to read configuration file", path.clone())?;
|
||||
|
||||
// treat all other extensions as json
|
||||
// from tauri-utils/src/config/parse.rs:
|
||||
// we also want to support **valid** json5 in the .json extension
|
||||
// if the json5 is not valid the serde_json error for regular json will be returned.
|
||||
match path.extension().and_then(|ext| ext.to_str()) {
|
||||
Some("toml") => Ok(Self(::toml::from_str(&raw).with_context(|| {
|
||||
format!("failed to parse config at {} as TOML", path.display())
|
||||
})?)),
|
||||
Some("json5") => Ok(Self(::json5::from_str(&raw).with_context(|| {
|
||||
format!("failed to parse config at {} as JSON5", path.display())
|
||||
})?)),
|
||||
_ => Ok(Self(match ::json5::from_str(&raw) {
|
||||
Ok(json5) => json5,
|
||||
Err(_) => serde_json::from_str(&raw)
|
||||
.with_context(|| format!("failed to parse config at {} as JSON", path.display()))?,
|
||||
})),
|
||||
match path.extension() {
|
||||
Some(ext) if ext == "toml" => {
|
||||
Ok(Self(::toml::from_str(&raw).with_context(|| {
|
||||
format!("failed to parse config at {} as TOML", path.display())
|
||||
})?))
|
||||
}
|
||||
Some(ext) if ext == "json5" => {
|
||||
Ok(Self(::json5::from_str(&raw).with_context(|| {
|
||||
format!("failed to parse config at {} as JSON5", path.display())
|
||||
})?))
|
||||
}
|
||||
// treat all other extensions as json
|
||||
_ => Ok(Self(
|
||||
// from tauri-utils/src/config/parse.rs:
|
||||
// we also want to support **valid** json5 in the .json extension
|
||||
// if the json5 is not valid the serde_json error for regular json will be returned.
|
||||
match ::json5::from_str(&raw) {
|
||||
Ok(json5) => json5,
|
||||
Err(_) => serde_json::from_str(&raw)
|
||||
.with_context(|| format!("failed to parse config at {} as JSON", path.display()))?,
|
||||
},
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -173,13 +178,6 @@ fn format_error<I: CommandFactory>(err: clap::Error) -> clap::Error {
|
||||
err.format(&mut app)
|
||||
}
|
||||
|
||||
fn get_verbosity(cli_verbose: u8) -> u8 {
|
||||
std::env::var("TAURI_CLI_VERBOSITY")
|
||||
.ok()
|
||||
.and_then(|v| v.parse().ok())
|
||||
.unwrap_or(cli_verbose)
|
||||
}
|
||||
|
||||
/// Run the Tauri CLI with the passed arguments, exiting if an error occurs.
|
||||
///
|
||||
/// The passed arguments should have the binary argument(s) stripped out before being passed.
|
||||
@@ -224,17 +222,23 @@ where
|
||||
Err(e) => e.exit(),
|
||||
};
|
||||
|
||||
let verbosity_number = get_verbosity(cli.verbose);
|
||||
let verbosity_number = std::env::var("TAURI_CLI_VERBOSITY")
|
||||
.ok()
|
||||
.and_then(|v| v.parse().ok())
|
||||
.unwrap_or(cli.verbose);
|
||||
// set the verbosity level so subsequent CLI calls (xcode-script, android-studio-script) refer to it
|
||||
std::env::set_var("TAURI_CLI_VERBOSITY", verbosity_number.to_string());
|
||||
|
||||
let mut builder = Builder::from_default_env();
|
||||
if let Err(err) = builder
|
||||
let init_res = builder
|
||||
.format_indent(Some(12))
|
||||
.filter(None, verbosity_level(verbosity_number).to_level_filter())
|
||||
// golbin spams an insane amount of really technical logs on the debug level so we're reducing one level
|
||||
.filter(
|
||||
Some("goblin"),
|
||||
verbosity_level(verbosity_number.saturating_sub(1)).to_level_filter(),
|
||||
)
|
||||
// handlebars is not that spammy but its debug logs are typically far from being helpful
|
||||
.filter(
|
||||
Some("handlebars"),
|
||||
verbosity_level(verbosity_number.saturating_sub(1)).to_level_filter(),
|
||||
@@ -246,6 +250,7 @@ where
|
||||
is_command_output = action == "stdout" || action == "stderr";
|
||||
if !is_command_output {
|
||||
let style = Style::new().fg_color(Some(AnsiColor::Green.into())).bold();
|
||||
|
||||
write!(f, "{style}{action:>12}{style:#} ")?;
|
||||
}
|
||||
} else {
|
||||
@@ -259,13 +264,15 @@ where
|
||||
|
||||
if !is_command_output && log::log_enabled!(Level::Debug) {
|
||||
let style = Style::new().fg_color(Some(AnsiColor::Black.into()));
|
||||
|
||||
write!(f, "[{style}{}{style:#}] ", record.target())?;
|
||||
}
|
||||
|
||||
writeln!(f, "{}", record.args())
|
||||
})
|
||||
.try_init()
|
||||
{
|
||||
.try_init();
|
||||
|
||||
if let Err(err) = init_res {
|
||||
eprintln!("Failed to attach logger: {err}");
|
||||
}
|
||||
|
||||
@@ -298,7 +305,7 @@ fn verbosity_level(num: u8) -> Level {
|
||||
match num {
|
||||
0 => Level::Info,
|
||||
1 => Level::Debug,
|
||||
_ => Level::Trace,
|
||||
2.. => Level::Trace,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,6 +321,8 @@ fn prettyprint_level(lvl: Level) -> &'static str {
|
||||
}
|
||||
|
||||
pub trait CommandExt {
|
||||
// The `pipe` function sets the stdout and stderr to properly
|
||||
// show the command output in the Node.js wrapper.
|
||||
fn piped(&mut self) -> std::io::Result<ExitStatus>;
|
||||
fn output_ok(&mut self) -> crate::Result<Output>;
|
||||
}
|
||||
@@ -323,15 +332,9 @@ impl CommandExt for Command {
|
||||
self.stdin(os_pipe::dup_stdin()?);
|
||||
self.stdout(os_pipe::dup_stdout()?);
|
||||
self.stderr(os_pipe::dup_stderr()?);
|
||||
|
||||
let program = self.get_program().to_string_lossy().into_owned();
|
||||
let args = self
|
||||
.get_args()
|
||||
.map(|a| a.to_string_lossy())
|
||||
.collect::<Vec<_>>()
|
||||
.join(" ");
|
||||
log::debug!(action = "Running"; "Command `{} {}`", program, self.get_args().map(|arg| arg.to_string_lossy()).fold(String::new(), |acc, arg| format!("{acc} {arg}")));
|
||||
|
||||
log::debug!(action = "Running"; "Command `{program} {args}`");
|
||||
self.status()
|
||||
}
|
||||
|
||||
@@ -339,9 +342,8 @@ impl CommandExt for Command {
|
||||
let program = self.get_program().to_string_lossy().into_owned();
|
||||
let args = self
|
||||
.get_args()
|
||||
.map(|a| a.to_string_lossy())
|
||||
.collect::<Vec<_>>()
|
||||
.join(" ");
|
||||
.map(|arg| arg.to_string_lossy())
|
||||
.fold(String::new(), |acc, arg| format!("{acc} {arg}"));
|
||||
let cmdline = format!("{program} {args}");
|
||||
log::debug!(action = "Running"; "Command `{cmdline}`");
|
||||
|
||||
@@ -357,17 +359,16 @@ impl CommandExt for Command {
|
||||
let stdout_lines_ = stdout_lines.clone();
|
||||
std::thread::spawn(move || {
|
||||
let mut line = String::new();
|
||||
if let Ok(mut lines) = stdout_lines_.lock() {
|
||||
loop {
|
||||
line.clear();
|
||||
match stdout.read_line(&mut line) {
|
||||
Ok(0) => break,
|
||||
Ok(_) => {
|
||||
log::debug!(action = "stdout"; "{}", line.trim_end());
|
||||
lines.extend(line.as_bytes());
|
||||
}
|
||||
Err(_) => (),
|
||||
let mut lines = stdout_lines_.lock().unwrap();
|
||||
loop {
|
||||
line.clear();
|
||||
match stdout.read_line(&mut line) {
|
||||
Ok(0) => break,
|
||||
Ok(_) => {
|
||||
log::debug!(action = "stdout"; "{}", line.trim_end());
|
||||
lines.extend(line.as_bytes().to_vec());
|
||||
}
|
||||
Err(_) => (),
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -377,17 +378,16 @@ impl CommandExt for Command {
|
||||
let stderr_lines_ = stderr_lines.clone();
|
||||
std::thread::spawn(move || {
|
||||
let mut line = String::new();
|
||||
if let Ok(mut lines) = stderr_lines_.lock() {
|
||||
loop {
|
||||
line.clear();
|
||||
match stderr.read_line(&mut line) {
|
||||
Ok(0) => break,
|
||||
Ok(_) => {
|
||||
log::debug!(action = "stderr"; "{}", line.trim_end());
|
||||
lines.extend(line.as_bytes());
|
||||
}
|
||||
Err(_) => (),
|
||||
let mut lines = stderr_lines_.lock().unwrap();
|
||||
loop {
|
||||
line.clear();
|
||||
match stderr.read_line(&mut line) {
|
||||
Ok(0) => break,
|
||||
Ok(_) => {
|
||||
log::debug!(action = "stderr"; "{}", line.trim_end());
|
||||
lines.extend(line.as_bytes().to_vec());
|
||||
}
|
||||
Err(_) => (),
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -423,10 +423,4 @@ mod tests {
|
||||
fn verify_cli() {
|
||||
Cli::command().debug_assert();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn help_output_includes_build() {
|
||||
let help = Cli::command().render_help().to_string();
|
||||
assert!(help.contains("Build"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1767,6 +1767,17 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"Referer": {
|
||||
"description": "TODO: docs",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/HeaderSource"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"Tauri-Custom-Header": {
|
||||
"description": "A custom header field Tauri-Custom-Header, don't use it.\n Remember to set Access-Control-Expose-Headers accordingly\n\n **NOT INTENDED FOR PRODUCTION USE**",
|
||||
"anyOf": [
|
||||
|
||||
@@ -2390,6 +2390,11 @@ impl HeaderAddition for Builder {
|
||||
self = self.header("X-Content-Type-Options", value.to_string());
|
||||
};
|
||||
|
||||
// Add the header X-Content-Type-Options, if we find a value for it
|
||||
if let Some(value) = &headers.referer {
|
||||
self = self.header("Referer", value.to_string());
|
||||
};
|
||||
|
||||
// Add the header Tauri-Custom-Header, if we find a value for it
|
||||
if let Some(value) = &headers.tauri_custom_header {
|
||||
// Keep in mind to correctly set the Access-Control-Expose-Headers
|
||||
@@ -2543,6 +2548,9 @@ pub struct HeaderConfig {
|
||||
/// See <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options>
|
||||
#[serde(rename = "X-Content-Type-Options")]
|
||||
pub x_content_type_options: Option<HeaderSource>,
|
||||
/// TODO: docs
|
||||
#[serde(rename = "Referer")]
|
||||
pub referer: Option<HeaderSource>,
|
||||
/// A custom header field Tauri-Custom-Header, don't use it.
|
||||
/// Remember to set Access-Control-Expose-Headers accordingly
|
||||
///
|
||||
@@ -2567,6 +2575,7 @@ impl HeaderConfig {
|
||||
service_worker_allowed: None,
|
||||
timing_allow_origin: None,
|
||||
x_content_type_options: None,
|
||||
referer: None,
|
||||
tauri_custom_header: None,
|
||||
}
|
||||
}
|
||||
@@ -3920,6 +3929,7 @@ mod build {
|
||||
let service_worker_allowed = opt_lit(self.service_worker_allowed.as_ref());
|
||||
let timing_allow_origin = opt_lit(self.timing_allow_origin.as_ref());
|
||||
let x_content_type_options = opt_lit(self.x_content_type_options.as_ref());
|
||||
let referer = opt_lit(self.referer.as_ref());
|
||||
let tauri_custom_header = opt_lit(self.tauri_custom_header.as_ref());
|
||||
|
||||
literal_struct!(
|
||||
@@ -3937,6 +3947,7 @@ mod build {
|
||||
service_worker_allowed,
|
||||
timing_allow_origin,
|
||||
x_content_type_options,
|
||||
referer,
|
||||
tauri_custom_header
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1037,7 +1037,6 @@ macro_rules! shared_app_impl {
|
||||
for (_, webview) in self.manager.webviews() {
|
||||
webview.resources_table().clear();
|
||||
}
|
||||
unsafe { self.manager.state.clear() };
|
||||
}
|
||||
|
||||
/// Gets the invoke key that must be referenced when using [`crate::webview::InvokeRequest`].
|
||||
|
||||
@@ -149,13 +149,6 @@ impl StateManager {
|
||||
Some(*value)
|
||||
}
|
||||
|
||||
/// SAFETY: This will cause all references obtained through [Self::try_get] to dangle.
|
||||
/// This must only be called on app exit (in cleanup_before_exit).
|
||||
pub(crate) unsafe fn clear(&self) {
|
||||
let mut map = self.map.lock().unwrap();
|
||||
map.clear();
|
||||
}
|
||||
|
||||
/// Gets the state associated with the specified type.
|
||||
pub fn get<T: Send + Sync + 'static>(&self) -> State<'_, T> {
|
||||
self
|
||||
|
||||
Reference in New Issue
Block a user