Skip to content

Commit 634baf3

Browse files
amrbashirtauri-bot
authored andcommitted
feat(http): handle 205, 304 null body (#2647)
followup to #2636 ref: tauri-apps/plugins-workspace#2636 (comment) Committed via a GitHub action: https://github.com/tauri-apps/plugins-workspace/actions/runs/14548398414 Co-authored-by: amrbashir <[email protected]>
1 parent ac918bd commit 634baf3

File tree

4 files changed

+99
-87
lines changed

4 files changed

+99
-87
lines changed

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.

dist-js/index.cjs

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -115,35 +115,39 @@ async function fetch(input, init) {
115115
const { status, statusText, url, headers: responseHeaders, rid: responseRid } = await core.invoke('plugin:http|fetch_send', {
116116
rid
117117
});
118-
const readableStreamBody = new ReadableStream({
119-
start: (controller) => {
120-
const streamChannel = new core.Channel();
121-
streamChannel.onmessage = (res) => {
122-
// close early if aborted
123-
if (signal?.aborted) {
124-
controller.error(ERROR_REQUEST_CANCELLED);
125-
return;
126-
}
127-
const resUint8 = new Uint8Array(res);
128-
const lastByte = resUint8[resUint8.byteLength - 1];
129-
const actualRes = resUint8.slice(0, resUint8.byteLength - 1);
130-
// close when the signal to close (last byte is 1) is sent from the IPC.
131-
if (lastByte == 1) {
132-
controller.close();
133-
return;
134-
}
135-
controller.enqueue(actualRes);
136-
};
137-
// run a non-blocking body stream fetch
138-
core.invoke('plugin:http|fetch_read_body', {
139-
rid: responseRid,
140-
streamChannel
141-
}).catch((e) => {
142-
controller.error(e);
143-
});
144-
}
145-
});
146-
const res = new Response(status !== 204 ? readableStreamBody : null, {
118+
// no body for 204, 205 and 304
119+
// see https://searchfox.org/mozilla-central/source/dom/fetch/Response.cpp#258
120+
const body = [204, 205, 304].includes(status)
121+
? null
122+
: new ReadableStream({
123+
start: (controller) => {
124+
const streamChannel = new core.Channel();
125+
streamChannel.onmessage = (res) => {
126+
// close early if aborted
127+
if (signal?.aborted) {
128+
controller.error(ERROR_REQUEST_CANCELLED);
129+
return;
130+
}
131+
const resUint8 = new Uint8Array(res);
132+
const lastByte = resUint8[resUint8.byteLength - 1];
133+
const actualRes = resUint8.slice(0, resUint8.byteLength - 1);
134+
// close when the signal to close (last byte is 1) is sent from the IPC.
135+
if (lastByte == 1) {
136+
controller.close();
137+
return;
138+
}
139+
controller.enqueue(actualRes);
140+
};
141+
// run a non-blocking body stream fetch
142+
core.invoke('plugin:http|fetch_read_body', {
143+
rid: responseRid,
144+
streamChannel
145+
}).catch((e) => {
146+
controller.error(e);
147+
});
148+
}
149+
});
150+
const res = new Response(body, {
147151
status,
148152
statusText
149153
});

dist-js/index.js

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -113,35 +113,39 @@ async function fetch(input, init) {
113113
const { status, statusText, url, headers: responseHeaders, rid: responseRid } = await invoke('plugin:http|fetch_send', {
114114
rid
115115
});
116-
const readableStreamBody = new ReadableStream({
117-
start: (controller) => {
118-
const streamChannel = new Channel();
119-
streamChannel.onmessage = (res) => {
120-
// close early if aborted
121-
if (signal?.aborted) {
122-
controller.error(ERROR_REQUEST_CANCELLED);
123-
return;
124-
}
125-
const resUint8 = new Uint8Array(res);
126-
const lastByte = resUint8[resUint8.byteLength - 1];
127-
const actualRes = resUint8.slice(0, resUint8.byteLength - 1);
128-
// close when the signal to close (last byte is 1) is sent from the IPC.
129-
if (lastByte == 1) {
130-
controller.close();
131-
return;
132-
}
133-
controller.enqueue(actualRes);
134-
};
135-
// run a non-blocking body stream fetch
136-
invoke('plugin:http|fetch_read_body', {
137-
rid: responseRid,
138-
streamChannel
139-
}).catch((e) => {
140-
controller.error(e);
141-
});
142-
}
143-
});
144-
const res = new Response(status !== 204 ? readableStreamBody : null, {
116+
// no body for 204, 205 and 304
117+
// see https://searchfox.org/mozilla-central/source/dom/fetch/Response.cpp#258
118+
const body = [204, 205, 304].includes(status)
119+
? null
120+
: new ReadableStream({
121+
start: (controller) => {
122+
const streamChannel = new Channel();
123+
streamChannel.onmessage = (res) => {
124+
// close early if aborted
125+
if (signal?.aborted) {
126+
controller.error(ERROR_REQUEST_CANCELLED);
127+
return;
128+
}
129+
const resUint8 = new Uint8Array(res);
130+
const lastByte = resUint8[resUint8.byteLength - 1];
131+
const actualRes = resUint8.slice(0, resUint8.byteLength - 1);
132+
// close when the signal to close (last byte is 1) is sent from the IPC.
133+
if (lastByte == 1) {
134+
controller.close();
135+
return;
136+
}
137+
controller.enqueue(actualRes);
138+
};
139+
// run a non-blocking body stream fetch
140+
invoke('plugin:http|fetch_read_body', {
141+
rid: responseRid,
142+
streamChannel
143+
}).catch((e) => {
144+
controller.error(e);
145+
});
146+
}
147+
});
148+
const res = new Response(body, {
145149
status,
146150
statusText
147151
});

guest-js/index.ts

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -229,40 +229,44 @@ export async function fetch(
229229
rid
230230
})
231231

232-
const readableStreamBody = new ReadableStream({
233-
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-
}
232+
// no body for 204, 205 and 304
233+
// see https://searchfox.org/mozilla-central/source/dom/fetch/Response.cpp#258
234+
const body = [204, 205, 304].includes(status)
235+
? null
236+
: new ReadableStream({
237+
start: (controller) => {
238+
const streamChannel = new Channel<ArrayBuffer | number[]>()
239+
streamChannel.onmessage = (res: ArrayBuffer | number[]) => {
240+
// close early if aborted
241+
if (signal?.aborted) {
242+
controller.error(ERROR_REQUEST_CANCELLED)
243+
return
244+
}
241245

242-
const resUint8 = new Uint8Array(res)
243-
const lastByte = resUint8[resUint8.byteLength - 1]
244-
const actualRes = resUint8.slice(0, resUint8.byteLength - 1)
246+
const resUint8 = new Uint8Array(res)
247+
const lastByte = resUint8[resUint8.byteLength - 1]
248+
const actualRes = resUint8.slice(0, resUint8.byteLength - 1)
245249

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-
}
250+
// close when the signal to close (last byte is 1) is sent from the IPC.
251+
if (lastByte == 1) {
252+
controller.close()
253+
return
254+
}
251255

252-
controller.enqueue(actualRes)
253-
}
256+
controller.enqueue(actualRes)
257+
}
254258

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)
259+
// run a non-blocking body stream fetch
260+
invoke('plugin:http|fetch_read_body', {
261+
rid: responseRid,
262+
streamChannel
263+
}).catch((e) => {
264+
controller.error(e)
265+
})
266+
}
261267
})
262-
}
263-
})
264268

265-
const res = new Response(status !== 204 ? readableStreamBody : null, {
269+
const res = new Response(body, {
266270
status,
267271
statusText
268272
})

0 commit comments

Comments
 (0)