commit
875ffbb651
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'log': 'minor:feat'
|
||||||
|
'log-js': 'minor:feat'
|
||||||
|
---
|
||||||
|
Add a `tracing` feature to the `log` plugin that emits log messages to the `tracing` system.
|
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
log: minor
|
||||||
|
log-js: minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Adds a new varient `TargetKind::Dispatch` that allows you to construct arbitrary log targets
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@ -1 +1 @@
|
|||||||
if("__TAURI__"in window){var __TAURI_PLUGIN_HTTP__=function(e){"use strict";async function t(e,t={},r){return window.__TAURI_INTERNALS__.invoke(e,t,r)}"function"==typeof SuppressedError&&SuppressedError;const r="Request canceled";return e.fetch=async function(e,n){const a=n?.signal;if(a?.aborted)throw new Error(r);const o=n?.maxRedirections,s=n?.connectTimeout,i=n?.proxy,d=n?.danger;n&&(delete n.maxRedirections,delete n.connectTimeout,delete n.proxy,delete n.danger);const c=n?.headers?n.headers instanceof Headers?n.headers:new Headers(n.headers):new Headers,u=new Request(e,n),f=await u.arrayBuffer(),_=0!==f.byteLength?Array.from(new Uint8Array(f)):null;for(const[e,t]of u.headers)c.get(e)||c.set(e,t);const h=(c instanceof Headers?Array.from(c.entries()):Array.isArray(c)?c:Object.entries(c)).map((([e,t])=>[e,"string"==typeof t?t:t.toString()]));if(a?.aborted)throw new Error(r);const l=await t("plugin:http|fetch",{clientConfig:{method:u.method,url:u.url,headers:h,data:_,maxRedirections:o,connectTimeout:s,proxy:i,danger:d}}),p=()=>t("plugin:http|fetch_cancel",{rid:l});if(a?.aborted)throw p(),new Error(r);a?.addEventListener("abort",(()=>{p()}));const{status:w,statusText:y,url:g,headers:T,rid:A}=await t("plugin:http|fetch_send",{rid:l}),R=await t("plugin:http|fetch_read_body",{rid:A}),b=new Response(R instanceof ArrayBuffer&&0!==R.byteLength?R:R instanceof Array&&R.length>0?new Uint8Array(R):null,{status:w,statusText:y});return Object.defineProperty(b,"url",{value:g}),Object.defineProperty(b,"headers",{value:new Headers(T)}),b},e}({});Object.defineProperty(window.__TAURI__,"http",{value:__TAURI_PLUGIN_HTTP__})}
|
if("__TAURI__"in window){var __TAURI_PLUGIN_HTTP__=function(e){"use strict";function t(e,t,r,n){if("function"==typeof t||!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===r?n:"a"===r?n.call(e):n?n.value:t.get(e)}function r(e,t,r,n,s){if("function"==typeof t||!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return t.set(e,r),r}var n,s,a;"function"==typeof SuppressedError&&SuppressedError;const i="__TAURI_TO_IPC_KEY__";class o{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,n.set(this,(()=>{})),s.set(this,0),a.set(this,[]),this.id=function(e,t=!1){return window.__TAURI_INTERNALS__.transformCallback(e,t)}((({message:e,id:i})=>{if(i==t(this,s,"f"))for(t(this,n,"f").call(this,e),r(this,s,t(this,s,"f")+1);t(this,s,"f")in t(this,a,"f");){const e=t(this,a,"f")[t(this,s,"f")];t(this,n,"f").call(this,e),delete t(this,a,"f")[t(this,s,"f")],r(this,s,t(this,s,"f")+1)}else t(this,a,"f")[i]=e}))}set onmessage(e){r(this,n,e)}get onmessage(){return t(this,n,"f")}[(n=new WeakMap,s=new WeakMap,a=new WeakMap,i)](){return`__CHANNEL__:${this.id}`}toJSON(){return this[i]()}}async function c(e,t={},r){return window.__TAURI_INTERNALS__.invoke(e,t,r)}const d="Request cancelled";return e.fetch=async function(e,t){const r=t?.signal;if(r?.aborted)throw new Error(d);const n=t?.maxRedirections,s=t?.connectTimeout,a=t?.proxy,i=t?.danger;t&&(delete t.maxRedirections,delete t.connectTimeout,delete t.proxy,delete t.danger);const h=t?.headers?t.headers instanceof Headers?t.headers:new Headers(t.headers):new Headers,f=new Request(e,t),_=await f.arrayBuffer(),u=0!==_.byteLength?Array.from(new Uint8Array(_)):null;for(const[e,t]of f.headers)h.get(e)||h.set(e,t);const l=(h instanceof Headers?Array.from(h.entries()):Array.isArray(h)?h:Object.entries(h)).map((([e,t])=>[e,"string"==typeof t?t:t.toString()]));if(r?.aborted)throw new Error(d);const w=await c("plugin:http|fetch",{clientConfig:{method:f.method,url:f.url,headers:l,data:u,maxRedirections:n,connectTimeout:s,proxy:a,danger:i}}),p=()=>c("plugin:http|fetch_cancel",{rid:w});if(r?.aborted)throw p(),new Error(d);r?.addEventListener("abort",(()=>{p()}));const{status:y,statusText:m,url:T,headers:g,rid:b}=await c("plugin:http|fetch_send",{rid:w}),A=new ReadableStream({start:e=>{const t=new o;t.onmessage=t=>{if(r?.aborted)return void e.error(d);const n=new Uint8Array(t),s=n[n.byteLength-1],a=n.slice(0,n.byteLength-1);1!=s?e.enqueue(a):e.close()},c("plugin:http|fetch_read_body",{rid:b,streamChannel:t}).catch((t=>{e.error(t)}))}}),R=new Response(A,{status:y,statusText:m});return Object.defineProperty(R,"url",{value:T}),Object.defineProperty(R,"headers",{value:new Headers(g)}),R},e}({});Object.defineProperty(window.__TAURI__,"http",{value:__TAURI_PLUGIN_HTTP__})}
|
||||||
|
@ -0,0 +1,133 @@
|
|||||||
|
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
// taken from https://github.com/pfernie/reqwest_cookie_store/blob/2ec4afabcd55e24d3afe3f0626ee6dc97bed938d/src/lib.rs
|
||||||
|
|
||||||
|
use std::{
|
||||||
|
path::PathBuf,
|
||||||
|
sync::{mpsc::Receiver, Mutex},
|
||||||
|
};
|
||||||
|
|
||||||
|
use cookie_store::{CookieStore, RawCookie, RawCookieParseError};
|
||||||
|
use reqwest::header::HeaderValue;
|
||||||
|
|
||||||
|
fn set_cookies(
|
||||||
|
cookie_store: &mut CookieStore,
|
||||||
|
cookie_headers: &mut dyn Iterator<Item = &HeaderValue>,
|
||||||
|
url: &url::Url,
|
||||||
|
) {
|
||||||
|
let cookies = cookie_headers.filter_map(|val| {
|
||||||
|
std::str::from_utf8(val.as_bytes())
|
||||||
|
.map_err(RawCookieParseError::from)
|
||||||
|
.and_then(RawCookie::parse)
|
||||||
|
.map(|c| c.into_owned())
|
||||||
|
.ok()
|
||||||
|
});
|
||||||
|
cookie_store.store_response_cookies(cookies, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cookies(cookie_store: &CookieStore, url: &url::Url) -> Option<HeaderValue> {
|
||||||
|
let s = cookie_store
|
||||||
|
.get_request_values(url)
|
||||||
|
.map(|(name, value)| format!("{}={}", name, value))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join("; ");
|
||||||
|
|
||||||
|
if s.is_empty() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
HeaderValue::from_maybe_shared(bytes::Bytes::from(s)).ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A [`cookie_store::CookieStore`] wrapped internally by a [`std::sync::Mutex`], suitable for use in
|
||||||
|
/// async/concurrent contexts.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct CookieStoreMutex {
|
||||||
|
pub path: PathBuf,
|
||||||
|
store: Mutex<CookieStore>,
|
||||||
|
save_task: Mutex<Option<CancellableTask>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CookieStoreMutex {
|
||||||
|
/// Create a new [`CookieStoreMutex`] from an existing [`cookie_store::CookieStore`].
|
||||||
|
pub fn new(path: PathBuf, cookie_store: CookieStore) -> CookieStoreMutex {
|
||||||
|
CookieStoreMutex {
|
||||||
|
path,
|
||||||
|
store: Mutex::new(cookie_store),
|
||||||
|
save_task: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load<R: std::io::BufRead>(
|
||||||
|
path: PathBuf,
|
||||||
|
reader: R,
|
||||||
|
) -> cookie_store::Result<CookieStoreMutex> {
|
||||||
|
cookie_store::serde::load(reader, |c| serde_json::from_str(c))
|
||||||
|
.map(|store| CookieStoreMutex::new(path, store))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cookies_to_str(&self) -> Result<String, serde_json::Error> {
|
||||||
|
let mut cookies = Vec::new();
|
||||||
|
for cookie in self
|
||||||
|
.store
|
||||||
|
.lock()
|
||||||
|
.expect("poisoned cookie jar mutex")
|
||||||
|
.iter_unexpired()
|
||||||
|
{
|
||||||
|
if cookie.is_persistent() {
|
||||||
|
cookies.push(cookie.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
serde_json::to_string(&cookies)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn request_save(&self) -> cookie_store::Result<Receiver<()>> {
|
||||||
|
let cookie_str = self.cookies_to_str()?;
|
||||||
|
let path = self.path.clone();
|
||||||
|
let (tx, rx) = std::sync::mpsc::channel();
|
||||||
|
let task = tauri::async_runtime::spawn(async move {
|
||||||
|
match tokio::fs::write(&path, &cookie_str).await {
|
||||||
|
Ok(()) => {
|
||||||
|
let _ = tx.send(());
|
||||||
|
}
|
||||||
|
Err(_e) => {
|
||||||
|
#[cfg(feature = "tracing")]
|
||||||
|
tracing::error!("failed to save cookie jar: {_e}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
self.save_task
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.replace(CancellableTask(task));
|
||||||
|
Ok(rx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl reqwest::cookie::CookieStore for CookieStoreMutex {
|
||||||
|
fn set_cookies(&self, cookie_headers: &mut dyn Iterator<Item = &HeaderValue>, url: &url::Url) {
|
||||||
|
set_cookies(&mut self.store.lock().unwrap(), cookie_headers, url);
|
||||||
|
|
||||||
|
// try to persist cookies immediately asynchronously
|
||||||
|
if let Err(_e) = self.request_save() {
|
||||||
|
#[cfg(feature = "tracing")]
|
||||||
|
tracing::error!("failed to save cookie jar: {_e}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cookies(&self, url: &url::Url) -> Option<HeaderValue> {
|
||||||
|
let store = self.store.lock().unwrap();
|
||||||
|
cookies(&store, url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct CancellableTask(tauri::async_runtime::JoinHandle<()>);
|
||||||
|
|
||||||
|
impl Drop for CancellableTask {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
self.0.abort();
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue