diff --git a/.changes/http-stream-cancel.md b/.changes/http-stream-cancel.md
new file mode 100644
index 00000000..66c29f71
--- /dev/null
+++ b/.changes/http-stream-cancel.md
@@ -0,0 +1,7 @@
+---
+"http": "patch"
+"http-js": "patch"
+---
+
+Fix aborting a request in the middle of a streaming response.
+
diff --git a/plugins/autostart/permissions/schemas/schema.json b/plugins/autostart/permissions/schemas/schema.json
index 59c81f52..defb923c 100644
--- a/plugins/autostart/permissions/schemas/schema.json
+++ b/plugins/autostart/permissions/schemas/schema.json
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri convention is to use
headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri internal convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri internal convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
diff --git a/plugins/barcode-scanner/permissions/schemas/schema.json b/plugins/barcode-scanner/permissions/schemas/schema.json
index f41214b4..dc2ab019 100644
--- a/plugins/barcode-scanner/permissions/schemas/schema.json
+++ b/plugins/barcode-scanner/permissions/schemas/schema.json
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri internal convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri internal convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
diff --git a/plugins/biometric/permissions/schemas/schema.json b/plugins/biometric/permissions/schemas/schema.json
index cc4d04d5..891877b6 100644
--- a/plugins/biometric/permissions/schemas/schema.json
+++ b/plugins/biometric/permissions/schemas/schema.json
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri internal convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri internal convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
diff --git a/plugins/cli/permissions/schemas/schema.json b/plugins/cli/permissions/schemas/schema.json
index b376890e..fb1ec637 100644
--- a/plugins/cli/permissions/schemas/schema.json
+++ b/plugins/cli/permissions/schemas/schema.json
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri internal convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri internal convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
diff --git a/plugins/clipboard-manager/permissions/schemas/schema.json b/plugins/clipboard-manager/permissions/schemas/schema.json
index c2763492..7e23e9a3 100644
--- a/plugins/clipboard-manager/permissions/schemas/schema.json
+++ b/plugins/clipboard-manager/permissions/schemas/schema.json
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri internal convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri internal convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
diff --git a/plugins/deep-link/permissions/schemas/schema.json b/plugins/deep-link/permissions/schemas/schema.json
index 7d887dc2..1c96c7d5 100644
--- a/plugins/deep-link/permissions/schemas/schema.json
+++ b/plugins/deep-link/permissions/schemas/schema.json
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri internal convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri internal convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
diff --git a/plugins/dialog/permissions/schemas/schema.json b/plugins/dialog/permissions/schemas/schema.json
index ed8c0733..4fa8bdf3 100644
--- a/plugins/dialog/permissions/schemas/schema.json
+++ b/plugins/dialog/permissions/schemas/schema.json
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri internal convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri internal convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
diff --git a/plugins/fs/permissions/schemas/schema.json b/plugins/fs/permissions/schemas/schema.json
index 2c13d5c6..e8706b04 100644
--- a/plugins/fs/permissions/schemas/schema.json
+++ b/plugins/fs/permissions/schemas/schema.json
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri internal convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri internal convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
diff --git a/plugins/geolocation/permissions/schemas/schema.json b/plugins/geolocation/permissions/schemas/schema.json
index 4474ec6b..fe0129bb 100644
--- a/plugins/geolocation/permissions/schemas/schema.json
+++ b/plugins/geolocation/permissions/schemas/schema.json
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri internal convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri internal convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
diff --git a/plugins/global-shortcut/permissions/schemas/schema.json b/plugins/global-shortcut/permissions/schemas/schema.json
index 66b92b07..6270e7f3 100644
--- a/plugins/global-shortcut/permissions/schemas/schema.json
+++ b/plugins/global-shortcut/permissions/schemas/schema.json
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri internal convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri internal convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
diff --git a/plugins/haptics/permissions/schemas/schema.json b/plugins/haptics/permissions/schemas/schema.json
index 763e0a72..889da78f 100644
--- a/plugins/haptics/permissions/schemas/schema.json
+++ b/plugins/haptics/permissions/schemas/schema.json
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri internal convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri internal convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
diff --git a/plugins/http/api-iife.js b/plugins/http/api-iife.js
index ec016360..5856df7e 100644
--- a/plugins/http/api-iife.js
+++ b/plugins/http/api-iife.js
@@ -1 +1 @@
-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__})}
+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 cancelled";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),_=await u.arrayBuffer(),l=0!==_.byteLength?Array.from(new Uint8Array(_)):null;for(const[e,t]of u.headers)c.get(e)||c.set(e,t);const f=(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 h=await t("plugin:http|fetch",{clientConfig:{method:u.method,url:u.url,headers:f,data:l,maxRedirections:o,connectTimeout:s,proxy:i,danger:d}}),p=()=>t("plugin:http|fetch_cancel",{rid:h});if(a?.aborted)throw p(),new Error(r);a?.addEventListener("abort",(()=>{p()}));const{status:y,statusText:w,url:b,headers:g,rid:T}=await t("plugin:http|fetch_send",{rid:h}),R=()=>t("plugin:http|fetch_cancel_body",{rid:T}),m=new ReadableStream({start:e=>{if(a?.aborted)return e.error(r),void R();a?.addEventListener("abort",(()=>{e.error(r),R()}))},pull:async e=>(async e=>{let r;try{r=await t("plugin:http|fetch_read_body",{rid:T})}catch(t){return e.error(t),void R()}const n=new Uint8Array(r),a=n[n.byteLength-1],o=n.slice(0,n.byteLength-1);1===a&&e.close(),e.enqueue(o)})(e)}),A=new Response(m,{status:y,statusText:w});return Object.defineProperty(A,"url",{value:b}),Object.defineProperty(A,"headers",{value:new Headers(g)}),A},e}({});Object.defineProperty(window.__TAURI__,"http",{value:__TAURI_PLUGIN_HTTP__})}
diff --git a/plugins/http/build.rs b/plugins/http/build.rs
index a4b802ad..31fa0237 100644
--- a/plugins/http/build.rs
+++ b/plugins/http/build.rs
@@ -6,7 +6,13 @@
#[allow(dead_code)]
mod scope;
-const COMMANDS: &[&str] = &["fetch", "fetch_cancel", "fetch_send", "fetch_read_body"];
+const COMMANDS: &[&str] = &[
+ "fetch",
+ "fetch_cancel",
+ "fetch_send",
+ "fetch_read_body",
+ "fetch_cancel_body",
+];
/// HTTP scope entry.
#[derive(schemars::JsonSchema)]
diff --git a/plugins/http/guest-js/index.ts b/plugins/http/guest-js/index.ts
index 62f4916c..037d3b12 100644
--- a/plugins/http/guest-js/index.ts
+++ b/plugins/http/guest-js/index.ts
@@ -26,7 +26,7 @@
* @module
*/
-import { Channel, invoke } from '@tauri-apps/api/core'
+import { invoke } from '@tauri-apps/api/core'
/**
* Configuration of a proxy that a Client should pass requests to.
@@ -229,37 +229,53 @@ export async function fetch(
rid
})
+ const dropBody = () => {
+ return invoke('plugin:http|fetch_cancel_body', { rid: responseRid })
+ }
+
+ const readChunk = async (
+ controller: ReadableStreamDefaultController
+ ) => {
+ let data: ArrayBuffer
+ try {
+ data = await invoke('plugin:http|fetch_read_body', {
+ rid: responseRid
+ })
+ } catch (e) {
+ // close the stream if an error occurs
+ // and drop the body on Rust side
+ controller.error(e)
+ void dropBody()
+ return
+ }
+
+ const dataUint8 = new Uint8Array(data)
+ const lastByte = dataUint8[dataUint8.byteLength - 1]
+ const actualData = dataUint8.slice(0, dataUint8.byteLength - 1)
+
+ // close when the signal to close (last byte is 1) is sent from the IPC.
+ if (lastByte === 1) {
+ controller.close()
+ }
+
+ controller.enqueue(actualData)
+ }
+
const readableStreamBody = new ReadableStream({
start: (controller) => {
- const streamChannel = new Channel()
- streamChannel.onmessage = (res: ArrayBuffer | number[]) => {
- // close early if aborted
- if (signal?.aborted) {
- controller.error(ERROR_REQUEST_CANCELLED)
- return
- }
-
- const resUint8 = new Uint8Array(res)
- const lastByte = resUint8[resUint8.byteLength - 1]
- const actualRes = resUint8.slice(0, resUint8.byteLength - 1)
-
- // close when the signal to close (last byte is 1) is sent from the IPC.
- if (lastByte == 1) {
- controller.close()
- return
- }
-
- controller.enqueue(actualRes)
+ // abort early here if needed and drop the body
+ if (signal?.aborted) {
+ controller.error(ERROR_REQUEST_CANCELLED)
+ void dropBody()
+ return
}
- // run a non-blocking body stream fetch
- invoke('plugin:http|fetch_read_body', {
- rid: responseRid,
- streamChannel
- }).catch((e) => {
- controller.error(e)
+ signal?.addEventListener('abort', () => {
+ controller.error(ERROR_REQUEST_CANCELLED)
+ void dropBody()
})
- }
+ },
+ pull: async (controller) => readChunk(controller)
})
const res = new Response(readableStreamBody, {
diff --git a/plugins/http/permissions/autogenerated/commands/fetch_cancel_body.toml b/plugins/http/permissions/autogenerated/commands/fetch_cancel_body.toml
new file mode 100644
index 00000000..19e66520
--- /dev/null
+++ b/plugins/http/permissions/autogenerated/commands/fetch_cancel_body.toml
@@ -0,0 +1,13 @@
+# Automatically generated - DO NOT EDIT!
+
+"$schema" = "../../schemas/schema.json"
+
+[[permission]]
+identifier = "allow-fetch-cancel-body"
+description = "Enables the fetch_cancel_body command without any pre-configured scope."
+commands.allow = ["fetch_cancel_body"]
+
+[[permission]]
+identifier = "deny-fetch-cancel-body"
+description = "Denies the fetch_cancel_body command without any pre-configured scope."
+commands.deny = ["fetch_cancel_body"]
diff --git a/plugins/http/permissions/autogenerated/reference.md b/plugins/http/permissions/autogenerated/reference.md
index 4126f0b9..f056be2e 100644
--- a/plugins/http/permissions/autogenerated/reference.md
+++ b/plugins/http/permissions/autogenerated/reference.md
@@ -15,8 +15,9 @@ All fetch operations are enabled.
- `allow-fetch`
- `allow-fetch-cancel`
-- `allow-fetch-read-body`
- `allow-fetch-send`
+- `allow-fetch-read-body`
+- `allow-fetch-cancel-body`
## Permission Table
@@ -82,6 +83,32 @@ Denies the fetch_cancel command without any pre-configured scope.
+`http:allow-fetch-cancel-body`
+
+ |
+
+
+Enables the fetch_cancel_body command without any pre-configured scope.
+
+ |
+
+
+
+
+
+`http:deny-fetch-cancel-body`
+
+ |
+
+
+Denies the fetch_cancel_body command without any pre-configured scope.
+
+ |
+
+
+
+
+
`http:allow-fetch-read-body`
|
diff --git a/plugins/http/permissions/default.toml b/plugins/http/permissions/default.toml
index b469536d..541bf49f 100644
--- a/plugins/http/permissions/default.toml
+++ b/plugins/http/permissions/default.toml
@@ -17,6 +17,7 @@ All fetch operations are enabled.
permissions = [
"allow-fetch",
"allow-fetch-cancel",
- "allow-fetch-read-body",
"allow-fetch-send",
+ "allow-fetch-read-body",
+ "allow-fetch-cancel-body",
]
diff --git a/plugins/http/permissions/schemas/schema.json b/plugins/http/permissions/schemas/schema.json
index 794ee204..626fea45 100644
--- a/plugins/http/permissions/schemas/schema.json
+++ b/plugins/http/permissions/schemas/schema.json
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri internal convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri internal convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -314,6 +314,16 @@
"type": "string",
"const": "deny-fetch-cancel"
},
+ {
+ "description": "Enables the fetch_cancel_body command without any pre-configured scope.",
+ "type": "string",
+ "const": "allow-fetch-cancel-body"
+ },
+ {
+ "description": "Denies the fetch_cancel_body command without any pre-configured scope.",
+ "type": "string",
+ "const": "deny-fetch-cancel-body"
+ },
{
"description": "Enables the fetch_read_body command without any pre-configured scope.",
"type": "string",
diff --git a/plugins/http/src/commands.rs b/plugins/http/src/commands.rs
index bb47444e..0ed6a12a 100644
--- a/plugins/http/src/commands.rs
+++ b/plugins/http/src/commands.rs
@@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize};
use tauri::{
async_runtime::Mutex,
command,
- ipc::{Channel, CommandScope, GlobalScope},
+ ipc::{CommandScope, GlobalScope},
Manager, ResourceId, ResourceTable, Runtime, State, Webview,
};
use tokio::sync::oneshot::{channel, Receiver, Sender};
@@ -415,26 +415,42 @@ pub async fn fetch_send(
pub async fn fetch_read_body(
webview: Webview,
rid: ResourceId,
- stream_channel: Channel,
-) -> crate::Result<()> {
+) -> crate::Result {
let res = {
- let mut resources_table = webview.resources_table();
- resources_table.take::(rid)?
+ let resources_table = webview.resources_table();
+ resources_table.get::(rid)?
};
- let mut res = Arc::into_inner(res).unwrap().0;
+ // SAFETY: we can access the inner value mutably
+ // because we are the only ones with a reference to it
+ // and we don't want to use `Arc::into_inner` because we want to keep the value in the table
+ // for potential future calls to `fetch_cancel_body`
+ let res_ptr = Arc::as_ptr(&res) as *mut ReqwestResponse;
+ let res = unsafe { &mut *res_ptr };
+ let res = &mut res.0;
- // send response through IPC channel
- while let Some(chunk) = res.chunk().await? {
- let mut chunk = chunk.to_vec();
- // append 0 to indicate we are not done yet
- chunk.push(0);
- stream_channel.send(tauri::ipc::InvokeResponseBody::Raw(chunk))?;
- }
+ let Some(chunk) = res.chunk().await? else {
+ let mut resources_table = webview.resources_table();
+ resources_table.close(rid)?;
- // send 1 to indicate we are done
- stream_channel.send(tauri::ipc::InvokeResponseBody::Raw(vec![1]))?;
+ // return a response with a single byte to indicate that the body is empty
+ return Ok(tauri::ipc::Response::new(vec![1]));
+ };
+
+ let mut chunk = chunk.to_vec();
+ // append a 0 byte to indicate that the body is not empty
+ chunk.push(0);
+ Ok(tauri::ipc::Response::new(chunk))
+}
+
+#[command]
+pub async fn fetch_cancel_body(
+ webview: Webview,
+ rid: ResourceId,
+) -> crate::Result<()> {
+ let mut resources_table = webview.resources_table();
+ resources_table.close(rid)?;
Ok(())
}
diff --git a/plugins/http/src/lib.rs b/plugins/http/src/lib.rs
index 5acc2b47..364d3bff 100644
--- a/plugins/http/src/lib.rs
+++ b/plugins/http/src/lib.rs
@@ -84,7 +84,8 @@ pub fn init() -> TauriPlugin {
commands::fetch,
commands::fetch_cancel,
commands::fetch_send,
- commands::fetch_read_body
+ commands::fetch_read_body,
+ commands::fetch_cancel_body,
])
.build()
}
diff --git a/plugins/log/permissions/schemas/schema.json b/plugins/log/permissions/schemas/schema.json
index 78d88826..547d1fd8 100644
--- a/plugins/log/permissions/schemas/schema.json
+++ b/plugins/log/permissions/schemas/schema.json
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri internal convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri internal convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
diff --git a/plugins/nfc/permissions/schemas/schema.json b/plugins/nfc/permissions/schemas/schema.json
index 5fe3743c..69b4eb23 100644
--- a/plugins/nfc/permissions/schemas/schema.json
+++ b/plugins/nfc/permissions/schemas/schema.json
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri internal convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri internal convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
diff --git a/plugins/notification/permissions/schemas/schema.json b/plugins/notification/permissions/schemas/schema.json
index 433f367f..4c50cde6 100644
--- a/plugins/notification/permissions/schemas/schema.json
+++ b/plugins/notification/permissions/schemas/schema.json
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri internal convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri internal convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
diff --git a/plugins/opener/permissions/schemas/schema.json b/plugins/opener/permissions/schemas/schema.json
index b958ac63..4f289a93 100644
--- a/plugins/opener/permissions/schemas/schema.json
+++ b/plugins/opener/permissions/schemas/schema.json
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri internal convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri internal convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
diff --git a/plugins/os/permissions/schemas/schema.json b/plugins/os/permissions/schemas/schema.json
index ad053532..ad3317c7 100644
--- a/plugins/os/permissions/schemas/schema.json
+++ b/plugins/os/permissions/schemas/schema.json
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri internal convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri internal convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
diff --git a/plugins/positioner/permissions/schemas/schema.json b/plugins/positioner/permissions/schemas/schema.json
index ccf55156..4b1d9221 100644
--- a/plugins/positioner/permissions/schemas/schema.json
+++ b/plugins/positioner/permissions/schemas/schema.json
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri internal convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri internal convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
diff --git a/plugins/process/permissions/schemas/schema.json b/plugins/process/permissions/schemas/schema.json
index 95f67149..1818871e 100644
--- a/plugins/process/permissions/schemas/schema.json
+++ b/plugins/process/permissions/schemas/schema.json
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri internal convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri internal convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
diff --git a/plugins/shell/permissions/schemas/schema.json b/plugins/shell/permissions/schemas/schema.json
index e70c3926..ff343467 100644
--- a/plugins/shell/permissions/schemas/schema.json
+++ b/plugins/shell/permissions/schemas/schema.json
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri internal convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri internal convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
diff --git a/plugins/sql/permissions/schemas/schema.json b/plugins/sql/permissions/schemas/schema.json
index e3add537..241cf33c 100644
--- a/plugins/sql/permissions/schemas/schema.json
+++ b/plugins/sql/permissions/schemas/schema.json
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri internal convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri internal convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
diff --git a/plugins/store/permissions/schemas/schema.json b/plugins/store/permissions/schemas/schema.json
index 4237bc62..d3cfc815 100644
--- a/plugins/store/permissions/schemas/schema.json
+++ b/plugins/store/permissions/schemas/schema.json
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri internal convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri internal convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
diff --git a/plugins/stronghold/permissions/schemas/schema.json b/plugins/stronghold/permissions/schemas/schema.json
index 5657e9bb..c7781f1f 100644
--- a/plugins/stronghold/permissions/schemas/schema.json
+++ b/plugins/stronghold/permissions/schemas/schema.json
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri internal convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri internal convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
diff --git a/plugins/updater/permissions/schemas/schema.json b/plugins/updater/permissions/schemas/schema.json
index 2df800da..8264f3e1 100644
--- a/plugins/updater/permissions/schemas/schema.json
+++ b/plugins/updater/permissions/schemas/schema.json
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri internal convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri internal convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
diff --git a/plugins/upload/permissions/schemas/schema.json b/plugins/upload/permissions/schemas/schema.json
index abe3a09f..1d8d9c4a 100644
--- a/plugins/upload/permissions/schemas/schema.json
+++ b/plugins/upload/permissions/schemas/schema.json
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri internal convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri internal convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
diff --git a/plugins/websocket/permissions/schemas/schema.json b/plugins/websocket/permissions/schemas/schema.json
index 9f574650..989d0159 100644
--- a/plugins/websocket/permissions/schemas/schema.json
+++ b/plugins/websocket/permissions/schemas/schema.json
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri internal convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri internal convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
diff --git a/plugins/window-state/permissions/schemas/schema.json b/plugins/window-state/permissions/schemas/schema.json
index 67888bc6..b94c2573 100644
--- a/plugins/window-state/permissions/schemas/schema.json
+++ b/plugins/window-state/permissions/schemas/schema.json
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
- "description": "Human-readable description of what the permission does. Tauri internal convention is to use headings in markdown content for Tauri documentation generation purposes.",
+ "description": "Human-readable description of what the permission does. Tauri internal convention is to use `` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"