@fails-components/webtransport-transport-http3-quiche 1.0.0-rc.1

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.
Files changed (67) hide show
  1. package/CMakeLists.txt +978 -0
  2. package/LICENSE +39 -0
  3. package/LICENSE.chromium +27 -0
  4. package/LICENSE.envoy +207 -0
  5. package/build.js +315 -0
  6. package/lib/clientsocket.js +80 -0
  7. package/lib/index.js +47 -0
  8. package/lib/serversocket.js +80 -0
  9. package/lib/socket.js +118 -0
  10. package/lib/types.ts +15 -0
  11. package/lib/utils.js +12 -0
  12. package/package.json +68 -0
  13. package/platform/icufix/fakedata.cpp +8 -0
  14. package/platform/quiche/quic/core/io/socket_win.inc +3 -0
  15. package/platform/quiche_platform_impl/quiche_bug_tracker_impl.h +7 -0
  16. package/platform/quiche_platform_impl/quiche_client_stats_impl.h +7 -0
  17. package/platform/quiche_platform_impl/quiche_command_line_flags_impl.h +7 -0
  18. package/platform/quiche_platform_impl/quiche_containers_impl.h +7 -0
  19. package/platform/quiche_platform_impl/quiche_event_loop_impl.h +7 -0
  20. package/platform/quiche_platform_impl/quiche_export_impl.h +6 -0
  21. package/platform/quiche_platform_impl/quiche_flag_utils_impl.h +11 -0
  22. package/platform/quiche_platform_impl/quiche_flags_impl.h +8 -0
  23. package/platform/quiche_platform_impl/quiche_googleurl_impl.h +8 -0
  24. package/platform/quiche_platform_impl/quiche_iovec_impl.h +10 -0
  25. package/platform/quiche_platform_impl/quiche_logging_impl.h +21 -0
  26. package/platform/quiche_platform_impl/quiche_mem_slice_impl.h +2 -0
  27. package/platform/quiche_platform_impl/quiche_mutex_impl.h +8 -0
  28. package/platform/quiche_platform_impl/quiche_prefetch_impl.h +11 -0
  29. package/platform/quiche_platform_impl/quiche_reference_counted_impl.h +16 -0
  30. package/platform/quiche_platform_impl/quiche_server_stats_impl.h +7 -0
  31. package/platform/quiche_platform_impl/quiche_stack_trace_impl.h +12 -0
  32. package/platform/quiche_platform_impl/quiche_stream_buffer_allocator_impl.h +8 -0
  33. package/platform/quiche_platform_impl/quiche_testvalue_impl.h +1 -0
  34. package/platform/quiche_platform_impl/quiche_thread_local_impl.h +6 -0
  35. package/platform/quiche_platform_impl/quiche_time_utils_impl.h +13 -0
  36. package/platform/quiche_platform_impl/quiche_udp_socket_platform_impl.h +39 -0
  37. package/readme.md +20 -0
  38. package/src/http3backendresponse.cc +36 -0
  39. package/src/http3backendresponse.h +109 -0
  40. package/src/http3client.cc +1402 -0
  41. package/src/http3client.h +531 -0
  42. package/src/http3clientsession.cc +65 -0
  43. package/src/http3clientsession.h +58 -0
  44. package/src/http3clientstream.cc +52 -0
  45. package/src/http3clientstream.h +42 -0
  46. package/src/http3dispatcher.cc +62 -0
  47. package/src/http3dispatcher.h +57 -0
  48. package/src/http3server.cc +529 -0
  49. package/src/http3server.h +149 -0
  50. package/src/http3serverbackend.cc +104 -0
  51. package/src/http3serverbackend.h +96 -0
  52. package/src/http3serversession.cc +123 -0
  53. package/src/http3serversession.h +95 -0
  54. package/src/http3serverstream.cc +463 -0
  55. package/src/http3serverstream.h +114 -0
  56. package/src/http3sessioncache.cc +85 -0
  57. package/src/http3sessioncache.h +59 -0
  58. package/src/http3wtsessionvisitor.cc +312 -0
  59. package/src/http3wtsessionvisitor.h +257 -0
  60. package/src/http3wtstreamvisitor.cc +286 -0
  61. package/src/http3wtstreamvisitor.h +323 -0
  62. package/src/librarymain.cc +86 -0
  63. package/src/librarymain.h +42 -0
  64. package/src/napialarmfactory.cc +51 -0
  65. package/src/napialarmfactory.h +165 -0
  66. package/src/socketjswriter.cc +46 -0
  67. package/src/socketjswriter.h +100 -0
@@ -0,0 +1,286 @@
1
+ // Copyright (c) 2022 Marten Richter or other contributers (see commit). 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 "src/http3wtstreamvisitor.h"
6
+ #include "src/http3server.h"
7
+
8
+ namespace quic
9
+ {
10
+ void Http3WTStreamJS::init(Http3WTStream *wtstream)
11
+ {
12
+ wtstream_ = std::unique_ptr<Http3WTStream>(wtstream);
13
+ }
14
+
15
+ Http3WTStream::Visitor::~Visitor()
16
+ {
17
+ // printf("stream ~Visitor %d %x %x\n", getpid(), this, stream_);
18
+ while (stream_->chunks_.size() > 0)
19
+ {
20
+ auto cur = stream_->chunks_.front();
21
+
22
+ // now we have to inform the server TODO
23
+ stream_->getJS()->processStreamWrite(cur.bufferhandle, false);
24
+
25
+ stream_->chunks_.pop_front();
26
+ }
27
+
28
+ if (!stream_->stop_sending_received_)
29
+ {
30
+ stream_->getJS()->processStreamRecvSignal(0, NetworkTask::stopSending);
31
+ }
32
+ if (!stream_->stream_was_reset_)
33
+ {
34
+ stream_->getJS()->processStreamRecvSignal(0, NetworkTask::resetStream);
35
+ }
36
+ Http3WTStreamJS *strobj = stream_->getJS();
37
+ if (strobj)
38
+ {
39
+ stream_->stream_ = nullptr;
40
+ strobj->Unref();
41
+ }
42
+ else
43
+ {
44
+ stream_->stream_ = nullptr;
45
+ }
46
+ }
47
+
48
+ void Http3WTStream::Visitor::OnWriteSideInDataRecvdState() // called if everything is written to the client and it is closed
49
+ {
50
+ if (stream_->send_fin_)
51
+ stream_->getJS()->processStreamNetworkFinish(NetworkTask::streamFinal);
52
+ }
53
+
54
+ void Http3WTStream::Visitor::OnResetStreamReceived(WebTransportStreamError error)
55
+ {
56
+ // should this be removed
57
+ /*
58
+
59
+ // Send FIN in response to a stream reset. We want to test that we can
60
+ // operate one side of the stream cleanly while the other is reset, thus
61
+ // replying with a FIN rather than a RESET_STREAM is more appropriate here.
62
+ stream_->send_fin_ = true;
63
+ OnCanWrite();*/
64
+ stream_->stream_was_reset_ = true;
65
+ lasterror = error;
66
+ stream_->getJS()->processStreamRecvSignal(error, NetworkTask::resetStream); // may be move below
67
+ }
68
+
69
+ void Http3WTStream::Visitor::OnStopSendingReceived(WebTransportStreamError error)
70
+ {
71
+ stream_->stop_sending_received_ = true;
72
+ stream_->getJS()->processStreamRecvSignal(error, NetworkTask::stopSending); // may be move below
73
+ // we should also finallize the stream, so send a fin
74
+ stream_->send_fin_ = true;
75
+ OnCanWrite();
76
+ }
77
+
78
+ void Http3WTStream::cancelWrite(Napi::ObjectReference *handle)
79
+ {
80
+ getJS()->processStreamWrite(handle, false);
81
+ }
82
+
83
+ void Http3WTStream::doCanRead()
84
+ {
85
+ // if (pause_reading_) return ; // back pressure folks!
86
+
87
+ if (pause_reading_ && !drain_reads_)
88
+ {
89
+ can_read_pending_ = true;
90
+ return; // back pressure folks!
91
+ }
92
+ size_t readable = stream_->ReadableBytes();
93
+ bool read = false;
94
+ while (readable > 0)
95
+ {
96
+ Http3WTStreamJS::StreamReadBuffer rbuf(js_);
97
+ rbuf.getBuffer(readable);
98
+
99
+ size_t remainSize = rbuf.bufferSize();
100
+ uint32_t writepos = 0;
101
+
102
+ while (readable > 0 && remainSize > 0) {
103
+ size_t len = remainSize;
104
+ WebTransportStream::ReadResult result =
105
+ stream_->Read(absl::Span<char>(((char *)rbuf.bufferData()) + writepos, len));
106
+ QUIC_DVLOG(1) << "Attempted reading on WebTransport stream "
107
+ << ", bytes read: " << result.bytes_read;
108
+ writepos += result.bytes_read;
109
+ remainSize -= result.bytes_read;
110
+ readable = stream_->ReadableBytes();
111
+ if (result.fin) rbuf.setFin();
112
+ }
113
+ rbuf.commitBuffer(writepos, readable == 0);
114
+ }
115
+ }
116
+
117
+ void Http3WTStream::doCanWrite()
118
+ {
119
+ /* if (/* stop_sending_received_ || * pause_reading_)
120
+ {
121
+ return;
122
+ } */
123
+ if (fin_was_sent_)
124
+ return;
125
+
126
+ while (chunks_.size() > 0)
127
+ {
128
+ auto cur = chunks_.front();
129
+ bool success = stream_->Write(absl::string_view(cur.buffer, cur.len));
130
+ QUIC_DVLOG(1) << "Attempted writing on WebTransport bidirectional stream "
131
+ << ", success: " << (success ? "yes" : "no");
132
+ if (!success)
133
+ {
134
+ return;
135
+ }
136
+ // now we have to inform the server TODO
137
+ getJS()->processStreamWrite(cur.bufferhandle, true);
138
+
139
+ chunks_.pop_front();
140
+ }
141
+
142
+ if (send_fin_)
143
+ {
144
+ bool success = stream_->SendFin();
145
+ if (success)
146
+ fin_was_sent_ = true;
147
+ }
148
+ }
149
+
150
+ void Http3WTStream::stopSendingInt(unsigned int reason)
151
+ {
152
+ if (stream_)
153
+ {
154
+ stream_->SendStopSending(reason);
155
+ getJS()->processStreamNetworkFinish(NetworkTask::stopSending);
156
+ }
157
+ }
158
+
159
+ void Http3WTStream::resetStreamInt(unsigned int reason)
160
+ {
161
+ if (stream_)
162
+ {
163
+ stream_->ResetWithUserCode(reason);
164
+ getJS()->processStreamNetworkFinish(NetworkTask::resetStream);
165
+ }
166
+ }
167
+
168
+ void Http3WTStreamJS::processStreamNetworkFinish(NetworkTask task)
169
+ {
170
+ Napi::HandleScope scope(Env());
171
+
172
+ Napi::Object objVal = Value().Get("jsobj").As<Napi::Object>();
173
+
174
+ std::string nettaskstr;
175
+ switch (task)
176
+ {
177
+ case NetworkTask::resetStream:
178
+ {
179
+ nettaskstr = "resetStream";
180
+ }
181
+ break;
182
+ case NetworkTask::stopSending:
183
+ {
184
+ nettaskstr = "stopSending";
185
+ }
186
+ break;
187
+ case NetworkTask::streamFinal:
188
+ {
189
+ nettaskstr = "streamFinal";
190
+ }
191
+ break;
192
+ default:
193
+ return;
194
+ };
195
+
196
+ Napi::Object retObj = Napi::Object::New(Env());
197
+ retObj.Set("nettask", nettaskstr);
198
+
199
+ objVal.Get("onStreamNetworkFinish").As<Napi::Function>().Call(objVal, {retObj});
200
+ }
201
+
202
+ void Http3WTStreamJS::processStreamRecvSignal(WebTransportStreamError error_code, NetworkTask task)
203
+ {
204
+ Napi::HandleScope scope(Env());
205
+
206
+ Napi::Object objVal = Value().Get("jsobj").As<Napi::Object>();
207
+
208
+ std::string nettaskstr;
209
+ switch (task)
210
+ {
211
+ case NetworkTask::resetStream:
212
+ {
213
+ nettaskstr = "resetStream";
214
+ }
215
+ break;
216
+ case NetworkTask::stopSending:
217
+ {
218
+ nettaskstr = "stopSending";
219
+ }
220
+ break;
221
+ case NetworkTask::streamFinal:
222
+ {
223
+ nettaskstr = "streamFinal";
224
+ }
225
+ break;
226
+ default:
227
+ return;
228
+ };
229
+
230
+ Napi::Object retObj = Napi::Object::New(Env());
231
+ retObj.Set("purpose", "StreamRecvSignal");
232
+ retObj.Set("code", error_code);
233
+ retObj.Set("nettask", nettaskstr);
234
+
235
+ objVal.Get("onStreamRecvSignal").As<Napi::Function>().Call(objVal, {retObj});
236
+ }
237
+
238
+ void Http3WTStreamJS::processStreamWrite(Napi::ObjectReference *bufferhandle, bool success)
239
+ {
240
+ Napi::HandleScope scope(Env());
241
+
242
+ Napi::Object objVal = Value().Get("jsobj").As<Napi::Object>();
243
+ bufferhandle->Unref(); // release the outgoing buffer
244
+ delete bufferhandle; // free the handle object
245
+
246
+ Napi::Object retObj = Napi::Object::New(Env());
247
+ retObj.Set("success", success);
248
+
249
+ objVal.Get("onStreamWrite").As<Napi::Function>().Call(objVal, {retObj});
250
+ }
251
+
252
+ void Http3WTStreamJS::StreamReadBuffer::getBuffer(size_t reqsize) {
253
+ Napi::HandleScope scope(jsobj_->Env());
254
+ Napi::Object objVal = jsobj_->Value().Get("jsobj").As<Napi::Object>();
255
+
256
+ Napi::Object argObj = Napi::Object::New(jsobj_->Env());
257
+ argObj.Set("byteSize", reqsize);
258
+
259
+ Napi::Value bufferVal = objVal.Get("getReadBuffer").As<Napi::Function>().Call(objVal, {argObj});
260
+ bufferObj = Napi::Persistent(bufferVal.As<Napi::Object>());
261
+ Napi::Object locBuf = bufferVal.As<Napi::Object>();
262
+ fin = locBuf.Get("fin").As<Napi::Boolean>();
263
+ if (locBuf.Has("buffer")) {
264
+ Napi::Uint8Array buffer = locBuf.Get("buffer").As<Napi::Uint8Array>();
265
+ buffer_ = buffer.Data();
266
+ buffersize_ =buffer.ByteLength();
267
+ }
268
+ // buffer
269
+ // byob
270
+ // readBytes
271
+ // fin
272
+ }
273
+
274
+ void Http3WTStreamJS::StreamReadBuffer::commitBuffer(uint32_t readbytes, bool drained) {
275
+ Napi::HandleScope scope(jsobj_->Env());
276
+ Napi::Object objVal = jsobj_->Value().Get("jsobj").As<Napi::Object>();
277
+
278
+ bufferObj.Set("fin", fin);
279
+ bufferObj.Set("readBytes", Napi::Value::From(jsobj_->Env(),readbytes));
280
+ bufferObj.Set("drained", drained);
281
+ Napi::Value bufferVal = objVal.Get("commitReadBuffer").As<Napi::Function>().Call(objVal, {bufferObj.Value()});
282
+
283
+
284
+ }
285
+
286
+ }
@@ -0,0 +1,323 @@
1
+ // modifications
2
+ // Copyright (c) 2022 Marten Richter or other contributers (see commit). All rights reserved.
3
+ // Use of this source code is governed by a BSD-style license that can be
4
+ // found in the LICENSE file.
5
+
6
+ // original copyright used only portions, see LICENSE.chromium
7
+ // Copyright (c) 2021 The Chromium Authors. All rights reserved.
8
+ // Use of this source code is governed by a BSD-style license that can be
9
+ // found in the LICENSE file.
10
+
11
+ #ifndef HTTP3_WT_STREAM_VISITOR_H_
12
+ #define HTTP3_WT_STREAM_VISITOR_H_
13
+
14
+ #include <napi.h>
15
+
16
+ #include <string>
17
+
18
+ #include "src/librarymain.h"
19
+ #include "quiche/common/simple_buffer_allocator.h"
20
+ #include "quiche/quic/core/web_transport_interface.h"
21
+ #include "quiche/quic/platform/api/quic_logging.h"
22
+ #include "quiche/common/quiche_circular_deque.h"
23
+
24
+ namespace quic
25
+ {
26
+ class Http3EventLoop;
27
+
28
+ class Http3WTStreamJS;
29
+
30
+ class Http3WTStream
31
+ {
32
+ friend Http3WTStreamJS;
33
+
34
+ public:
35
+ Http3WTStream(WebTransportStream *stream) : stream_(stream),
36
+ js_(nullptr)
37
+ {
38
+ }
39
+
40
+ ~Http3WTStream(){/*printf("stream destruct %x\n", this);*/};
41
+
42
+ class Visitor : public WebTransportStreamVisitor
43
+ {
44
+ public:
45
+ Visitor(Http3WTStream *stream) : stream_(stream), lasterror(0) {}
46
+
47
+ ~Visitor();
48
+
49
+ void OnCanRead() override
50
+ {
51
+ stream_->doCanRead();
52
+ }
53
+
54
+ void OnCanWrite() override
55
+ {
56
+ stream_->doCanWrite();
57
+ }
58
+
59
+ void OnResetStreamReceived(WebTransportStreamError error) override;
60
+
61
+ void OnStopSendingReceived(WebTransportStreamError /*error*/) override;
62
+
63
+ void OnWriteSideInDataRecvdState() override;
64
+
65
+ protected:
66
+ Http3WTStream *stream_;
67
+ WebTransportStreamError lasterror;
68
+ };
69
+
70
+ void doCanRead();
71
+
72
+ void doCanWrite();
73
+
74
+ void doStopReading()
75
+ {
76
+ pause_reading_ = true;
77
+ }
78
+
79
+ void doDrainReads()
80
+ {
81
+ pause_reading_ = false;
82
+ drain_reads_ = true;
83
+ }
84
+
85
+ void tryWrite()
86
+ {
87
+ if (stream_ && stream_->CanWrite())
88
+ {
89
+ doCanWrite();
90
+ }
91
+ }
92
+
93
+ void tryRead()
94
+ {
95
+ pause_reading_ = false;
96
+ if (stream_ && ((stream_->ReadableBytes() > 0) || can_read_pending_))
97
+ {
98
+ can_read_pending_ = false;
99
+ doCanRead();
100
+ }
101
+ }
102
+
103
+ Http3WTStreamJS *getJS()
104
+ {
105
+ return js_;
106
+ }
107
+
108
+ void setJS(Http3WTStreamJS *js)
109
+ {
110
+ js_ = js;
111
+ };
112
+
113
+ bool gone()
114
+ {
115
+ return !stream_;
116
+ }
117
+
118
+ protected:
119
+ // internal functions called by js object
120
+
121
+ void streamFinalInt()
122
+ {
123
+ send_fin_ = true;
124
+ tryWrite();
125
+ }
126
+
127
+ void stopSendingInt(unsigned int reason);
128
+ void resetStreamInt(unsigned int reason);
129
+
130
+ WebTransportStream *stream() { return stream_; }
131
+
132
+ struct WChunks
133
+ {
134
+ char *buffer;
135
+ size_t len;
136
+ Napi::ObjectReference *bufferhandle;
137
+ };
138
+
139
+ void writeChunkInt(char *buffer, size_t len, Napi::ObjectReference *bufferhandle)
140
+ {
141
+ if (fin_was_sent_ || send_fin_)
142
+ {
143
+ cancelWrite(bufferhandle);
144
+ return;
145
+ }
146
+ if (!stream_)
147
+ {
148
+ cancelWrite(bufferhandle);
149
+ return;
150
+ }
151
+ WChunks cur;
152
+ cur.buffer = buffer;
153
+ cur.len = len;
154
+ cur.bufferhandle = bufferhandle;
155
+ chunks_.push_back(cur);
156
+ tryWrite();
157
+ }
158
+
159
+ void cancelWrite(Napi::ObjectReference *handle);
160
+
161
+ private:
162
+ Http3WTStreamJS *js_;
163
+
164
+ WebTransportStream *stream_;
165
+ bool send_fin_ = false;
166
+ bool fin_was_sent_ = false;
167
+ bool stop_sending_received_ = false;
168
+ bool pause_reading_ = false;
169
+ bool drain_reads_ = false;
170
+ bool can_read_pending_ = false;
171
+ bool stream_was_reset_ = false;
172
+ std::deque<WChunks> chunks_;
173
+ };
174
+
175
+ class Http3WTStreamJS : public Napi::ObjectWrap<Http3WTStreamJS>
176
+ {
177
+ friend Http3WTStream;
178
+ friend Http3WTStream::Visitor;
179
+
180
+ public:
181
+ class StreamReadBuffer
182
+ {
183
+ public:
184
+ StreamReadBuffer(Http3WTStreamJS *jsobj) : fin(false), jsobj_(jsobj),
185
+ buffer_(nullptr), buffersize_(0)
186
+ {
187
+ }
188
+
189
+ void getBuffer(size_t reqsize);
190
+
191
+
192
+
193
+ unsigned char * bufferData() { return buffer_;};
194
+ size_t bufferSize() { return buffersize_;};
195
+
196
+ bool hasBuffer() {return buffer_ != nullptr;}
197
+
198
+ void commitBuffer(uint32_t readbytes, bool drained);
199
+
200
+ void setFin() { fin = true;}
201
+
202
+
203
+ protected:
204
+ Napi::ObjectReference bufferObj;
205
+ unsigned char *buffer_;
206
+ size_t buffersize_;
207
+ // buffer?: Uint8Array
208
+ // byob?
209
+ bool fin;
210
+ Http3WTStreamJS *jsobj_; // unowned
211
+ };
212
+
213
+ public:
214
+
215
+ Http3WTStreamJS(const Napi::CallbackInfo &info) : Napi::ObjectWrap<Http3WTStreamJS>(info)
216
+ {
217
+ }
218
+
219
+ void init(Http3WTStream *wtstream);
220
+
221
+ // nan stuff
222
+
223
+ void startReading(const Napi::CallbackInfo &info)
224
+ {
225
+ wtstream_->tryRead();
226
+ }
227
+
228
+ void stopReading(const Napi::CallbackInfo &info)
229
+ {
230
+ wtstream_->doStopReading();
231
+ }
232
+
233
+ void drainReads(const Napi::CallbackInfo &info)
234
+ {
235
+ wtstream_->doDrainReads();
236
+ }
237
+
238
+ void writeChunk(const Napi::CallbackInfo &info)
239
+ {
240
+ // ok we have to get the buffer
241
+
242
+ const Napi::Object bufferlocal = info[0].ToObject();
243
+ Napi::ObjectReference *bufferhandle = new Napi::ObjectReference();
244
+ *bufferhandle = Napi::Persistent(bufferlocal);
245
+
246
+ char *buffer = bufferlocal.As<Napi::Buffer<char>>().Data();
247
+ size_t len = bufferlocal.As<Napi::Buffer<char>>().Length();
248
+
249
+ wtstream_->writeChunkInt(buffer, len, bufferhandle);
250
+ }
251
+
252
+ void streamFinal(const Napi::CallbackInfo &info)
253
+ {
254
+ wtstream_->streamFinalInt();
255
+ }
256
+
257
+ void stopSending(const Napi::CallbackInfo &info)
258
+ {
259
+ unsigned int reason = 0;
260
+
261
+ if (!info[0].IsUndefined())
262
+ {
263
+ Napi::Number reasonl = info[0].ToNumber();
264
+ reason = reasonl.Int32Value();
265
+ }
266
+
267
+ wtstream_->stopSendingInt(reason);
268
+ }
269
+
270
+ void resetStream(const Napi::CallbackInfo &info)
271
+ {
272
+ int code = 0;
273
+ unsigned int reason = 0;
274
+
275
+ if (!info[0].IsUndefined())
276
+ {
277
+ Napi::Number reasonl = info[0].ToNumber();
278
+ reason = reasonl.Int32Value();
279
+ }
280
+
281
+ wtstream_->resetStreamInt(reason);
282
+ }
283
+
284
+ static void InitExports(Napi::Env env, Napi::Object exports, Http3Constructors *constr)
285
+ {
286
+ Napi::Function tplwtsv =
287
+ DefineClass(env, "Http3WTStreamVisitor",
288
+ {InstanceMethod<&Http3WTStreamJS::writeChunk>("writeChunk",
289
+ static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
290
+ InstanceMethod<&Http3WTStreamJS::resetStream>("resetStream",
291
+ static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
292
+ InstanceMethod<&Http3WTStreamJS::stopSending>("stopSending", static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
293
+ InstanceMethod<&Http3WTStreamJS::streamFinal>("streamFinal", static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
294
+ InstanceMethod<&Http3WTStreamJS::startReading>("startReading",
295
+ static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
296
+ InstanceMethod<&Http3WTStreamJS::startReading>("drainReads",
297
+ static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
298
+ InstanceMethod<&Http3WTStreamJS::stopReading>("stopReading",
299
+ static_cast<napi_property_attributes>(napi_writable | napi_configurable))});
300
+ constr->stream = Napi::Persistent(tplwtsv);
301
+ exports.Set("Http3WTStreamVisitor", tplwtsv);
302
+ }
303
+
304
+ void setObj(Http3WTStream *wtstream)
305
+ {
306
+ wtstream_ = std::unique_ptr<Http3WTStream>(wtstream);
307
+ }
308
+
309
+ Http3WTStream *getObj()
310
+ {
311
+ return wtstream_.get();
312
+ }
313
+
314
+ protected:
315
+ std::unique_ptr<Http3WTStream> wtstream_;
316
+
317
+ void processStreamWrite(Napi::ObjectReference *bufferhandle, bool success);
318
+ void processStreamNetworkFinish(NetworkTask task);
319
+ void processStreamRecvSignal(WebTransportStreamError error_code, NetworkTask task);
320
+ };
321
+ }
322
+
323
+ #endif
@@ -0,0 +1,86 @@
1
+ // Copyright (c) 2022 Marten Richter or other contributers (see commit). 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
+ // portions taken from libquiche, original copyright, see LICENSE.chromium
6
+ // Copyright (c) The Chromium Authors. All rights reserved.
7
+ // Use of this source code is governed by a BSD-style license that can be
8
+ // found in the LICENSE file.
9
+
10
+ #include "src/librarymain.h"
11
+ #include "src/http3server.h"
12
+ #include "src/http3client.h"
13
+ #include "src/http3dispatcher.h"
14
+ #include "src/http3wtsessionvisitor.h"
15
+ #include "src/napialarmfactory.h"
16
+ #include "quiche/common/platform/api/quiche_command_line_flags.h"
17
+
18
+ #include "absl/log/initialize.h"
19
+ #include "absl/strings/string_view.h"
20
+
21
+ using namespace Napi;
22
+
23
+ namespace quic
24
+ {
25
+ bool hasSetLogging = false;
26
+
27
+ void quicheInit(const Napi::CallbackInfo &info)
28
+ {
29
+ std::vector<std::string> quiche_cmd_line;
30
+ quiche_cmd_line.push_back(std::string("webtransport.node"));
31
+ if (!info[0].IsUndefined() /*|| info[1].IsFunction()*/)
32
+ {
33
+ Napi::Object lobj = info[0].ToObject();
34
+ if (lobj.IsEmpty())
35
+ {
36
+ Napi::Error::New(info.Env(), "No callback obj for Http3Transport").ThrowAsJavaScriptException();
37
+ return;
38
+ }
39
+
40
+ quiche_cmd_line.push_back(std::string("-v"));
41
+ if (lobj.Has("quicheLogVerbose") && lobj.Get("quicheLogVerbose").IsFunction())
42
+ {
43
+ Napi::Value verboseValue = (lobj).Get("quicheLogVerbose");
44
+ quiche_cmd_line.push_back(verboseValue.ToString().Utf8Value());
45
+ }
46
+ else
47
+ {
48
+ quiche_cmd_line.push_back(std::string("-1"));
49
+ }
50
+ }
51
+ else
52
+ {
53
+ Napi::Error::New(info.Env(), "Callback not passed to Webtransport library internals").ThrowAsJavaScriptException();
54
+ return;
55
+ }
56
+ std::vector<const char *> quiche_cmd_line_char;
57
+ for (auto cur = quiche_cmd_line.begin(); cur != quiche_cmd_line.end(); cur++)
58
+ {
59
+ quiche_cmd_line_char.push_back((*cur).c_str());
60
+ }
61
+ if (!hasSetLogging)
62
+ {
63
+ quiche::QuicheParseCommandLineFlags("No use instruction.", quiche_cmd_line.size(), &(*quiche_cmd_line_char.begin()));
64
+ hasSetLogging = true;
65
+ }
66
+ }
67
+
68
+ Napi::Object Init(Napi::Env env, Napi::Object exports)
69
+ {
70
+ Http3Constructors *constr = new Http3Constructors();
71
+
72
+ Http3ServerJS::InitExports(env, exports);
73
+ Http3ClientJS::InitExports(env, exports);
74
+ Http3WTSessionJS::InitExports(env, exports, constr);
75
+ Http3WTStreamJS::InitExports(env, exports, constr);
76
+ NapiAlarmJS::InitExports(env, exports, constr);
77
+ Napi::Function qinitna = Function::New<quicheInit>(env);
78
+ constr->quicheInit = Napi::Persistent(qinitna);
79
+ exports.Set("quicheInit", qinitna);
80
+
81
+ env.SetInstanceData<Http3Constructors>(constr);
82
+ return exports;
83
+ }
84
+
85
+ NODE_API_MODULE(webtransport, Init)
86
+ }