SPDX license
This commit is contained in:
parent
43fdd7fb53
commit
e33ec5b72e
35 changed files with 987 additions and 587 deletions
|
|
@ -1,22 +1,5 @@
|
|||
/*
|
||||
Crafter®.Network
|
||||
Copyright (C) 2026 Catcrafts®
|
||||
Catcrafts.net
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 3.0 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
//SPDX-License-Identifier: LGPL-3.0-only
|
||||
//SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
|
||||
|
||||
// CRAFTER_NETWORK_BROWSER implementation of ClientHTTP. Each SendAsync
|
||||
// hands its request to the JS bridge (additional/network-env.js), which
|
||||
|
|
|
|||
|
|
@ -1,22 +1,5 @@
|
|||
/*
|
||||
Crafter®.Network
|
||||
Copyright (C) 2026 Catcrafts®
|
||||
Catcrafts.net
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 3.0 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
//SPDX-License-Identifier: LGPL-3.0-only
|
||||
//SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
|
||||
|
||||
module;
|
||||
#include <msquic.h>
|
||||
|
|
|
|||
|
|
@ -1,22 +1,5 @@
|
|||
/*
|
||||
Crafter®.Network
|
||||
Copyright (C) 2026 Catcrafts®
|
||||
Catcrafts.net
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 3.0 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
//SPDX-License-Identifier: LGPL-3.0-only
|
||||
//SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®ation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
// CRAFTER_NETWORK_BROWSER implementation of ClientQUIC / QUICStream backed
|
||||
// by the browser's WebTransport API. WebTransport is HTTP/3-based and
|
||||
|
|
|
|||
|
|
@ -1,22 +1,5 @@
|
|||
/*
|
||||
Crafter®.Network
|
||||
Copyright (C) 2026 Catcrafts®
|
||||
Catcrafts.net
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 3.0 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
//SPDX-License-Identifier: LGPL-3.0-only
|
||||
//SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
|
||||
|
||||
module;
|
||||
#include <msquic.h>
|
||||
|
|
@ -92,8 +75,32 @@ struct QUICStream::Impl {
|
|||
bool shutdownComplete = false;
|
||||
bool sendInFlight = false;
|
||||
|
||||
// Lifetime: msquic delivers stream callbacks (RECEIVE, SHUTDOWN_COMPLETE, …)
|
||||
// possibly AFTER the owning QUICStream wrapper is destroyed (the wrapper only
|
||||
// initiates a graceful shutdown; completion is async). To make that safe, the
|
||||
// callback context is a heap `shared_ptr<Impl>*` (selfRef) that holds one
|
||||
// strong ref; every callback copies it locally so the Impl stays alive for
|
||||
// the callback's duration. The terminal SHUTDOWN_COMPLETE callback closes the
|
||||
// stream and releases selfRef, after which the Impl is freed once the last
|
||||
// ref (wrapper / in-flight callback copy) drops.
|
||||
std::shared_ptr<Impl>* selfRef = nullptr;
|
||||
|
||||
// Detach the msquic handler, close the stream, and release the callback's
|
||||
// strong ref. Called once, from SHUTDOWN_COMPLETE (normal path) or the
|
||||
// OpenStream error path — never racing another close of the same stream.
|
||||
static void FinalizeClose(Impl* self, HQUIC stream) {
|
||||
Runtime().api->SetCallbackHandler(stream, nullptr, nullptr);
|
||||
Runtime().api->StreamClose(stream);
|
||||
std::shared_ptr<Impl>* ref = self->selfRef;
|
||||
self->selfRef = nullptr;
|
||||
delete ref;
|
||||
}
|
||||
|
||||
static QUIC_STATUS QUIC_API Callback(HQUIC stream, void* ctx, QUIC_STREAM_EVENT* ev) {
|
||||
auto* self = static_cast<Impl*>(ctx);
|
||||
// Keep the Impl alive for the whole callback, even if the wrapper (and
|
||||
// its ref) go away concurrently.
|
||||
std::shared_ptr<Impl> keepAlive = *static_cast<std::shared_ptr<Impl>*>(ctx);
|
||||
Impl* self = keepAlive.get();
|
||||
switch (ev->Type) {
|
||||
case QUIC_STREAM_EVENT_RECEIVE: {
|
||||
std::vector<char> chunk;
|
||||
|
|
@ -140,8 +147,7 @@ struct QUICStream::Impl {
|
|||
self->shutdownComplete = true;
|
||||
}
|
||||
self->cv.notify_all();
|
||||
Runtime().api->SetCallbackHandler(stream, nullptr, nullptr);
|
||||
Runtime().api->StreamClose(stream);
|
||||
FinalizeClose(self, stream);
|
||||
return QUIC_STATUS_SUCCESS;
|
||||
}
|
||||
default:
|
||||
|
|
@ -153,11 +159,12 @@ struct QUICStream::Impl {
|
|||
QUICStream::QUICStream() = default;
|
||||
|
||||
QUICStream::QUICStream(HQUIC handle, ClientQUIC* connection)
|
||||
: handle(handle), connection(connection), impl(std::make_unique<Impl>())
|
||||
: handle(handle), connection(connection), impl(std::make_shared<Impl>())
|
||||
{
|
||||
impl->handle = handle;
|
||||
impl->connection = connection;
|
||||
Runtime().api->SetCallbackHandler(handle, reinterpret_cast<void*>(&Impl::Callback), impl.get());
|
||||
impl->selfRef = new std::shared_ptr<Impl>(impl); // strong ref owned by the callback
|
||||
Runtime().api->SetCallbackHandler(handle, reinterpret_cast<void*>(&Impl::Callback), impl->selfRef);
|
||||
}
|
||||
|
||||
QUICStream::QUICStream(QUICStream&& other) noexcept
|
||||
|
|
@ -189,12 +196,12 @@ QUICStream::~QUICStream() {
|
|||
|
||||
void QUICStream::Stop() {
|
||||
if (!handle) return;
|
||||
// If the stream's SHUTDOWN_COMPLETE event has already fired, msquic has
|
||||
// internally called StreamClose for us (see Impl::Callback) and the
|
||||
// handle is no longer valid — calling StreamShutdown on it trips a
|
||||
// quic_bugcheck inside msquic. Skip in that case. This is the common
|
||||
// path for short-lived request/response streams where both peers FIN
|
||||
// before the wrapper is destroyed.
|
||||
// Only INITIATE a graceful shutdown here; the async SHUTDOWN_COMPLETE
|
||||
// callback performs the actual StreamClose + ref release. The Impl is a
|
||||
// shared_ptr held by the callback's selfRef, so it safely outlives this
|
||||
// wrapper until that callback runs. If SHUTDOWN_COMPLETE already fired,
|
||||
// msquic has closed the stream and calling StreamShutdown again would trip
|
||||
// a bugcheck — skip it.
|
||||
bool alreadyClosed = false;
|
||||
if (impl) {
|
||||
std::lock_guard lk(impl->mtx);
|
||||
|
|
@ -204,7 +211,10 @@ void QUICStream::Stop() {
|
|||
Runtime().api->StreamShutdown(handle, QUIC_STREAM_SHUTDOWN_FLAG_GRACEFUL, 0);
|
||||
}
|
||||
handle = nullptr;
|
||||
if (impl) impl->handle = nullptr;
|
||||
if (impl) {
|
||||
std::lock_guard lk(impl->mtx);
|
||||
impl->handle = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void QUICStream::SendSync(const void* buffer, std::uint32_t size, bool finish) {
|
||||
|
|
@ -450,7 +460,14 @@ static HQUIC OpenClientConfiguration(const std::string& alpn, const QUICClientCr
|
|||
|
||||
QUIC_SETTINGS settings{};
|
||||
settings.IsSet.IdleTimeoutMs = 1;
|
||||
settings.IdleTimeoutMs = 30'000;
|
||||
settings.IdleTimeoutMs = 120'000;
|
||||
// Keep the connection alive across long idle gaps. msquic sends PING frames
|
||||
// on its own timer thread (independent of the app), so a request/response
|
||||
// connection survives even while the app is blocked for a long time between
|
||||
// requests (e.g. a client waiting on slow LLM inference). Interval < idle
|
||||
// timeout so the peer's idle timer never expires.
|
||||
settings.IsSet.KeepAliveIntervalMs = 1;
|
||||
settings.KeepAliveIntervalMs = 10'000;
|
||||
settings.IsSet.DatagramReceiveEnabled = 1;
|
||||
settings.DatagramReceiveEnabled = 1;
|
||||
// Allow the server to open unidi/bidi streams to us. msquic defaults
|
||||
|
|
@ -554,15 +571,20 @@ void ClientQUIC::Stop() {
|
|||
QUICStream ClientQUIC::OpenStream(bool unidirectional) {
|
||||
HQUIC streamHandle = nullptr;
|
||||
QUICStream stream;
|
||||
stream.impl = std::make_unique<QUICStream::Impl>();
|
||||
stream.impl = std::make_shared<QUICStream::Impl>();
|
||||
stream.impl->connection = this;
|
||||
stream.impl->selfRef = new std::shared_ptr<QUICStream::Impl>(stream.impl);
|
||||
QUIC_STREAM_OPEN_FLAGS openFlags = unidirectional
|
||||
? QUIC_STREAM_OPEN_FLAG_UNIDIRECTIONAL
|
||||
: QUIC_STREAM_OPEN_FLAG_NONE;
|
||||
QUIC_STATUS s = Runtime().api->StreamOpen(impl->connection, openFlags,
|
||||
reinterpret_cast<QUIC_STREAM_CALLBACK_HANDLER>(&QUICStream::Impl::Callback),
|
||||
stream.impl.get(), &streamHandle);
|
||||
if (QUIC_FAILED(s)) throw QUICException(std::format("StreamOpen failed: 0x{:x}", static_cast<unsigned>(s)));
|
||||
stream.impl->selfRef, &streamHandle);
|
||||
if (QUIC_FAILED(s)) {
|
||||
delete stream.impl->selfRef;
|
||||
stream.impl->selfRef = nullptr;
|
||||
throw QUICException(std::format("StreamOpen failed: 0x{:x}", static_cast<unsigned>(s)));
|
||||
}
|
||||
stream.handle = streamHandle;
|
||||
stream.connection = this;
|
||||
stream.impl->handle = streamHandle;
|
||||
|
|
@ -573,7 +595,11 @@ QUICStream ClientQUIC::OpenStream(bool unidirectional) {
|
|||
}
|
||||
s = Runtime().api->StreamStart(streamHandle, QUIC_STREAM_START_FLAG_NONE);
|
||||
if (QUIC_FAILED(s)) {
|
||||
Runtime().api->StreamClose(streamHandle);
|
||||
// Handler is registered; detach + close so no callback fires on the
|
||||
// failed stream, and clear the wrapper handle so ~QUICStream is a no-op.
|
||||
QUICStream::Impl::FinalizeClose(stream.impl.get(), streamHandle);
|
||||
stream.handle = nullptr;
|
||||
stream.impl->handle = nullptr;
|
||||
throw QUICException(std::format("StreamStart failed: 0x{:x}", static_cast<unsigned>(s)));
|
||||
}
|
||||
return stream;
|
||||
|
|
|
|||
|
|
@ -1,22 +1,5 @@
|
|||
/*
|
||||
Crafter®.Network
|
||||
Copyright (C) 2026 Catcrafts®
|
||||
Catcrafts.net
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 3.0 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
//SPDX-License-Identifier: LGPL-3.0-only
|
||||
//SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
|
||||
|
||||
module;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,22 +1,5 @@
|
|||
/*
|
||||
Crafter®.Network
|
||||
Copyright (C) 2026 Catcrafts®
|
||||
Catcrafts.net
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 3.0 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
//SPDX-License-Identifier: LGPL-3.0-only
|
||||
//SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
|
||||
|
||||
module;
|
||||
#include <msquic.h>
|
||||
|
|
|
|||
|
|
@ -1,22 +1,5 @@
|
|||
/*
|
||||
Crafter®.Network
|
||||
Copyright (C) 2026 Catcrafts®
|
||||
Catcrafts.net
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 3.0 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
//SPDX-License-Identifier: LGPL-3.0-only
|
||||
//SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
|
||||
|
||||
module;
|
||||
#include <msquic.h>
|
||||
|
|
@ -237,7 +220,7 @@ static HQUIC OpenServerConfiguration(const std::string& alpn,
|
|||
|
||||
QUIC_SETTINGS settings{};
|
||||
settings.IsSet.IdleTimeoutMs = 1;
|
||||
settings.IdleTimeoutMs = 30'000;
|
||||
settings.IdleTimeoutMs = 120'000;
|
||||
settings.IsSet.PeerBidiStreamCount = 1;
|
||||
settings.PeerBidiStreamCount = 16;
|
||||
settings.IsSet.PeerUnidiStreamCount = 1;
|
||||
|
|
|
|||
|
|
@ -1,22 +1,5 @@
|
|||
/*
|
||||
Crafter®.Network
|
||||
Copyright (C) 2026 Catcrafts®
|
||||
Catcrafts.net
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 3.0 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
//SPDX-License-Identifier: LGPL-3.0-only
|
||||
//SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
|
||||
|
||||
module;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,22 +1,5 @@
|
|||
/*
|
||||
Crafter®.Network
|
||||
Copyright (C) 2026 Catcrafts®
|
||||
Catcrafts.net
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 3.0 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
//SPDX-License-Identifier: LGPL-3.0-only
|
||||
//SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
|
||||
|
||||
module;
|
||||
module Crafter.Network:WebTransport_impl;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue