summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/modules/webtransport/quic_transport.h
blob: 9ecbdb63bd7128c9b21eb2329c1b9cd073631918 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBTRANSPORT_QUIC_TRANSPORT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBTRANSPORT_QUIC_TRANSPORT_H_

#include <stdint.h>

#include "base/containers/span.h"
#include "base/types/pass_key.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/system/data_pipe.h"
#include "services/network/public/mojom/quic_transport.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"

namespace blink {

class ExceptionState;
class QuicTransportOptions;
class ReadableStream;
class ReadableStreamDefaultControllerWithScriptScope;
class ScriptPromise;
class ScriptPromiseResolver;
class ScriptPromiseResolver;
class ScriptState;
class WebTransportCloseInfo;
class WebTransportStream;
class WritableStream;

// https://wicg.github.io/web-transport/#quic-transport
class MODULES_EXPORT QuicTransport final
    : public ScriptWrappable,
      public ActiveScriptWrappable<QuicTransport>,
      public ExecutionContextLifecycleObserver,
      public network::mojom::blink::QuicTransportHandshakeClient,
      public network::mojom::blink::QuicTransportClient {
  DEFINE_WRAPPERTYPEINFO();
  USING_PRE_FINALIZER(QuicTransport, Dispose);

 public:
  using PassKey = base::PassKey<QuicTransport>;
  static QuicTransport* Create(ScriptState*,
                               const String& url,
                               QuicTransportOptions*,
                               ExceptionState&);

  QuicTransport(PassKey, ScriptState*, const String& url);
  ~QuicTransport() override;

  // QuicTransport IDL implementation.
  ScriptPromise createSendStream(ScriptState*, ExceptionState&);
  ReadableStream* receiveStreams();

  ScriptPromise createBidirectionalStream(ScriptState*, ExceptionState&);
  ReadableStream* receiveBidirectionalStreams();

  WritableStream* sendDatagrams();
  ReadableStream* receiveDatagrams();
  void close(const WebTransportCloseInfo*);
  ScriptPromise ready() { return ready_; }
  ScriptPromise closed() { return closed_; }

  // QuicTransportHandshakeClient implementation
  void OnConnectionEstablished(
      mojo::PendingRemote<network::mojom::blink::QuicTransport>,
      mojo::PendingReceiver<network::mojom::blink::QuicTransportClient>)
      override;
  void OnHandshakeFailed(network::mojom::blink::QuicTransportErrorPtr) override;

  // QuicTransportClient implementation
  void OnDatagramReceived(base::span<const uint8_t> data) override;
  void OnIncomingStreamClosed(uint32_t stream_id, bool fin_received) override;

  // Implementation of ExecutionContextLifecycleObserver
  void ContextDestroyed() final;

  // Implementation of ActiveScriptWrappable
  bool HasPendingActivity() const final;

  // Forwards a SendFin() message to the mojo interface.
  void SendFin(uint32_t stream_id);

  // Forwards a AbortStream() message to the mojo interface.
  void AbortStream(uint32_t stream_id);

  // Removes the reference to a stream.
  void ForgetStream(uint32_t stream_id);

  void SetDatagramWritableQueueExpirationDuration(base::TimeDelta duration);

  // ScriptWrappable implementation
  void Trace(Visitor* visitor) const override;

 private:
  class DatagramUnderlyingSink;
  class DatagramUnderlyingSource;
  class StreamVendingUnderlyingSource;
  class ReceiveStreamVendor;
  class BidirectionalStreamVendor;

  QuicTransport(ScriptState*, const String& url, ExecutionContext* context);

  void Init(const String& url, const QuicTransportOptions&, ExceptionState&);

  // Reset the QuicTransport object and all associated streams.
  void ResetAll();

  void Dispose();
  void OnConnectionError();
  void RejectPendingStreamResolvers();
  void OnCreateSendStreamResponse(ScriptPromiseResolver*,
                                  mojo::ScopedDataPipeProducerHandle,
                                  bool succeeded,
                                  uint32_t stream_id);
  void OnCreateBidirectionalStreamResponse(ScriptPromiseResolver*,
                                           mojo::ScopedDataPipeProducerHandle,
                                           mojo::ScopedDataPipeConsumerHandle,
                                           bool succeeded,
                                           uint32_t stream_id);

  bool cleanly_closed_ = false;
  Member<ReadableStream> received_datagrams_;
  Member<ReadableStreamDefaultControllerWithScriptScope>
      received_datagrams_controller_;

  // This corresponds to the [[SentDatagrams]] internal slot in the standard.
  Member<WritableStream> outgoing_datagrams_;

  const Member<ScriptState> script_state_;

  const KURL url_;

  // Map from stream_id to SendStream, ReceiveStream or BidirectionalStream.
  // Intentionally keeps streams reachable by GC as long as they are open.
  // This doesn't support stream ids of 0xfffffffe or larger.
  // TODO(ricea): Find out if such large stream ids are possible.
  HeapHashMap<uint32_t,
              Member<WebTransportStream>,
              WTF::DefaultHash<uint32_t>::Hash,
              WTF::UnsignedWithZeroKeyHashTraits<uint32_t>>
      stream_map_;

  HeapMojoRemote<network::mojom::blink::QuicTransport> quic_transport_;
  HeapMojoReceiver<network::mojom::blink::QuicTransportHandshakeClient,
                   QuicTransport>
      handshake_client_receiver_;
  HeapMojoReceiver<network::mojom::blink::QuicTransportClient, QuicTransport>
      client_receiver_;
  Member<ScriptPromiseResolver> ready_resolver_;
  ScriptPromise ready_;
  Member<ScriptPromiseResolver> closed_resolver_;
  ScriptPromise closed_;

  // Tracks resolvers for in-progress createSendStream() and
  // createBidirectionalStream() operations so they can be rejected.
  HeapHashSet<Member<ScriptPromiseResolver>> create_stream_resolvers_;

  // The [[ReceivedStreams]] slot.
  // https://wicg.github.io/web-transport/#dom-quictransport-receivedstreams-slot
  Member<ReadableStream> received_streams_;
  Member<StreamVendingUnderlyingSource> received_streams_underlying_source_;

  Member<ReadableStream> received_bidirectional_streams_;
  Member<StreamVendingUnderlyingSource>
      received_bidirectional_streams_underlying_source_;

  const uint64_t inspector_transport_id_;
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBTRANSPORT_QUIC_TRANSPORT_H_