@fails-components/webtransport 0.0.5 → 0.0.7
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 +11 -8
- package/package.json +2 -1
- package/platform/quiche_platform_impl/quic_udp_socket_winsock.cc +605 -523
- package/src/http3client.cc +115 -80
- package/src/http3client.h +26 -20
- package/src/http3dispatcher.cc +5 -3
- package/src/http3dispatcher.h +2 -1
- package/src/http3server.cc +47 -10
- package/src/http3server.h +2 -1
- package/src/http3serverbackend.h +1 -1
- package/src/http3wtsessionvisitor.cc +1 -1
- package/src/http3wtsessionvisitor.h +1 -1
- package/src/webtransport.js +1 -0
- package/test/testsuite.js +8 -8
- package/platform/quiche_platform_impl/quic_flags_impl.h +0 -9
package/src/http3client.cc
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
#include "absl/strings/match.h"
|
|
21
21
|
#include "absl/strings/string_view.h"
|
|
22
|
+
#include "absl/cleanup/cleanup.h"
|
|
22
23
|
#include "openssl/x509.h"
|
|
23
24
|
#include "quiche/quic/core/crypto/proof_verifier.h"
|
|
24
25
|
#include "quiche/quic/core/http/quic_spdy_client_stream.h"
|
|
@@ -44,6 +45,42 @@ using spdy::Http2HeaderBlock;
|
|
|
44
45
|
namespace quic
|
|
45
46
|
{
|
|
46
47
|
|
|
48
|
+
// taken from libquiche
|
|
49
|
+
namespace
|
|
50
|
+
{
|
|
51
|
+
|
|
52
|
+
// For level-triggered I/O, we need to manually rearm the kSocketEventWritable
|
|
53
|
+
// listener whenever the socket gets blocked.
|
|
54
|
+
class LevelTriggeredPacketWriter : public QuicDefaultPacketWriter
|
|
55
|
+
{
|
|
56
|
+
public:
|
|
57
|
+
explicit LevelTriggeredPacketWriter(int fd, QuicEventLoop *event_loop)
|
|
58
|
+
: QuicDefaultPacketWriter(fd), event_loop_(event_loop)
|
|
59
|
+
{
|
|
60
|
+
QUICHE_DCHECK(!event_loop->SupportsEdgeTriggered());
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
WriteResult WritePacket(const char *buffer, size_t buf_len,
|
|
64
|
+
const QuicIpAddress &self_address,
|
|
65
|
+
const QuicSocketAddress &peer_address,
|
|
66
|
+
PerPacketOptions *options) override
|
|
67
|
+
{
|
|
68
|
+
WriteResult result = QuicDefaultPacketWriter::WritePacket(
|
|
69
|
+
buffer, buf_len, self_address, peer_address, options);
|
|
70
|
+
if (IsWriteBlockedStatus(result.status))
|
|
71
|
+
{
|
|
72
|
+
bool success = event_loop_->RearmSocket(fd(), kSocketEventWritable);
|
|
73
|
+
QUICHE_DCHECK(success);
|
|
74
|
+
}
|
|
75
|
+
return result;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
private:
|
|
79
|
+
QuicEventLoop *event_loop_;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
} // namespace
|
|
83
|
+
|
|
47
84
|
// taken from chromium to behave like the browser
|
|
48
85
|
// A version of WebTransportFingerprintProofVerifier that enforces
|
|
49
86
|
// Chromium-specific policies.
|
|
@@ -168,7 +205,7 @@ namespace quic
|
|
|
168
205
|
|
|
169
206
|
void Http3Client::SendRequest(const std::string &uri)
|
|
170
207
|
{
|
|
171
|
-
spdy::
|
|
208
|
+
spdy::Http2HeaderBlock headers;
|
|
172
209
|
if (!PopulateHeaderBlockFromUrl(uri, &headers))
|
|
173
210
|
{
|
|
174
211
|
return;
|
|
@@ -178,7 +215,7 @@ namespace quic
|
|
|
178
215
|
|
|
179
216
|
void Http3Client::SendRequestAndRstTogether(const std::string &uri)
|
|
180
217
|
{
|
|
181
|
-
spdy::
|
|
218
|
+
spdy::Http2HeaderBlock headers;
|
|
182
219
|
if (!PopulateHeaderBlockFromUrl(uri, &headers))
|
|
183
220
|
{
|
|
184
221
|
return;
|
|
@@ -194,7 +231,7 @@ namespace quic
|
|
|
194
231
|
}
|
|
195
232
|
|
|
196
233
|
void Http3Client::GetOrCreateStreamAndSendRequest(
|
|
197
|
-
const spdy::
|
|
234
|
+
const spdy::Http2HeaderBlock *headers, absl::string_view body, bool fin)
|
|
198
235
|
{
|
|
199
236
|
if (headers)
|
|
200
237
|
{
|
|
@@ -206,8 +243,8 @@ namespace quic
|
|
|
206
243
|
if (rv == QUIC_PENDING)
|
|
207
244
|
{
|
|
208
245
|
// May need to retry request if asynchronous rendezvous fails.
|
|
209
|
-
std::unique_ptr<spdy::
|
|
210
|
-
new spdy::
|
|
246
|
+
std::unique_ptr<spdy::Http2HeaderBlock> new_headers(
|
|
247
|
+
new spdy::Http2HeaderBlock(headers->Clone()));
|
|
211
248
|
push_promise_data_to_resend_ = std::make_unique<Http3ClientDataToResend>(
|
|
212
249
|
std::move(new_headers), body, fin, this);
|
|
213
250
|
return;
|
|
@@ -218,7 +255,7 @@ namespace quic
|
|
|
218
255
|
bool hasheaders = false;
|
|
219
256
|
if (headers != nullptr)
|
|
220
257
|
{
|
|
221
|
-
spdy_headers = std::make_shared<spdy::
|
|
258
|
+
spdy_headers = std::make_shared<spdy::Http2HeaderBlock>(headers->Clone());
|
|
222
259
|
hasheaders = true;
|
|
223
260
|
}
|
|
224
261
|
|
|
@@ -252,13 +289,13 @@ namespace quic
|
|
|
252
289
|
});
|
|
253
290
|
}
|
|
254
291
|
|
|
255
|
-
void Http3Client::SendMessageAsync(const spdy::
|
|
292
|
+
void Http3Client::SendMessageAsync(const spdy::Http2HeaderBlock &headers,
|
|
256
293
|
absl::string_view body)
|
|
257
294
|
{
|
|
258
295
|
return SendMessageAsync(headers, body, /*fin=*/true);
|
|
259
296
|
}
|
|
260
297
|
|
|
261
|
-
void Http3Client::SendMessageAsync(const spdy::
|
|
298
|
+
void Http3Client::SendMessageAsync(const spdy::Http2HeaderBlock &headers,
|
|
262
299
|
absl::string_view body, bool fin)
|
|
263
300
|
{
|
|
264
301
|
// Always force creation of a stream for SendMessage.
|
|
@@ -444,6 +481,9 @@ namespace quic
|
|
|
444
481
|
overflow_supported_ = api.EnableDroppedPacketCount(fd);
|
|
445
482
|
api.EnableReceiveTimestamp(fd);
|
|
446
483
|
|
|
484
|
+
auto closer = absl::MakeCleanup([fd]
|
|
485
|
+
{ QuicUdpSocketApi api;api.Destroy(fd); });
|
|
486
|
+
|
|
447
487
|
QuicSocketAddress client_address;
|
|
448
488
|
if (bind_to_address.IsInitialized())
|
|
449
489
|
{
|
|
@@ -492,10 +532,13 @@ namespace quic
|
|
|
492
532
|
}
|
|
493
533
|
const int kEpollFlags = kSocketEventReadable | kSocketEventWritable; // there is no analogue to EPOLLET in libuv hopefully not a problem
|
|
494
534
|
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
535
|
+
if (eventloop_->getQuicEventLoop()->RegisterSocket(fd, kEpollFlags, this))
|
|
536
|
+
{
|
|
537
|
+
fd_address_map_[fd] = client_address;
|
|
538
|
+
std::move(closer).Cancel();
|
|
539
|
+
return true;
|
|
540
|
+
}
|
|
541
|
+
return false;
|
|
499
542
|
}
|
|
500
543
|
|
|
501
544
|
void Http3Client::CleanUpUDPSocket(int fd)
|
|
@@ -651,8 +694,8 @@ namespace quic
|
|
|
651
694
|
Http3WTSession *wtsessionobj =
|
|
652
695
|
new Http3WTSession();
|
|
653
696
|
wtsessionobj->init(
|
|
654
|
-
|
|
655
|
-
|
|
697
|
+
static_cast<WebTransportSession *>(wtsession),
|
|
698
|
+
eventloop_);
|
|
656
699
|
eventloop_->informNewClientSession(this, wtsessionobj);
|
|
657
700
|
auto visitor = std::make_unique<Http3WTSession::Visitor>(wtsessionobj);
|
|
658
701
|
wtsession->SetVisitor(std::move(visitor));
|
|
@@ -667,7 +710,7 @@ namespace quic
|
|
|
667
710
|
|
|
668
711
|
void Http3Client::openWTSessionInt(absl::string_view path)
|
|
669
712
|
{
|
|
670
|
-
spdy::
|
|
713
|
+
spdy::Http2HeaderBlock headers;
|
|
671
714
|
headers[":scheme"] = "https";
|
|
672
715
|
headers[":authority"] = "localhost";
|
|
673
716
|
headers[":path"] = path;
|
|
@@ -691,7 +734,7 @@ namespace quic
|
|
|
691
734
|
{
|
|
692
735
|
QUICHE_DCHECK(initialized_);
|
|
693
736
|
QUICHE_DCHECK(!connected());
|
|
694
|
-
QuicPacketWriter *writer = new
|
|
737
|
+
QuicPacketWriter *writer = new LevelTriggeredPacketWriter(GetLatestFD(), eventloop_->getQuicEventLoop());
|
|
695
738
|
ParsedQuicVersion mutual_version = UnsupportedQuicVersion();
|
|
696
739
|
const bool can_reconnect_with_different_version =
|
|
697
740
|
CanReconnectWithDifferentVersion(&mutual_version);
|
|
@@ -717,7 +760,7 @@ namespace quic
|
|
|
717
760
|
|
|
718
761
|
session_ = std::make_unique<Http3ClientSession>(
|
|
719
762
|
config_, client_supported_versions, new QuicConnection(newconnid, QuicSocketAddress(), server_address_, helper_.get(), alarm_factory_.get(), writer,
|
|
720
|
-
/* owns_writer= */ false, Perspective::IS_CLIENT, client_supported_versions),
|
|
763
|
+
/* owns_writer= */ false, Perspective::IS_CLIENT, client_supported_versions, connection_id_generator_),
|
|
721
764
|
server_id_, &crypto_config_,
|
|
722
765
|
&push_promise_index_, false /*drop_response_body_*/, true /* enable_web_transport */);
|
|
723
766
|
|
|
@@ -888,22 +931,17 @@ namespace quic
|
|
|
888
931
|
bool success =
|
|
889
932
|
event_loop->ArtificiallyNotifyEvent(fd, kSocketEventReadable);
|
|
890
933
|
QUICHE_DCHECK(success);
|
|
891
|
-
}
|
|
934
|
+
}
|
|
892
935
|
if (!event_loop->SupportsEdgeTriggered())
|
|
893
936
|
{
|
|
894
937
|
bool success = event_loop->RearmSocket(fd, kSocketEventReadable);
|
|
895
938
|
QUICHE_DCHECK(success);
|
|
896
939
|
}
|
|
897
940
|
}
|
|
898
|
-
bool writeblocked = false;
|
|
899
941
|
if (connected() && (events & kSocketEventWritable))
|
|
900
942
|
{
|
|
901
943
|
writer_->SetWritable();
|
|
902
944
|
session_->connection()->OnCanWrite();
|
|
903
|
-
if (writer_->IsWriteBlocked())
|
|
904
|
-
{
|
|
905
|
-
writeblocked = true;
|
|
906
|
-
}
|
|
907
945
|
}
|
|
908
946
|
|
|
909
947
|
if (handleConnecting())
|
|
@@ -912,16 +950,6 @@ namespace quic
|
|
|
912
950
|
event_loop->ArtificiallyNotifyEvent(fd, kSocketEventReadable);
|
|
913
951
|
QUICHE_DCHECK(success);
|
|
914
952
|
}
|
|
915
|
-
if (writer_->IsWriteBlocked())
|
|
916
|
-
{
|
|
917
|
-
writeblocked = true;
|
|
918
|
-
}
|
|
919
|
-
if (!event_loop->SupportsEdgeTriggered() && writeblocked)
|
|
920
|
-
{
|
|
921
|
-
bool success = event_loop->RearmSocket(fd, kSocketEventWritable);
|
|
922
|
-
QUICHE_DCHECK(success);
|
|
923
|
-
|
|
924
|
-
}
|
|
925
953
|
}
|
|
926
954
|
|
|
927
955
|
void Http3Client::ProcessPacket(
|
|
@@ -943,7 +971,7 @@ namespace quic
|
|
|
943
971
|
return response_headers_complete_;
|
|
944
972
|
}
|
|
945
973
|
|
|
946
|
-
const spdy::
|
|
974
|
+
const spdy::Http2HeaderBlock *Http3Client::response_headers() const
|
|
947
975
|
{
|
|
948
976
|
for (std::pair<QuicStreamId, QuicSpdyClientStream *> stream : open_streams_)
|
|
949
977
|
{
|
|
@@ -956,7 +984,7 @@ namespace quic
|
|
|
956
984
|
return &response_headers_;
|
|
957
985
|
}
|
|
958
986
|
|
|
959
|
-
const spdy::
|
|
987
|
+
const spdy::Http2HeaderBlock *Http3Client::preliminary_headers() const
|
|
960
988
|
{
|
|
961
989
|
for (std::pair<QuicStreamId, QuicSpdyClientStream *> stream : open_streams_)
|
|
962
990
|
{
|
|
@@ -971,7 +999,7 @@ namespace quic
|
|
|
971
999
|
return &preliminary_headers_;
|
|
972
1000
|
}
|
|
973
1001
|
|
|
974
|
-
const spdy::
|
|
1002
|
+
const spdy::Http2HeaderBlock &Http3Client::response_trailers() const
|
|
975
1003
|
{
|
|
976
1004
|
return response_trailers_;
|
|
977
1005
|
}
|
|
@@ -1080,9 +1108,9 @@ namespace quic
|
|
|
1080
1108
|
}
|
|
1081
1109
|
|
|
1082
1110
|
bool Http3Client::CheckVary(
|
|
1083
|
-
const spdy::
|
|
1084
|
-
const spdy::
|
|
1085
|
-
const spdy::
|
|
1111
|
+
const spdy::Http2HeaderBlock & /*client_request*/,
|
|
1112
|
+
const spdy::Http2HeaderBlock & /*promise_request*/,
|
|
1113
|
+
const spdy::Http2HeaderBlock & /*promise_response*/)
|
|
1086
1114
|
{
|
|
1087
1115
|
return true;
|
|
1088
1116
|
}
|
|
@@ -1174,7 +1202,7 @@ namespace quic
|
|
|
1174
1202
|
}
|
|
1175
1203
|
|
|
1176
1204
|
Http3Client::Http3ClientDataToResend::Http3ClientDataToResend(
|
|
1177
|
-
std::unique_ptr<spdy::
|
|
1205
|
+
std::unique_ptr<spdy::Http2HeaderBlock> headers, absl::string_view body,
|
|
1178
1206
|
bool fin, Http3Client *client)
|
|
1179
1207
|
: headers_(std::move(headers)), body_(body), fin_(fin),
|
|
1180
1208
|
client_(client) {}
|
|
@@ -1202,9 +1230,9 @@ namespace quic
|
|
|
1202
1230
|
Http3Client::PerStreamState::PerStreamState(
|
|
1203
1231
|
QuicRstStreamErrorCode stream_error, bool response_complete,
|
|
1204
1232
|
bool response_headers_complete,
|
|
1205
|
-
const spdy::
|
|
1206
|
-
const spdy::
|
|
1207
|
-
const std::string &response, const spdy::
|
|
1233
|
+
const spdy::Http2HeaderBlock &response_headers,
|
|
1234
|
+
const spdy::Http2HeaderBlock &preliminary_headers,
|
|
1235
|
+
const std::string &response, const spdy::Http2HeaderBlock &response_trailers,
|
|
1208
1236
|
uint64_t bytes_read, uint64_t bytes_written, int64_t response_body_size)
|
|
1209
1237
|
: stream_error(stream_error),
|
|
1210
1238
|
response_complete(response_complete),
|
|
@@ -1220,7 +1248,7 @@ namespace quic
|
|
|
1220
1248
|
Http3Client::PerStreamState::~PerStreamState() = default;
|
|
1221
1249
|
|
|
1222
1250
|
bool Http3Client::PopulateHeaderBlockFromUrl(
|
|
1223
|
-
const std::string &uri, spdy::
|
|
1251
|
+
const std::string &uri, spdy::Http2HeaderBlock *headers)
|
|
1224
1252
|
{
|
|
1225
1253
|
std::string url;
|
|
1226
1254
|
if (absl::StartsWith(uri, "https://") || absl::StartsWith(uri, "http://"))
|
|
@@ -1271,8 +1299,7 @@ namespace quic
|
|
|
1271
1299
|
latest_created_stream_ = nullptr;
|
|
1272
1300
|
}
|
|
1273
1301
|
|
|
1274
|
-
Http3ClientJS::Http3ClientJS(const Napi::CallbackInfo &info) :
|
|
1275
|
-
Napi::ObjectWrap<Http3ClientJS>(info)
|
|
1302
|
+
Http3ClientJS::Http3ClientJS(const Napi::CallbackInfo &info) : Napi::ObjectWrap<Http3ClientJS>(info)
|
|
1276
1303
|
{
|
|
1277
1304
|
|
|
1278
1305
|
std::string port = "443";
|
|
@@ -1289,39 +1316,41 @@ namespace quic
|
|
|
1289
1316
|
if (!lobj.IsEmpty())
|
|
1290
1317
|
{
|
|
1291
1318
|
|
|
1292
|
-
if (lobj.Has(
|
|
1319
|
+
if (lobj.Has("allowPooling") && !(lobj).Get("allowPooling").IsEmpty())
|
|
1293
1320
|
{
|
|
1294
1321
|
Napi::Value poolValue = (lobj).Get("allowPooling");
|
|
1295
1322
|
allowPooling = poolValue.As<Napi::Boolean>().Value();
|
|
1296
1323
|
}
|
|
1297
1324
|
|
|
1298
|
-
if (lobj.Has(
|
|
1325
|
+
if (lobj.Has("forceIpv6") && !(lobj).Get("forceIpv6").IsEmpty())
|
|
1299
1326
|
{
|
|
1300
1327
|
Napi::Value ipv6Value = (lobj).Get("forceIpv6");
|
|
1301
1328
|
forceipv6 = ipv6Value.As<Napi::Boolean>().Value();
|
|
1302
1329
|
}
|
|
1303
1330
|
|
|
1304
|
-
if (lobj.Has(
|
|
1331
|
+
if (lobj.Has("port") && !(lobj).Get("port").IsEmpty())
|
|
1305
1332
|
{
|
|
1306
1333
|
Napi::Value portValue = (lobj).Get("port");
|
|
1307
1334
|
port = portValue.ToString().Utf8Value();
|
|
1308
1335
|
}
|
|
1309
|
-
else
|
|
1336
|
+
else
|
|
1337
|
+
{
|
|
1310
1338
|
Napi::Error::New(env, "no port specified").ThrowAsJavaScriptException();
|
|
1311
|
-
return
|
|
1339
|
+
return;
|
|
1312
1340
|
}
|
|
1313
1341
|
|
|
1314
|
-
if (lobj.Has(
|
|
1342
|
+
if (lobj.Has("hostname") && !(lobj).Get("hostname").IsEmpty())
|
|
1315
1343
|
{
|
|
1316
1344
|
Napi::Value hostnameValue = (lobj).Get("hostname");
|
|
1317
1345
|
hostname = hostnameValue.ToString().Utf8Value();
|
|
1318
1346
|
}
|
|
1319
|
-
else
|
|
1347
|
+
else
|
|
1348
|
+
{
|
|
1320
1349
|
Napi::Error::New(env, "no hostname specified").ThrowAsJavaScriptException();
|
|
1321
|
-
return
|
|
1350
|
+
return;
|
|
1322
1351
|
}
|
|
1323
1352
|
|
|
1324
|
-
if (lobj.Has(
|
|
1353
|
+
if (lobj.Has("serverCertificateHashes") && !(lobj).Get("serverCertificateHashes").IsEmpty())
|
|
1325
1354
|
{
|
|
1326
1355
|
Napi::Value hashValue = (lobj).Get("serverCertificateHashes");
|
|
1327
1356
|
if (hashValue.IsArray())
|
|
@@ -1341,40 +1370,45 @@ namespace quic
|
|
|
1341
1370
|
size_t len = bufferlocal.As<Napi::Buffer<char>>().Length();
|
|
1342
1371
|
curhash.value = std::string(buffer, len);
|
|
1343
1372
|
}
|
|
1344
|
-
else
|
|
1373
|
+
else
|
|
1374
|
+
{
|
|
1345
1375
|
Napi::Error::New(env, "serverCertificateHashes wrong format").ThrowAsJavaScriptException();
|
|
1346
|
-
return
|
|
1376
|
+
return;
|
|
1347
1377
|
}
|
|
1348
1378
|
if (hashobj.Has("algorithm") && !(hashobj).Get("algorithm").IsEmpty())
|
|
1349
1379
|
{
|
|
1350
1380
|
Napi::Value algorithmValue = (hashobj).Get("algorithm");
|
|
1351
1381
|
curhash.algorithm = algorithmValue.ToString().Utf8Value();
|
|
1352
1382
|
}
|
|
1353
|
-
else
|
|
1383
|
+
else
|
|
1384
|
+
{
|
|
1354
1385
|
Napi::Error::New(env, "serverCertificateHashes wrong format").ThrowAsJavaScriptException();
|
|
1355
|
-
return
|
|
1386
|
+
return;
|
|
1356
1387
|
}
|
|
1357
|
-
if (curhash.algorithm.compare(WebTransportHash::kSha256) != 0)
|
|
1388
|
+
if (curhash.algorithm.compare(WebTransportHash::kSha256) != 0)
|
|
1389
|
+
{
|
|
1358
1390
|
Napi::Error::New(env, "serverCertificateHashes unknown algorithm").ThrowAsJavaScriptException();
|
|
1359
|
-
return
|
|
1391
|
+
return;
|
|
1360
1392
|
}
|
|
1361
1393
|
serverCertificateHashes.push_back(curhash);
|
|
1362
1394
|
}
|
|
1363
1395
|
}
|
|
1364
|
-
else
|
|
1396
|
+
else
|
|
1397
|
+
{
|
|
1365
1398
|
Napi::Error::New(env, "serverCertificateHashes is not an array").ThrowAsJavaScriptException();
|
|
1366
|
-
return
|
|
1399
|
+
return;
|
|
1367
1400
|
}
|
|
1368
1401
|
}
|
|
1369
1402
|
|
|
1370
|
-
if (lobj.Has(
|
|
1403
|
+
if (lobj.Has("localPort") && !(lobj).Get("localPort").IsEmpty())
|
|
1371
1404
|
{
|
|
1372
1405
|
Napi::Value localPortValue = (lobj).Get("localPort");
|
|
1373
1406
|
if (localPortValue.IsNumber())
|
|
1374
1407
|
local_port = localPortValue.As<Napi::Number>().Int32Value();
|
|
1375
|
-
else
|
|
1408
|
+
else
|
|
1409
|
+
{
|
|
1376
1410
|
Napi::Error::New(env, "localPort is not a number").ThrowAsJavaScriptException();
|
|
1377
|
-
return
|
|
1411
|
+
return;
|
|
1378
1412
|
}
|
|
1379
1413
|
}
|
|
1380
1414
|
}
|
|
@@ -1391,7 +1425,7 @@ namespace quic
|
|
|
1391
1425
|
else
|
|
1392
1426
|
{
|
|
1393
1427
|
Napi::Error::New(env, "No eventloop arguments passed to Http3Client").ThrowAsJavaScriptException();
|
|
1394
|
-
return
|
|
1428
|
+
return;
|
|
1395
1429
|
}
|
|
1396
1430
|
|
|
1397
1431
|
std::unique_ptr<QuicConnectionHelperInterface> helper =
|
|
@@ -1409,13 +1443,14 @@ namespace quic
|
|
|
1409
1443
|
if (!verifier->AddFingerprint(*cur))
|
|
1410
1444
|
{
|
|
1411
1445
|
Napi::Error::New(env, "serverCertificateHashes is not valid fingerprint").ThrowAsJavaScriptException();
|
|
1412
|
-
return
|
|
1446
|
+
return;
|
|
1413
1447
|
}
|
|
1414
1448
|
}
|
|
1415
1449
|
}
|
|
1416
|
-
else
|
|
1450
|
+
else
|
|
1451
|
+
{
|
|
1417
1452
|
Napi::Error::New(env, "No supported verification method included").ThrowAsJavaScriptException();
|
|
1418
|
-
return
|
|
1453
|
+
return;
|
|
1419
1454
|
}
|
|
1420
1455
|
|
|
1421
1456
|
std::unique_ptr<Http3SessionCache> cache;
|
|
@@ -1442,7 +1477,7 @@ namespace quic
|
|
|
1442
1477
|
<< gai_strerror(result);
|
|
1443
1478
|
info_list = nullptr;
|
|
1444
1479
|
Napi::Error::New(env, "URL host lookup failed").ThrowAsJavaScriptException();
|
|
1445
|
-
return
|
|
1480
|
+
return;
|
|
1446
1481
|
}
|
|
1447
1482
|
|
|
1448
1483
|
QUICHE_CHECK(info_list != nullptr);
|
|
@@ -1450,7 +1485,7 @@ namespace quic
|
|
|
1450
1485
|
freeaddrinfo(info_list);
|
|
1451
1486
|
|
|
1452
1487
|
client_ = std::make_unique<Http3Client>(eventloop, address, hostname, local_port,
|
|
1453
|
-
|
|
1488
|
+
std::move(verifier), std::move(cache), std::move(helper));
|
|
1454
1489
|
client_->SetUserAgentID("fails-components/webtransport");
|
|
1455
1490
|
|
|
1456
1491
|
client_->setJS(this);
|
|
@@ -1462,11 +1497,10 @@ namespace quic
|
|
|
1462
1497
|
client_->Connect();
|
|
1463
1498
|
};
|
|
1464
1499
|
client_->eventloop_->Schedule(task);
|
|
1465
|
-
return
|
|
1500
|
+
return;
|
|
1466
1501
|
}
|
|
1467
1502
|
|
|
1468
|
-
|
|
1469
|
-
void Http3ClientJS::openWTSession(const Napi::CallbackInfo& info)
|
|
1503
|
+
void Http3ClientJS::openWTSession(const Napi::CallbackInfo &info)
|
|
1470
1504
|
{
|
|
1471
1505
|
Http3Client *obj = getObj();
|
|
1472
1506
|
// got the object we can now start the server
|
|
@@ -1480,13 +1514,14 @@ namespace quic
|
|
|
1480
1514
|
};
|
|
1481
1515
|
obj->eventloop_->Schedule(task);
|
|
1482
1516
|
}
|
|
1483
|
-
else
|
|
1517
|
+
else
|
|
1518
|
+
{
|
|
1484
1519
|
Napi::Error::New(info.Env(), "openWTSession without path").ThrowAsJavaScriptException();
|
|
1485
|
-
return
|
|
1520
|
+
return;
|
|
1486
1521
|
}
|
|
1487
1522
|
}
|
|
1488
1523
|
|
|
1489
|
-
void Http3ClientJS::closeClient(const Napi::CallbackInfo&
|
|
1524
|
+
void Http3ClientJS::closeClient(const Napi::CallbackInfo &info)
|
|
1490
1525
|
{
|
|
1491
1526
|
Http3Client *obj = getObj();
|
|
1492
1527
|
// got the object we can now start the server
|
|
@@ -1494,8 +1529,8 @@ namespace quic
|
|
|
1494
1529
|
{
|
|
1495
1530
|
if (!obj->closeClientInt())
|
|
1496
1531
|
{
|
|
1497
|
-
printf(
|
|
1498
|
-
return
|
|
1532
|
+
printf("closeClientInt failed for Http3Client");
|
|
1533
|
+
return;
|
|
1499
1534
|
}
|
|
1500
1535
|
};
|
|
1501
1536
|
obj->eventloop_->Schedule(task);
|
package/src/http3client.h
CHANGED
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
#include "quiche/quic/core/quic_packet_reader.h"
|
|
30
30
|
#include "quiche/quic/platform/api/quic_socket_address.h"
|
|
31
31
|
#include "quiche/quic/core/proto/cached_network_parameters_proto.h"
|
|
32
|
+
#include "quiche/quic/core/deterministic_connection_id_generator.h"
|
|
32
33
|
#include "quiche/quic/core/quic_framer.h"
|
|
33
34
|
#include "quiche/quic/core/quic_packet_creator.h"
|
|
34
35
|
#include "quiche/quic/core/quic_packets.h"
|
|
@@ -133,12 +134,12 @@ namespace quic
|
|
|
133
134
|
|
|
134
135
|
// Sends a request containing |headers| and |body| and returns the number of
|
|
135
136
|
// bytes sent (the size of the serialized request headers and body).
|
|
136
|
-
void SendMessageAsync(const spdy::
|
|
137
|
+
void SendMessageAsync(const spdy::Http2HeaderBlock &headers,
|
|
137
138
|
absl::string_view body);
|
|
138
139
|
// Sends a request containing |headers| and |body| with the fin bit set to
|
|
139
140
|
// |fin| and returns the number of bytes sent (the size of the serialized
|
|
140
141
|
// request headers and body).
|
|
141
|
-
void SendMessageAsync(const spdy::
|
|
142
|
+
void SendMessageAsync(const spdy::Http2HeaderBlock &headers,
|
|
142
143
|
absl::string_view body, bool fin);
|
|
143
144
|
|
|
144
145
|
void SendConnectivityProbing();
|
|
@@ -173,14 +174,14 @@ namespace quic
|
|
|
173
174
|
// is received. 2) returns state of the oldest active stream which have
|
|
174
175
|
// received partial response (if any).
|
|
175
176
|
// Group 1.
|
|
176
|
-
const spdy::
|
|
177
|
+
const spdy::Http2HeaderBlock &response_trailers() const;
|
|
177
178
|
bool response_complete() const;
|
|
178
179
|
int64_t response_body_size() const;
|
|
179
180
|
const std::string &response_body() const;
|
|
180
181
|
// Group 2.
|
|
181
182
|
bool response_headers_complete() const;
|
|
182
|
-
const spdy::
|
|
183
|
-
const spdy::
|
|
183
|
+
const spdy::Http2HeaderBlock *response_headers() const;
|
|
184
|
+
const spdy::Http2HeaderBlock *preliminary_headers() const;
|
|
184
185
|
int64_t response_size() const;
|
|
185
186
|
size_t bytes_read() const;
|
|
186
187
|
size_t bytes_written() const;
|
|
@@ -221,9 +222,9 @@ namespace quic
|
|
|
221
222
|
const std::string &response_body);
|
|
222
223
|
|
|
223
224
|
// From QuicClientPushPromiseIndex::Delegate
|
|
224
|
-
bool CheckVary(const spdy::
|
|
225
|
-
const spdy::
|
|
226
|
-
const spdy::
|
|
225
|
+
bool CheckVary(const spdy::Http2HeaderBlock &client_request,
|
|
226
|
+
const spdy::Http2HeaderBlock &promise_request,
|
|
227
|
+
const spdy::Http2HeaderBlock &promise_response) override;
|
|
227
228
|
void OnRendezvousResult(QuicSpdyStream *) override;
|
|
228
229
|
|
|
229
230
|
// Returns nullptr if the maximum number of streams have already been created.
|
|
@@ -235,7 +236,7 @@ namespace quic
|
|
|
235
236
|
// stores the request in case it needs to be resent. If |headers| is
|
|
236
237
|
// null, only the body will be sent on the stream.
|
|
237
238
|
void GetOrCreateStreamAndSendRequest(
|
|
238
|
-
const spdy::
|
|
239
|
+
const spdy::Http2HeaderBlock *headers, absl::string_view body, bool fin);
|
|
239
240
|
|
|
240
241
|
QuicRstStreamErrorCode stream_error() { return stream_error_; }
|
|
241
242
|
QuicErrorCode connection_error() const;
|
|
@@ -272,7 +273,7 @@ namespace quic
|
|
|
272
273
|
// request. If |uri| is a relative URL, the QuicServerId will be
|
|
273
274
|
// use to specify the authority.
|
|
274
275
|
bool PopulateHeaderBlockFromUrl(const std::string &uri,
|
|
275
|
-
spdy::
|
|
276
|
+
spdy::Http2HeaderBlock *headers);
|
|
276
277
|
|
|
277
278
|
QuicSpdyClientStream *latest_created_stream()
|
|
278
279
|
{
|
|
@@ -300,7 +301,7 @@ namespace quic
|
|
|
300
301
|
{
|
|
301
302
|
public:
|
|
302
303
|
Http3ClientDataToResend(
|
|
303
|
-
std::unique_ptr<spdy::
|
|
304
|
+
std::unique_ptr<spdy::Http2HeaderBlock> headers, absl::string_view body,
|
|
304
305
|
bool fin, Http3Client *client);
|
|
305
306
|
|
|
306
307
|
~Http3ClientDataToResend();
|
|
@@ -320,10 +321,10 @@ namespace quic
|
|
|
320
321
|
PerStreamState(const PerStreamState &other);
|
|
321
322
|
PerStreamState(QuicRstStreamErrorCode stream_error, bool response_complete,
|
|
322
323
|
bool response_headers_complete,
|
|
323
|
-
const spdy::
|
|
324
|
-
const spdy::
|
|
324
|
+
const spdy::Http2HeaderBlock &response_headers,
|
|
325
|
+
const spdy::Http2HeaderBlock &preliminary_headers,
|
|
325
326
|
const std::string &response,
|
|
326
|
-
const spdy::
|
|
327
|
+
const spdy::Http2HeaderBlock &response_trailers,
|
|
327
328
|
uint64_t bytes_read, uint64_t bytes_written,
|
|
328
329
|
int64_t response_body_size);
|
|
329
330
|
~PerStreamState();
|
|
@@ -331,10 +332,10 @@ namespace quic
|
|
|
331
332
|
QuicRstStreamErrorCode stream_error;
|
|
332
333
|
bool response_complete;
|
|
333
334
|
bool response_headers_complete;
|
|
334
|
-
spdy::
|
|
335
|
-
spdy::
|
|
335
|
+
spdy::Http2HeaderBlock response_headers;
|
|
336
|
+
spdy::Http2HeaderBlock preliminary_headers;
|
|
336
337
|
std::string response;
|
|
337
|
-
spdy::
|
|
338
|
+
spdy::Http2HeaderBlock response_trailers;
|
|
338
339
|
uint64_t bytes_read;
|
|
339
340
|
uint64_t bytes_written;
|
|
340
341
|
int64_t response_body_size;
|
|
@@ -353,6 +354,8 @@ namespace quic
|
|
|
353
354
|
// Returns true if the corresponding of this client has active requests.
|
|
354
355
|
bool HasActiveRequests();
|
|
355
356
|
|
|
357
|
+
ConnectionIdGeneratorInterface &connection_id_generator();
|
|
358
|
+
|
|
356
359
|
// Actually clean up |fd|.
|
|
357
360
|
void CleanUpUDPSocketImpl(QuicUdpSocketFd fd);
|
|
358
361
|
|
|
@@ -396,11 +399,11 @@ namespace quic
|
|
|
396
399
|
|
|
397
400
|
bool response_complete_;
|
|
398
401
|
bool response_headers_complete_;
|
|
399
|
-
mutable spdy::
|
|
400
|
-
mutable spdy::
|
|
402
|
+
mutable spdy::Http2HeaderBlock preliminary_headers_;
|
|
403
|
+
mutable spdy::Http2HeaderBlock response_headers_;
|
|
401
404
|
|
|
402
405
|
// Parsed response trailers (if present), copied from the stream in OnClose.
|
|
403
|
-
spdy::
|
|
406
|
+
spdy::Http2HeaderBlock response_trailers_;
|
|
404
407
|
|
|
405
408
|
spdy::SpdyPriority priority_;
|
|
406
409
|
std::string response_;
|
|
@@ -541,6 +544,9 @@ namespace quic
|
|
|
541
544
|
// space than allowed on the stack.
|
|
542
545
|
std::unique_ptr<QuicPacketReader> packet_reader_;
|
|
543
546
|
|
|
547
|
+
DeterministicConnectionIdGenerator connection_id_generator_{
|
|
548
|
+
kQuicDefaultConnectionIdLength};
|
|
549
|
+
|
|
544
550
|
Http3EventLoop *eventloop_;
|
|
545
551
|
// connection workflow
|
|
546
552
|
bool wait_for_encryption_;
|
package/src/http3dispatcher.cc
CHANGED
|
@@ -23,14 +23,16 @@ Http3Dispatcher::Http3Dispatcher(
|
|
|
23
23
|
std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
|
|
24
24
|
std::unique_ptr<QuicAlarmFactory> alarm_factory,
|
|
25
25
|
Http3ServerBackend* http3_server_backend,
|
|
26
|
-
uint8_t expected_server_connection_id_length
|
|
26
|
+
uint8_t expected_server_connection_id_length,
|
|
27
|
+
ConnectionIdGeneratorInterface& generator)
|
|
27
28
|
: QuicDispatcher(config,
|
|
28
29
|
crypto_config,
|
|
29
30
|
version_manager,
|
|
30
31
|
std::move(helper),
|
|
31
32
|
std::move(session_helper),
|
|
32
33
|
std::move(alarm_factory),
|
|
33
|
-
expected_server_connection_id_length
|
|
34
|
+
expected_server_connection_id_length,
|
|
35
|
+
generator),
|
|
34
36
|
http3_server_backend_(http3_server_backend) {}
|
|
35
37
|
|
|
36
38
|
Http3Dispatcher::~Http3Dispatcher() = default;
|
|
@@ -47,7 +49,7 @@ std::unique_ptr<QuicSession> Http3Dispatcher::CreateQuicSession(
|
|
|
47
49
|
new QuicConnection(connection_id, self_address, peer_address, helper(),
|
|
48
50
|
alarm_factory(), writer(),
|
|
49
51
|
/* owns_writer= */ false, Perspective::IS_SERVER,
|
|
50
|
-
ParsedQuicVersionVector{version});
|
|
52
|
+
ParsedQuicVersionVector{version}, connection_id_generator());
|
|
51
53
|
|
|
52
54
|
auto session = std::make_unique<Http3ServerSession>(
|
|
53
55
|
config(), GetSupportedVersions(), connection, this, session_helper(),
|
package/src/http3dispatcher.h
CHANGED
|
@@ -30,7 +30,8 @@ namespace quic
|
|
|
30
30
|
std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
|
|
31
31
|
std::unique_ptr<QuicAlarmFactory> alarm_factory,
|
|
32
32
|
Http3ServerBackend *http3_server_backend,
|
|
33
|
-
uint8_t expected_server_connection_id_length
|
|
33
|
+
uint8_t expected_server_connection_id_length,
|
|
34
|
+
ConnectionIdGeneratorInterface& generator);
|
|
34
35
|
|
|
35
36
|
~Http3Dispatcher() override;
|
|
36
37
|
|