@fails-components/webtransport-transport-http3-quiche 1.1.4 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CMakeLists.txt CHANGED
@@ -27,6 +27,7 @@ ENDIF(WIN32)
27
27
 
28
28
  set(ABSL_PROPAGATE_CXX_STD ON)
29
29
  # include abseil
30
+ set(ABSL_MSVC_STATIC_RUNTIME ON)
30
31
  add_subdirectory(third_party/abseil-cpp EXCLUDE_FROM_ALL)
31
32
 
32
33
 
@@ -82,12 +83,10 @@ platform/quiche_platform_impl/quiche_event_loop_impl.h
82
83
  platform/quiche_platform_impl/quiche_bug_tracker_impl.h
83
84
  platform/quiche_platform_impl/quiche_googleurl_impl.h
84
85
  platform/quiche_platform_impl/quiche_iovec_impl.h
85
- platform/quiche_platform_impl/quiche_mutex_impl.h
86
86
  platform/quiche_platform_impl/quiche_stack_trace_impl.h
87
87
  platform/quiche_platform_impl/quiche_stream_buffer_allocator_impl.h
88
88
  platform/quiche_platform_impl/quiche_time_utils_impl.h
89
89
  platform/quiche_platform_impl/quiche_udp_socket_platform_impl.h
90
- platform/quiche_platform_impl/quiche_prefetch_impl.h
91
90
  platform/quiche_platform_impl/quiche_server_stats_impl.h
92
91
  platform/quiche_platform_impl/quiche_mem_slice_impl.h
93
92
  platform/quiche_platform_impl/quiche_flag_utils_impl.h
@@ -159,9 +158,6 @@ third_party/quiche/quiche/common/platform/api/quiche_hostname_utils.h
159
158
  third_party/quiche/quiche/common/platform/api/quiche_iovec.h
160
159
  third_party/quiche/quiche/common/platform/api/quiche_logging.h
161
160
  third_party/quiche/quiche/common/platform/api/quiche_mem_slice.h
162
- third_party/quiche/quiche/common/platform/api/quiche_mutex.cc
163
- third_party/quiche/quiche/common/platform/api/quiche_mutex.h
164
- third_party/quiche/quiche/common/platform/api/quiche_prefetch.h
165
161
  third_party/quiche/quiche/common/platform/api/quiche_reference_counted.h
166
162
  third_party/quiche/quiche/common/platform/api/quiche_time_utils.h
167
163
  third_party/quiche/quiche/common/platform/api/quiche_url_utils.h
@@ -170,11 +166,9 @@ third_party/quiche/quiche/common/platform/default/quiche_platform_impl/quiche_co
170
166
  third_party/quiche/quiche/common/platform/default/quiche_platform_impl/quiche_flag_utils_impl.h
171
167
  third_party/quiche/quiche/common/platform/default/quiche_platform_impl/quiche_flags_impl.h
172
168
  third_party/quiche/quiche/common/platform/default/quiche_platform_impl/quiche_flags_impl.cc
173
- third_party/quiche/quiche/common/platform/default/quiche_platform_impl/quiche_prefetch_impl.h
174
169
  third_party/quiche/quiche/common/platform/default/quiche_platform_impl/quiche_logging_impl.cc
175
170
  third_party/quiche/quiche/common/platform/default/quiche_platform_impl/quiche_logging_impl.h
176
- third_party/quiche/quiche/common/platform/default/quiche_platform_impl/quiche_mutex_impl.cc
177
- third_party/quiche/quiche/common/platform/default/quiche_platform_impl/quiche_mutex_impl.h
171
+ third_party/quiche/quiche/common/platform/api/quiche_mem_slice.cc
178
172
  third_party/quiche/quiche/common/platform/default/quiche_platform_impl/quiche_stack_trace_impl.cc
179
173
  third_party/quiche/quiche/common/platform/default/quiche_platform_impl/quiche_stack_trace_impl.h
180
174
  third_party/quiche/quiche/common/platform/default/quiche_platform_impl/quiche_iovec_impl.h
@@ -201,11 +195,15 @@ third_party/quiche/quiche/common/quiche_random.cc
201
195
  third_party/quiche/quiche/common/quiche_random.h
202
196
  third_party/quiche/quiche/common/quiche_simple_arena.cc
203
197
  third_party/quiche/quiche/common/quiche_simple_arena.h
198
+ third_party/quiche/quiche/common/quiche_socket_address.cc
199
+ third_party/quiche/quiche/common/quiche_socket_address.h
204
200
  third_party/quiche/quiche/common/quiche_text_utils.cc
205
201
  third_party/quiche/quiche/common/quiche_text_utils.h
206
202
  third_party/quiche/quiche/common/simple_buffer_allocator.cc
207
203
  third_party/quiche/quiche/common/structured_headers.h
208
204
  third_party/quiche/quiche/common/structured_headers.cc
205
+ third_party/quiche/quiche/common/vectorized_io_utils.h
206
+ third_party/quiche/quiche/common/vectorized_io_utils.cc
209
207
  third_party/quiche/quiche/http2/adapter/data_source.h
210
208
  third_party/quiche/quiche/http2/adapter/event_forwarder.cc
211
209
  third_party/quiche/quiche/http2/adapter/event_forwarder.h
@@ -228,8 +226,12 @@ third_party/quiche/quiche/http2/adapter/oghttp2_util.cc
228
226
  third_party/quiche/quiche/http2/adapter/oghttp2_util.h
229
227
  third_party/quiche/quiche/http2/adapter/window_manager.cc
230
228
  third_party/quiche/quiche/http2/adapter/window_manager.h
229
+ third_party/quiche/quiche/http2/core/http2_constants.cc
230
+ third_party/quiche/quiche/http2/core/http2_constants.h
231
231
  third_party/quiche/quiche/http2/core/http2_frame_decoder_adapter.cc
232
232
  third_party/quiche/quiche/http2/core/http2_frame_decoder_adapter.h
233
+ third_party/quiche/quiche/http2/core/http2_structures.cc
234
+ third_party/quiche/quiche/http2/core/http2_structures.h
233
235
  third_party/quiche/quiche/http2/core/http2_trace_logging.cc
234
236
  third_party/quiche/quiche/http2/core/http2_trace_logging.h
235
237
  third_party/quiche/quiche/http2/core/priority_write_scheduler.h
@@ -343,10 +345,6 @@ third_party/quiche/quiche/http2/hpack/varint/hpack_varint_decoder.cc
343
345
  third_party/quiche/quiche/http2/hpack/varint/hpack_varint_decoder.h
344
346
  third_party/quiche/quiche/http2/hpack/varint/hpack_varint_encoder.cc
345
347
  third_party/quiche/quiche/http2/hpack/varint/hpack_varint_encoder.h
346
- third_party/quiche/quiche/http2/http2_constants.cc
347
- third_party/quiche/quiche/http2/http2_constants.h
348
- third_party/quiche/quiche/http2/http2_structures.cc
349
- third_party/quiche/quiche/http2/http2_structures.h
350
348
  #third_party/quiche/quiche/http2/platform/api/http2_macros.h
351
349
  #third_party/quiche/quiche/quic/bindings/quic_libevent.h
352
350
  #third_party/quiche/quiche/quic/bindings/quic_libevent.cc
@@ -504,6 +502,8 @@ third_party/quiche/quiche/quic/core/frames/quic_goaway_frame.cc
504
502
  third_party/quiche/quiche/quic/core/frames/quic_goaway_frame.h
505
503
  third_party/quiche/quiche/quic/core/frames/quic_handshake_done_frame.cc
506
504
  third_party/quiche/quiche/quic/core/frames/quic_handshake_done_frame.h
505
+ third_party/quiche/quiche/quic/core/frames/quic_immediate_ack_frame.cc
506
+ third_party/quiche/quiche/quic/core/frames/quic_immediate_ack_frame.h
507
507
  third_party/quiche/quiche/quic/core/frames/quic_inlined_frame.h
508
508
  third_party/quiche/quiche/quic/core/frames/quic_max_streams_frame.cc
509
509
  third_party/quiche/quiche/quic/core/frames/quic_max_streams_frame.h
@@ -596,8 +596,6 @@ third_party/quiche/quiche/quic/core/packet_number_indexed_queue.h
596
596
  third_party/quiche/quiche/quic/core/proto/cached_network_parameters_proto.h
597
597
  third_party/quiche/quiche/quic/core/proto/crypto_server_config_proto.h
598
598
  third_party/quiche/quiche/quic/core/proto/source_address_token_proto.h
599
- third_party/quiche/quiche/quic/core/qpack/qpack_blocking_manager.cc
600
- third_party/quiche/quiche/quic/core/qpack/qpack_blocking_manager.h
601
599
  third_party/quiche/quiche/quic/core/qpack/qpack_decoded_headers_accumulator.cc
602
600
  third_party/quiche/quiche/quic/core/qpack/qpack_decoded_headers_accumulator.h
603
601
  third_party/quiche/quiche/quic/core/qpack/qpack_decoder.cc
@@ -634,6 +632,8 @@ third_party/quiche/quiche/quic/core/qpack/qpack_static_table.cc
634
632
  third_party/quiche/quiche/quic/core/qpack/qpack_static_table.h
635
633
  third_party/quiche/quiche/quic/core/qpack/qpack_stream_receiver.h
636
634
  third_party/quiche/quiche/quic/core/qpack/qpack_stream_sender_delegate.h
635
+ third_party/quiche/quiche/quic/core/qpack/new_qpack_blocking_manager.h
636
+ third_party/quiche/quiche/quic/core/qpack/new_qpack_blocking_manager.cc
637
637
  third_party/quiche/quiche/quic/core/qpack/value_splitting_header_list.cc
638
638
  third_party/quiche/quiche/quic/core/qpack/value_splitting_header_list.h
639
639
  third_party/quiche/quiche/quic/core/quic_ack_listener_interface.cc
@@ -807,12 +807,14 @@ third_party/quiche/quiche/quic/platform/api/quic_logging.h
807
807
  #third_party/quiche/quiche/quic/platform/api/quic_mem_slice_storage.cc
808
808
  #third_party/quiche/quiche/quic/platform/api/quic_mem_slice_storage.h
809
809
  third_party/quiche/quiche/quic/platform/api/quic_server_stats.h
810
- third_party/quiche/quiche/quic/platform/api/quic_socket_address.cc
811
- third_party/quiche/quiche/quic/platform/api/quic_socket_address.h
812
810
  third_party/quiche/quiche/quic/platform/api/quic_stack_trace.h
813
811
  third_party/quiche/quiche/quic/platform/api/quic_thread.h
814
812
  third_party/quiche/quiche/quic/tools/quic_simple_crypto_server_stream_helper.cc
815
813
  third_party/quiche/quiche/quic/tools/quic_simple_crypto_server_stream_helper.h
814
+ third_party/quiche/quiche/web_transport/web_transport_headers.cc
815
+ third_party/quiche/quiche/web_transport/web_transport_headers.h
816
+ third_party/quiche/quiche/web_transport/web_transport_priority_scheduler.cc
817
+ third_party/quiche/quiche/web_transport/web_transport_priority_scheduler.h
816
818
  )
817
819
 
818
820
  IF(APPLE OR WIN32)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fails-components/webtransport-transport-http3-quiche",
3
- "version": "1.1.4",
3
+ "version": "1.2.0",
4
4
  "description": "A component to add webtransport support (server and client) to node.js, transport using libquiche",
5
5
  "exports": {
6
6
  ".": {
@@ -50,13 +50,13 @@
50
50
  "@types/node": "^18.15.3",
51
51
  "eslint": "^9.3.0",
52
52
  "eslint-config-prettier": "^9.1.0",
53
- "eslint-config-standard": "^16.0.2",
54
- "eslint-plugin-import": "^2.25.2",
53
+ "eslint-plugin-import": "^2.31.0",
55
54
  "eslint-plugin-node": "^11.1.0",
56
55
  "eslint-plugin-prettier": "^5.1.3",
57
- "eslint-plugin-promise": "^4.3.1",
58
- "eslint-plugin-standard": "^4.1.0",
56
+ "eslint-plugin-promise": "^7.2.1",
59
57
  "prettier": "^3.2.5",
58
+ "prettier-linter-helpers": "^1.0.0",
59
+ "synckit": "^0.11.4",
60
60
  "typescript": "^4.8.4"
61
61
  },
62
62
  "binary": {
@@ -14,7 +14,7 @@
14
14
  #include <memory>
15
15
 
16
16
  #include "absl/strings/string_view.h"
17
- #include "quiche/spdy/core/spdy_protocol.h"
17
+ #include "quiche/http2/core/spdy_protocol.h"
18
18
 
19
19
  namespace quic
20
20
  {
@@ -162,7 +162,8 @@ namespace quic
162
162
  std::unique_ptr<ProofVerifier> proof_verifier,
163
163
  std::unique_ptr<SessionCache> session_cache,
164
164
  std::unique_ptr<QuicConnectionHelperInterface> helper,
165
- QuicConfig config) :
165
+ QuicConfig config,
166
+ const std::vector<std::string>& protocols) :
166
167
  initialized_(false),
167
168
  store_response_(false),
168
169
  latest_response_code_(-1),
@@ -188,7 +189,8 @@ namespace quic
188
189
  num_attempts_connect_(0),
189
190
  webtransport_server_support_inform_(false),
190
191
  connection_debug_visitor_(nullptr),
191
- priority_(HttpStreamPriority())
192
+ priority_(HttpStreamPriority()),
193
+ protocols_(protocols)
192
194
  {
193
195
 
194
196
  }
@@ -622,7 +624,16 @@ namespace quic
622
624
  headers[":path"] = path;
623
625
  headers[":method"] = "CONNECT";
624
626
  headers[":protocol"] = "webtransport";
625
-
627
+ if (protocols_.size() > 0) { // not very efficient
628
+ std::string protocols = "";
629
+ for (size_t i=0; i < protocols_.size(); i++) {
630
+ protocols += protocols_[i];
631
+ if (i!= protocols_.size()-1) {
632
+ protocols += ',';
633
+ }
634
+ }
635
+ headers["wt-available-protocols"] = protocols;
636
+ }
626
637
  SendMessageAsync(headers, "", /*fin=*/false);
627
638
  }
628
639
 
@@ -1141,6 +1152,7 @@ namespace quic
1141
1152
  {
1142
1153
  bool allowPooling = false;
1143
1154
  std::vector<WebTransportHash> serverCertificateHashes;
1155
+ std::vector<std::string> protocols;
1144
1156
  std::string privkey;
1145
1157
  QuicConfig cconfig;
1146
1158
  auto env = info.Env();
@@ -1240,6 +1252,26 @@ namespace quic
1240
1252
  cconfig.SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(streamFlowControlWindowSizeLimitWindow);
1241
1253
  cconfig.SetInitialMaxStreamDataBytesUnidirectionalToSend(streamFlowControlWindowSizeLimitWindow);
1242
1254
  }
1255
+ if (lobj.Has("protocols") && !(lobj).Get("protocols").IsEmpty()) {
1256
+ Napi::Value protocolValue = (lobj).Get("protocols");
1257
+ if (protocolValue.IsArray())
1258
+ {
1259
+ Napi::Array protocolArray = protocolValue.As<Napi::Array>();
1260
+ unsigned int length = protocolArray.Length();
1261
+
1262
+ for (unsigned int i = 0; i < length; i++)
1263
+ {
1264
+ Napi::Value protocolValue = protocolArray.Get(i);
1265
+ Napi::String protocolString = protocolValue.ToString();
1266
+ protocols.push_back(protocolString.Utf8Value());
1267
+ }
1268
+ }
1269
+ else
1270
+ {
1271
+ Napi::Error::New(env, "protocols is not an array").ThrowAsJavaScriptException();
1272
+ return;
1273
+ }
1274
+ }
1243
1275
  }
1244
1276
  }
1245
1277
 
@@ -1271,7 +1303,7 @@ namespace quic
1271
1303
 
1272
1304
  std::unique_ptr<Http3SessionCache> cache;
1273
1305
 
1274
- client_ = std::make_unique<Http3Client>(this, std::move(verifier), std::move(cache), std::move(helper), cconfig);
1306
+ client_ = std::make_unique<Http3Client>(this, std::move(verifier), std::move(cache), std::move(helper), cconfig, protocols);
1275
1307
  client_->SetUserAgentID("fails-components/webtransport");
1276
1308
 
1277
1309
  Ref(); // do not garbage collect
@@ -1380,10 +1412,10 @@ namespace quic
1380
1412
 
1381
1413
  void Http3ClientJS::processClientWebtransportSupport()
1382
1414
  {
1415
+ Http3Client *obj = getObj();
1383
1416
  Napi::HandleScope scope(Env());
1384
1417
  Napi::Object objVal = Value().Get("jsobj").As<Napi::Object>();
1385
1418
  Napi::Object retObj = Napi::Object::New(Env());
1386
-
1387
1419
  objVal.Get("onClientWebTransportSupport")
1388
1420
  .As<Napi::Function>()
1389
1421
  .Call(objVal, {retObj});
package/src/http3client.h CHANGED
@@ -121,7 +121,8 @@ namespace quic
121
121
  std::unique_ptr<ProofVerifier> proof_verifier,
122
122
  std::unique_ptr<SessionCache> session_cache,
123
123
  std::unique_ptr<QuicConnectionHelperInterface> helper,
124
- QuicConfig config);
124
+ QuicConfig config,
125
+ const std::vector<std::string>& protocols);
125
126
 
126
127
  ~Http3Client() override;
127
128
 
@@ -528,6 +529,7 @@ namespace quic
528
529
  bool connectionrecheck_;
529
530
 
530
531
  std::queue<std::function<void(QuicSpdyClientStream *)>> finish_stream_open_;
532
+ std::vector<std::string> protocols_;
531
533
  };
532
534
 
533
535
  } // namespace quic
@@ -34,7 +34,7 @@ namespace quic
34
34
  bool drop_response_body,
35
35
  bool enable_web_transport)
36
36
  : QuicSpdyClientSession(config, supported_versions, connection, server_id,
37
- crypto_config),
37
+ crypto_config, QuicPriorityType::kWebTransport),
38
38
  drop_response_body_(drop_response_body),
39
39
  enable_web_transport_(enable_web_transport) {}
40
40
 
@@ -494,6 +494,7 @@ namespace quic
494
494
  int status = -1;
495
495
  std::string path = "";
496
496
  Napi::Object lobj = info[0].ToObject();
497
+ std::string selectedProtocol = "";
497
498
  if (!lobj.IsEmpty())
498
499
  {
499
500
  if (lobj.Has("status") && !(lobj).Get("status").IsEmpty())
@@ -552,6 +553,11 @@ namespace quic
552
553
  NAPI_THROW_IF_FAILED(Env(), status, Reference<Napi::Value>());
553
554
  userDataValue = new Napi::Reference<Napi::Value>(Env(), ref);
554
555
  }
556
+ if (lobj.Has("selectedProtocol") && !(lobj).Get("selectedProtocol").IsUndefined())
557
+ {
558
+ Napi::Value selectedProtocolValue = (lobj).Get("selectedProtocol");
559
+ selectedProtocol = selectedProtocolValue.ToString().Utf8Value();
560
+ }
555
561
  }
556
562
  if (status != 200)
557
563
  {
@@ -563,6 +569,9 @@ namespace quic
563
569
  {
564
570
  std::unique_ptr<Http3ServerBackend::WebTransportResponse> response = std::make_unique<Http3ServerBackend::WebTransportResponse>();
565
571
  response->response_headers[":status"] = std::to_string(status);
572
+ if (selectedProtocol != "") {
573
+ response->response_headers["wt-protocol"] = selectedProtocol;
574
+ }
566
575
  Http3WTSession *wtsession = new Http3WTSession();
567
576
  wtsession->init(session);
568
577
  response->visitor =
@@ -33,7 +33,10 @@ namespace quic
33
33
  QuicCompressedCertsCache *compressed_certs_cache,
34
34
  Http3ServerBackend *http3_server_backend)
35
35
  : QuicServerSessionBase(config, supported_versions, connection, visitor,
36
- helper, crypto_config, compressed_certs_cache),
36
+ helper, crypto_config, compressed_certs_cache,
37
+ http3_server_backend->SupportsWebTransport()
38
+ ? QuicPriorityType::kWebTransport
39
+ : QuicPriorityType::kHttp),
37
40
  http3_server_backend_(http3_server_backend)
38
41
  {
39
42
  QUICHE_DCHECK(http3_server_backend_);
@@ -25,7 +25,7 @@
25
25
  #include "quiche/quic/platform/api/quic_flags.h"
26
26
  #include "quiche/quic/platform/api/quic_logging.h"
27
27
  #include "src/http3serversession.h"
28
- #include "quiche/spdy/core/spdy_protocol.h"
28
+ #include "quiche/http2/core/spdy_protocol.h"
29
29
 
30
30
  using quiche::HttpHeaderBlock;
31
31
 
@@ -45,7 +45,7 @@ namespace quic
45
45
  << stream->GetStreamId();
46
46
  stream->SetVisitor(
47
47
  std::make_unique<Http3WTStream::Visitor>(wtstream));
48
- session_->getJS()->processStream(true, true, static_cast<Http3WTStream *>(wtstream));
48
+ session_->getJS()->processStream(true, true, 0/*sendOrder*/, 0 /*sendGroup*/, static_cast<Http3WTStream *>(wtstream));
49
49
  stream->visitor()->OnCanRead();
50
50
  }
51
51
  }
@@ -67,7 +67,7 @@ namespace quic
67
67
  << "Http3WTSession received a unidirectional stream";
68
68
  stream->SetVisitor(
69
69
  std::make_unique<Http3WTStream::Visitor>(wtstream));
70
- session_->getJS()->processStream(true, false, static_cast<Http3WTStream *>(wtstream));
70
+ session_->getJS()->processStream(true, false, 0/*sendOrder*/, 0 /*sendGroup*/, static_cast<Http3WTStream *>(wtstream));
71
71
  stream->visitor()->OnCanRead();
72
72
  }
73
73
  }
@@ -104,22 +104,30 @@ namespace quic
104
104
  getJS()->processDatagramStats(session_->GetDatagramStats());
105
105
  }
106
106
 
107
+ size_t Http3WTSession::getMaxDatagramSizeInt()
108
+ {
109
+ if (!session_) return 0;
110
+ return session_->GetMaxDatagramSize();
111
+ }
112
+
107
113
  void Http3WTSession::TrySendingBidirectionalStreams()
108
114
  {
109
115
  if (!session_)
110
116
  return;
111
- while (ordBidiStreams > 0 &&
117
+ while (!ordBidiStreams.empty() &&
112
118
  session_->CanOpenNextOutgoingBidirectionalStream())
113
119
  {
114
120
  QUIC_DVLOG(1)
115
121
  << "Http3WTSessionVisitor opens a bidirectional stream";
116
122
  WebTransportStream *stream = session_->OpenOutgoingBidirectionalStream();
123
+ webtransport::StreamPriority prio = ordBidiStreams.front();
124
+ stream->SetPriority(prio);
117
125
  Http3WTStream *wtstream = new Http3WTStream(stream);
118
126
  stream->SetVisitor(
119
127
  std::make_unique<Http3WTStream::Visitor>(wtstream));
120
- getJS()->processStream(false, true, static_cast<Http3WTStream *>(wtstream));
128
+ getJS()->processStream(false, true, prio.send_order, prio.send_group_id, static_cast<Http3WTStream *>(wtstream));
121
129
  stream->visitor()->OnCanWrite();
122
- ordBidiStreams--;
130
+ ordBidiStreams.pop();
123
131
  }
124
132
  }
125
133
 
@@ -127,7 +135,7 @@ namespace quic
127
135
  {
128
136
  if (!session_->session_) return;
129
137
 
130
- session_->getJS()->processSessionReady();
138
+ session_->getJS()->processSessionReady(session_->session_->GetNegotiatedSubprotocol());
131
139
 
132
140
  if (session_->session_->CanOpenNextOutgoingBidirectionalStream())
133
141
  {
@@ -144,37 +152,43 @@ namespace quic
144
152
  if (!session_)
145
153
  return;
146
154
  // move to some where else?
147
- while (ordUnidiStreams > 0 &&
155
+ while (!ordUnidiStreams.empty() &&
148
156
  session_->CanOpenNextOutgoingUnidirectionalStream())
149
157
  {
150
158
  QUIC_DVLOG(1)
151
159
  << "Http3WTSessionVisitor opened a unidirectional stream";
152
160
  WebTransportStream *stream = session_->OpenOutgoingUnidirectionalStream();
161
+ webtransport::StreamPriority prio = ordUnidiStreams.front();
162
+ stream->SetPriority(prio);
153
163
  Http3WTStream *wtstream = new Http3WTStream(stream);
154
164
  stream->SetVisitor(
155
165
  std::make_unique<Http3WTStream::Visitor>(wtstream));
156
166
 
157
- getJS()->processStream(false, false, static_cast<Http3WTStream *>(wtstream));
167
+ getJS()->processStream(false, false, prio.send_order, prio.send_group_id, static_cast<Http3WTStream *>(wtstream));
158
168
  stream->visitor()->OnCanWrite();
159
- ordUnidiStreams--;
169
+ ordUnidiStreams.pop();
160
170
  }
161
171
  }
162
172
 
163
- void Http3WTSession::writeDatagramInt(char *buffer, size_t len, Napi::ObjectReference *bufferhandle)
173
+ webtransport::DatagramStatus Http3WTSession::writeDatagramInt(char *buffer, size_t len, Napi::ObjectReference *bufferhandle)
164
174
  {
165
175
  // printf("Datagram write %d %x %x\n", getpid(), this, session_ );
166
176
  if (!session_)
167
177
  {
168
178
  // printf("Datagram session gone %d %x %x\n", getpid(), this, session_);
169
- getJS()->processDatagramSend(bufferhandle);
170
- return;
179
+ bufferhandle->Unref(); // release the outgoing buffer
180
+ delete bufferhandle; // free the handle object
181
+ webtransport::DatagramStatus status(webtransport::DatagramStatusCode::kInternalError, "Session not present");
182
+ return status;
171
183
  }
172
- auto status = session_->SendOrQueueDatagram(absl::string_view(buffer, len));
184
+ webtransport::DatagramStatus status = session_->SendOrQueueDatagram(absl::string_view(buffer, len));
173
185
  // printf("Datagram status %d %d %s %x %x\n", getpid(), status.code, status.error_message.c_str(), this, session_);
174
- getJS()->processDatagramSend(bufferhandle);
186
+ bufferhandle->Unref(); // release the outgoing buffer
187
+ delete bufferhandle; // free the handle object
188
+ return status;
175
189
  }
176
190
 
177
- void Http3WTSessionJS::processStream(bool incom, bool bidi, Http3WTStream *stream)
191
+ void Http3WTSessionJS::processStream(bool incom, bool bidi, uint64_t sendOrder, uint64_t sendGroupId, Http3WTStream *stream)
178
192
  {
179
193
  Napi::HandleScope scope(Env());
180
194
  Http3Constructors *constr = Env().GetInstanceData<Http3Constructors>();
@@ -192,6 +206,8 @@ namespace quic
192
206
  retObj.Set("stream", strobj);
193
207
  retObj.Set("incoming", incom);
194
208
  retObj.Set("bidirectional", bidi);
209
+ retObj.Set("sendOrder", sendOrder);
210
+ retObj.Set("sendGroupId", sendGroupId);
195
211
 
196
212
  objVal.Get("onStream").As<Napi::Function>().Call(objVal, {retObj});
197
213
  }
@@ -263,13 +279,16 @@ namespace quic
263
279
  objVal.Get("onDatagramSend").As<Napi::Function>().Call(objVal, {retObj});
264
280
  }
265
281
 
266
- void Http3WTSessionJS::processSessionReady()
282
+ void Http3WTSessionJS::processSessionReady(std::optional<std::string> protocol)
267
283
  {
268
284
  Napi::HandleScope scope(Env());
269
285
  Napi::Object objVal = Value().Get("jsobj").As<Napi::Object>();
270
286
 
271
287
  Napi::Object retObj = Napi::Object::New(Env());
272
288
 
289
+ if (protocol.has_value()) {
290
+ retObj.Set("protocol", protocol.value());
291
+ }
273
292
  objVal.Get("onReady").As<Napi::Function>().Call(objVal, {retObj});
274
293
  }
275
294
 
@@ -16,6 +16,7 @@
16
16
  #include <atomic>
17
17
 
18
18
  #include <string>
19
+ #include <queue>
19
20
 
20
21
  #include "src/librarymain.h"
21
22
  #include "src/http3wtstreamvisitor.h"
@@ -37,7 +38,7 @@ namespace quic
37
38
 
38
39
  public:
39
40
  Http3WTSession()
40
- : ordBidiStreams(0), ordUnidiStreams(0), session_(nullptr), js_(nullptr)
41
+ : session_(nullptr), js_(nullptr)
41
42
  {
42
43
  }
43
44
 
@@ -83,11 +84,14 @@ namespace quic
83
84
  };
84
85
 
85
86
  bool
86
- tryOpenBidiStream(bool waitUntilAvailable)
87
+ tryOpenBidiStream(bool waitUntilAvailable, uint64_t sendGroupId, uint64_t sendOrder)
87
88
  {
88
89
  if (session_->CanOpenNextOutgoingBidirectionalStream()
89
90
  || waitUntilAvailable) {
90
- ordBidiStreams++;
91
+ webtransport::StreamPriority priority;
92
+ priority.send_group_id = sendGroupId;
93
+ priority.send_order = sendOrder;
94
+ ordBidiStreams.push(priority);
91
95
  TrySendingBidirectionalStreams();
92
96
  return true;
93
97
  } else {
@@ -95,11 +99,14 @@ namespace quic
95
99
  }
96
100
  }
97
101
 
98
- bool tryOpenUnidiStream(bool waitUntilAvailable)
102
+ bool tryOpenUnidiStream(bool waitUntilAvailable, uint64_t sendGroupId, uint64_t sendOrder)
99
103
  {
100
104
  if (session_->CanOpenNextOutgoingUnidirectionalStream()
101
105
  || waitUntilAvailable) {
102
- ordUnidiStreams++;
106
+ webtransport::StreamPriority priority;
107
+ priority.send_group_id = sendGroupId;
108
+ priority.send_order = sendOrder;
109
+ ordUnidiStreams.push(priority);
103
110
  TrySendingUnidirectionalStreams();
104
111
  return true;
105
112
  } else {
@@ -130,18 +137,21 @@ namespace quic
130
137
 
131
138
  void orderDatagramStatsInt();
132
139
 
140
+ size_t getMaxDatagramSizeInt();
141
+
133
142
  void closeInt(int code, std::string &reason)
134
143
  {
135
144
  if (session_)
136
145
  session_->CloseSession(code, reason);
137
146
  }
138
147
 
139
- void writeDatagramInt(char *buffer, size_t len, Napi::ObjectReference *bufferhandle);
148
+ webtransport::DatagramStatus writeDatagramInt(char *buffer, size_t len, Napi::ObjectReference *bufferhandle);
140
149
 
141
150
  WebTransportSession *session_;
142
151
  bool echo_stream_opened_ = false;
143
- uint32_t ordBidiStreams;
144
- uint32_t ordUnidiStreams;
152
+
153
+ std::queue<webtransport::StreamPriority> ordBidiStreams;
154
+ std::queue<webtransport::StreamPriority> ordUnidiStreams;
145
155
  };
146
156
 
147
157
  class Http3WTSessionJS : public Napi::ObjectWrap<Http3WTSessionJS>
@@ -167,6 +177,8 @@ namespace quic
167
177
  Napi::Value orderBidiStream(const Napi::CallbackInfo &info)
168
178
  {
169
179
  bool waitUntilAvailable = false;
180
+ uint64_t sendGroupId = 0;
181
+ uint64_t sendOrder = 0;
170
182
  if (!info[0].IsUndefined())
171
183
  {
172
184
  Napi::Object lobj = info[0].ToObject();
@@ -177,9 +189,20 @@ namespace quic
177
189
  Napi::Value waitUntilAvailableValue = (lobj).Get("waitUntilAvailable");
178
190
  waitUntilAvailable = waitUntilAvailableValue.As<Napi::Boolean>().Value();
179
191
  }
192
+ if (lobj.Has("sendGroup") && !(lobj).Get("sendGroup").IsEmpty()
193
+ && !(lobj).Get("sendGroup").IsNull()) {
194
+ Napi::Value sendGroupIdValue = (lobj).Get("sendGroup").ToObject().Get("_sendGroupId");
195
+ bool lossless;
196
+ sendGroupId = sendGroupIdValue.As<Napi::BigInt>().Uint64Value(&lossless);
197
+ }
198
+ if (lobj.Has("sendOrder") && !(lobj).Get("sendOrder").IsEmpty()) {
199
+ Napi::Value sendOrderValue = (lobj).Get("sendOrder");
200
+ bool lossless;
201
+ sendOrder = sendOrderValue.As<Napi::BigInt>().Uint64Value(&lossless);
202
+ }
180
203
  }
181
204
  }
182
- if (wtsession_->tryOpenBidiStream(waitUntilAvailable))
205
+ if (wtsession_->tryOpenBidiStream(waitUntilAvailable, sendGroupId, sendOrder))
183
206
  {
184
207
  return Napi::Value::From(Env(), true);
185
208
  }
@@ -192,6 +215,8 @@ namespace quic
192
215
  Napi::Value orderUnidiStream(const Napi::CallbackInfo &info)
193
216
  {
194
217
  bool waitUntilAvailable = false;
218
+ uint64_t sendGroupId = 0;
219
+ uint64_t sendOrder = 0;
195
220
  if (!info[0].IsUndefined())
196
221
  {
197
222
  Napi::Object lobj = info[0].ToObject();
@@ -202,9 +227,20 @@ namespace quic
202
227
  Napi::Value waitUntilAvailableValue = (lobj).Get("waitUntilAvailable");
203
228
  waitUntilAvailable = waitUntilAvailableValue.As<Napi::Boolean>().Value();
204
229
  }
230
+ if (lobj.Has("sendGroup") && !(lobj).Get("sendGroup").IsEmpty()
231
+ && !(lobj).Get("sendGroup").IsNull()) {
232
+ Napi::Value sendGroupIdValue = (lobj).Get("sendGroup").ToObject().Get("_sendGroupId");
233
+ bool lossless;
234
+ sendGroupId = sendGroupIdValue.As<Napi::BigInt>().Uint64Value(&lossless);
235
+ }
236
+ if (lobj.Has("sendOrder") && !(lobj).Get("sendOrder").IsEmpty()) {
237
+ Napi::Value sendOrderValue = (lobj).Get("sendOrder");
238
+ bool lossless;
239
+ sendOrder = sendOrderValue.As<Napi::BigInt>().Uint64Value(&lossless);
240
+ }
205
241
  }
206
242
  }
207
- if (wtsession_->tryOpenUnidiStream(waitUntilAvailable))
243
+ if (wtsession_->tryOpenUnidiStream(waitUntilAvailable, sendGroupId, sendOrder))
208
244
  {
209
245
  return Napi::Value::From(Env(), true);
210
246
  }
@@ -214,7 +250,7 @@ namespace quic
214
250
  }
215
251
  }
216
252
 
217
- void writeDatagram(const Napi::CallbackInfo &info)
253
+ Napi::Value writeDatagram(const Napi::CallbackInfo &info)
218
254
  {
219
255
  if (!info[0].IsUndefined())
220
256
  {
@@ -223,8 +259,27 @@ namespace quic
223
259
  *bufferhandle = Napi::Persistent(bufferlocal);
224
260
  char *buffer = bufferlocal.As<Napi::Buffer<char>>().Data();
225
261
  size_t len = bufferlocal.As<Napi::Buffer<char>>().Length();
226
- wtsession_->writeDatagramInt(buffer, len, bufferhandle);
262
+ webtransport::DatagramStatus status = wtsession_->writeDatagramInt(buffer, len, bufferhandle);
263
+
264
+ Napi::Object retObj = Napi::Object::New(Env());
265
+ switch (status.code) {
266
+ case webtransport::DatagramStatusCode::kBlocked:
267
+ retObj.Set("code", "blocked");
268
+ break;
269
+ case webtransport::DatagramStatusCode::kInternalError:
270
+ retObj.Set("code", "internalError");
271
+ break;
272
+ case webtransport::DatagramStatusCode::kSuccess:
273
+ retObj.Set("code", "success");
274
+ break;
275
+ case webtransport::DatagramStatusCode::kTooBig:
276
+ retObj.Set("code", "tooBig");
277
+ break;
278
+ };
279
+ retObj.Set("message", status.error_message);
280
+ return retObj;
227
281
  }
282
+ return Napi::Object::New(Env());
228
283
  }
229
284
 
230
285
  void notifySessionDraining(const Napi::CallbackInfo &info)
@@ -242,6 +297,11 @@ namespace quic
242
297
  wtsession_->orderDatagramStatsInt();
243
298
  }
244
299
 
300
+ Napi::Value getMaxDatagramSize(const Napi::CallbackInfo &info) {
301
+ size_t size = wtsession_->getMaxDatagramSizeInt();
302
+ return Napi::Value::From(Env(), size);
303
+ }
304
+
245
305
  void close(const Napi::CallbackInfo &info)
246
306
  {
247
307
  int code = 0;
@@ -284,6 +344,8 @@ namespace quic
284
344
  static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
285
345
  InstanceMethod<&Http3WTSessionJS::orderDatagramStats>("orderDatagramStats",
286
346
  static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
347
+ InstanceMethod<&Http3WTSessionJS::getMaxDatagramSize>("getMaxDatagramSize",
348
+ static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
287
349
  InstanceMethod<&Http3WTSessionJS::close>("close",
288
350
  static_cast<napi_property_attributes>(napi_writable | napi_configurable))});
289
351
  constr->session = Napi::Persistent(tplwt);
@@ -295,13 +357,13 @@ namespace quic
295
357
 
296
358
  static void freeData(Napi::Env env, void *data, std::string *hint);
297
359
 
298
- void processStream(bool incom, bool bidi, Http3WTStream *stream);
360
+ void processStream(bool incom, bool bidi, uint64_t sendOrder, uint64_t sendGroupId, Http3WTStream *stream);
299
361
  void processSessionStats(webtransport::SessionStats sessstats);
300
362
  void processDatagramStats(webtransport::DatagramStats datastats);
301
363
  void processGoawayReceived();
302
364
  void processDatagramSend(Napi::ObjectReference *bufferhandle);
303
365
  void processDatagramReceived(std::string *datagram);
304
- void processSessionReady();
366
+ void processSessionReady(std::optional<std::string> protocol);
305
367
  void processSessionClose(uint32_t errorcode, const std::string &error);
306
368
  };
