mirror of
https://github.com/servo/servo.git
synced 2025-07-22 14:53:49 +01:00
Auto merge of #26810 - CYBAI:fix-infinite-stream, r=gterzian
Fix infinite stream and its missing incumbent script environment when newing a new stream --- - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix #26807 - [ ] There are tests for these changes OR - [ ] These changes do not require tests because ___
This commit is contained in:
commit
581ade575e
3 changed files with 34 additions and 9 deletions
|
@ -117,7 +117,7 @@ pub enum ParserMetadata {
|
|||
}
|
||||
|
||||
/// <https://fetch.spec.whatwg.org/#concept-body-source>
|
||||
#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
|
||||
#[derive(Clone, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
|
||||
pub enum BodySource {
|
||||
Null,
|
||||
Object,
|
||||
|
@ -178,10 +178,7 @@ impl RequestBody {
|
|||
}
|
||||
|
||||
pub fn source_is_null(&self) -> bool {
|
||||
if let BodySource::Null = self.source {
|
||||
return true;
|
||||
}
|
||||
false
|
||||
self.source == BodySource::Null
|
||||
}
|
||||
|
||||
pub fn len(&self) -> Option<usize> {
|
||||
|
|
|
@ -55,7 +55,7 @@ pub enum BodySource {
|
|||
Null,
|
||||
/// Another Dom object as source,
|
||||
/// TODO: store the actual object
|
||||
/// and re-exctact a stream on re-direct.
|
||||
/// and re-extract a stream on re-direct.
|
||||
Object,
|
||||
}
|
||||
|
||||
|
@ -72,6 +72,7 @@ struct TransmitBodyConnectHandler {
|
|||
bytes_sender: Option<IpcSender<Vec<u8>>>,
|
||||
control_sender: IpcSender<BodyChunkRequest>,
|
||||
in_memory: Option<Vec<u8>>,
|
||||
in_memory_done: bool,
|
||||
source: BodySource,
|
||||
}
|
||||
|
||||
|
@ -91,14 +92,22 @@ impl TransmitBodyConnectHandler {
|
|||
bytes_sender: None,
|
||||
control_sender,
|
||||
in_memory,
|
||||
in_memory_done: false,
|
||||
source,
|
||||
}
|
||||
}
|
||||
|
||||
/// Reset `in_memory_done`, called when a stream is
|
||||
/// re-extracted from the source to support a re-direct.
|
||||
pub fn reset_in_memory_done(&mut self) {
|
||||
self.in_memory_done = false;
|
||||
}
|
||||
|
||||
/// Re-extract the source to support streaming it again for a re-direct.
|
||||
/// TODO: actually re-extract the source, instead of just cloning data, to support Blob.
|
||||
fn re_extract(&self, chunk_request_receiver: IpcReceiver<BodyChunkRequest>) {
|
||||
fn re_extract(&mut self, chunk_request_receiver: IpcReceiver<BodyChunkRequest>) {
|
||||
let mut body_handler = self.clone();
|
||||
body_handler.reset_in_memory_done();
|
||||
|
||||
ROUTER.add_route(
|
||||
chunk_request_receiver.to_opaque(),
|
||||
|
@ -126,11 +135,20 @@ impl TransmitBodyConnectHandler {
|
|||
/// TODO: this method should be deprecated
|
||||
/// in favor of making `re_extract` actually re-extract a stream from the source.
|
||||
/// See #26686
|
||||
fn transmit_source(&self) {
|
||||
fn transmit_source(&mut self) {
|
||||
if self.in_memory_done {
|
||||
// Step 5.1.3
|
||||
self.stop_reading();
|
||||
return;
|
||||
}
|
||||
|
||||
if let BodySource::Null = self.source {
|
||||
panic!("ReadableStream(Null) sources should not re-direct.");
|
||||
}
|
||||
|
||||
if let Some(bytes) = self.in_memory.clone() {
|
||||
// The memoized bytes are sent so we mark it as done again
|
||||
self.in_memory_done = true;
|
||||
let _ = self
|
||||
.bytes_sender
|
||||
.as_ref()
|
||||
|
@ -155,6 +173,12 @@ impl TransmitBodyConnectHandler {
|
|||
|
||||
/// The entry point to <https://fetch.spec.whatwg.org/#concept-request-transmit-body>
|
||||
fn transmit_body_chunk(&mut self) {
|
||||
if self.in_memory_done {
|
||||
// Step 5.1.3
|
||||
self.stop_reading();
|
||||
return;
|
||||
}
|
||||
|
||||
let stream = self.stream.clone();
|
||||
let control_sender = self.control_sender.clone();
|
||||
let bytes_sender = self
|
||||
|
@ -165,6 +189,9 @@ impl TransmitBodyConnectHandler {
|
|||
// In case of the data being in-memory, send everything in one chunk, by-passing SpiderMonkey.
|
||||
if let Some(bytes) = self.in_memory.clone() {
|
||||
let _ = bytes_sender.send(bytes);
|
||||
// Mark this body as `done` so that we can stop reading in the next tick,
|
||||
// matching the behavior of the promise-based flow
|
||||
self.in_memory_done = true;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ use crate::dom::bindings::conversions::{ConversionBehavior, ConversionResult};
|
|||
use crate::dom::bindings::error::Error;
|
||||
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
|
||||
use crate::dom::bindings::root::DomRoot;
|
||||
use crate::dom::bindings::settings_stack::AutoEntryScript;
|
||||
use crate::dom::bindings::settings_stack::{AutoEntryScript, AutoIncumbentScript};
|
||||
use crate::dom::bindings::utils::get_dictionary_property;
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::promise::Promise;
|
||||
|
@ -118,6 +118,7 @@ impl ReadableStream {
|
|||
source: ExternalUnderlyingSource,
|
||||
) -> DomRoot<ReadableStream> {
|
||||
let _ar = enter_realm(global);
|
||||
let _ais = AutoIncumbentScript::new(global);
|
||||
let cx = global.get_cx();
|
||||
|
||||
let source = Rc::new(ExternalUnderlyingSourceController::new(source));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue