Skip to content

Commit fec2b7f

Browse files
committed
fix(http): fix aborting a streaming response
closes #2557
1 parent 35c1cd9 commit fec2b7f

File tree

36 files changed

+198
-101
lines changed

36 files changed

+198
-101
lines changed

.changes/http-stream-cancel.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"http": "patch"
3+
"http-js": "patch"
4+
---
5+
6+
Fix aborting a request in the middle of a streaming response.
7+

plugins/autostart/permissions/schemas/schema.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
"minimum": 1.0
5050
},
5151
"description": {
52-
"description": "Human-readable description of what the permission does. Tauri convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
52+
"description": "Human-readable description of what the permission does. Tauri convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
5353
"type": [
5454
"string",
5555
"null"
@@ -111,7 +111,7 @@
111111
"type": "string"
112112
},
113113
"description": {
114-
"description": "Human-readable description of what the permission does. Tauri internal convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
114+
"description": "Human-readable description of what the permission does. Tauri internal convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
115115
"type": [
116116
"string",
117117
"null"

plugins/barcode-scanner/permissions/schemas/schema.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
"minimum": 1.0
5050
},
5151
"description": {
52-
"description": "Human-readable description of what the permission does. Tauri convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
52+
"description": "Human-readable description of what the permission does. Tauri convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
5353
"type": [
5454
"string",
5555
"null"
@@ -111,7 +111,7 @@
111111
"type": "string"
112112
},
113113
"description": {
114-
"description": "Human-readable description of what the permission does. Tauri internal convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
114+
"description": "Human-readable description of what the permission does. Tauri internal convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
115115
"type": [
116116
"string",
117117
"null"

plugins/biometric/permissions/schemas/schema.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
"minimum": 1.0
5050
},
5151
"description": {
52-
"description": "Human-readable description of what the permission does. Tauri convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
52+
"description": "Human-readable description of what the permission does. Tauri convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
5353
"type": [
5454
"string",
5555
"null"
@@ -111,7 +111,7 @@
111111
"type": "string"
112112
},
113113
"description": {
114-
"description": "Human-readable description of what the permission does. Tauri internal convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
114+
"description": "Human-readable description of what the permission does. Tauri internal convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
115115
"type": [
116116
"string",
117117
"null"

plugins/cli/permissions/schemas/schema.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
"minimum": 1.0
5050
},
5151
"description": {
52-
"description": "Human-readable description of what the permission does. Tauri convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
52+
"description": "Human-readable description of what the permission does. Tauri convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
5353
"type": [
5454
"string",
5555
"null"
@@ -111,7 +111,7 @@
111111
"type": "string"
112112
},
113113
"description": {
114-
"description": "Human-readable description of what the permission does. Tauri internal convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
114+
"description": "Human-readable description of what the permission does. Tauri internal convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
115115
"type": [
116116
"string",
117117
"null"

plugins/clipboard-manager/permissions/schemas/schema.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
"minimum": 1.0
5050
},
5151
"description": {
52-
"description": "Human-readable description of what the permission does. Tauri convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
52+
"description": "Human-readable description of what the permission does. Tauri convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
5353
"type": [
5454
"string",
5555
"null"
@@ -111,7 +111,7 @@
111111
"type": "string"
112112
},
113113
"description": {
114-
"description": "Human-readable description of what the permission does. Tauri internal convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
114+
"description": "Human-readable description of what the permission does. Tauri internal convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
115115
"type": [
116116
"string",
117117
"null"

plugins/deep-link/permissions/schemas/schema.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
"minimum": 1.0
5050
},
5151
"description": {
52-
"description": "Human-readable description of what the permission does. Tauri convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
52+
"description": "Human-readable description of what the permission does. Tauri convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
5353
"type": [
5454
"string",
5555
"null"
@@ -111,7 +111,7 @@
111111
"type": "string"
112112
},
113113
"description": {
114-
"description": "Human-readable description of what the permission does. Tauri internal convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
114+
"description": "Human-readable description of what the permission does. Tauri internal convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
115115
"type": [
116116
"string",
117117
"null"

plugins/dialog/permissions/schemas/schema.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
"minimum": 1.0
5050
},
5151
"description": {
52-
"description": "Human-readable description of what the permission does. Tauri convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
52+
"description": "Human-readable description of what the permission does. Tauri convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
5353
"type": [
5454
"string",
5555
"null"
@@ -111,7 +111,7 @@
111111
"type": "string"
112112
},
113113
"description": {
114-
"description": "Human-readable description of what the permission does. Tauri internal convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
114+
"description": "Human-readable description of what the permission does. Tauri internal convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
115115
"type": [
116116
"string",
117117
"null"

plugins/fs/permissions/schemas/schema.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
"minimum": 1.0
5050
},
5151
"description": {
52-
"description": "Human-readable description of what the permission does. Tauri convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
52+
"description": "Human-readable description of what the permission does. Tauri convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
5353
"type": [
5454
"string",
5555
"null"
@@ -111,7 +111,7 @@
111111
"type": "string"
112112
},
113113
"description": {
114-
"description": "Human-readable description of what the permission does. Tauri internal convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
114+
"description": "Human-readable description of what the permission does. Tauri internal convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
115115
"type": [
116116
"string",
117117
"null"

plugins/geolocation/permissions/schemas/schema.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
"minimum": 1.0
5050
},
5151
"description": {
52-
"description": "Human-readable description of what the permission does. Tauri convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
52+
"description": "Human-readable description of what the permission does. Tauri convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
5353
"type": [
5454
"string",
5555
"null"
@@ -111,7 +111,7 @@
111111
"type": "string"
112112
},
113113
"description": {
114-
"description": "Human-readable description of what the permission does. Tauri internal convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
114+
"description": "Human-readable description of what the permission does. Tauri internal convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
115115
"type": [
116116
"string",
117117
"null"

plugins/global-shortcut/permissions/schemas/schema.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
"minimum": 1.0
5050
},
5151
"description": {
52-
"description": "Human-readable description of what the permission does. Tauri convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
52+
"description": "Human-readable description of what the permission does. Tauri convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
5353
"type": [
5454
"string",
5555
"null"
@@ -111,7 +111,7 @@
111111
"type": "string"
112112
},
113113
"description": {
114-
"description": "Human-readable description of what the permission does. Tauri internal convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
114+
"description": "Human-readable description of what the permission does. Tauri internal convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
115115
"type": [
116116
"string",
117117
"null"

plugins/haptics/permissions/schemas/schema.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
"minimum": 1.0
5050
},
5151
"description": {
52-
"description": "Human-readable description of what the permission does. Tauri convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
52+
"description": "Human-readable description of what the permission does. Tauri convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
5353
"type": [
5454
"string",
5555
"null"
@@ -111,7 +111,7 @@
111111
"type": "string"
112112
},
113113
"description": {
114-
"description": "Human-readable description of what the permission does. Tauri internal convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
114+
"description": "Human-readable description of what the permission does. Tauri internal convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
115115
"type": [
116116
"string",
117117
"null"

plugins/http/api-iife.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

plugins/http/build.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,13 @@
66
#[allow(dead_code)]
77
mod scope;
88

9-
const COMMANDS: &[&str] = &["fetch", "fetch_cancel", "fetch_send", "fetch_read_body"];
9+
const COMMANDS: &[&str] = &[
10+
"fetch",
11+
"fetch_cancel",
12+
"fetch_send",
13+
"fetch_read_body",
14+
"fetch_cancel_body",
15+
];
1016

1117
/// HTTP scope entry.
1218
#[derive(schemars::JsonSchema)]

plugins/http/guest-js/index.ts

Lines changed: 43 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
* @module
2727
*/
2828

29-
import { Channel, invoke } from '@tauri-apps/api/core'
29+
import { invoke } from '@tauri-apps/api/core'
3030

3131
/**
3232
* Configuration of a proxy that a Client should pass requests to.
@@ -229,37 +229,53 @@ export async function fetch(
229229
rid
230230
})
231231

232+
const dropBody = () => {
233+
return invoke('plugin:http|fetch_cancel_body', { rid: responseRid })
234+
}
235+
236+
const readChunk = async (
237+
controller: ReadableStreamDefaultController<any>
238+
) => {
239+
let data: ArrayBuffer
240+
try {
241+
data = await invoke('plugin:http|fetch_read_body', {
242+
rid: responseRid
243+
})
244+
} catch (e) {
245+
// close the stream if an error occurs
246+
// and drop the body on Rust side
247+
controller.error(e)
248+
void dropBody()
249+
return
250+
}
251+
252+
const dataUint8 = new Uint8Array(data)
253+
const lastByte = dataUint8[dataUint8.byteLength - 1]
254+
const actualData = dataUint8.slice(0, dataUint8.byteLength - 1)
255+
256+
// close when the signal to close (last byte is 1) is sent from the IPC.
257+
if (lastByte === 1) {
258+
controller.close()
259+
}
260+
261+
controller.enqueue(actualData)
262+
}
263+
232264
const readableStreamBody = new ReadableStream({
233265
start: (controller) => {
234-
const streamChannel = new Channel<ArrayBuffer | number[]>()
235-
streamChannel.onmessage = (res: ArrayBuffer | number[]) => {
236-
// close early if aborted
237-
if (signal?.aborted) {
238-
controller.error(ERROR_REQUEST_CANCELLED)
239-
return
240-
}
241-
242-
const resUint8 = new Uint8Array(res)
243-
const lastByte = resUint8[resUint8.byteLength - 1]
244-
const actualRes = resUint8.slice(0, resUint8.byteLength - 1)
245-
246-
// close when the signal to close (last byte is 1) is sent from the IPC.
247-
if (lastByte == 1) {
248-
controller.close()
249-
return
250-
}
251-
252-
controller.enqueue(actualRes)
266+
// abort early here if needed and drop the body
267+
if (signal?.aborted) {
268+
controller.error(ERROR_REQUEST_CANCELLED)
269+
void dropBody()
270+
return
253271
}
254272

255-
// run a non-blocking body stream fetch
256-
invoke('plugin:http|fetch_read_body', {
257-
rid: responseRid,
258-
streamChannel
259-
}).catch((e) => {
260-
controller.error(e)
273+
signal?.addEventListener('abort', () => {
274+
controller.error(ERROR_REQUEST_CANCELLED)
275+
void dropBody()
261276
})
262-
}
277+
},
278+
pull: async (controller) => readChunk(controller)
263279
})
264280

265281
const res = new Response(readableStreamBody, {
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Automatically generated - DO NOT EDIT!
2+
3+
"$schema" = "../../schemas/schema.json"
4+
5+
[[permission]]
6+
identifier = "allow-fetch-cancel-body"
7+
description = "Enables the fetch_cancel_body command without any pre-configured scope."
8+
commands.allow = ["fetch_cancel_body"]
9+
10+
[[permission]]
11+
identifier = "deny-fetch-cancel-body"
12+
description = "Denies the fetch_cancel_body command without any pre-configured scope."
13+
commands.deny = ["fetch_cancel_body"]

0 commit comments

Comments
 (0)