307
369
 
@@ -179,6 +179,16 @@ namespace quic
179
179
  }
180
180
  }
181
181
 
182
+ void Http3WTStream::updateSendOrderAndGroupInt(uint64_t sendOrder, uint64_t sendGroupId) {
183
+ if (stream_)
184
+ {
185
+ webtransport::StreamPriority prio;
186
+ prio.send_group_id = sendGroupId;
187
+ prio.send_order = sendOrder;
188
+ stream_->SetPriority(prio);
189
+ }
190
+ }
191
+
182
192
 
183
193
  void Http3WTStreamJS::signalFinOnly() {
184
194
  Napi::HandleScope scope(Env());
@@ -127,6 +127,8 @@ namespace quic
127
127
  void stopSendingInt(unsigned int reason);
128
128
  void resetStreamInt(unsigned int reason);
129
129
 
130
+ void updateSendOrderAndGroupInt(uint64_t sendOrder, uint64_t sendGroupId);
131
+
130
132
  WebTransportStream *stream() { return stream_; }
131
133
 
132
134
  struct WChunks
@@ -281,6 +283,30 @@ namespace quic
281
283
  wtstream_->resetStreamInt(reason);
282
284
  }
283
285
 
286
+ void updateSendOrderAndGroup(const Napi::CallbackInfo &info)
287
+ {
288
+ if (!info[0].IsUndefined())
289
+ {
290
+ Napi::Object obj = info[0].ToObject();
291
+ uint64_t sendOrder = 0;
292
+ uint64_t sendGroupId = 0;
293
+
294
+ if (obj.Has("sendOrder") && !(obj).Get("sendOrder").IsEmpty())
295
+ {
296
+ Napi::Value sendOrderValue = (obj).Get("sendOrder");
297
+ bool approx;
298
+ sendOrder = sendOrderValue.As<Napi::BigInt>().Uint64Value(&approx);
299
+ }
300
+ if (obj.Has("sendGroupId") && !(obj).Get("sendGroupId").IsEmpty())
301
+ {
302
+ Napi::Value sendGroupIdValue = (obj).Get("sendGroupId");
303
+ bool approx;
304
+ sendGroupId = sendGroupIdValue.As<Napi::BigInt>().Uint64Value(&approx);
305
+ }
306
+ wtstream_->updateSendOrderAndGroupInt(sendOrder, sendGroupId);
307
+ }
308
+ }
309
+
284
310
  static void InitExports(Napi::Env env, Napi::Object exports, Http3Constructors *constr)
285
311
  {
286
312
  Napi::Function tplwtsv =
@@ -296,7 +322,10 @@ namespace quic
296
322
  InstanceMethod<&Http3WTStreamJS::startReading>("drainReads",
297
323
  static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
298
324
  InstanceMethod<&Http3WTStreamJS::stopReading>("stopReading",
299
- static_cast<napi_property_attributes>(napi_writable | napi_configurable))});
325
+ static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
326
+ InstanceMethod<&Http3WTStreamJS::updateSendOrderAndGroup>("updateSendOrderAndGroup",
327
+ static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
328
+ });
300
329
  constr->stream = Napi::Persistent(tplwtsv);
301
330
  exports.Set("Http3WTStreamVisitor", tplwtsv);
302
331
  }
@@ -1,8 +0,0 @@
1
- // from envoy so LICENSE.envoy applies
2
- // use default impl
3
- #ifndef QUICHE_MUTEX_IMPL
4
- #define QUICHE_MUTEX_IMPL
5
-
6
- #include "third_party/quiche/quiche/common/platform/default/quiche_platform_impl/quiche_mutex_impl.h"
7
-
8
- #endif
@@ -1,11 +0,0 @@
1
- // Copyright 2017 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
- #ifndef QUICHE_PREFETCH_IMPL_H_
6
- #define QUICHE_PREFETCH_IMPL_H_
7
-
8
- #include "third_party/quiche/quiche/common/platform/default/quiche_platform_impl/quiche_prefetch_impl.h"
9
-
10
-
11
- #endif