@fails-components/webtransport 0.3.1 → 1.0.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.
- package/lib/client.js +81 -40
- package/lib/dom.ts +7 -5
- package/lib/http2/browser/browser.js +168 -0
- package/lib/http2/browser/browserparser.js +248 -0
- package/lib/http2/flowcontroller.js +371 -0
- package/lib/http2/node/capsuleparser.js +291 -0
- package/lib/http2/node/client.js +239 -0
- package/lib/http2/node/index.js +2 -0
- package/lib/http2/node/server.js +499 -0
- package/lib/http2/node/websocketparser.js +829 -0
- package/lib/http2/parserbase.js +139 -0
- package/lib/http2/parserbasehttp2.js +128 -0
- package/lib/http2/session.js +225 -0
- package/lib/http2/stream.js +354 -0
- package/lib/http2/websocketcommon.js +1 -0
- package/lib/{index.js → index.browser.js} +6 -10
- package/lib/index.node.js +27 -0
- package/lib/server.js +252 -69
- package/lib/session.js +31 -68
- package/lib/stream.js +103 -179
- package/lib/types.ts +174 -87
- package/lib/utils.js +2 -1
- package/lib/webstreams.browser.js +6 -0
- package/lib/webstreams.js +7 -0
- package/lib/webtransport.browser.js +284 -0
- package/lib/webtransport.node.js +137 -0
- package/lib/{webtransport.js → webtransportbase.js} +47 -41
- package/old_test/test.js +31 -29
- package/old_test/testsuite.js +1 -1
- package/package.json +18 -17
- package/readme.md +94 -30
- package/test/bidirectional-streams.spec.js +51 -9
- package/test/datagrams.spec.js +8 -2
- package/test/fixtures/known-bytes.js +29 -0
- package/test/fixtures/read-stream.js +1 -1
- package/test/fixtures/reader-value.js +1 -1
- package/test/fixtures/server.js +24 -10
- package/test/fixtures/webtransport.browser.js +20 -2
- package/test/fixtures/webtransport.js +1 -1
- package/test/index.js +33 -6
- package/test/pw-no-https-errors.json +5 -0
- package/test/session.spec.js +71 -52
- package/test/unidirectional-streams.spec.js +20 -4
- package/CMakeLists.txt +0 -991
- package/LICENSE.chromium +0 -27
- package/LICENSE.envoy +0 -207
- package/build.js +0 -313
- package/dist/lib/client.d.ts +0 -78
- package/dist/lib/client.d.ts.map +0 -1
- package/dist/lib/dom.d.ts +0 -87
- package/dist/lib/dom.d.ts.map +0 -1
- package/dist/lib/error.d.ts +0 -8
- package/dist/lib/error.d.ts.map +0 -1
- package/dist/lib/event-loop.d.ts +0 -33
- package/dist/lib/event-loop.d.ts.map +0 -1
- package/dist/lib/index.d.ts +0 -79
- package/dist/lib/index.d.ts.map +0 -1
- package/dist/lib/native.d.ts +0 -2
- package/dist/lib/native.d.ts.map +0 -1
- package/dist/lib/server.d.ts +0 -92
- package/dist/lib/server.d.ts.map +0 -1
- package/dist/lib/session.d.ts +0 -298
- package/dist/lib/session.d.ts.map +0 -1
- package/dist/lib/stream.d.ts +0 -135
- package/dist/lib/stream.d.ts.map +0 -1
- package/dist/lib/transport.d.ts +0 -34
- package/dist/lib/transport.d.ts.map +0 -1
- package/dist/lib/types.d.ts +0 -212
- package/dist/lib/types.d.ts.map +0 -1
- package/dist/lib/utils.d.ts +0 -11
- package/dist/lib/utils.d.ts.map +0 -1
- package/dist/lib/webtransport.d.ts +0 -47
- package/dist/lib/webtransport.d.ts.map +0 -1
- package/dist/test/bidirectional-streams.spec.d.ts +0 -5
- package/dist/test/bidirectional-streams.spec.d.ts.map +0 -1
- package/dist/test/datagrams.spec.d.ts +0 -5
- package/dist/test/datagrams.spec.d.ts.map +0 -1
- package/dist/test/event-loop.node.d.ts +0 -2
- package/dist/test/event-loop.node.d.ts.map +0 -1
- package/dist/test/fixtures/certificate.d.ts +0 -21
- package/dist/test/fixtures/certificate.d.ts.map +0 -1
- package/dist/test/fixtures/chai.d.ts +0 -2
- package/dist/test/fixtures/chai.d.ts.map +0 -1
- package/dist/test/fixtures/known-bytes.d.ts +0 -6
- package/dist/test/fixtures/known-bytes.d.ts.map +0 -1
- package/dist/test/fixtures/p-timeout.d.ts +0 -8
- package/dist/test/fixtures/p-timeout.d.ts.map +0 -1
- package/dist/test/fixtures/read-cert-hash.d.ts +0 -6
- package/dist/test/fixtures/read-cert-hash.d.ts.map +0 -1
- package/dist/test/fixtures/read-stream.d.ts +0 -19
- package/dist/test/fixtures/read-stream.d.ts.map +0 -1
- package/dist/test/fixtures/reader-value.d.ts +0 -22
- package/dist/test/fixtures/reader-value.d.ts.map +0 -1
- package/dist/test/fixtures/server.d.ts +0 -5
- package/dist/test/fixtures/server.d.ts.map +0 -1
- package/dist/test/fixtures/webtransport.browser.d.ts +0 -3
- package/dist/test/fixtures/webtransport.browser.d.ts.map +0 -1
- package/dist/test/fixtures/webtransport.d.ts +0 -3
- package/dist/test/fixtures/webtransport.d.ts.map +0 -1
- package/dist/test/fixtures/write-stream.d.ts +0 -10
- package/dist/test/fixtures/write-stream.d.ts.map +0 -1
- package/dist/test/index.d.ts +0 -2
- package/dist/test/index.d.ts.map +0 -1
- package/dist/test/session.spec.d.ts +0 -5
- package/dist/test/session.spec.d.ts.map +0 -1
- package/dist/test/unidirectional-streams.spec.d.ts +0 -2
- package/dist/test/unidirectional-streams.spec.d.ts.map +0 -1
- package/failslogolicensereadme.txt +0 -4
- package/lib/event-loop.js +0 -88
- package/lib/native.js +0 -28
- package/lib/transport.js +0 -82
- package/platform/icufix/fakedata.cpp +0 -8
- package/platform/quiche/quic/core/io/socket_win.inc +0 -3
- package/platform/quiche_platform_impl/quiche_bug_tracker_impl.h +0 -7
- package/platform/quiche_platform_impl/quiche_client_stats_impl.h +0 -7
- package/platform/quiche_platform_impl/quiche_command_line_flags_impl.h +0 -7
- package/platform/quiche_platform_impl/quiche_containers_impl.h +0 -7
- package/platform/quiche_platform_impl/quiche_event_loop_impl.h +0 -7
- package/platform/quiche_platform_impl/quiche_export_impl.h +0 -6
- package/platform/quiche_platform_impl/quiche_flag_utils_impl.h +0 -11
- package/platform/quiche_platform_impl/quiche_flags_impl.h +0 -8
- package/platform/quiche_platform_impl/quiche_iovec_impl.h +0 -10
- package/platform/quiche_platform_impl/quiche_logging_impl.h +0 -21
- package/platform/quiche_platform_impl/quiche_mem_slice_impl.h +0 -2
- package/platform/quiche_platform_impl/quiche_mutex_impl.h +0 -8
- package/platform/quiche_platform_impl/quiche_prefetch_impl.h +0 -11
- package/platform/quiche_platform_impl/quiche_reference_counted_impl.h +0 -16
- package/platform/quiche_platform_impl/quiche_server_stats_impl.h +0 -7
- package/platform/quiche_platform_impl/quiche_stack_trace_impl.h +0 -12
- package/platform/quiche_platform_impl/quiche_stream_buffer_allocator_impl.h +0 -8
- package/platform/quiche_platform_impl/quiche_testvalue_impl.h +0 -1
- package/platform/quiche_platform_impl/quiche_thread_local_impl.h +0 -6
- package/platform/quiche_platform_impl/quiche_time_utils_impl.h +0 -13
- package/platform/quiche_platform_impl/quiche_udp_socket_platform_impl.h +0 -39
- package/src/http3backendresponse.cc +0 -36
- package/src/http3backendresponse.h +0 -109
- package/src/http3client.cc +0 -1529
- package/src/http3client.h +0 -557
- package/src/http3clientsession.cc +0 -65
- package/src/http3clientsession.h +0 -60
- package/src/http3clientstream.cc +0 -52
- package/src/http3clientstream.h +0 -42
- package/src/http3dispatcher.cc +0 -62
- package/src/http3dispatcher.h +0 -57
- package/src/http3eventloop.cc +0 -1107
- package/src/http3eventloop.h +0 -316
- package/src/http3server.cc +0 -514
- package/src/http3server.h +0 -151
- package/src/http3serverbackend.cc +0 -105
- package/src/http3serverbackend.h +0 -98
- package/src/http3serversession.cc +0 -123
- package/src/http3serversession.h +0 -95
- package/src/http3serverstream.cc +0 -463
- package/src/http3serverstream.h +0 -114
- package/src/http3sessioncache.cc +0 -85
- package/src/http3sessioncache.h +0 -59
- package/src/http3wtsessionvisitor.cc +0 -46
- package/src/http3wtsessionvisitor.h +0 -397
- package/src/http3wtstreamvisitor.cc +0 -155
- package/src/http3wtstreamvisitor.h +0 -404
- package/test/event-loop.node.js +0 -24
- package/tsconfig.json +0 -39
package/src/http3server.cc
DELETED
|
@@ -1,514 +0,0 @@
|
|
|
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 "absl/cleanup/cleanup.h"
|
|
11
|
-
#include "src/http3server.h"
|
|
12
|
-
#include "src/http3dispatcher.h"
|
|
13
|
-
#include "src/http3wtsessionvisitor.h"
|
|
14
|
-
#include "src/http3eventloop.h"
|
|
15
|
-
#include "quiche/quic/core/quic_default_packet_writer.h"
|
|
16
|
-
#include "quiche/quic/core/quic_default_connection_helper.h"
|
|
17
|
-
#include "quiche/quic/core/quic_default_clock.h"
|
|
18
|
-
#include "quiche/quic/tools/quic_simple_crypto_server_stream_helper.h"
|
|
19
|
-
#include "quiche/quic/core/crypto/proof_source_x509.h"
|
|
20
|
-
#include "quiche/common/platform/api/quiche_reference_counted.h"
|
|
21
|
-
|
|
22
|
-
using namespace Napi;
|
|
23
|
-
|
|
24
|
-
namespace quic
|
|
25
|
-
{
|
|
26
|
-
|
|
27
|
-
const size_t kNumSessionsToCreatePerSocketEvent = 16;
|
|
28
|
-
|
|
29
|
-
Http3Server::Http3Server(Http3EventLoop *eventloop, std::string host, int port, std::unique_ptr<ProofSource> proof_source,
|
|
30
|
-
const char *secret, QuicConfig config)
|
|
31
|
-
: port_(port), host_(host), fd_(-1), overflow_supported_(false),
|
|
32
|
-
config_(config),
|
|
33
|
-
eventloop_(eventloop),
|
|
34
|
-
http3_server_backend_(eventloop),
|
|
35
|
-
packet_reader_(new QuicPacketReader()),
|
|
36
|
-
packets_dropped_(0),
|
|
37
|
-
version_manager_({ParsedQuicVersion::RFCv1()}),
|
|
38
|
-
crypto_config_(secret,
|
|
39
|
-
QuicRandom::GetInstance(),
|
|
40
|
-
std::move(proof_source),
|
|
41
|
-
KeyExchangeSource::Default()),
|
|
42
|
-
expected_server_connection_id_length_(kQuicDefaultConnectionIdLength),
|
|
43
|
-
js_(nullptr),
|
|
44
|
-
connection_id_generator_(expected_server_connection_id_length_)
|
|
45
|
-
{
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
Http3Server::~Http3Server()
|
|
49
|
-
{
|
|
50
|
-
// printf("server destruct %x\n", this);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
bool Http3Server::CreateUDPSocketAndListen(const QuicSocketAddress &address)
|
|
54
|
-
{
|
|
55
|
-
QuicUdpSocketApi socket_api;
|
|
56
|
-
fd_ = socket_api.Create(address.host().AddressFamilyToInt(),
|
|
57
|
-
/*receive_buffer_size =*/kDefaultSocketReceiveBuffer,
|
|
58
|
-
/*send_buffer_size =*/kDefaultSocketReceiveBuffer);
|
|
59
|
-
if (fd_ == kQuicInvalidSocketFd)
|
|
60
|
-
{
|
|
61
|
-
QUIC_LOG(ERROR) << "CreateSocket() failed: " << strerror(errno);
|
|
62
|
-
return false;
|
|
63
|
-
}
|
|
64
|
-
auto closer = absl::MakeCleanup([this]
|
|
65
|
-
{ { QuicUdpSocketApi api;api.Destroy(fd_); } });
|
|
66
|
-
|
|
67
|
-
overflow_supported_ = socket_api.EnableDroppedPacketCount(fd_);
|
|
68
|
-
socket_api.EnableReceiveTimestamp(fd_);
|
|
69
|
-
|
|
70
|
-
if (!socket_api.Bind(fd_, address))
|
|
71
|
-
{
|
|
72
|
-
QUIC_LOG(ERROR) << "Bind failed: " << strerror(errno) << " for " << address.ToString() << "\n";
|
|
73
|
-
return false;
|
|
74
|
-
}
|
|
75
|
-
QUIC_LOG(INFO) << "Listening on " << address.ToString() << "\n";
|
|
76
|
-
port_ = address.port();
|
|
77
|
-
if (port_ == 0)
|
|
78
|
-
{
|
|
79
|
-
QuicSocketAddress address;
|
|
80
|
-
if (address.FromSocket(fd_) != 0)
|
|
81
|
-
{
|
|
82
|
-
QUIC_LOG(ERROR) << "Unable to get self address. Error: "
|
|
83
|
-
<< strerror(errno) << "\n";
|
|
84
|
-
}
|
|
85
|
-
port_ = address.port();
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const int kEpollFlags = kSocketEventReadable | kSocketEventWritable;
|
|
89
|
-
|
|
90
|
-
if (eventloop_->getQuicEventLoop()->RegisterSocket(fd_, kEpollFlags, this))
|
|
91
|
-
{
|
|
92
|
-
// eventloop_->SetNonblocking(fd_); // eventuelly should be part of register socket.
|
|
93
|
-
dispatcher_.reset(CreateQuicDispatcher());
|
|
94
|
-
dispatcher_->InitializeWithWriter(new QuicDefaultPacketWriter(fd_));
|
|
95
|
-
std::move(closer).Cancel();
|
|
96
|
-
|
|
97
|
-
eventloop_->informServerStatus(this, NetListening, getStatusDetails());
|
|
98
|
-
return true;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
eventloop_->informServerStatus(this, NetError, getStatusDetails());
|
|
102
|
-
return false;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
bool Http3Server::stopServerInt()
|
|
106
|
-
{
|
|
107
|
-
|
|
108
|
-
eventloop_->getQuicEventLoop()->UnregisterSocket(fd_);
|
|
109
|
-
|
|
110
|
-
// if (!silent_close_) {
|
|
111
|
-
// Before we shut down the epoll server, give all active sessions a chance
|
|
112
|
-
// to notify clients that they're closing.
|
|
113
|
-
dispatcher_->Shutdown();
|
|
114
|
-
//}
|
|
115
|
-
|
|
116
|
-
QuicUdpSocketApi api;
|
|
117
|
-
api.Destroy(fd_);
|
|
118
|
-
fd_ = -1;
|
|
119
|
-
eventloop_->informServerStatus(this, NetClose, getStatusDetails());
|
|
120
|
-
eventloop_->informUnref(this->getJS()); // must be done on the other thread...
|
|
121
|
-
return true;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
QuicDispatcher *Http3Server::CreateQuicDispatcher()
|
|
125
|
-
{
|
|
126
|
-
http3_server_backend_.setServer(this);
|
|
127
|
-
return new Http3Dispatcher(
|
|
128
|
-
&config_, &crypto_config_, &version_manager_,
|
|
129
|
-
std::unique_ptr<QuicDefaultConnectionHelper>(new QuicDefaultConnectionHelper()),
|
|
130
|
-
std::unique_ptr<QuicCryptoServerStreamBase::Helper>(
|
|
131
|
-
new QuicSimpleCryptoServerStreamHelper()),
|
|
132
|
-
std::unique_ptr<QuicAlarmFactory>(
|
|
133
|
-
eventloop_->getQuicEventLoop()->CreateAlarmFactory()),
|
|
134
|
-
&http3_server_backend_, expected_server_connection_id_length_, connection_id_generator_);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
Http3ServerJS::Http3ServerJS(const Napi::CallbackInfo &info) : Napi::ObjectWrap<Http3ServerJS>(info)
|
|
138
|
-
{
|
|
139
|
-
int port = 443;
|
|
140
|
-
std::string secret;
|
|
141
|
-
std::string cert;
|
|
142
|
-
std::string privkey;
|
|
143
|
-
std::string host("localhost");
|
|
144
|
-
|
|
145
|
-
QuicConfig sconfig;
|
|
146
|
-
if (!info[0].IsUndefined())
|
|
147
|
-
{
|
|
148
|
-
Napi::Object lobj = info[0].ToObject();
|
|
149
|
-
if (!lobj.IsEmpty())
|
|
150
|
-
{
|
|
151
|
-
if (lobj.Has("port") && !(lobj).Get("port").IsEmpty())
|
|
152
|
-
{
|
|
153
|
-
Napi::Value portValue = (lobj).Get("port");
|
|
154
|
-
port = portValue.As<Napi::Number>().Int32Value();
|
|
155
|
-
}
|
|
156
|
-
if (lobj.Has("secret") && !(lobj).Get("secret").IsEmpty())
|
|
157
|
-
{
|
|
158
|
-
Napi::Value secretValue = (lobj).Get("secret");
|
|
159
|
-
secret = secretValue.ToString().Utf8Value();
|
|
160
|
-
}
|
|
161
|
-
else
|
|
162
|
-
{
|
|
163
|
-
Napi::Error::New(Env(), "No secret set for Http3Server").ThrowAsJavaScriptException();
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
if (lobj.Has("host") && !(lobj).Get("host").IsEmpty())
|
|
167
|
-
{
|
|
168
|
-
Napi::Value hostValue = (lobj).Get("host");
|
|
169
|
-
host = hostValue.ToString().Utf8Value();
|
|
170
|
-
}
|
|
171
|
-
if (lobj.Has("cert") && !(lobj).Get("cert").IsEmpty())
|
|
172
|
-
{
|
|
173
|
-
Napi::Value certValue = (lobj).Get("cert");
|
|
174
|
-
cert = certValue.ToString().Utf8Value();
|
|
175
|
-
}
|
|
176
|
-
else
|
|
177
|
-
{
|
|
178
|
-
Napi::Error::New(Env(), "No cert set for Http3Server").ThrowAsJavaScriptException();
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
if (lobj.Has("privKey") && !(lobj).Get("privKey").IsEmpty())
|
|
182
|
-
{
|
|
183
|
-
Napi::Value keyValue = (lobj).Get("privKey");
|
|
184
|
-
privkey = keyValue.ToString().Utf8Value();
|
|
185
|
-
}
|
|
186
|
-
else
|
|
187
|
-
{
|
|
188
|
-
Napi::Error::New(Env(), "No privKey set for Http3Server").ThrowAsJavaScriptException();
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
191
|
-
if (lobj.Has("maxConnections") && !(lobj).Get("maxConnections").IsEmpty())
|
|
192
|
-
{
|
|
193
|
-
Napi::Value maxconnValue = (lobj).Get("maxConnections");
|
|
194
|
-
int maxconn = maxconnValue.As<Napi::Number>().Int32Value();
|
|
195
|
-
sconfig.SetMaxBidirectionalStreamsToSend(maxconn);
|
|
196
|
-
sconfig.SetMaxUnidirectionalStreamsToSend(maxconn);
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
if (lobj.Has("initialStreamFlowControlWindow") && !(lobj).Get("initialStreamFlowControlWindow").IsEmpty())
|
|
200
|
-
{
|
|
201
|
-
Napi::Value initialStreamFlowControlWindowValue = (lobj).Get("initialStreamFlowControlWindow");
|
|
202
|
-
int initialStreamFlowControlWindow = initialStreamFlowControlWindowValue.As<Napi::Number>().Int32Value();
|
|
203
|
-
sconfig.SetInitialStreamFlowControlWindowToSend(initialStreamFlowControlWindow);
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
if (lobj.Has("initialSessionFlowControlWindow") && !(lobj).Get("initialSessionFlowControlWindow").IsEmpty())
|
|
207
|
-
{
|
|
208
|
-
Napi::Value initialSessionFlowControlWindowValue = (lobj).Get("initialSessionFlowControlWindow");
|
|
209
|
-
int initialSessionFlowControlWindow = initialSessionFlowControlWindowValue.As<Napi::Number>().Int32Value();
|
|
210
|
-
sconfig.SetInitialSessionFlowControlWindowToSend(initialSessionFlowControlWindow);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
// Callback *callback, int port, std::unique_ptr<ProofSource> proof_source, const char *secret
|
|
214
|
-
|
|
215
|
-
std::stringstream certstream(cert, std::ios_base::in);
|
|
216
|
-
quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain(new ProofSource::Chain(CertificateView::LoadPemFromStream(&certstream)));
|
|
217
|
-
|
|
218
|
-
std::stringstream privkeystream(privkey, std::ios_base::in);
|
|
219
|
-
|
|
220
|
-
auto certprivkey = CertificatePrivateKey::LoadPemFromStream(&privkeystream);
|
|
221
|
-
if (certprivkey == nullptr)
|
|
222
|
-
{
|
|
223
|
-
Napi::Error::New(Env(), "LoadPemFromStream privKey failed for Http3Server").ThrowAsJavaScriptException();
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
std::unique_ptr<ProofSourceX509> proofsource = ProofSourceX509::Create(chain, std::move(*certprivkey));
|
|
228
|
-
if (proofsource == nullptr)
|
|
229
|
-
{
|
|
230
|
-
Napi::Error::New(Env(), "LoadPemFromStream cert failed for Http3Server").ThrowAsJavaScriptException();
|
|
231
|
-
return;
|
|
232
|
-
}
|
|
233
|
-
Http3EventLoop *eventloop = nullptr;
|
|
234
|
-
if (!info[1].IsUndefined())
|
|
235
|
-
{
|
|
236
|
-
Napi::Object lobj = info[1].ToObject();
|
|
237
|
-
eventloop = dynamic_cast<Http3EventLoop *>(Napi::ObjectWrap<Http3EventLoop>::Unwrap(lobj));
|
|
238
|
-
}
|
|
239
|
-
else
|
|
240
|
-
{
|
|
241
|
-
Napi::Error::New(Env(), "No eventloop arguments passed to Http3Server").ThrowAsJavaScriptException();
|
|
242
|
-
return;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
server_ = std::make_unique<Http3Server>(eventloop, host, port, std::move(proofsource), secret.c_str(), sconfig);
|
|
246
|
-
|
|
247
|
-
server_->setJS(this);
|
|
248
|
-
return;
|
|
249
|
-
}
|
|
250
|
-
else
|
|
251
|
-
{
|
|
252
|
-
Napi::Error::New(Env(), "No arguments passed to Http3Server").ThrowAsJavaScriptException();
|
|
253
|
-
return;
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
bool Http3Server::startServerInt()
|
|
258
|
-
{
|
|
259
|
-
|
|
260
|
-
QuicIpAddress ipaddress;
|
|
261
|
-
|
|
262
|
-
ipaddress.FromString(host_);
|
|
263
|
-
if (!ipaddress.IsIPv4() && !ipaddress.IsIPv6())
|
|
264
|
-
{
|
|
265
|
-
struct addrinfo hints, *servinfo, *p;
|
|
266
|
-
int rv;
|
|
267
|
-
|
|
268
|
-
memset(&hints, 0, sizeof hints);
|
|
269
|
-
hints.ai_family = AF_UNSPEC; // use AF_INET6 to force IPv6
|
|
270
|
-
hints.ai_socktype = SOCK_STREAM;
|
|
271
|
-
|
|
272
|
-
if ((rv = getaddrinfo(host_.c_str(), "http", &hints, &servinfo)) != 0)
|
|
273
|
-
{
|
|
274
|
-
printf("getaddrinfo: %s\n", gai_strerror(rv));
|
|
275
|
-
return false;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
for (p = servinfo; p != nullptr; p = p->ai_next)
|
|
279
|
-
{
|
|
280
|
-
if (p->ai_family == AF_INET)
|
|
281
|
-
{
|
|
282
|
-
struct sockaddr_in *h = (struct sockaddr_in *)p->ai_addr;
|
|
283
|
-
|
|
284
|
-
ipaddress = QuicIpAddress(h->sin_addr);
|
|
285
|
-
// printf("ssi mark address %s %d\n",inet_ntoa( h->sin_addr),h->sin_family);
|
|
286
|
-
break;
|
|
287
|
-
}
|
|
288
|
-
else if (p->ai_family == AF_INET6)
|
|
289
|
-
{
|
|
290
|
-
struct sockaddr_in6 *h = (struct sockaddr_in6 *)p->ai_addr;
|
|
291
|
-
ipaddress = QuicIpAddress(h->sin6_addr);
|
|
292
|
-
// printf("ssi mark address %d\n",h->sin6_family);
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
freeaddrinfo(servinfo);
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
const uint32_t kInitialSessionFlowControlWindow = 1 * 1024 * 1024; // 1 MB
|
|
300
|
-
const uint32_t kInitialStreamFlowControlWindow = 64 * 1024; // 64 KB
|
|
301
|
-
if (config_.GetInitialStreamFlowControlWindowToSend() ==
|
|
302
|
-
kDefaultFlowControlSendWindow)
|
|
303
|
-
{
|
|
304
|
-
config_.SetInitialStreamFlowControlWindowToSend(
|
|
305
|
-
kInitialStreamFlowControlWindow);
|
|
306
|
-
}
|
|
307
|
-
if (config_.GetInitialSessionFlowControlWindowToSend() ==
|
|
308
|
-
kDefaultFlowControlSendWindow)
|
|
309
|
-
{
|
|
310
|
-
config_.SetInitialSessionFlowControlWindowToSend(
|
|
311
|
-
kInitialSessionFlowControlWindow);
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
QuicSocketAddress address(ipaddress, port_);
|
|
315
|
-
if (!CreateUDPSocketAndListen(address))
|
|
316
|
-
return false; // move to this class
|
|
317
|
-
return true;
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
void Http3Server::OnSocketEvent(QuicEventLoop *event_loop, QuicUdpSocketFd fd,
|
|
321
|
-
QuicSocketEventMask events)
|
|
322
|
-
{
|
|
323
|
-
QUICHE_DCHECK_EQ(fd, fd_);
|
|
324
|
-
|
|
325
|
-
if (events & kSocketEventReadable)
|
|
326
|
-
{
|
|
327
|
-
QUIC_DVLOG(1) << "kSocketEventReadable";
|
|
328
|
-
|
|
329
|
-
dispatcher_->ProcessBufferedChlos(kNumSessionsToCreatePerSocketEvent);
|
|
330
|
-
|
|
331
|
-
bool more_to_read = true;
|
|
332
|
-
while (more_to_read)
|
|
333
|
-
{
|
|
334
|
-
more_to_read = packet_reader_->ReadAndDispatchPackets(
|
|
335
|
-
fd_, port_, *QuicDefaultClock::Get(), dispatcher_.get(),
|
|
336
|
-
overflow_supported_ ? &packets_dropped_ : nullptr);
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
if (dispatcher_->HasChlosBuffered())
|
|
340
|
-
{
|
|
341
|
-
// Register EPOLLIN event to consume buffered CHLO(s).
|
|
342
|
-
bool success =
|
|
343
|
-
event_loop->ArtificiallyNotifyEvent(fd, kSocketEventReadable);
|
|
344
|
-
QUICHE_DCHECK(success);
|
|
345
|
-
} else if (!event_loop->SupportsEdgeTriggered())
|
|
346
|
-
{
|
|
347
|
-
bool success = event_loop->RearmSocket(fd, kSocketEventReadable);
|
|
348
|
-
QUICHE_DCHECK(success);
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
if (events & kSocketEventWritable)
|
|
352
|
-
{
|
|
353
|
-
dispatcher_->OnCanWrite();
|
|
354
|
-
if (!event_loop->SupportsEdgeTriggered() &&
|
|
355
|
-
dispatcher_->HasPendingWrites())
|
|
356
|
-
{
|
|
357
|
-
bool success = event_loop->RearmSocket(fd, kSocketEventWritable);
|
|
358
|
-
QUICHE_DCHECK(success);
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
void Http3ServerJS::startServer(const Napi::CallbackInfo &info)
|
|
364
|
-
{
|
|
365
|
-
Http3Server *obj = getObj();
|
|
366
|
-
// got the object we can now start the server
|
|
367
|
-
Ref(); // do not garbage collect
|
|
368
|
-
std::function<void()> task = [obj]()
|
|
369
|
-
{ if (!obj->startServerInt())
|
|
370
|
-
{
|
|
371
|
-
printf("startServerInt failed for Http3Server\n");
|
|
372
|
-
} };
|
|
373
|
-
obj->eventloop_->Schedule(task);
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
void Http3ServerJS::stopServer(const Napi::CallbackInfo &info)
|
|
377
|
-
{
|
|
378
|
-
Http3Server *obj = getObj();
|
|
379
|
-
// got the object we can now start the server
|
|
380
|
-
std::function<void()> task = [obj]()
|
|
381
|
-
{ if (!obj->stopServerInt())
|
|
382
|
-
{
|
|
383
|
-
printf("stopServerInt failed for Http3Server\n");
|
|
384
|
-
} };
|
|
385
|
-
obj->eventloop_->Schedule(task);
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
void Http3ServerJS::addPath(const Napi::CallbackInfo &info)
|
|
389
|
-
{
|
|
390
|
-
Http3Server *obj = getObj();
|
|
391
|
-
|
|
392
|
-
if (!info[0].IsUndefined())
|
|
393
|
-
{
|
|
394
|
-
|
|
395
|
-
std::string lpath(info[0].ToString().Utf8Value());
|
|
396
|
-
std::function<void()> task = [obj, lpath]()
|
|
397
|
-
{
|
|
398
|
-
obj->http3_server_backend_.addPath(lpath);
|
|
399
|
-
};
|
|
400
|
-
obj->eventloop_->Schedule(task);
|
|
401
|
-
}
|
|
402
|
-
else
|
|
403
|
-
return Napi::Error::New(Env(), "No path set for addPath").ThrowAsJavaScriptException();
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
void Http3ServerJS::finishSessionRequest(const Napi::CallbackInfo &info)
|
|
407
|
-
{
|
|
408
|
-
Http3Server *obj = getObj();
|
|
409
|
-
|
|
410
|
-
if (!info[0].IsUndefined())
|
|
411
|
-
{
|
|
412
|
-
// needs two properties
|
|
413
|
-
int status = -1;
|
|
414
|
-
std::string path = "";
|
|
415
|
-
Napi::Object lobj = info[0].ToObject();
|
|
416
|
-
if (!lobj.IsEmpty())
|
|
417
|
-
{
|
|
418
|
-
if (lobj.Has("status") && !(lobj).Get("status").IsEmpty())
|
|
419
|
-
{
|
|
420
|
-
Napi::Value statusValue = (lobj).Get("status");
|
|
421
|
-
status = statusValue.As<Napi::Number>().Int32Value();
|
|
422
|
-
}
|
|
423
|
-
else
|
|
424
|
-
return Napi::Error::New(Env(), "No status code passed for finishSessionRequest").ThrowAsJavaScriptException();
|
|
425
|
-
|
|
426
|
-
if (lobj.Has("path") && !(lobj).Get("path").IsEmpty())
|
|
427
|
-
{
|
|
428
|
-
Napi::Value pathValue = (lobj).Get("path");
|
|
429
|
-
path = pathValue.ToString().Utf8Value();
|
|
430
|
-
}
|
|
431
|
-
else
|
|
432
|
-
return Napi::Error::New(Env(), "No status code passed for finishSessionRequest").ThrowAsJavaScriptException();
|
|
433
|
-
WebTransportSession *session = nullptr;
|
|
434
|
-
if (lobj.Has("session") && !(lobj).Get("session").IsEmpty())
|
|
435
|
-
{
|
|
436
|
-
Napi::Value sessionVal = (lobj).Get("session");
|
|
437
|
-
if (!sessionVal.IsExternal())
|
|
438
|
-
return Napi::Error::New(Env(), "Session is not external for finishSessionRequest").ThrowAsJavaScriptException();
|
|
439
|
-
Napi::External<WebTransportSession> sessionExt = sessionVal.As<Napi::External<WebTransportSession>>();
|
|
440
|
-
session = sessionExt.Data();
|
|
441
|
-
}
|
|
442
|
-
else
|
|
443
|
-
return Napi::Error::New(Env(), "No session passed for finishSessionRequest").ThrowAsJavaScriptException();
|
|
444
|
-
|
|
445
|
-
if (lobj.Has("promise") && !(lobj).Get("promise").IsEmpty())
|
|
446
|
-
{
|
|
447
|
-
Napi::Value promiseVal = (lobj).Get("promise");
|
|
448
|
-
if (!promiseVal.IsExternal())
|
|
449
|
-
return Napi::Error::New(Env(), "Promise is not external for finishSessionRequest").ThrowAsJavaScriptException();
|
|
450
|
-
Napi::External<Http3ServerBackend::WebTransportRespPromisePtr> promise = promiseVal.As<Napi::External<Http3ServerBackend::WebTransportRespPromisePtr>>();
|
|
451
|
-
|
|
452
|
-
Http3ServerBackend::WebTransportRespPromisePtr *prom = promise.Data();
|
|
453
|
-
Napi::Reference<Napi::Value> *headerValue = nullptr;
|
|
454
|
-
if (status == 200)
|
|
455
|
-
{
|
|
456
|
-
|
|
457
|
-
if (lobj.Has("header") && !(lobj).Get("header").IsEmpty())
|
|
458
|
-
{
|
|
459
|
-
napi_ref ref;
|
|
460
|
-
napi_status status = napi_create_reference(Env(), lobj.Get("header"), 1, &ref);
|
|
461
|
-
NAPI_THROW_IF_FAILED(Env(), status, Reference<Napi::Value>());
|
|
462
|
-
headerValue = new Napi::Reference<Napi::Value>(Env(), ref);
|
|
463
|
-
}
|
|
464
|
-
else
|
|
465
|
-
return Napi::Error::New(Env(), "No status code passed for finishSessionRequest").ThrowAsJavaScriptException();
|
|
466
|
-
}
|
|
467
|
-
std::function<void()> task = [status, prom, path, headerValue, session, obj, this]()
|
|
468
|
-
{
|
|
469
|
-
if (status != 200)
|
|
470
|
-
{
|
|
471
|
-
std::unique_ptr<Http3ServerBackend::WebTransportResponse> response = std::make_unique<Http3ServerBackend::WebTransportResponse>();
|
|
472
|
-
response->response_headers[":status"] = std::to_string(status);
|
|
473
|
-
(*prom)->resolve(std::move(response));
|
|
474
|
-
}
|
|
475
|
-
else
|
|
476
|
-
{
|
|
477
|
-
std::unique_ptr<Http3ServerBackend::WebTransportResponse> response = std::make_unique<Http3ServerBackend::WebTransportResponse>();
|
|
478
|
-
response->response_headers[":status"] = std::to_string(status);
|
|
479
|
-
Http3WTSession *wtsession = new Http3WTSession();
|
|
480
|
-
wtsession->init(session, obj->eventloop_);
|
|
481
|
-
response->visitor =
|
|
482
|
-
std::make_unique<Http3WTSession::Visitor>(wtsession);
|
|
483
|
-
obj->eventloop_->informAboutNewSession(obj, static_cast<Http3WTSession *>(wtsession), path, headerValue);
|
|
484
|
-
(*prom)->resolve(std::move(response));
|
|
485
|
-
}
|
|
486
|
-
};
|
|
487
|
-
obj->eventloop_->Schedule(task);
|
|
488
|
-
}
|
|
489
|
-
else
|
|
490
|
-
return Napi::Error::New(Env(), "No promise passed for finishSessionRequest").ThrowAsJavaScriptException();
|
|
491
|
-
}
|
|
492
|
-
else
|
|
493
|
-
return Napi::Error::New(Env(), "No object passed for finishSessionRequest").ThrowAsJavaScriptException();
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
void Http3ServerJS::setJSRequestHandler(const Napi::CallbackInfo &info)
|
|
498
|
-
{
|
|
499
|
-
Http3Server *obj = getObj();
|
|
500
|
-
|
|
501
|
-
if (!info[0].IsUndefined())
|
|
502
|
-
{
|
|
503
|
-
|
|
504
|
-
bool hashandler = info[0].ToBoolean();
|
|
505
|
-
std::function<void()> task = [obj, hashandler]()
|
|
506
|
-
{
|
|
507
|
-
obj->http3_server_backend_.setJSHandler(hashandler);
|
|
508
|
-
};
|
|
509
|
-
obj->eventloop_->Schedule(task);
|
|
510
|
-
}
|
|
511
|
-
else
|
|
512
|
-
return Napi::Error::New(Env(), "No bool set for setJSRequestHandler").ThrowAsJavaScriptException();
|
|
513
|
-
}
|
|
514
|
-
}
|
package/src/http3server.h
DELETED
|
@@ -1,151 +0,0 @@
|
|
|
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
|
-
#ifndef WT_HTTP3_SERVER_H
|
|
11
|
-
#define WT_HTTP3_SERVER_H
|
|
12
|
-
|
|
13
|
-
#include <memory>
|
|
14
|
-
|
|
15
|
-
#include <napi.h>
|
|
16
|
-
#include <uv.h>
|
|
17
|
-
|
|
18
|
-
#include "src/http3serverbackend.h"
|
|
19
|
-
#include "src/http3eventloop.h"
|
|
20
|
-
#include "quiche/quic/core/crypto/quic_crypto_server_config.h"
|
|
21
|
-
#include "quiche/quic/core/deterministic_connection_id_generator.h"
|
|
22
|
-
#include "quiche/quic/core/quic_udp_socket.h"
|
|
23
|
-
#include "quiche/quic/core/quic_dispatcher.h"
|
|
24
|
-
#include "quiche/quic/core/quic_packet_reader.h"
|
|
25
|
-
#include "quiche/quic/platform/api/quic_socket_address.h"
|
|
26
|
-
|
|
27
|
-
using namespace Napi;
|
|
28
|
-
|
|
29
|
-
namespace quic
|
|
30
|
-
{
|
|
31
|
-
|
|
32
|
-
class Http3EventLoop;
|
|
33
|
-
|
|
34
|
-
class Http3Server;
|
|
35
|
-
|
|
36
|
-
class Http3ServerJS : public Napi::ObjectWrap<Http3ServerJS>,
|
|
37
|
-
public LifetimeHelper
|
|
38
|
-
{
|
|
39
|
-
public:
|
|
40
|
-
Http3ServerJS(const Napi::CallbackInfo &info);
|
|
41
|
-
|
|
42
|
-
Http3Server *getObj()
|
|
43
|
-
{
|
|
44
|
-
return server_.get();
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
void startServer(const Napi::CallbackInfo &info);
|
|
48
|
-
|
|
49
|
-
void stopServer(const Napi::CallbackInfo &info);
|
|
50
|
-
|
|
51
|
-
void addPath(const Napi::CallbackInfo &info);
|
|
52
|
-
|
|
53
|
-
void finishSessionRequest(const Napi::CallbackInfo &info);
|
|
54
|
-
|
|
55
|
-
void setJSRequestHandler(const Napi::CallbackInfo &info);
|
|
56
|
-
|
|
57
|
-
static void InitExports(Napi::Env env, Napi::Object exports)
|
|
58
|
-
{
|
|
59
|
-
Napi::Function tplsrv = DefineClass(env, "Http3WebTransportServer",
|
|
60
|
-
{InstanceMethod<&Http3ServerJS::startServer>("startServer",
|
|
61
|
-
static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
|
|
62
|
-
InstanceMethod<&Http3ServerJS::stopServer>("stopServer",
|
|
63
|
-
static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
|
|
64
|
-
InstanceMethod<&Http3ServerJS::addPath>("addPath",
|
|
65
|
-
static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
|
|
66
|
-
InstanceMethod<&Http3ServerJS::finishSessionRequest>("finishSessionRequest",
|
|
67
|
-
static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
|
|
68
|
-
InstanceMethod<&Http3ServerJS::setJSRequestHandler>("setJSRequestHandler",
|
|
69
|
-
static_cast<napi_property_attributes>(napi_writable | napi_configurable))});
|
|
70
|
-
exports.Set("Http3WebTransportServer", tplsrv);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
void doUnref() override
|
|
74
|
-
{
|
|
75
|
-
Unref();
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
protected:
|
|
79
|
-
std::unique_ptr<Http3Server> server_;
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
class Http3Server : public QuicSocketEventListener
|
|
83
|
-
{
|
|
84
|
-
friend class Http3ServerJS;
|
|
85
|
-
|
|
86
|
-
public:
|
|
87
|
-
Http3Server(Http3EventLoop *eventloop, std::string host, int port,
|
|
88
|
-
std::unique_ptr<ProofSource> proof_source,
|
|
89
|
-
const char *secret,
|
|
90
|
-
QuicConfig config);
|
|
91
|
-
|
|
92
|
-
Http3Server(const Http3Server &) = delete;
|
|
93
|
-
Http3Server &operator=(const Http3Server &) = delete;
|
|
94
|
-
|
|
95
|
-
~Http3Server();
|
|
96
|
-
|
|
97
|
-
bool CreateUDPSocketAndListen(const QuicSocketAddress &address);
|
|
98
|
-
|
|
99
|
-
// From QuicSocketEventListener
|
|
100
|
-
void OnSocketEvent(QuicEventLoop *event_loop, QuicUdpSocketFd fd,
|
|
101
|
-
QuicSocketEventMask events) override;
|
|
102
|
-
|
|
103
|
-
Http3ServerJS *getJS() { return js_; };
|
|
104
|
-
|
|
105
|
-
ServerStatusDetails *getStatusDetails()
|
|
106
|
-
{
|
|
107
|
-
ServerStatusDetails *details = new ServerStatusDetails();
|
|
108
|
-
details->host = host_;
|
|
109
|
-
details->port = port_;
|
|
110
|
-
return details;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
private:
|
|
114
|
-
bool startServerInt();
|
|
115
|
-
bool stopServerInt();
|
|
116
|
-
|
|
117
|
-
void setJS(Http3ServerJS *js) { js_ = js; };
|
|
118
|
-
Http3ServerJS *js_;
|
|
119
|
-
|
|
120
|
-
QuicUdpSocketFd fd_;
|
|
121
|
-
bool overflow_supported_;
|
|
122
|
-
int port_;
|
|
123
|
-
std::string host_;
|
|
124
|
-
QuicPacketCount packets_dropped_;
|
|
125
|
-
std::unique_ptr<QuicPacketReader> packet_reader_;
|
|
126
|
-
std::unique_ptr<QuicDispatcher> dispatcher_;
|
|
127
|
-
// config_ contains non-crypto parameters that are negotiated in the crypto
|
|
128
|
-
// handshake.
|
|
129
|
-
QuicConfig config_;
|
|
130
|
-
// crypto_config_ contains crypto parameters for the handshake.
|
|
131
|
-
QuicCryptoServerConfig crypto_config_;
|
|
132
|
-
// crypto_config_options_ contains crypto parameters for the handshake.
|
|
133
|
-
QuicCryptoServerConfig::ConfigOptions crypto_config_options_;
|
|
134
|
-
|
|
135
|
-
// Used to generate current supported versions.
|
|
136
|
-
QuicVersionManager version_manager_;
|
|
137
|
-
|
|
138
|
-
Http3ServerBackend http3_server_backend_; // unowned.
|
|
139
|
-
|
|
140
|
-
// Connection ID length expected to be read on incoming IETF short headers.
|
|
141
|
-
uint8_t expected_server_connection_id_length_;
|
|
142
|
-
|
|
143
|
-
QuicDispatcher *CreateQuicDispatcher();
|
|
144
|
-
|
|
145
|
-
Http3EventLoop *eventloop_;
|
|
146
|
-
DeterministicConnectionIdGenerator connection_id_generator_;
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
#endif
|