зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1805196 - implement initial webtransport connection and close. r=necko-reviewers,jesup
Differential Revision: https://phabricator.services.mozilla.com/D165312
This commit is contained in:
Родитель
092c5a5d1f
Коммит
c01f5b855f
|
@ -104,6 +104,7 @@ bool WebTransport::Init(const GlobalObject& aGlobal, const nsAString& aURL,
|
|||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal = nsContentUtils::GetSystemPrincipal();
|
||||
// Create a new IPC connection
|
||||
Endpoint<PWebTransportParent> parentEndpoint;
|
||||
Endpoint<PWebTransportChild> childEndpoint;
|
||||
|
@ -138,7 +139,8 @@ bool WebTransport::Init(const GlobalObject& aGlobal, const nsAString& aURL,
|
|||
|
||||
// https://w3c.github.io/webtransport/#webtransport-constructor Spec 5.2
|
||||
backgroundChild
|
||||
->SendCreateWebTransportParent(aURL, dedicated, requireUnreliable,
|
||||
->SendCreateWebTransportParent(aURL, principal, dedicated,
|
||||
requireUnreliable,
|
||||
(uint32_t)congestionControl,
|
||||
// XXX serverCertHashes,
|
||||
std::move(parentEndpoint))
|
||||
|
@ -172,6 +174,7 @@ void WebTransport::ResolveWaitingConnection(
|
|||
WebTransportReliabilityMode aReliability, WebTransportChild* aChild) {
|
||||
LOG(("Resolved Connection %p, reliability = %u", this,
|
||||
(unsigned)aReliability));
|
||||
|
||||
MOZ_ASSERT(mState == WebTransportState::CONNECTING);
|
||||
mChild = aChild;
|
||||
mState = WebTransportState::CONNECTED;
|
||||
|
|
|
@ -5,25 +5,30 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "WebTransportParent.h"
|
||||
|
||||
#include "Http3WebTransportSession.h"
|
||||
#include "mozilla/StaticPrefs_network.h"
|
||||
#include "mozilla/dom/WebTransportBinding.h"
|
||||
#include "mozilla/dom/WebTransportLog.h"
|
||||
#include "mozilla/ipc/BackgroundParent.h"
|
||||
#include "nsIEventTarget.h"
|
||||
#include "nsIOService.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsIWebTransport.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
NS_IMPL_ISUPPORTS(WebTransportParent, WebTransportSessionEventListener);
|
||||
|
||||
using IPCResult = mozilla::ipc::IPCResult;
|
||||
using CreateWebTransportPromise =
|
||||
MozPromise<WebTransportReliabilityMode, nsresult, true>;
|
||||
using ResolveType = Tuple<const nsresult&, const uint8_t&>;
|
||||
WebTransportParent::~WebTransportParent() {
|
||||
LOG(("Destroying WebTransportParent %p", this));
|
||||
}
|
||||
|
||||
// static
|
||||
void WebTransportParent::Create(
|
||||
const nsAString& aURL, const bool& aDedicated,
|
||||
const nsAString& aURL, nsIPrincipal* aPrincipal, const bool& aDedicated,
|
||||
const bool& aRequireUnreliable, const uint32_t& aCongestionControl,
|
||||
// Sequence<WebTransportHash>* aServerCertHashes,
|
||||
Endpoint<PWebTransportParent>&& aParentEndpoint,
|
||||
|
@ -54,39 +59,68 @@ void WebTransportParent::Create(
|
|||
return;
|
||||
}
|
||||
|
||||
MOZ_DIAGNOSTIC_ASSERT(mozilla::net::gIOService);
|
||||
nsresult rv =
|
||||
mozilla::net::gIOService->NewWebTransport(getter_AddRefs(mWebTransport));
|
||||
if (NS_FAILED(rv)) {
|
||||
aResolver(ResolveType(
|
||||
rv, static_cast<uint8_t>(WebTransportReliabilityMode::Pending)));
|
||||
return;
|
||||
}
|
||||
|
||||
mOwningEventTarget = GetCurrentEventTarget();
|
||||
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = NS_NewURI(getter_AddRefs(uri), aURL);
|
||||
if (NS_FAILED(rv)) {
|
||||
aResolver(ResolveType(
|
||||
NS_ERROR_INVALID_ARG,
|
||||
static_cast<uint8_t>(WebTransportReliabilityMode::Pending)));
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
|
||||
"WebTransport AsyncConnect",
|
||||
[self = RefPtr{this}, uri = std::move(uri),
|
||||
principal = RefPtr{aPrincipal},
|
||||
flags = nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL] {
|
||||
self->mWebTransport->AsyncConnect(uri, principal, flags, self);
|
||||
});
|
||||
|
||||
// Bind to SocketThread for IPC - connection creation/destruction must
|
||||
// hit MainThread, but keep all other traffic on SocketThread. Note that
|
||||
// we must call aResolver() on this (PBackground) thread.
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsISerialEventTarget> sts =
|
||||
do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
InvokeAsync(sts, __func__,
|
||||
[parentEndpoint = std::move(aParentEndpoint)]() mutable {
|
||||
RefPtr<WebTransportParent> parent = new WebTransportParent();
|
||||
mResolver = aResolver;
|
||||
|
||||
LOG(("Binding parent endpoint"));
|
||||
if (!parentEndpoint.Bind(parent)) {
|
||||
return CreateWebTransportPromise::CreateAndReject(
|
||||
NS_ERROR_FAILURE, __func__);
|
||||
}
|
||||
// IPC now holds a ref to parent
|
||||
// XXX Send connection to the server via MainThread
|
||||
return CreateWebTransportPromise::CreateAndResolve(
|
||||
WebTransportReliabilityMode::Supports_unreliable, __func__);
|
||||
})
|
||||
InvokeAsync(
|
||||
sts, __func__,
|
||||
[parentEndpoint = std::move(aParentEndpoint), runnable = r]() mutable {
|
||||
RefPtr<WebTransportParent> parent = new WebTransportParent();
|
||||
|
||||
LOG(("Binding parent endpoint"));
|
||||
if (!parentEndpoint.Bind(parent)) {
|
||||
return CreateWebTransportPromise::CreateAndReject(NS_ERROR_FAILURE,
|
||||
__func__);
|
||||
}
|
||||
// IPC now holds a ref to parent
|
||||
// Send connection to the server via MainThread
|
||||
NS_DispatchToMainThread(runnable, NS_DISPATCH_NORMAL);
|
||||
return CreateWebTransportPromise::CreateAndResolve(
|
||||
WebTransportReliabilityMode::Supports_unreliable, __func__);
|
||||
})
|
||||
->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[aResolver](
|
||||
[self = RefPtr{this}](
|
||||
const CreateWebTransportPromise::ResolveOrRejectValue& aValue) {
|
||||
if (aValue.IsReject()) {
|
||||
aResolver(ResolveType(
|
||||
self->mResolver(ResolveType(
|
||||
aValue.RejectValue(),
|
||||
static_cast<uint8_t>(WebTransportReliabilityMode::Pending)));
|
||||
} else {
|
||||
aResolver(ResolveType(
|
||||
NS_OK, static_cast<uint8_t>(aValue.ResolveValue())));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -101,9 +135,106 @@ mozilla::ipc::IPCResult WebTransportParent::RecvClose(
|
|||
const uint32_t& aCode, const nsACString& aReason) {
|
||||
LOG(("Close received, code = %u, reason = %s", aCode,
|
||||
PromiseFlatCString(aReason).get()));
|
||||
// XXX shut down streams cleanly
|
||||
MOZ_ASSERT(!mClosed);
|
||||
mClosed.Flip();
|
||||
NS_DispatchToMainThread(NS_NewRunnableFunction(
|
||||
"WebTransport Close", [self = RefPtr{this}, aCode, &aReason] {
|
||||
if (self->mWebTransport) {
|
||||
self->mWebTransport->CloseSession(aCode, aReason);
|
||||
}
|
||||
}));
|
||||
Close();
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
// We recieve this notification from the WebTransportSessionProxy if session was
|
||||
// successfully created at the end of
|
||||
// WebTransportSessionProxy::OnStopRequest
|
||||
NS_IMETHODIMP
|
||||
WebTransportParent::OnSessionReady(uint64_t aSessionId) {
|
||||
MOZ_ASSERT(mOwningEventTarget);
|
||||
MOZ_ASSERT(!mOwningEventTarget->IsOnCurrentThread());
|
||||
|
||||
LOG(("Created web transport session, sessionID = %" PRIu64 "", aSessionId));
|
||||
|
||||
mOwningEventTarget->Dispatch(NS_NewRunnableFunction(
|
||||
"WebTransportParent::OnSessionReady", [self = RefPtr{this}] {
|
||||
if (!self->IsClosed()) {
|
||||
self->mResolver(ResolveType(
|
||||
NS_OK, static_cast<uint8_t>(
|
||||
WebTransportReliabilityMode::Supports_unreliable)));
|
||||
}
|
||||
}));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// We recieve this notification from the WebTransportSessionProxy if session
|
||||
// creation was unsuccessful at the end of
|
||||
// WebTransportSessionProxy::OnStopRequest
|
||||
NS_IMETHODIMP
|
||||
WebTransportParent::OnSessionClosed(const uint32_t aErrorCode,
|
||||
const nsACString& aReason) {
|
||||
LOG(("Creating web transport session failed code= %u, reason= %s", aErrorCode,
|
||||
PromiseFlatCString(aReason).get()));
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (aErrorCode != 0) {
|
||||
// currently we just know if session was closed gracefully or not.
|
||||
// we need better error propagation from lower-levels of http3
|
||||
// webtransport session and it's subsequent error mapping to DOM.
|
||||
// XXX See Bug 1806834
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
MOZ_ASSERT(mOwningEventTarget);
|
||||
MOZ_ASSERT(!mOwningEventTarget->IsOnCurrentThread());
|
||||
|
||||
mOwningEventTarget->Dispatch(NS_NewRunnableFunction(
|
||||
"WebTransportParent::OnSessionClosed",
|
||||
[self = RefPtr{this}, result = rv] {
|
||||
if (!self->IsClosed()) {
|
||||
self->mResolver(ResolveType(
|
||||
result, static_cast<uint8_t>(
|
||||
WebTransportReliabilityMode::Supports_unreliable)));
|
||||
}
|
||||
}));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// This method is currently not used by WebTransportSessionProxy to inform of
|
||||
// any session related events. All notification is recieved via
|
||||
// WebTransportSessionProxy::OnSessionReady and
|
||||
// WebTransportSessionProxy::OnSessionClosed methods
|
||||
NS_IMETHODIMP
|
||||
WebTransportParent::OnSessionReadyInternal(
|
||||
mozilla::net::Http3WebTransportSession* aSession) {
|
||||
Unused << aSession;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebTransportParent::OnIncomingStreamAvailableInternal(
|
||||
mozilla::net::Http3WebTransportStream* aStream) {
|
||||
// XXX implement once DOM WebAPI supports creation of streams
|
||||
Unused << aStream;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebTransportParent::OnIncomingUnidirectionalStreamAvailable(
|
||||
nsIWebTransportReceiveStream* aStream) {
|
||||
// XXX implement once DOM WebAPI supports creation of streams
|
||||
Unused << aStream;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebTransportParent::OnIncomingBidirectionalStreamAvailable(
|
||||
nsIWebTransportBidirectionalStream* aStream) {
|
||||
// XXX implement once DOM WebAPI supports creation of streams
|
||||
Unused << aStream;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
|
@ -12,19 +12,23 @@
|
|||
#include "mozilla/dom/PWebTransportParent.h"
|
||||
#include "mozilla/ipc/Endpoint.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsIWebTransport.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
enum class WebTransportReliabilityMode : uint8_t;
|
||||
|
||||
class WebTransportParent : public PWebTransportParent {
|
||||
class WebTransportParent : public PWebTransportParent,
|
||||
public WebTransportSessionEventListener {
|
||||
public:
|
||||
WebTransportParent() = default;
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WebTransportParent, override)
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_WEBTRANSPORTSESSIONEVENTLISTENER
|
||||
|
||||
static void Create(
|
||||
const nsAString& aURL, const bool& aDedicated,
|
||||
void Create(
|
||||
const nsAString& aURL, nsIPrincipal* aPrincipal, const bool& aDedicated,
|
||||
const bool& aRequireUnreliable, const uint32_t& aCongestionControl,
|
||||
// Sequence<WebTransportHash>* aServerCertHashes,
|
||||
Endpoint<PWebTransportParent>&& aParentEndpoint,
|
||||
|
@ -35,8 +39,17 @@ class WebTransportParent : public PWebTransportParent {
|
|||
|
||||
void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
bool IsClosed() const { return mClosed; }
|
||||
|
||||
protected:
|
||||
virtual ~WebTransportParent();
|
||||
|
||||
private:
|
||||
using ResolveType = Tuple<const nsresult&, const uint8_t&>;
|
||||
std::function<void(ResolveType)> mResolver;
|
||||
FlippedOnce<false> mClosed;
|
||||
nsCOMPtr<nsIWebTransport> mWebTransport;
|
||||
nsCOMPtr<nsIEventTarget> mOwningEventTarget;
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
|
@ -15,3 +15,8 @@ UNIFIED_SOURCES += [
|
|||
FINAL_LIBRARY = "xul"
|
||||
|
||||
include("/ipc/chromium/chromium-config.mozbuild")
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
"/netwerk/base",
|
||||
"/netwerk/protocol/http",
|
||||
]
|
||||
|
|
|
@ -504,7 +504,7 @@ mozilla::ipc::IPCResult BackgroundParentImpl::RecvCreateFileSystemManagerParent(
|
|||
}
|
||||
|
||||
mozilla::ipc::IPCResult BackgroundParentImpl::RecvCreateWebTransportParent(
|
||||
const nsAString& aURL, const bool& aDedicated,
|
||||
const nsAString& aURL, nsIPrincipal* aPrincipal, const bool& aDedicated,
|
||||
const bool& aRequireUnreliable, const uint32_t& aCongestionControl,
|
||||
// Sequence<WebTransportHash>* aServerCertHashes,
|
||||
Endpoint<PWebTransportParent>&& aParentEndpoint,
|
||||
|
@ -512,8 +512,10 @@ mozilla::ipc::IPCResult BackgroundParentImpl::RecvCreateWebTransportParent(
|
|||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
mozilla::dom::WebTransportParent::Create(
|
||||
aURL, aDedicated, aRequireUnreliable, aCongestionControl,
|
||||
RefPtr<mozilla::dom::WebTransportParent> webt =
|
||||
new mozilla::dom::WebTransportParent();
|
||||
webt->Create(
|
||||
aURL, aPrincipal, aDedicated, aRequireUnreliable, aCongestionControl,
|
||||
/*aServerCertHashes, */ std::move(aParentEndpoint), std::move(aResolver));
|
||||
return IPC_OK();
|
||||
}
|
||||
|
|
|
@ -138,7 +138,7 @@ class BackgroundParentImpl : public PBackgroundParent {
|
|||
CreateFileSystemManagerParentResolver&& aResolver) override;
|
||||
|
||||
mozilla::ipc::IPCResult RecvCreateWebTransportParent(
|
||||
const nsAString& aURL, const bool& aDedicated,
|
||||
const nsAString& aURL, nsIPrincipal* aPrincipal, const bool& aDedicated,
|
||||
const bool& aRequireUnreliable, const uint32_t& aCongestionControl,
|
||||
// Sequence<WebTransportHash>* aServerCertHashes,
|
||||
Endpoint<PWebTransportParent>&& aParentEndpoint,
|
||||
|
|
|
@ -201,6 +201,7 @@ parent:
|
|||
*/
|
||||
async CreateWebTransportParent(
|
||||
nsString aURL,
|
||||
nsIPrincipal aPrincipal,
|
||||
bool aDedicated,
|
||||
bool aRequireUnreliable,
|
||||
uint32_t aCongestionControl,
|
||||
|
|
|
@ -93,6 +93,8 @@ nsresult WebTransportSessionProxy::AsyncConnect(
|
|||
rv = mChannel->AsyncOpen(this);
|
||||
if (NS_FAILED(rv)) {
|
||||
MutexAutoLock lock(mMutex);
|
||||
mChannel = nullptr;
|
||||
mListener = nullptr;
|
||||
ChangeState(WebTransportSessionProxyState::DONE);
|
||||
}
|
||||
return rv;
|
||||
|
|
Загрузка…
Ссылка в новой задаче