1use std::cell::{Cell, RefCell};
6use std::collections::VecDeque;
7use std::ptr::{self};
8use std::rc::Rc;
9
10use dom_struct::dom_struct;
11use js::context::JSContext;
12use js::conversions::{FromJSValConvertible, ToJSValConvertible};
13use js::jsapi::{Heap, JSObject};
14use js::jsval::{JSVal, ObjectValue, UndefinedValue};
15use js::realm::CurrentRealm;
16use js::rust::{
17 HandleObject as SafeHandleObject, HandleValue as SafeHandleValue,
18 MutableHandleValue as SafeMutableHandleValue,
19};
20use js::typedarray::{ArrayBufferViewU8, Uint8};
21use rustc_hash::FxHashMap;
22use servo_base::generic_channel::GenericSharedMemory;
23use servo_base::id::{MessagePortId, MessagePortIndex};
24use servo_constellation_traits::MessagePortImpl;
25
26use crate::dom::bindings::codegen::Bindings::QueuingStrategyBinding::QueuingStrategy;
27use crate::dom::bindings::codegen::Bindings::ReadableStreamBinding::{
28 ReadableStreamGetReaderOptions, ReadableStreamMethods, ReadableStreamReaderMode,
29 ReadableWritablePair, StreamPipeOptions,
30};
31use script_bindings::str::DOMString;
32use crate::dom::domexception::{DOMErrorName, DOMException};
33use crate::dom::encoding::textdecoderstream::TextDecoderStream;
34use script_bindings::codegen::GenericBindings::TextDecoderStreamBinding::TextDecoderStreamMethods;
35use script_bindings::conversions::{is_array_like, StringificationBehavior};
36use crate::dom::bindings::codegen::Bindings::QueuingStrategyBinding::QueuingStrategySize;
37use crate::dom::abortsignal::{AbortAlgorithm, AbortSignal};
38use crate::dom::bindings::codegen::Bindings::ReadableStreamDefaultReaderBinding::ReadableStreamDefaultReaderMethods;
39use crate::dom::bindings::codegen::Bindings::ReadableStreamDefaultControllerBinding::ReadableStreamDefaultController_Binding::ReadableStreamDefaultControllerMethods;
40use crate::dom::bindings::codegen::Bindings::UnderlyingSourceBinding::UnderlyingSource as JsUnderlyingSource;
41use crate::dom::bindings::conversions::{ConversionBehavior, ConversionResult, get_property, get_property_jsval};
42use crate::dom::bindings::error::{Error, ErrorToJsval, Fallible};
43use crate::dom::bindings::codegen::GenericBindings::WritableStreamDefaultWriterBinding::WritableStreamDefaultWriter_Binding::WritableStreamDefaultWriterMethods;
44use crate::dom::stream::writablestream::WritableStream;
45use crate::dom::bindings::codegen::UnionTypes::ReadableStreamDefaultReaderOrReadableStreamBYOBReader as ReadableStreamReader;
46use crate::dom::bindings::reflector::DomGlobal;
47use script_bindings::reflector::{Reflector, reflect_dom_object_with_proto};
48use crate::dom::bindings::root::{DomRoot, MutNullableDom, Dom};
49use crate::dom::bindings::trace::RootedTraceableBox;
50use crate::dom::stream::byteteeunderlyingsource::{ByteTeeCancelAlgorithm, ByteTeePullAlgorithm, ByteTeeUnderlyingSource};
51use crate::dom::stream::countqueuingstrategy::{extract_high_water_mark, extract_size_algorithm};
52use crate::dom::stream::readablestreamgenericreader::ReadableStreamGenericReader;
53use crate::dom::globalscope::GlobalScope;
54use crate::dom::promise::{wait_for_all_promise, Promise};
55use crate::dom::stream::readablebytestreamcontroller::ReadableByteStreamController;
56use crate::dom::stream::readablestreambyobreader::ReadableStreamBYOBReader;
57use crate::dom::stream::readablestreamdefaultcontroller::ReadableStreamDefaultController;
58use crate::dom::stream::readablestreamdefaultreader::{ReadRequest, ReadableStreamDefaultReader};
59use crate::dom::stream::defaultteeunderlyingsource::DefaultTeeCancelAlgorithm;
60use crate::dom::types::DefaultTeeUnderlyingSource;
61use crate::dom::stream::underlyingsourcecontainer::UnderlyingSourceType;
62use crate::dom::stream::writablestreamdefaultwriter::WritableStreamDefaultWriter;
63use script_bindings::codegen::GenericBindings::MessagePortBinding::MessagePortMethods;
64use crate::dom::messageport::MessagePort;
65use crate::realms::{enter_auto_realm};
66use crate::dom::promisenativehandler::{Callback, PromiseNativeHandler};
67use crate::dom::bindings::transferable::Transferable;
68use crate::dom::bindings::structuredclone::StructuredData;
69
70use super::readablestreambyobreader::ReadIntoRequest;
71use crate::dom::bindings::buffer_source::{HeapBufferSource, create_buffer_source};
72
73#[derive(Clone, Debug, Default, MallocSizeOf, PartialEq)]
75enum PipeToState {
76 #[default]
78 Starting,
79 PendingReady,
81 PendingRead,
83 ShuttingDownWithPendingWrites(Option<ShutdownAction>),
86 ShuttingDownPendingAction,
90 Finalized,
93}
94
95#[derive(Clone, Debug, MallocSizeOf, PartialEq)]
97enum ShutdownAction {
98 WritableStreamAbort,
100 ReadableStreamCancel,
102 WritableStreamDefaultWriterCloseWithErrorPropagation,
104 Abort,
106}
107
108impl js::gc::Rootable for PipeTo {}
109
110#[derive(Clone, JSTraceable, MallocSizeOf)]
119#[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)]
120pub(crate) struct PipeTo {
121 reader: Dom<ReadableStreamDefaultReader>,
123
124 writer: Dom<WritableStreamDefaultWriter>,
126
127 #[ignore_malloc_size_of = "nested Rc"]
130 pending_writes: Rc<RefCell<VecDeque<Rc<Promise>>>>,
131
132 #[conditional_malloc_size_of]
134 #[no_trace]
135 state: Rc<RefCell<PipeToState>>,
136
137 prevent_abort: bool,
139
140 prevent_cancel: bool,
142
143 prevent_close: bool,
145
146 #[conditional_malloc_size_of]
149 shutting_down: Rc<Cell<bool>>,
150
151 #[ignore_malloc_size_of = "mozjs"]
154 abort_reason: Rc<Heap<JSVal>>,
155
156 #[ignore_malloc_size_of = "mozjs"]
159 shutdown_error: Rc<RefCell<Option<Heap<JSVal>>>>,
160
161 #[ignore_malloc_size_of = "nested Rc"]
164 shutdown_action_promise: Rc<RefCell<Option<Rc<Promise>>>>,
165
166 #[conditional_malloc_size_of]
169 result_promise: Rc<Promise>,
170}
171
172impl PipeTo {
173 pub(crate) fn abort_with_reason(
176 &self,
177 cx: &mut CurrentRealm,
178 global: &GlobalScope,
179 reason: SafeHandleValue,
180 ) {
181 if self.shutting_down.get() {
183 return;
184 }
185
186 self.abort_reason.set(reason.get());
190
191 self.set_shutdown_error(reason);
196
197 self.shutdown(cx, global, Some(ShutdownAction::Abort));
203 }
204}
205
206impl Callback for PipeTo {
207 fn callback(&self, cx: &mut CurrentRealm, result: SafeHandleValue) {
216 let global = self.reader.global();
217
218 self.pending_writes.borrow_mut().retain(|p| {
224 let pending = p.is_pending();
225 if !pending {
226 p.set_promise_is_handled(cx);
227 }
228 pending
229 });
230
231 let state_before_checks = self.state.borrow().clone();
233
234 if state_before_checks == PipeToState::PendingRead {
241 let source = self.reader.get_stream().expect("Source stream must be set");
242 if source.is_closed() {
243 let dest = self
244 .writer
245 .get_stream()
246 .expect("Destination stream must be set");
247
248 if dest.is_writable() && !dest.close_queued_or_in_flight() {
251 let Ok(done) = get_read_promise_done(cx, &result) else {
252 return;
259 };
260
261 if !done {
262 self.write_chunk(cx, &global, result);
264 }
265 }
266 }
267 }
268
269 self.check_and_propagate_errors_forward(cx, &global);
270 self.check_and_propagate_errors_backward(cx, &global);
271 self.check_and_propagate_closing_forward(cx, &global);
272 self.check_and_propagate_closing_backward(cx, &global);
273
274 let state = self.state.borrow().clone();
276
277 if state != state_before_checks {
281 return;
282 }
283
284 match state {
285 PipeToState::Starting => unreachable!("PipeTo should not be in the Starting state."),
286 PipeToState::PendingReady => {
287 self.read_chunk(cx, &global);
289 },
290 PipeToState::PendingRead => {
291 self.write_chunk(cx, &global, result);
293
294 if self.shutting_down.get() {
296 return;
297 }
298
299 self.wait_for_writer_ready(cx, &global);
301 },
302 PipeToState::ShuttingDownWithPendingWrites(action) => {
303 if let Some(write) = self.pending_writes.borrow_mut().front().cloned() {
306 self.wait_on_pending_write(cx, &global, write);
307 return;
308 }
309
310 if let Some(action) = action {
312 self.perform_action(cx, &global, action);
314 } else {
315 self.finalize(cx, &global);
317 }
318 },
319 PipeToState::ShuttingDownPendingAction => {
320 let Some(ref promise) = *self.shutdown_action_promise.borrow() else {
321 unreachable!();
322 };
323 if promise.is_pending() {
324 return;
328 }
329
330 let is_array_like = {
331 if !result.is_object() {
332 false
333 } else {
334 is_array_like::<crate::DomTypeHolder>(cx, result)
335 }
336 };
337
338 if !result.is_undefined() && !is_array_like {
340 self.set_shutdown_error(result);
350 }
351 self.finalize(cx, &global);
352 },
353 PipeToState::Finalized => {},
354 }
355 }
356}
357
358impl PipeTo {
359 fn set_shutdown_error(&self, error: SafeHandleValue) {
362 *self.shutdown_error.borrow_mut() = Some(Heap::default());
363 let Some(ref heap) = *self.shutdown_error.borrow() else {
364 unreachable!("Option set to Some(heap) above.");
365 };
366 heap.set(error.get())
367 }
368
369 fn wait_for_writer_ready(&self, cx: &mut CurrentRealm, global: &GlobalScope) {
372 {
373 let mut state = self.state.borrow_mut();
374 *state = PipeToState::PendingReady;
375 }
376
377 let ready_promise = self.writer.Ready();
378 if ready_promise.is_fulfilled() {
379 self.read_chunk(cx, global);
380 } else {
381 let handler = PromiseNativeHandler::new(
382 cx,
383 global,
384 Some(Box::new(self.clone())),
385 Some(Box::new(self.clone())),
386 );
387 ready_promise.append_native_handler(cx, &handler);
388
389 let closed_promise = self.reader.Closed();
393 closed_promise.append_native_handler(cx, &handler);
394 }
395 }
396
397 fn read_chunk(&self, cx: &mut CurrentRealm, global: &GlobalScope) {
399 *self.state.borrow_mut() = PipeToState::PendingRead;
400 let chunk_promise = self.reader.Read(cx);
401 let handler = PromiseNativeHandler::new(
402 cx,
403 global,
404 Some(Box::new(self.clone())),
405 Some(Box::new(self.clone())),
406 );
407 chunk_promise.append_native_handler(cx, &handler);
408
409 let ready_promise = self.writer.Closed();
412 ready_promise.append_native_handler(cx, &handler);
413 }
414
415 fn write_chunk(
418 &self,
419 cx: &mut JSContext,
420 global: &GlobalScope,
421 chunk: SafeHandleValue,
422 ) -> bool {
423 if chunk.is_object() {
424 rooted!(&in(cx) let object = chunk.to_object());
425 rooted!(&in(cx) let mut bytes = UndefinedValue());
426 get_property_jsval(cx, object.handle(), c"value", bytes.handle_mut())
427 .expect("Chunk should have a value.");
428
429 let write_promise = self.writer.write(cx, global, bytes.handle());
431 self.pending_writes.borrow_mut().push_back(write_promise);
432 return true;
433 }
434 false
435 }
436
437 fn wait_on_pending_write(
441 &self,
442 cx: &mut CurrentRealm,
443 global: &GlobalScope,
444 promise: Rc<Promise>,
445 ) {
446 let handler = PromiseNativeHandler::new(
447 cx,
448 global,
449 Some(Box::new(self.clone())),
450 Some(Box::new(self.clone())),
451 );
452 promise.append_native_handler(cx, &handler);
453 }
454
455 fn check_and_propagate_errors_forward(&self, cx: &mut CurrentRealm, global: &GlobalScope) {
458 if self.shutting_down.get() {
461 return;
462 }
463
464 let source = self
466 .reader
467 .get_stream()
468 .expect("Reader should still have a stream");
469 if source.is_errored() {
470 rooted!(&in(cx) let mut source_error = UndefinedValue());
471 source.get_stored_error(source_error.handle_mut());
472 self.set_shutdown_error(source_error.handle());
473
474 if !self.prevent_abort {
476 self.shutdown(cx, global, Some(ShutdownAction::WritableStreamAbort))
479 } else {
480 self.shutdown(cx, global, None);
482 }
483 }
484 }
485
486 fn check_and_propagate_errors_backward(&self, cx: &mut CurrentRealm, global: &GlobalScope) {
489 if self.shutting_down.get() {
492 return;
493 }
494
495 let dest = self
497 .writer
498 .get_stream()
499 .expect("Writer should still have a stream");
500 if dest.is_errored() {
501 rooted!(&in(cx) let mut dest_error = UndefinedValue());
502 dest.get_stored_error(dest_error.handle_mut());
503 self.set_shutdown_error(dest_error.handle());
504
505 if !self.prevent_cancel {
507 self.shutdown(cx, global, Some(ShutdownAction::ReadableStreamCancel))
510 } else {
511 self.shutdown(cx, global, None);
513 }
514 }
515 }
516
517 fn check_and_propagate_closing_forward(&self, cx: &mut CurrentRealm, global: &GlobalScope) {
520 if self.shutting_down.get() {
523 return;
524 }
525
526 let source = self
528 .reader
529 .get_stream()
530 .expect("Reader should still have a stream");
531 if source.is_closed() {
532 if !self.prevent_close {
534 self.shutdown(
537 cx,
538 global,
539 Some(ShutdownAction::WritableStreamDefaultWriterCloseWithErrorPropagation),
540 )
541 } else {
542 self.shutdown(cx, global, None);
544 }
545 }
546 }
547
548 fn check_and_propagate_closing_backward(&self, cx: &mut CurrentRealm, global: &GlobalScope) {
551 if self.shutting_down.get() {
554 return;
555 }
556
557 let dest = self
560 .writer
561 .get_stream()
562 .expect("Writer should still have a stream");
563 if dest.close_queued_or_in_flight() || dest.is_closed() {
564 rooted!(&in(cx) let mut dest_closed = UndefinedValue());
569 let error =
570 Error::Type(c"Destination is closed or has closed queued or in flight".to_owned());
571 error.to_jsval(cx, global, dest_closed.handle_mut());
572 self.set_shutdown_error(dest_closed.handle());
573
574 if !self.prevent_cancel {
576 self.shutdown(cx, global, Some(ShutdownAction::ReadableStreamCancel))
579 } else {
580 self.shutdown(cx, global, None);
582 }
583 }
584 }
585
586 fn shutdown(
590 &self,
591 cx: &mut CurrentRealm,
592 global: &GlobalScope,
593 action: Option<ShutdownAction>,
594 ) {
595 if !self.shutting_down.replace(true) {
598 let dest = self.writer.get_stream().expect("Stream must be set");
599 if dest.is_writable() && !dest.close_queued_or_in_flight() {
602 if let Some(write) = self.pending_writes.borrow_mut().front() {
608 *self.state.borrow_mut() = PipeToState::ShuttingDownWithPendingWrites(action);
609 self.wait_on_pending_write(cx, global, write.clone());
610 return;
611 }
612 }
613
614 if let Some(action) = action {
616 self.perform_action(cx, global, action);
618 } else {
619 self.finalize(cx, global);
621 }
622 }
623 }
624
625 fn perform_action(&self, cx: &mut CurrentRealm, global: &GlobalScope, action: ShutdownAction) {
628 rooted!(&in(cx) let mut error = UndefinedValue());
629 if let Some(shutdown_error) = self.shutdown_error.borrow().as_ref() {
630 error.set(shutdown_error.get());
631 }
632
633 *self.state.borrow_mut() = PipeToState::ShuttingDownPendingAction;
634
635 let promise = match action {
637 ShutdownAction::WritableStreamAbort => {
638 let dest = self.writer.get_stream().expect("Stream must be set");
639 dest.abort(cx, global, error.handle())
640 },
641 ShutdownAction::ReadableStreamCancel => {
642 let source = self
643 .reader
644 .get_stream()
645 .expect("Reader should have a stream.");
646 source.cancel(cx, global, error.handle())
647 },
648 ShutdownAction::WritableStreamDefaultWriterCloseWithErrorPropagation => {
649 self.writer.close_with_error_propagation(cx, global)
650 },
651 ShutdownAction::Abort => {
652 rooted!(&in(cx) let mut error = UndefinedValue());
657 error.set(self.abort_reason.get());
658
659 let mut actions = vec![];
661
662 if !self.prevent_abort {
664 let dest = self
665 .writer
666 .get_stream()
667 .expect("Destination stream must be set");
668
669 let promise = if dest.is_writable() {
671 dest.abort(cx, global, error.handle())
673 } else {
674 Promise::new_resolved(cx, global, ())
676 };
677 actions.push(promise);
678 }
679
680 if !self.prevent_cancel {
682 let source = self.reader.get_stream().expect("Source stream must be set");
683
684 let promise = if source.is_readable() {
686 source.cancel(cx, global, error.handle())
688 } else {
689 Promise::new_resolved(cx, global, ())
691 };
692 actions.push(promise);
693 }
694
695 wait_for_all_promise(cx, global, actions)
699 },
700 };
701
702 let handler = PromiseNativeHandler::new(
705 cx,
706 global,
707 Some(Box::new(self.clone())),
708 Some(Box::new(self.clone())),
709 );
710 promise.append_native_handler(cx, &handler);
711 *self.shutdown_action_promise.borrow_mut() = Some(promise);
712 }
713
714 fn finalize(&self, cx: &mut JSContext, global: &GlobalScope) {
716 *self.state.borrow_mut() = PipeToState::Finalized;
717
718 self.writer.release(cx, global);
720
721 self.reader
727 .release(cx)
728 .expect("Releasing the reader should not fail");
729
730 if let Some(shutdown_error) = self.shutdown_error.borrow().as_ref() {
736 rooted!(&in(cx) let mut error = UndefinedValue());
737 error.set(shutdown_error.get());
738 self.result_promise.reject_native(cx, &error.handle());
740 } else {
741 self.result_promise.resolve_native(cx, &());
743 }
744 }
745}
746
747#[derive(Clone, JSTraceable, MallocSizeOf)]
750struct SourceCancelPromiseFulfillmentHandler {
751 #[conditional_malloc_size_of]
752 result: Rc<Promise>,
753}
754
755impl Callback for SourceCancelPromiseFulfillmentHandler {
756 fn callback(&self, cx: &mut CurrentRealm, _v: SafeHandleValue) {
760 self.result.resolve_native(cx, &());
761 }
762}
763
764#[derive(Clone, JSTraceable, MallocSizeOf)]
767struct SourceCancelPromiseRejectionHandler {
768 #[conditional_malloc_size_of]
769 result: Rc<Promise>,
770}
771
772impl Callback for SourceCancelPromiseRejectionHandler {
773 fn callback(&self, cx: &mut CurrentRealm, v: SafeHandleValue) {
777 self.result.reject_native(cx, &v);
778 }
779}
780
781#[derive(Clone, Copy, Debug, Default, JSTraceable, MallocSizeOf, PartialEq)]
783pub(crate) enum ReadableStreamState {
784 #[default]
785 Readable,
786 Closed,
787 Errored,
788}
789
790#[derive(JSTraceable, MallocSizeOf)]
792#[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)]
793pub(crate) enum ControllerType {
794 Byte(MutNullableDom<ReadableByteStreamController>),
796 Default(MutNullableDom<ReadableStreamDefaultController>),
798}
799
800#[derive(JSTraceable, MallocSizeOf)]
802#[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)]
803pub(crate) enum ReaderType {
804 #[allow(clippy::upper_case_acronyms)]
806 BYOB(MutNullableDom<ReadableStreamBYOBReader>),
807 Default(MutNullableDom<ReadableStreamDefaultReader>),
809}
810
811impl js::gc::Rootable for ReaderType {}
812
813impl Eq for ReaderType {}
814impl PartialEq for ReaderType {
815 fn eq(&self, other: &Self) -> bool {
816 matches!(
817 (self, other),
818 (ReaderType::BYOB(_), ReaderType::BYOB(_)) |
819 (ReaderType::Default(_), ReaderType::Default(_))
820 )
821 }
822}
823
824pub(crate) fn create_readable_stream(
826 cx: &mut JSContext,
827 global: &GlobalScope,
828 underlying_source_type: UnderlyingSourceType,
829 queuing_strategy: Option<Rc<QueuingStrategySize>>,
830 high_water_mark: Option<f64>,
831) -> DomRoot<ReadableStream> {
832 let high_water_mark = high_water_mark.unwrap_or(1.0);
834
835 let size_algorithm =
837 queuing_strategy.unwrap_or(extract_size_algorithm(cx, &QueuingStrategy::empty()));
838
839 assert!(high_water_mark >= 0.0);
841
842 let stream = ReadableStream::new_with_proto(cx, global, None);
845
846 let controller = ReadableStreamDefaultController::new(
848 cx,
849 global,
850 underlying_source_type,
851 high_water_mark,
852 size_algorithm,
853 );
854
855 controller
858 .setup(cx, &stream)
859 .expect("Setup of default controller cannot fail");
860
861 stream
863}
864
865fn readable_byte_stream_tee(
867 cx: &mut JSContext,
868 global: &GlobalScope,
869 underlying_source_type: UnderlyingSourceType,
870) -> DomRoot<ReadableStream> {
871 let tee_stream = ReadableStream::new_with_proto(cx, global, None);
874
875 let controller = ReadableByteStreamController::new(cx, underlying_source_type, 0.0, global);
877
878 controller
880 .setup(cx, global, &tee_stream)
881 .expect("Setup of byte stream controller cannot fail");
882
883 tee_stream
885}
886
887#[dom_struct]
889pub(crate) struct ReadableStream {
890 reflector_: Reflector,
891
892 controller: RefCell<Option<ControllerType>>,
896
897 #[ignore_malloc_size_of = "mozjs"]
899 stored_error: Heap<JSVal>,
900
901 disturbed: Cell<bool>,
903
904 reader: RefCell<Option<ReaderType>>,
906
907 state: Cell<ReadableStreamState>,
909}
910
911impl ReadableStream {
912 fn new_inherited() -> ReadableStream {
914 ReadableStream {
915 reflector_: Reflector::new(),
916 controller: RefCell::new(None),
917 stored_error: Heap::default(),
918 disturbed: Default::default(),
919 reader: RefCell::new(None),
920 state: Cell::new(Default::default()),
921 }
922 }
923
924 pub(crate) fn new_with_proto(
925 cx: &mut JSContext,
926 global: &GlobalScope,
927 proto: Option<SafeHandleObject>,
928 ) -> DomRoot<ReadableStream> {
929 reflect_dom_object_with_proto(cx, Box::new(ReadableStream::new_inherited()), global, proto)
930 }
931
932 pub(crate) fn set_default_controller(&self, controller: &ReadableStreamDefaultController) {
935 *self.controller.borrow_mut() = Some(ControllerType::Default(MutNullableDom::new(Some(
936 controller,
937 ))));
938 }
939
940 pub(crate) fn set_byte_controller(&self, controller: &ReadableByteStreamController) {
943 *self.controller.borrow_mut() =
944 Some(ControllerType::Byte(MutNullableDom::new(Some(controller))));
945 }
946
947 pub(crate) fn assert_no_controller(&self) {
950 let has_no_controller = self.controller.borrow().is_none();
951 assert!(has_no_controller);
952 }
953
954 pub(crate) fn new_from_bytes(
956 cx: &mut JSContext,
957 global: &GlobalScope,
958 bytes: Vec<u8>,
959 ) -> Fallible<DomRoot<ReadableStream>> {
960 let stream = ReadableStream::new_with_external_underlying_source(
961 cx,
962 global,
963 UnderlyingSourceType::Memory(bytes.len()),
964 )?;
965 stream.enqueue_native(cx, bytes);
966 stream.controller_close_native(cx);
967 Ok(stream)
968 }
969
970 pub(crate) fn new_empty(
973 cx: &mut JSContext,
974 global: &GlobalScope,
975 ) -> Fallible<DomRoot<ReadableStream>> {
976 let empty_stream = ReadableStream::new_with_external_underlying_source(
979 cx,
980 global,
981 UnderlyingSourceType::Memory(0),
982 )?;
983 empty_stream.controller_close_native(cx);
985 Ok(empty_stream)
987 }
988
989 pub(crate) fn new_from_bytes_with_byte_reading_support(
991 cx: &mut JSContext,
992 global: &GlobalScope,
993 bytes: Vec<u8>,
994 ) -> Fallible<DomRoot<ReadableStream>> {
995 let stream = ReadableStream::new_with_external_underlying_byte_source(
996 cx,
997 global,
998 UnderlyingSourceType::Memory(bytes.len()),
999 )?;
1000 stream.enqueue_native(cx, bytes);
1001 stream.controller_close_native(cx);
1002 Ok(stream)
1003 }
1004
1005 pub(crate) fn new_with_external_underlying_source(
1008 cx: &mut JSContext,
1009 global: &GlobalScope,
1010 source: UnderlyingSourceType,
1011 ) -> Fallible<DomRoot<ReadableStream>> {
1012 assert!(source.is_native());
1013 let stream = ReadableStream::new_with_proto(cx, global, None);
1014 let strategy_size = extract_size_algorithm(cx, &QueuingStrategy::empty());
1015 let controller =
1016 ReadableStreamDefaultController::new(cx, global, source, 1.0, strategy_size);
1017 controller.setup(cx, &stream)?;
1018 Ok(stream)
1019 }
1020
1021 pub(crate) fn new_with_external_underlying_byte_source(
1023 cx: &mut JSContext,
1024 global: &GlobalScope,
1025 source: UnderlyingSourceType,
1026 ) -> Fallible<DomRoot<ReadableStream>> {
1027 assert!(source.is_native());
1028 let stream = ReadableStream::new_with_proto(cx, global, None);
1029 let controller = ReadableByteStreamController::new(cx, source, 0.0, global);
1030 controller.setup(cx, global, &stream)?;
1031 Ok(stream)
1032 }
1033
1034 pub(crate) fn perform_release_steps(&self) -> Fallible<()> {
1036 match self.controller.borrow().as_ref() {
1037 Some(ControllerType::Default(controller)) => {
1038 let controller = controller
1039 .get()
1040 .ok_or_else(|| Error::Type(c"Stream should have controller.".to_owned()))?;
1041 controller.perform_release_steps()
1042 },
1043 Some(ControllerType::Byte(controller)) => {
1044 let controller = controller
1045 .get()
1046 .ok_or_else(|| Error::Type(c"Stream should have controller.".to_owned()))?;
1047 controller.perform_release_steps()
1048 },
1049 None => Err(Error::Type(c"Stream should have controller.".to_owned())),
1050 }
1051 }
1052
1053 pub(crate) fn perform_pull_steps(&self, cx: &mut JSContext, read_request: &ReadRequest) {
1057 match self.controller.borrow().as_ref() {
1058 Some(ControllerType::Default(controller)) => controller
1059 .get()
1060 .expect("Stream should have controller.")
1061 .perform_pull_steps(cx, read_request),
1062 Some(ControllerType::Byte(controller)) => controller
1063 .get()
1064 .expect("Stream should have controller.")
1065 .perform_pull_steps(cx, read_request),
1066 None => {
1067 unreachable!("Stream does not have a controller.");
1068 },
1069 }
1070 }
1071
1072 pub(crate) fn perform_pull_into(
1076 &self,
1077 cx: &mut JSContext,
1078 read_into_request: &ReadIntoRequest,
1079 view: &HeapBufferSource<ArrayBufferViewU8>,
1080 min: u64,
1081 ) {
1082 match self.controller.borrow().as_ref() {
1083 Some(ControllerType::Byte(controller)) => controller
1084 .get()
1085 .expect("Stream should have controller.")
1086 .perform_pull_into(cx, read_into_request, view, min),
1087 _ => {
1088 unreachable!(
1089 "Pulling a chunk from a stream with a default controller using a BYOB reader"
1090 )
1091 },
1092 }
1093 }
1094
1095 pub(crate) fn add_read_request(&self, read_request: &ReadRequest) {
1097 match self.reader.borrow().as_ref() {
1098 Some(ReaderType::Default(reader)) => {
1099 let Some(reader) = reader.get() else {
1100 panic!("Attempt to add a read request without having first acquired a reader.");
1101 };
1102
1103 assert!(self.is_readable());
1105
1106 reader.add_read_request(read_request);
1108 },
1109 _ => {
1110 unreachable!("Adding a read request can only be done on a default reader.")
1111 },
1112 }
1113 }
1114
1115 pub(crate) fn add_read_into_request(&self, read_request: &ReadIntoRequest) {
1117 match self.reader.borrow().as_ref() {
1118 Some(ReaderType::BYOB(reader)) => {
1120 let Some(reader) = reader.get() else {
1121 unreachable!(
1122 "Attempt to add a read into request without having first acquired a reader."
1123 );
1124 };
1125
1126 assert!(self.is_readable() || self.is_closed());
1128
1129 reader.add_read_into_request(read_request);
1131 },
1132 _ => {
1133 unreachable!("Adding a read into request can only be done on a BYOB reader.")
1134 },
1135 }
1136 }
1137
1138 pub(crate) fn enqueue_native(&self, cx: &mut JSContext, bytes: Vec<u8>) {
1140 match self.controller.borrow().as_ref() {
1141 Some(ControllerType::Default(controller)) => controller
1142 .get()
1143 .expect("Stream should have controller.")
1144 .enqueue_native(cx, bytes),
1145 Some(ControllerType::Byte(controller)) => {
1146 if bytes.is_empty() {
1147 return;
1148 }
1149
1150 let controller = controller.get().expect("Stream should have controller.");
1151 rooted!(&in(cx) let mut chunk_object = ptr::null_mut::<JSObject>());
1152 create_buffer_source::<Uint8>(cx, &bytes, chunk_object.handle_mut())
1153 .expect("failed to create buffer source for native byte chunk.");
1154
1155 let chunk = RootedTraceableBox::new(HeapBufferSource::<ArrayBufferViewU8>::new(
1156 chunk_object.handle(),
1157 ));
1158 controller
1159 .enqueue(cx, chunk)
1160 .expect("Enqueuing a native byte chunk should not fail.");
1161 },
1162 _ => {
1163 unreachable!("Enqueueing chunk to a stream from Rust without a controller");
1164 },
1165 }
1166 }
1167
1168 pub(crate) fn error(&self, cx: &mut JSContext, e: SafeHandleValue) {
1170 assert!(self.is_readable());
1172
1173 self.state.set(ReadableStreamState::Errored);
1175
1176 self.stored_error.set(e.get());
1178
1179 let default_reader = {
1182 let reader_ref = self.reader.borrow();
1183 match reader_ref.as_ref() {
1184 Some(ReaderType::Default(reader)) => reader.get(),
1185 _ => None,
1186 }
1187 };
1188
1189 if let Some(reader) = default_reader {
1190 reader.error(cx, e);
1192 return;
1193 }
1194
1195 let byob_reader = {
1196 let reader_ref = self.reader.borrow();
1197 match reader_ref.as_ref() {
1198 Some(ReaderType::BYOB(reader)) => reader.get(),
1199 _ => None,
1200 }
1201 };
1202
1203 if let Some(reader) = byob_reader {
1204 reader.error_read_into_requests(cx, e);
1206 }
1207
1208 }
1210
1211 pub(crate) fn get_stored_error(&self, mut handle_mut: SafeMutableHandleValue) {
1213 handle_mut.set(self.stored_error.get());
1214 }
1215
1216 pub(crate) fn error_native(&self, cx: &mut JSContext, error: Error) {
1219 rooted!(&in(cx) let mut error_val = UndefinedValue());
1220 error.to_jsval(cx, &self.global(), error_val.handle_mut());
1221 self.error(cx, error_val.handle());
1222 }
1223
1224 pub(crate) fn controller_close_native(&self, cx: &mut JSContext) {
1227 match self.controller.borrow().as_ref() {
1228 Some(ControllerType::Default(controller)) => {
1229 let _ = controller
1230 .get()
1231 .expect("Stream should have controller.")
1232 .Close(cx);
1233 },
1234 Some(ControllerType::Byte(controller)) => {
1235 let _ = controller
1236 .get()
1237 .expect("Stream should have controller.")
1238 .close(cx);
1239 },
1240 _ => {
1241 unreachable!("Native closing requires a stream controller.")
1242 },
1243 }
1244 }
1245
1246 pub(crate) fn in_memory(&self) -> bool {
1249 match self.controller.borrow().as_ref() {
1250 Some(ControllerType::Default(controller)) => controller
1251 .get()
1252 .expect("Stream should have controller.")
1253 .in_memory(),
1254 Some(ControllerType::Byte(controller)) => controller
1255 .get()
1256 .expect("Stream should have controller.")
1257 .in_memory(),
1258 _ => unreachable!("Checking if source is in memory for a stream without a controller"),
1259 }
1260 }
1261
1262 pub(crate) fn get_in_memory_bytes(&self, cx: &mut JSContext) -> Option<GenericSharedMemory> {
1265 match self.controller.borrow().as_ref() {
1266 Some(ControllerType::Default(controller)) => controller
1267 .get()
1268 .expect("Stream should have controller.")
1269 .get_in_memory_bytes()
1270 .map(GenericSharedMemory::from_vec),
1271 Some(ControllerType::Byte(controller)) => controller
1272 .get()
1273 .expect("Stream should have controller.")
1274 .get_in_memory_bytes(cx)
1275 .map(GenericSharedMemory::from_vec),
1276 _ => unreachable!("Getting in-memory bytes for a stream without a controller"),
1277 }
1278 }
1279
1280 pub(crate) fn acquire_default_reader(
1285 &self,
1286 cx: &mut JSContext,
1287 ) -> Fallible<DomRoot<ReadableStreamDefaultReader>> {
1288 let reader = ReadableStreamDefaultReader::new(cx, &self.global());
1290
1291 reader.set_up(cx, self, &self.global())?;
1293
1294 Ok(reader)
1296 }
1297
1298 pub(crate) fn acquire_byob_reader(
1300 &self,
1301 cx: &mut JSContext,
1302 ) -> Fallible<DomRoot<ReadableStreamBYOBReader>> {
1303 let reader = ReadableStreamBYOBReader::new(cx, &self.global());
1305 reader.set_up(cx, self, &self.global())?;
1307
1308 Ok(reader)
1310 }
1311
1312 pub(crate) fn get_default_controller(&self) -> DomRoot<ReadableStreamDefaultController> {
1313 match self.controller.borrow().as_ref() {
1314 Some(ControllerType::Default(controller)) => {
1315 controller.get().expect("Stream should have controller.")
1316 },
1317 _ => {
1318 unreachable!(
1319 "Getting default controller for a stream with a non-default controller"
1320 )
1321 },
1322 }
1323 }
1324
1325 pub(crate) fn get_byte_controller(&self) -> DomRoot<ReadableByteStreamController> {
1326 match self.controller.borrow().as_ref() {
1327 Some(ControllerType::Byte(controller)) => {
1328 controller.get().expect("Stream should have controller.")
1329 },
1330 _ => {
1331 unreachable!("Getting byte controller for a stream with a non-byte controller")
1332 },
1333 }
1334 }
1335
1336 pub(crate) fn get_default_reader(&self) -> DomRoot<ReadableStreamDefaultReader> {
1337 match self.reader.borrow().as_ref() {
1338 Some(ReaderType::Default(reader)) => reader.get().expect("Stream should have reader."),
1339 _ => {
1340 unreachable!("Getting default reader for a stream with a non-default reader")
1341 },
1342 }
1343 }
1344
1345 pub(crate) fn read_a_chunk(&self, cx: &mut JSContext) -> Rc<Promise> {
1351 match self.reader.borrow().as_ref() {
1352 Some(ReaderType::Default(reader)) => {
1353 let Some(reader) = reader.get() else {
1354 unreachable!(
1355 "Attempt to read stream chunk without having first acquired a reader."
1356 );
1357 };
1358 reader.Read(cx)
1359 },
1360 _ => {
1361 unreachable!("Native reading of a chunk can only be done with a default reader.")
1362 },
1363 }
1364 }
1365
1366 pub(crate) fn stop_reading(&self, cx: &mut JSContext) {
1371 let reader_ref = self.reader.borrow();
1372
1373 match reader_ref.as_ref() {
1374 Some(ReaderType::Default(reader)) => {
1375 let Some(reader) = reader.get() else {
1376 unreachable!("Attempt to stop reading without having first acquired a reader.");
1377 };
1378
1379 drop(reader_ref);
1380 reader.release(cx).expect("Reader release cannot fail.");
1381 },
1382 _ => {
1383 unreachable!("Native stop reading can only be done with a default reader.")
1384 },
1385 }
1386 }
1387
1388 pub(crate) fn is_locked(&self) -> bool {
1390 match self.reader.borrow().as_ref() {
1391 Some(ReaderType::Default(reader)) => reader.get().is_some(),
1392 Some(ReaderType::BYOB(reader)) => reader.get().is_some(),
1393 None => false,
1394 }
1395 }
1396
1397 pub(crate) fn is_disturbed(&self) -> bool {
1398 self.disturbed.get()
1399 }
1400
1401 pub(crate) fn set_is_disturbed(&self, disturbed: bool) {
1402 self.disturbed.set(disturbed);
1403 }
1404
1405 pub(crate) fn is_closed(&self) -> bool {
1406 self.state.get() == ReadableStreamState::Closed
1407 }
1408
1409 pub(crate) fn is_errored(&self) -> bool {
1410 self.state.get() == ReadableStreamState::Errored
1411 }
1412
1413 pub(crate) fn is_readable(&self) -> bool {
1414 self.state.get() == ReadableStreamState::Readable
1415 }
1416
1417 pub(crate) fn has_default_reader(&self) -> bool {
1418 match self.reader.borrow().as_ref() {
1419 Some(ReaderType::Default(reader)) => reader.get().is_some(),
1420 _ => false,
1421 }
1422 }
1423
1424 pub(crate) fn has_byob_reader(&self) -> bool {
1425 match self.reader.borrow().as_ref() {
1426 Some(ReaderType::BYOB(reader)) => reader.get().is_some(),
1427 _ => false,
1428 }
1429 }
1430
1431 pub(crate) fn has_byte_controller(&self) -> bool {
1432 match self.controller.borrow().as_ref() {
1433 Some(ControllerType::Byte(controller)) => controller.get().is_some(),
1434 _ => false,
1435 }
1436 }
1437
1438 pub(crate) fn get_num_read_requests(&self) -> usize {
1440 match self.reader.borrow().as_ref() {
1441 Some(ReaderType::Default(reader)) => {
1442 let reader = reader
1443 .get()
1444 .expect("Stream must have a reader when getting the number of read requests.");
1445 reader.get_num_read_requests()
1446 },
1447 _ => unreachable!(
1448 "Stream must have a default reader when get num read requests is called into."
1449 ),
1450 }
1451 }
1452
1453 pub(crate) fn get_num_read_into_requests(&self) -> usize {
1455 assert!(self.has_byob_reader());
1456
1457 match self.reader.borrow().as_ref() {
1458 Some(ReaderType::BYOB(reader)) => {
1459 let Some(reader) = reader.get() else {
1460 unreachable!(
1461 "Stream must have a reader when get num read into requests is called into."
1462 );
1463 };
1464 reader.get_num_read_into_requests()
1465 },
1466 _ => {
1467 unreachable!(
1468 "Stream must have a BYOB reader when get num read into requests is called into."
1469 );
1470 },
1471 }
1472 }
1473
1474 pub(crate) fn fulfill_read_request(
1476 &self,
1477 cx: &mut JSContext,
1478 chunk: SafeHandleValue,
1479 done: bool,
1480 ) {
1481 assert!(self.has_default_reader());
1483
1484 match self.reader.borrow().as_ref() {
1485 Some(ReaderType::Default(reader)) => {
1486 let reader = reader
1488 .get()
1489 .expect("Stream must have a reader when a read request is fulfilled.");
1490 assert_ne!(reader.get_num_read_requests(), 0);
1492 let request = reader.remove_read_request();
1495
1496 if done {
1497 request.close_steps(cx);
1499 } else {
1500 let result = RootedTraceableBox::new(Heap::default());
1502 result.set(*chunk);
1503 request.chunk_steps(cx, result, &self.global());
1504 }
1505 },
1506 _ => {
1507 unreachable!(
1508 "Stream must have a default reader when fulfill read requests is called into."
1509 );
1510 },
1511 }
1512 }
1513
1514 pub(crate) fn fulfill_read_into_request(
1516 &self,
1517 cx: &mut JSContext,
1518 chunk: SafeHandleValue,
1519 done: bool,
1520 ) {
1521 assert!(self.has_byob_reader());
1523
1524 match self.reader.borrow().as_ref() {
1526 Some(ReaderType::BYOB(reader)) => {
1527 let Some(reader) = reader.get() else {
1528 unreachable!(
1529 "Stream must have a reader when a read into request is fulfilled."
1530 );
1531 };
1532
1533 assert!(reader.get_num_read_into_requests() > 0);
1535
1536 let read_into_request = reader.remove_read_into_request();
1539
1540 let result = RootedTraceableBox::new(Heap::default());
1542 if done {
1543 result.set(*chunk);
1544 read_into_request.close_steps(cx, Some(result));
1545 } else {
1546 result.set(*chunk);
1548 read_into_request.chunk_steps(cx, result);
1549 }
1550 },
1551 _ => {
1552 unreachable!(
1553 "Stream must have a BYOB reader when fulfill read into requests is called into."
1554 );
1555 },
1556 };
1557 }
1558
1559 pub(crate) fn close(&self, cx: &mut JSContext) {
1561 assert!(self.is_readable());
1563 self.state.set(ReadableStreamState::Closed);
1565 let default_reader = {
1571 let reader_ref = self.reader.borrow();
1572 match reader_ref.as_ref() {
1573 Some(ReaderType::Default(reader)) => reader.get(),
1574 _ => None,
1575 }
1576 };
1577
1578 if let Some(reader) = default_reader {
1579 reader.close(cx);
1581 return;
1582 }
1583
1584 let byob_reader = {
1586 let reader_ref = self.reader.borrow();
1587 match reader_ref.as_ref() {
1588 Some(ReaderType::BYOB(reader)) => reader.get(),
1589 _ => None,
1590 }
1591 };
1592
1593 if let Some(reader) = byob_reader {
1594 reader.close(cx);
1596 }
1597
1598 }
1600
1601 pub(crate) fn cancel(
1603 &self,
1604 cx: &mut JSContext,
1605 global: &GlobalScope,
1606 reason: SafeHandleValue,
1607 ) -> Rc<Promise> {
1608 self.disturbed.set(true);
1610
1611 if self.is_closed() {
1613 return Promise::new_resolved(cx, global, ());
1614 }
1615 if self.is_errored() {
1617 let promise = Promise::new(cx, global);
1618 rooted!(&in(cx) let mut rval = UndefinedValue());
1619 self.stored_error.safe_to_jsval(cx, rval.handle_mut());
1620 promise.reject_native(cx, &rval.handle());
1621 return promise;
1622 }
1623 self.close(cx);
1625
1626 let byob_reader = {
1628 let reader_ref = self.reader.borrow();
1629 match reader_ref.as_ref() {
1630 Some(ReaderType::BYOB(reader)) => reader.get(),
1631 _ => None,
1632 }
1633 };
1634
1635 if let Some(reader) = byob_reader {
1636 reader.cancel(cx);
1638 }
1639
1640 let source_cancel_promise = match self.controller.borrow().as_ref() {
1643 Some(ControllerType::Default(controller)) => controller
1644 .get()
1645 .expect("Stream should have controller.")
1646 .perform_cancel_steps(cx, global, reason),
1647 Some(ControllerType::Byte(controller)) => controller
1648 .get()
1649 .expect("Stream should have controller.")
1650 .perform_cancel_steps(cx, global, reason),
1651 None => {
1652 panic!("Stream does not have a controller.");
1653 },
1654 };
1655
1656 let global = self.global();
1659 let result_promise = Promise::new(cx, &global);
1660 let fulfillment_handler = Box::new(SourceCancelPromiseFulfillmentHandler {
1661 result: result_promise.clone(),
1662 });
1663 let rejection_handler = Box::new(SourceCancelPromiseRejectionHandler {
1664 result: result_promise.clone(),
1665 });
1666 let handler = PromiseNativeHandler::new(
1667 cx,
1668 &global,
1669 Some(fulfillment_handler),
1670 Some(rejection_handler),
1671 );
1672 let mut realm = enter_auto_realm(cx, &*global);
1673 let cx = &mut realm.current_realm();
1674 source_cancel_promise.append_native_handler(cx, &handler);
1675
1676 result_promise
1679 }
1680
1681 #[cfg_attr(crown, expect(crown::unrooted_must_root))]
1682 pub(crate) fn set_reader(&self, new_reader: Option<ReaderType>) {
1683 *self.reader.borrow_mut() = new_reader;
1684 }
1685
1686 #[cfg_attr(crown, expect(crown::unrooted_must_root))]
1687 fn byte_tee(&self, cx: &mut JSContext) -> Fallible<Vec<DomRoot<ReadableStream>>> {
1689 let reader = self.acquire_default_reader(cx)?;
1694 let reader = Rc::new(RefCell::new(ReaderType::Default(MutNullableDom::new(
1695 Some(&reader),
1696 ))));
1697
1698 let reading = Rc::new(Cell::new(false));
1700
1701 let read_again_for_branch_1 = Rc::new(Cell::new(false));
1703
1704 let read_again_for_branch_2 = Rc::new(Cell::new(false));
1706
1707 let canceled_1 = Rc::new(Cell::new(false));
1709
1710 let canceled_2 = Rc::new(Cell::new(false));
1712
1713 let reason_1 = Rc::new(Heap::default());
1715
1716 let reason_2 = Rc::new(Heap::default());
1718
1719 let cancel_promise = Promise::new(cx, &self.global());
1721 let reader_version = Rc::new(Cell::new(0));
1722
1723 let byte_tee_source_1 = ByteTeeUnderlyingSource::new(
1724 cx,
1725 reader.clone(),
1726 self,
1727 reading.clone(),
1728 read_again_for_branch_1.clone(),
1729 read_again_for_branch_2.clone(),
1730 canceled_1.clone(),
1731 canceled_2.clone(),
1732 reason_1.clone(),
1733 reason_2.clone(),
1734 cancel_promise.clone(),
1735 reader_version.clone(),
1736 ByteTeeCancelAlgorithm::Cancel1Algorithm,
1737 ByteTeePullAlgorithm::Pull1Algorithm,
1738 );
1739
1740 let byte_tee_source_2 = ByteTeeUnderlyingSource::new(
1741 cx,
1742 reader.clone(),
1743 self,
1744 reading,
1745 read_again_for_branch_1,
1746 read_again_for_branch_2,
1747 canceled_1,
1748 canceled_2,
1749 reason_1,
1750 reason_2,
1751 cancel_promise,
1752 reader_version,
1753 ByteTeeCancelAlgorithm::Cancel2Algorithm,
1754 ByteTeePullAlgorithm::Pull2Algorithm,
1755 );
1756
1757 let branch_1 = readable_byte_stream_tee(
1759 cx,
1760 &self.global(),
1761 UnderlyingSourceType::TeeByte(&byte_tee_source_1),
1762 );
1763 byte_tee_source_1.set_branch_1(&branch_1);
1764 byte_tee_source_2.set_branch_1(&branch_1);
1765
1766 let branch_2 = readable_byte_stream_tee(
1768 cx,
1769 &self.global(),
1770 UnderlyingSourceType::TeeByte(&byte_tee_source_2),
1771 );
1772 byte_tee_source_1.set_branch_2(&branch_2);
1773 byte_tee_source_2.set_branch_2(&branch_2);
1774
1775 byte_tee_source_1.forward_reader_error(cx, reader.clone());
1777 byte_tee_source_2.forward_reader_error(cx, reader);
1778
1779 Ok(vec![branch_1, branch_2])
1781 }
1782
1783 #[cfg_attr(crown, expect(crown::unrooted_must_root))]
1785 fn default_tee(
1786 &self,
1787 cx: &mut JSContext,
1788 clone_for_branch_2: bool,
1789 ) -> Fallible<Vec<DomRoot<ReadableStream>>> {
1790 let clone_for_branch_2 = Rc::new(Cell::new(clone_for_branch_2));
1794
1795 let reader = self.acquire_default_reader(cx)?;
1797
1798 let reading = Rc::new(Cell::new(false));
1800 let read_again = Rc::new(Cell::new(false));
1802 let canceled_1 = Rc::new(Cell::new(false));
1804 let canceled_2 = Rc::new(Cell::new(false));
1806
1807 let reason_1 = Rc::new(Heap::default());
1809 let reason_2 = Rc::new(Heap::default());
1811 let cancel_promise = Promise::new(cx, &self.global());
1813
1814 let tee_source_1 = DefaultTeeUnderlyingSource::new(
1815 cx,
1816 &reader,
1817 self,
1818 reading.clone(),
1819 read_again.clone(),
1820 canceled_1.clone(),
1821 canceled_2.clone(),
1822 clone_for_branch_2.clone(),
1823 reason_1.clone(),
1824 reason_2.clone(),
1825 cancel_promise.clone(),
1826 DefaultTeeCancelAlgorithm::Cancel1Algorithm,
1827 );
1828
1829 let underlying_source_type_branch_1 = UnderlyingSourceType::Tee(&tee_source_1);
1830
1831 let tee_source_2 = DefaultTeeUnderlyingSource::new(
1832 cx,
1833 &reader,
1834 self,
1835 reading,
1836 read_again,
1837 canceled_1.clone(),
1838 canceled_2.clone(),
1839 clone_for_branch_2,
1840 reason_1,
1841 reason_2,
1842 cancel_promise.clone(),
1843 DefaultTeeCancelAlgorithm::Cancel2Algorithm,
1844 );
1845
1846 let underlying_source_type_branch_2 = UnderlyingSourceType::Tee(&tee_source_2);
1847
1848 let branch_1 = create_readable_stream(
1850 cx,
1851 &self.global(),
1852 underlying_source_type_branch_1,
1853 None,
1854 None,
1855 );
1856 tee_source_1.set_branch_1(&branch_1);
1857 tee_source_2.set_branch_1(&branch_1);
1858
1859 let branch_2 = create_readable_stream(
1861 cx,
1862 &self.global(),
1863 underlying_source_type_branch_2,
1864 None,
1865 None,
1866 );
1867 tee_source_1.set_branch_2(&branch_2);
1868 tee_source_2.set_branch_2(&branch_2);
1869
1870 reader.default_tee_append_native_handler_to_closed_promise(
1872 cx,
1873 &branch_1,
1874 &branch_2,
1875 canceled_1,
1876 canceled_2,
1877 cancel_promise,
1878 );
1879
1880 Ok(vec![branch_1, branch_2])
1882 }
1883
1884 #[allow(clippy::too_many_arguments)]
1886 pub(crate) fn pipe_to(
1887 &self,
1888 cx: &mut CurrentRealm,
1889 global: &GlobalScope,
1890 dest: &WritableStream,
1891 prevent_close: bool,
1892 prevent_abort: bool,
1893 prevent_cancel: bool,
1894 signal: Option<&AbortSignal>,
1895 ) -> Rc<Promise> {
1896 assert!(!self.is_locked());
1907
1908 assert!(!dest.is_locked());
1910
1911 let reader = self
1919 .acquire_default_reader(cx)
1920 .expect("Acquiring a default reader for pipe_to cannot fail");
1921
1922 let writer = dest
1924 .aquire_default_writer(cx, global)
1925 .expect("Acquiring a default writer for pipe_to cannot fail");
1926
1927 self.disturbed.set(true);
1929
1930 let promise = Promise::new(cx, global);
1935
1936 rooted!(&in(cx) let pipe_to = PipeTo {
1938 reader: Dom::from_ref(&reader),
1939 writer: Dom::from_ref(&writer),
1940 pending_writes: Default::default(),
1941 state: Default::default(),
1942 prevent_abort,
1943 prevent_cancel,
1944 prevent_close,
1945 shutting_down: Default::default(),
1946 abort_reason: Default::default(),
1947 shutdown_error: Default::default(),
1948 shutdown_action_promise: Default::default(),
1949 result_promise: promise.clone(),
1950 });
1951
1952 if let Some(signal) = signal {
1955 rooted!(&in(cx) let abort_algorithm = AbortAlgorithm::StreamPiping(pipe_to.clone()));
1958
1959 if signal.aborted() {
1961 signal.run_abort_algorithm(cx, global, &abort_algorithm);
1962 return promise;
1963 }
1964
1965 signal.add(&abort_algorithm);
1967 }
1968
1969 pipe_to.check_and_propagate_errors_forward(cx, global);
1971 pipe_to.check_and_propagate_errors_backward(cx, global);
1972 pipe_to.check_and_propagate_closing_forward(cx, global);
1973 pipe_to.check_and_propagate_closing_backward(cx, global);
1974
1975 if *pipe_to.state.borrow() == PipeToState::Starting {
1977 pipe_to.wait_for_writer_ready(cx, global);
1979 }
1980
1981 promise
1983 }
1984
1985 pub(crate) fn tee(
1987 &self,
1988 cx: &mut JSContext,
1989 clone_for_branch_2: bool,
1990 ) -> Fallible<Vec<DomRoot<ReadableStream>>> {
1991 match self.controller.borrow().as_ref() {
1995 Some(ControllerType::Default(_)) => {
1996 self.default_tee(cx, clone_for_branch_2)
1998 },
1999 Some(ControllerType::Byte(_)) => {
2000 self.byte_tee(cx)
2003 },
2004 None => {
2005 unreachable!("Stream should have a controller.");
2006 },
2007 }
2008 }
2009
2010 fn set_up_byte_controller(
2012 &self,
2013 cx: &mut JSContext,
2014 global: &GlobalScope,
2015 underlying_source_dict: JsUnderlyingSource,
2016 underlying_source_handle: SafeHandleObject,
2017 stream: &ReadableStream,
2018 strategy_hwm: f64,
2019 ) -> Fallible<()> {
2020 if let Some(0) = underlying_source_dict.autoAllocateChunkSize {
2036 return Err(Error::Type(c"autoAllocateChunkSize cannot be 0".to_owned()));
2037 }
2038
2039 let controller = ReadableByteStreamController::new(
2040 cx,
2041 UnderlyingSourceType::Js(underlying_source_dict),
2042 strategy_hwm,
2043 global,
2044 );
2045
2046 controller.set_underlying_source_this_object(underlying_source_handle);
2049
2050 controller.setup(cx, global, stream)
2053 }
2054
2055 pub(crate) fn setup_cross_realm_transform_readable(
2057 &self,
2058 cx: &mut JSContext,
2059 port: &MessagePort,
2060 ) {
2061 let port_id = port.message_port_id();
2062 let global = self.global();
2063
2064 let size_algorithm = extract_size_algorithm(cx, &QueuingStrategy::default());
2069
2070 let controller = ReadableStreamDefaultController::new(
2074 cx,
2075 &self.global(),
2076 UnderlyingSourceType::Transfer(port),
2077 0.,
2078 size_algorithm,
2079 );
2080
2081 rooted!(&in(cx) let cross_realm_transform_readable = CrossRealmTransformReadable {
2084 controller: Dom::from_ref(&controller),
2085 });
2086 global.note_cross_realm_transform_readable(&cross_realm_transform_readable, port_id);
2087
2088 port.Start(cx);
2090
2091 controller
2093 .setup(cx, self)
2094 .expect("Setting up controller for transfer cannot fail.");
2095 }
2096}
2097
2098impl ReadableStreamMethods<crate::DomTypeHolder> for ReadableStream {
2099 fn Constructor(
2101 cx: &mut JSContext,
2102 global: &GlobalScope,
2103 proto: Option<SafeHandleObject>,
2104 underlying_source: Option<*mut JSObject>,
2105 strategy: &QueuingStrategy,
2106 ) -> Fallible<DomRoot<Self>> {
2107 rooted!(&in(cx) let underlying_source_obj = underlying_source.unwrap_or(ptr::null_mut()));
2109 let underlying_source_dict = if !underlying_source_obj.is_null() {
2112 rooted!(&in(cx) let obj_val = ObjectValue(underlying_source_obj.get()));
2113 match JsUnderlyingSource::new(cx, obj_val.handle()) {
2114 Ok(ConversionResult::Success(val)) => val,
2115 Ok(ConversionResult::Failure(error)) => {
2116 return Err(Error::Type(error.into_owned()));
2117 },
2118 _ => {
2119 return Err(Error::JSFailed);
2120 },
2121 }
2122 } else {
2123 JsUnderlyingSource::empty()
2124 };
2125
2126 let stream = ReadableStream::new_with_proto(cx, global, proto);
2128
2129 if underlying_source_dict.type_.is_some() {
2130 if strategy.size.is_some() {
2132 return Err(Error::Range(
2133 c"size is not supported for byte streams".to_owned(),
2134 ));
2135 }
2136
2137 let strategy_hwm = extract_high_water_mark(strategy, 0.0)?;
2139
2140 stream.set_up_byte_controller(
2143 cx,
2144 global,
2145 underlying_source_dict,
2146 underlying_source_obj.handle(),
2147 &stream,
2148 strategy_hwm,
2149 )?;
2150 } else {
2151 let high_water_mark = extract_high_water_mark(strategy, 1.0)?;
2153
2154 let size_algorithm = extract_size_algorithm(cx, strategy);
2156
2157 let controller = ReadableStreamDefaultController::new(
2158 cx,
2159 global,
2160 UnderlyingSourceType::Js(underlying_source_dict),
2161 high_water_mark,
2162 size_algorithm,
2163 );
2164
2165 controller.set_underlying_source_this_object(underlying_source_obj.handle());
2168
2169 controller.setup(cx, &stream)?;
2171 };
2172
2173 Ok(stream)
2174 }
2175
2176 fn Locked(&self) -> bool {
2178 self.is_locked()
2179 }
2180
2181 fn Cancel(&self, cx: &mut JSContext, reason: SafeHandleValue) -> Rc<Promise> {
2183 let global = self.global();
2184 if self.is_locked() {
2185 let promise = Promise::new(cx, &global);
2188 promise.reject_error(cx, Error::Type(c"stream is locked".to_owned()));
2189 promise
2190 } else {
2191 self.cancel(cx, &global, reason)
2193 }
2194 }
2195
2196 fn GetReader(
2198 &self,
2199 cx: &mut JSContext,
2200 options: &ReadableStreamGetReaderOptions,
2201 ) -> Fallible<ReadableStreamReader> {
2202 if options.mode.is_none() {
2204 return Ok(ReadableStreamReader::ReadableStreamDefaultReader(
2205 self.acquire_default_reader(cx)?,
2206 ));
2207 }
2208 assert!(options.mode.unwrap() == ReadableStreamReaderMode::Byob);
2210
2211 Ok(ReadableStreamReader::ReadableStreamBYOBReader(
2213 self.acquire_byob_reader(cx)?,
2214 ))
2215 }
2216
2217 fn Tee(&self, cx: &mut JSContext) -> Fallible<Vec<DomRoot<ReadableStream>>> {
2219 self.tee(cx, false)
2221 }
2222
2223 fn PipeTo(
2225 &self,
2226 cx: &mut CurrentRealm,
2227 destination: &WritableStream,
2228 options: &StreamPipeOptions,
2229 ) -> Rc<Promise> {
2230 let global = self.global();
2231
2232 if self.is_locked() {
2234 let promise = Promise::new(cx, &global);
2236 promise.reject_error(cx, Error::Type(c"Source stream is locked".to_owned()));
2237 return promise;
2238 }
2239
2240 if destination.is_locked() {
2242 let promise = Promise::new(cx, &global);
2244 promise.reject_error(cx, Error::Type(c"Destination stream is locked".to_owned()));
2245 return promise;
2246 }
2247
2248 let signal = options.signal.as_deref();
2250
2251 self.pipe_to(
2253 cx,
2254 &global,
2255 destination,
2256 options.preventClose,
2257 options.preventAbort,
2258 options.preventCancel,
2259 signal,
2260 )
2261 }
2262
2263 fn PipeThrough(
2265 &self,
2266 cx: &mut CurrentRealm,
2267 transform: &ReadableWritablePair,
2268 options: &StreamPipeOptions,
2269 ) -> Fallible<DomRoot<ReadableStream>> {
2270 let global = self.global();
2271
2272 if self.is_locked() {
2274 return Err(Error::Type(c"Source stream is locked".to_owned()));
2275 }
2276
2277 if transform.writable.is_locked() {
2279 return Err(Error::Type(c"Destination stream is locked".to_owned()));
2280 }
2281
2282 let signal = options.signal.as_deref();
2284
2285 let promise = self.pipe_to(
2288 cx,
2289 &global,
2290 &transform.writable,
2291 options.preventClose,
2292 options.preventAbort,
2293 options.preventCancel,
2294 signal,
2295 );
2296
2297 promise.set_promise_is_handled(cx);
2299
2300 Ok(transform.readable.clone())
2302 }
2303}
2304
2305pub(crate) fn get_type_and_value_from_message(
2309 cx: &mut JSContext,
2310 data: SafeHandleValue,
2311 value: SafeMutableHandleValue,
2312) -> DOMString {
2313 assert!(data.is_object());
2319 rooted!(&in(cx) let data_object = data.to_object());
2320
2321 let type_ = get_property::<DOMString>(
2323 cx,
2324 data_object.handle(),
2325 c"type",
2326 StringificationBehavior::Empty,
2327 );
2328
2329 get_property_jsval(cx, data_object.handle(), c"value", value)
2331 .expect("Getting the value should not fail.");
2332
2333 type_
2335 .expect("The type of the message should be a string")
2336 .expect("Property should be present")
2337}
2338
2339impl js::gc::Rootable for CrossRealmTransformReadable {}
2340
2341#[derive(Clone, JSTraceable, MallocSizeOf)]
2345#[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)]
2346pub(crate) struct CrossRealmTransformReadable {
2347 controller: Dom<ReadableStreamDefaultController>,
2349}
2350
2351impl CrossRealmTransformReadable {
2352 pub(crate) fn handle_message(
2355 &self,
2356 cx: &mut CurrentRealm,
2357 global: &GlobalScope,
2358 port: &MessagePort,
2359 message: SafeHandleValue,
2360 ) {
2361 rooted!(&in(cx) let mut value = UndefinedValue());
2362 let type_string = get_type_and_value_from_message(cx, message, value.handle_mut());
2363
2364 if type_string == "chunk" {
2366 self.controller
2368 .enqueue(cx, value.handle())
2369 .expect("Enqueing a chunk should not fail.");
2370 }
2371
2372 if type_string == "close" {
2374 self.controller.close(cx);
2376
2377 global.disentangle_port(cx, port);
2379 }
2380
2381 if type_string == "error" {
2383 self.controller.error(cx, value.handle());
2385
2386 global.disentangle_port(cx, port);
2388 }
2389 }
2390
2391 pub(crate) fn handle_error(
2394 &self,
2395 cx: &mut CurrentRealm,
2396 global: &GlobalScope,
2397 port: &MessagePort,
2398 ) {
2399 let error = DOMException::new(cx, global, DOMErrorName::DataCloneError);
2401 rooted!(&in(cx) let mut rooted_error = UndefinedValue());
2402 error.safe_to_jsval(cx, rooted_error.handle_mut());
2403
2404 port.cross_realm_transform_send_error(cx, rooted_error.handle());
2406
2407 self.controller.error(cx, rooted_error.handle());
2409
2410 global.disentangle_port(cx, port);
2412 }
2413}
2414
2415pub(crate) fn get_read_promise_done(
2417 cx: &mut JSContext,
2418 v: &SafeHandleValue,
2419) -> Result<bool, Error> {
2420 if !v.is_object() {
2421 return Err(Error::Type(c"Unknown format for done property.".to_owned()));
2422 }
2423
2424 rooted!(&in(cx) let object = v.to_object());
2425 get_property::<bool>(cx, object.handle(), c"done", ())?
2426 .ok_or(Error::Type(c"Promise has no done property.".to_owned()))
2427}
2428
2429pub(crate) fn get_read_promise_bytes(
2431 cx: &mut JSContext,
2432 v: &SafeHandleValue,
2433) -> Result<Vec<u8>, Error> {
2434 if !v.is_object() {
2435 return Err(Error::Type(
2436 c"Unknown format for for bytes read.".to_owned(),
2437 ));
2438 }
2439
2440 rooted!(&in(cx) let object = v.to_object());
2441 get_property::<Vec<u8>>(
2442 cx,
2443 object.handle(),
2444 c"value",
2445 ConversionBehavior::EnforceRange,
2446 )?
2447 .ok_or(Error::Type(c"Promise has no value property.".to_owned()))
2448}
2449
2450pub(crate) fn bytes_from_chunk_jsval(
2454 cx: &mut JSContext,
2455 chunk: &RootedTraceableBox<Heap<JSVal>>,
2456) -> Result<Vec<u8>, Error> {
2457 match Vec::<u8>::safe_from_jsval(cx, chunk.handle(), ConversionBehavior::EnforceRange) {
2458 Ok(ConversionResult::Success(vec)) => Ok(vec),
2459 Ok(ConversionResult::Failure(error)) => Err(Error::Type(error.into_owned())),
2460 _ => Err(Error::Type(c"Unknown format for bytes read.".to_owned())),
2461 }
2462}
2463
2464impl Transferable for ReadableStream {
2466 type Index = MessagePortIndex;
2467 type Data = MessagePortImpl;
2468
2469 fn transfer(&self, cx: &mut JSContext) -> Fallible<(MessagePortId, MessagePortImpl)> {
2471 if self.is_locked() {
2474 return Err(Error::DataClone(None));
2475 }
2476
2477 let global = self.global();
2478 let mut realm = enter_auto_realm(cx, &*global);
2479 let mut realm = realm.current_realm();
2480 let cx = &mut realm;
2481
2482 let port_1 = MessagePort::new(cx, &global);
2484 global.track_message_port(&port_1, None);
2485
2486 let port_2 = MessagePort::new(cx, &global);
2488 global.track_message_port(&port_2, None);
2489
2490 global.entangle_ports(*port_1.message_port_id(), *port_2.message_port_id());
2492
2493 let writable = WritableStream::new_with_proto(cx, &global, None);
2495
2496 writable.setup_cross_realm_transform_writable(cx, &port_1);
2498
2499 let promise = self.pipe_to(cx, &global, &writable, false, false, false, None);
2501
2502 promise.set_promise_is_handled(cx);
2504
2505 port_2.transfer(cx)
2507 }
2508
2509 fn transfer_receive(
2511 cx: &mut JSContext,
2512 owner: &GlobalScope,
2513 id: MessagePortId,
2514 port_impl: MessagePortImpl,
2515 ) -> Result<DomRoot<Self>, ()> {
2516 let value = ReadableStream::new_with_proto(cx, owner, None);
2519
2520 let transferred_port = MessagePort::transfer_receive(cx, owner, id, port_impl)?;
2527
2528 value.setup_cross_realm_transform_readable(cx, &transferred_port);
2530 Ok(value)
2531 }
2532
2533 fn serialized_storage<'a>(
2535 data: StructuredData<'a, '_>,
2536 ) -> &'a mut Option<FxHashMap<MessagePortId, Self::Data>> {
2537 match data {
2538 StructuredData::Reader(r) => &mut r.port_impls,
2539 StructuredData::Writer(w) => &mut w.ports,
2540 }
2541 }
2542}
2543
2544pub(crate) fn pipe_through(
2551 source: &ReadableStream,
2552 cx: &mut JSContext,
2553 global: &GlobalScope,
2554 transform: &TextDecoderStream,
2555) -> DomRoot<ReadableStream> {
2556 let mut realm = CurrentRealm::assert(cx);
2562 let promise = source.pipe_to(
2565 &mut realm,
2566 global,
2567 &transform.Writable(),
2568 false, false, false, None, );
2573
2574 promise.set_promise_is_handled(cx);
2576 transform.Readable()
2578}