mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
script: allow for undefined chunks in stream piping (#38470)
Current code uses `undefined` as chunk value to identify the closing of
a stream, but this breaks once you start streaming a chunk that is
actually `undefined`, as shown in
https://github.com/servo/servo/pull/38466. This PR re-implement the
logic in a way that allows for chunks to be `undefined`.
Testing: Should maintain `streams/piping` WPT pass rates. Also makes the
`undefined` case of
[`/encoding/streams/encode-bad-chunks.any.js`](c59ee57b5d/tests/wpt/tests/encoding/streams/encode-bad-chunks.any.js (L29)
),
but that is only noticeable in https://github.com/servo/servo/pull/38466
Fixes: None, but noted in https://github.com/servo/servo/pull/38466
Signed-off-by: gterzian <2792687+gterzian@users.noreply.github.com>
This commit is contained in:
parent
778dc70181
commit
7ad32f944f
1 changed files with 7 additions and 23 deletions
|
@ -249,28 +249,7 @@ impl Callback for PipeTo {
|
||||||
// If dest.[[state]] is "writable",
|
// If dest.[[state]] is "writable",
|
||||||
// and ! WritableStreamCloseQueuedOrInFlight(dest) is false,
|
// and ! WritableStreamCloseQueuedOrInFlight(dest) is false,
|
||||||
if dest.is_writable() && !dest.close_queued_or_in_flight() {
|
if dest.is_writable() && !dest.close_queued_or_in_flight() {
|
||||||
let has_done = {
|
let Ok(done) = get_read_promise_done(cx, &result, can_gc) else {
|
||||||
if !result.is_object() {
|
|
||||||
false
|
|
||||||
} else {
|
|
||||||
rooted!(in(*cx) let object = result.to_object());
|
|
||||||
rooted!(in(*cx) let mut done = UndefinedValue());
|
|
||||||
unsafe {
|
|
||||||
get_dictionary_property(
|
|
||||||
*cx,
|
|
||||||
object.handle(),
|
|
||||||
"done",
|
|
||||||
done.handle_mut(),
|
|
||||||
can_gc,
|
|
||||||
)
|
|
||||||
.unwrap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// If any chunks have been read but not yet written, write them to dest.
|
|
||||||
let contained_bytes = self.write_chunk(cx, &global, result, can_gc);
|
|
||||||
|
|
||||||
if !contained_bytes && !has_done {
|
|
||||||
// This is the case that the microtask ran in reaction
|
// This is the case that the microtask ran in reaction
|
||||||
// to the closed promise of the reader,
|
// to the closed promise of the reader,
|
||||||
// so we should wait for subsequent chunks,
|
// so we should wait for subsequent chunks,
|
||||||
|
@ -278,6 +257,11 @@ impl Callback for PipeTo {
|
||||||
// (reader is closed, but there are still pending reads).
|
// (reader is closed, but there are still pending reads).
|
||||||
// Shutdown will happen when the last chunk has been received.
|
// Shutdown will happen when the last chunk has been received.
|
||||||
return;
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
if !done {
|
||||||
|
// If any chunks have been read but not yet written, write them to dest.
|
||||||
|
self.write_chunk(cx, &global, result, can_gc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -446,7 +430,7 @@ impl PipeTo {
|
||||||
get_dictionary_property(*cx, object.handle(), "value", bytes.handle_mut(), can_gc)
|
get_dictionary_property(*cx, object.handle(), "value", bytes.handle_mut(), can_gc)
|
||||||
.expect("Chunk should have a value.")
|
.expect("Chunk should have a value.")
|
||||||
};
|
};
|
||||||
if !bytes.is_undefined() && has_value {
|
if has_value {
|
||||||
// Write the chunk.
|
// Write the chunk.
|
||||||
let write_promise = self.writer.write(cx, global, bytes.handle(), can_gc);
|
let write_promise = self.writer.write(cx, global, bytes.handle(), can_gc);
|
||||||
self.pending_writes.borrow_mut().push_back(write_promise);
|
self.pending_writes.borrow_mut().push_back(write_promise);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue