1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "third_party/blink/renderer/modules/webtransport/bidirectional_stream.h"
6 
7 #include <utility>
8 
9 #include "base/check.h"
10 #include "third_party/blink/renderer/modules/webtransport/quic_transport.h"
11 #include "third_party/blink/renderer/platform/heap/heap.h"
12 #include "third_party/blink/renderer/platform/heap/persistent.h"
13 #include "third_party/blink/renderer/platform/heap/visitor.h"
14 
15 namespace blink {
16 
BidirectionalStream(ScriptState * script_state,QuicTransport * quic_transport,uint32_t stream_id,mojo::ScopedDataPipeProducerHandle outgoing_producer,mojo::ScopedDataPipeConsumerHandle incoming_consumer)17 BidirectionalStream::BidirectionalStream(
18     ScriptState* script_state,
19     QuicTransport* quic_transport,
20     uint32_t stream_id,
21     mojo::ScopedDataPipeProducerHandle outgoing_producer,
22     mojo::ScopedDataPipeConsumerHandle incoming_consumer)
23     : outgoing_stream_(
24           MakeGarbageCollected<OutgoingStream>(script_state,
25                                                this,
26                                                std::move(outgoing_producer))),
27       incoming_stream_(MakeGarbageCollected<IncomingStream>(
28           script_state,
29           WTF::Bind(&BidirectionalStream::OnIncomingStreamAbort,
30                     WrapWeakPersistent(this)),
31           std::move(incoming_consumer))),
32       quic_transport_(quic_transport),
33       stream_id_(stream_id) {}
34 
Init()35 void BidirectionalStream::Init() {
36   outgoing_stream_->Init();
37   incoming_stream_->Init();
38 }
39 
OnIncomingStreamClosed(bool fin_received)40 void BidirectionalStream::OnIncomingStreamClosed(bool fin_received) {
41   incoming_stream_->OnIncomingStreamClosed(fin_received);
42   if (outgoing_stream_->GetState() == OutgoingStream::State::kSentFin) {
43     return;
44   }
45 
46   ScriptState::Scope scope(outgoing_stream_->GetScriptState());
47   outgoing_stream_->Reset();
48 }
49 
Reset()50 void BidirectionalStream::Reset() {
51   ScriptState::Scope scope(outgoing_stream_->GetScriptState());
52   outgoing_stream_->Reset();
53   incoming_stream_->Reset();
54 }
55 
ContextDestroyed()56 void BidirectionalStream::ContextDestroyed() {
57   outgoing_stream_->ContextDestroyed();
58   incoming_stream_->ContextDestroyed();
59 }
60 
SendFin()61 void BidirectionalStream::SendFin() {
62   quic_transport_->SendFin(stream_id_);
63   // The IncomingStream will be closed on the network service side.
64 }
65 
OnOutgoingStreamAbort()66 void BidirectionalStream::OnOutgoingStreamAbort() {
67   quic_transport_->AbortStream(stream_id_);
68   quic_transport_->ForgetStream(stream_id_);
69   if (incoming_stream_->GetState() == IncomingStream::State::kOpen) {
70     incoming_stream_->Reset();
71   }
72 }
73 
Trace(Visitor * visitor) const74 void BidirectionalStream::Trace(Visitor* visitor) const {
75   visitor->Trace(outgoing_stream_);
76   visitor->Trace(incoming_stream_);
77   visitor->Trace(quic_transport_);
78   ScriptWrappable::Trace(visitor);
79   WebTransportStream::Trace(visitor);
80   OutgoingStream::Client::Trace(visitor);
81 }
82 
OnIncomingStreamAbort()83 void BidirectionalStream::OnIncomingStreamAbort() {
84   quic_transport_->ForgetStream(stream_id_);
85   if (outgoing_stream_->GetState() == OutgoingStream::State::kAborted) {
86     return;
87   }
88   ScriptState::Scope scope(outgoing_stream_->GetScriptState());
89   outgoing_stream_->Reset();
90 }
91 
92 }  // namespace blink
93