Bug 1790677: Initial WebTransport IPC for creating and closing WebTransport r=webidl,ipc-reviewers,smaug,nika

Differential Revision: https://phabricator.services.mozilla.com/D164124
This commit is contained in:
Randell Jesup 2022-12-19 17:57:59 +00:00
Родитель d3c6c33e10
Коммит faeae8bbf8
23 изменённых файлов: 582 добавлений и 26 удалений

Просмотреть файл

@ -29,7 +29,7 @@ enum WebTransportCongestionControl {
dictionary WebTransportCloseInfo { dictionary WebTransportCloseInfo {
unsigned long closeCode = 0; unsigned long closeCode = 0;
DOMString reason = ""; UTF8String reason = "";
}; };
/* https://w3c.github.io/webtransport/#web-transport-stats */ /* https://w3c.github.io/webtransport/#web-transport-stats */
@ -62,6 +62,7 @@ dictionary WebTransportDatagramStats {
[Exposed=(Window,Worker), SecureContext, Pref="network.webtransport.enabled"] [Exposed=(Window,Worker), SecureContext, Pref="network.webtransport.enabled"]
interface WebTransport { interface WebTransport {
[Throws]
constructor(USVString url, optional WebTransportOptions options = {}); constructor(USVString url, optional WebTransportOptions options = {});
[NewObject] [NewObject]

Просмотреть файл

@ -5,12 +5,22 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "WebTransport.h" #include "WebTransport.h"
#include "nsUTF8Utils.h"
#include "mozilla/Assertions.h" #include "mozilla/Assertions.h"
#include "mozilla/dom/Promise.h" #include "mozilla/dom/Promise.h"
#include "mozilla/dom/PWebTransport.h"
#include "mozilla/dom/ReadableStream.h"
#include "mozilla/dom/WebTransportLog.h"
#include "mozilla/ipc/BackgroundChild.h"
#include "mozilla/ipc/Endpoint.h"
#include "mozilla/ipc/PBackgroundChild.h"
namespace mozilla::dom { namespace mozilla::dom {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WebTransport, mGlobal) NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WebTransport, mGlobal,
mIncomingUnidirectionalStreams,
mIncomingBidirectionalStreams, mReady)
NS_IMPL_CYCLE_COLLECTING_ADDREF(WebTransport) NS_IMPL_CYCLE_COLLECTING_ADDREF(WebTransport)
NS_IMPL_CYCLE_COLLECTING_RELEASE(WebTransport) NS_IMPL_CYCLE_COLLECTING_RELEASE(WebTransport)
@ -19,6 +29,11 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebTransport)
NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END NS_INTERFACE_MAP_END
WebTransport::WebTransport(nsIGlobalObject* aGlobal)
: mGlobal(aGlobal), mState(WebTransportState::CONNECTING) {
LOG(("Creating WebTransport %p", this));
}
// WebIDL Boilerplate // WebIDL Boilerplate
nsIGlobalObject* WebTransport::GetParentObject() const { return mGlobal; } nsIGlobalObject* WebTransport::GetParentObject() const { return mGlobal; }
@ -32,9 +47,110 @@ JSObject* WebTransport::WrapObject(JSContext* aCx,
/* static */ /* static */
already_AddRefed<WebTransport> WebTransport::Constructor( already_AddRefed<WebTransport> WebTransport::Constructor(
const GlobalObject& aGlobal, const nsAString& aUrl, const GlobalObject& aGlobal, const nsAString& aURL,
const WebTransportOptions& aOptions) { const WebTransportOptions& aOptions, ErrorResult& aError) {
return nullptr; LOG(("Creating WebTransport for %s", NS_ConvertUTF16toUTF8(aURL).get()));
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
RefPtr<WebTransport> result = new WebTransport(global);
if (!result->Init(aGlobal, aURL, aOptions, aError)) {
return nullptr;
}
return result.forget();
}
bool WebTransport::Init(const GlobalObject& aGlobal, const nsAString& aURL,
const WebTransportOptions& aOptions,
ErrorResult& aError) {
// Initiate connection with parent
using mozilla::ipc::BackgroundChild;
using mozilla::ipc::Endpoint;
using mozilla::ipc::PBackgroundChild;
mReady = Promise::Create(mGlobal, aError);
if (NS_WARN_IF(aError.Failed())) {
return false;
}
QueuingStrategy strategy;
Optional<JS::Handle<JSObject*>> underlying;
mIncomingUnidirectionalStreams =
ReadableStream::Constructor(aGlobal, underlying, strategy, aError);
if (aError.Failed()) {
return false;
}
mIncomingBidirectionalStreams =
ReadableStream::Constructor(aGlobal, underlying, strategy, aError);
if (aError.Failed()) {
return false;
}
PBackgroundChild* backgroundChild =
BackgroundChild::GetOrCreateForCurrentThread();
if (NS_WARN_IF(!backgroundChild)) {
return false;
}
// Create a new IPC connection
Endpoint<PWebTransportParent> parentEndpoint;
Endpoint<PWebTransportChild> childEndpoint;
MOZ_ALWAYS_SUCCEEDS(
PWebTransport::CreateEndpoints(&parentEndpoint, &childEndpoint));
RefPtr<WebTransportChild> child = new WebTransportChild();
if (!childEndpoint.Bind(child)) {
return false;
}
mState = WebTransportState::CONNECTING;
LOG(("Connecting WebTransport to parent for %s",
NS_ConvertUTF16toUTF8(aURL).get()));
// XXX TODO: Parse string for validity and Throw a SyntaxError if it isn't
// XXX and other steps in the constructor requirement (TypeError). Order is
// important.
// https://w3c.github.io/webtransport/#webtransport-constructor Spec 5.2
backgroundChild
->SendCreateWebTransportParent(aURL /*, aOptions*/,
std::move(parentEndpoint))
->Then(
GetCurrentSerialEventTarget(), __func__,
[self = RefPtr{this}, child](nsresult rv) {
if (NS_FAILED(rv)) {
self->RejectWaitingConnection(rv);
} else {
// This will process anything waiting for the connection to
// complete;
self->ResolveWaitingConnection(child);
}
},
[self = RefPtr<WebTransport>(this)](
const mozilla::ipc::ResponseRejectReason&) {
// This will process anything waiting for the connection to
// complete;
self->RejectWaitingConnection(NS_ERROR_FAILURE);
});
return true;
}
void WebTransport::ResolveWaitingConnection(WebTransportChild* aChild) {
LOG(("Resolved Connection %p", this));
MOZ_ASSERT(mState == WebTransportState::CONNECTING);
mChild = aChild;
mState = WebTransportState::CONNECTED;
mReady->MaybeResolve(true);
}
void WebTransport::RejectWaitingConnection(nsresult aRv) {
LOG(("Reject Connection %p", this));
MOZ_ASSERT(mState == WebTransportState::CONNECTING);
mState = WebTransportState::FAILED;
LOG(("Rejected connection %x", aRv));
mReady->MaybeReject(aRv);
} }
already_AddRefed<Promise> WebTransport::GetStats(ErrorResult& aError) { already_AddRefed<Promise> WebTransport::GetStats(ErrorResult& aError) {
@ -42,15 +158,7 @@ already_AddRefed<Promise> WebTransport::GetStats(ErrorResult& aError) {
return nullptr; return nullptr;
} }
already_AddRefed<Promise> WebTransport::Ready() { already_AddRefed<Promise> WebTransport::Ready() { return do_AddRef(mReady); }
ErrorResult error;
RefPtr<Promise> promise = Promise::Create(GetParentObject(), error);
if (error.Failed()) {
return nullptr;
}
promise->MaybeRejectWithUndefined();
return promise.forget();
}
WebTransportReliabilityMode WebTransport::Reliability() { WebTransportReliabilityMode WebTransport::Reliability() {
// XXX not implemented // XXX not implemented
@ -68,37 +176,70 @@ already_AddRefed<Promise> WebTransport::Closed() {
if (error.Failed()) { if (error.Failed()) {
return nullptr; return nullptr;
} }
promise->MaybeRejectWithUndefined(); promise->MaybeResolve(mState == WebTransportState::CLOSED);
return promise.forget(); return promise.forget();
} }
void WebTransport::Close(const WebTransportCloseInfo& aOptions) {} void WebTransport::Close(const WebTransportCloseInfo& aOptions) {
LOG(("Close() called"));
if (mState == WebTransportState::CONNECTED ||
mState == WebTransportState::CONNECTING) {
MOZ_ASSERT(mChild);
LOG(("Sending Close"));
// "Let reasonString be the maximal code unit prefix of
// closeInfo.reason where the length of the UTF-8 encoded prefix
// doesnt exceed 1024."
// Take the maximal "code unit prefix" of mReason and limit to 1024 bytes
// https://w3c.github.io/webtransport/#webtransport-methods 5.4
if (aOptions.mReason.Length() > 1024u) {
// We want to start looking for the previous code point at one past the
// limit, since if a code point ends exactly at the specified length, the
// next byte will be the start of a new code point. Note
// RewindToPriorUTF8Codepoint doesn't reduce the index if it points to the
// start of a code point. We know reason[1024] is accessible since
// Length() > 1024
mChild->SendClose(
aOptions.mCloseCode,
Substring(aOptions.mReason, 0,
RewindToPriorUTF8Codepoint(aOptions.mReason.get(), 1024u)));
} else {
mChild->SendClose(aOptions.mCloseCode, aOptions.mReason);
}
mState = WebTransportState::CLOSED;
// The other side will call `Close()` for us now, make sure we don't call it
// in our destructor.
mChild = nullptr;
}
}
already_AddRefed<WebTransportDatagramDuplexStream> WebTransport::Datagrams() { already_AddRefed<WebTransportDatagramDuplexStream> WebTransport::Datagrams() {
LOG(("Datagrams() called"));
// XXX not implemented // XXX not implemented
return nullptr; return nullptr;
} }
already_AddRefed<Promise> WebTransport::CreateBidirectionalStream( already_AddRefed<Promise> WebTransport::CreateBidirectionalStream(
ErrorResult& aError) { ErrorResult& aError) {
LOG(("CreateBidirectionalStream() called"));
aError.Throw(NS_ERROR_NOT_IMPLEMENTED); aError.Throw(NS_ERROR_NOT_IMPLEMENTED);
return nullptr; return nullptr;
} }
already_AddRefed<ReadableStream> WebTransport::IncomingBidirectionalStreams() { already_AddRefed<ReadableStream> WebTransport::IncomingBidirectionalStreams() {
// XXX not implemented return do_AddRef(mIncomingBidirectionalStreams);
return nullptr;
} }
already_AddRefed<Promise> WebTransport::CreateUnidirectionalStream( already_AddRefed<Promise> WebTransport::CreateUnidirectionalStream(
ErrorResult& aError) { ErrorResult& aError) {
LOG(("CreateUnidirectionalStream() called"));
aError.Throw(NS_ERROR_NOT_IMPLEMENTED); aError.Throw(NS_ERROR_NOT_IMPLEMENTED);
return nullptr; return nullptr;
} }
already_AddRefed<ReadableStream> WebTransport::IncomingUnidirectionalStreams() { already_AddRefed<ReadableStream> WebTransport::IncomingUnidirectionalStreams() {
// XXX not implemented return do_AddRef(mIncomingUnidirectionalStreams);
return nullptr;
} }
} // namespace mozilla::dom } // namespace mozilla::dom

Просмотреть файл

@ -11,6 +11,7 @@
#include "nsISupports.h" #include "nsISupports.h"
#include "nsWrapperCache.h" #include "nsWrapperCache.h"
#include "mozilla/dom/WebTransportBinding.h" #include "mozilla/dom/WebTransportBinding.h"
#include "mozilla/dom/WebTransportChild.h"
namespace mozilla::dom { namespace mozilla::dom {
@ -20,11 +21,18 @@ class WritableStream;
class WebTransport final : public nsISupports, public nsWrapperCache { class WebTransport final : public nsISupports, public nsWrapperCache {
public: public:
explicit WebTransport(nsIGlobalObject* aGlobal) : mGlobal(aGlobal) {} explicit WebTransport(nsIGlobalObject* aGlobal);
NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(WebTransport) NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(WebTransport)
enum class WebTransportState { CONNECTING, CONNECTED, CLOSED, FAILED };
bool Init(const GlobalObject& aGlobal, const nsAString& aUrl,
const WebTransportOptions& aOptions, ErrorResult& aError);
void ResolveWaitingConnection(WebTransportChild* aChild);
void RejectWaitingConnection(nsresult aRv);
// WebIDL Boilerplate // WebIDL Boilerplate
nsIGlobalObject* GetParentObject() const; nsIGlobalObject* GetParentObject() const;
@ -34,7 +42,7 @@ class WebTransport final : public nsISupports, public nsWrapperCache {
// WebIDL Interface // WebIDL Interface
static already_AddRefed<WebTransport> Constructor( static already_AddRefed<WebTransport> Constructor(
const GlobalObject& aGlobal, const nsAString& aUrl, const GlobalObject& aGlobal, const nsAString& aUrl,
const WebTransportOptions& aOptions); const WebTransportOptions& aOptions, ErrorResult& aRv);
already_AddRefed<Promise> GetStats(ErrorResult& aError); already_AddRefed<Promise> GetStats(ErrorResult& aError);
@ -49,11 +57,25 @@ class WebTransport final : public nsISupports, public nsWrapperCache {
already_AddRefed<Promise> CreateUnidirectionalStream(ErrorResult& aError); already_AddRefed<Promise> CreateUnidirectionalStream(ErrorResult& aError);
already_AddRefed<ReadableStream> IncomingUnidirectionalStreams(); already_AddRefed<ReadableStream> IncomingUnidirectionalStreams();
void Shutdown() {}
private: private:
~WebTransport() = default; ~WebTransport() {
// If this WebTransport was destroyed without being closed properly, make
// sure to clean up the channel.
if (mChild) {
mChild->Shutdown();
}
}
nsCOMPtr<nsIGlobalObject> mGlobal; nsCOMPtr<nsIGlobalObject> mGlobal;
// RefPtr<WebTransportChannel> mChannel; RefPtr<WebTransportChild> mChild;
// These are created in the constructor
RefPtr<ReadableStream> mIncomingUnidirectionalStreams;
RefPtr<ReadableStream> mIncomingBidirectionalStreams;
RefPtr<Promise> mReady;
WebTransportState mState;
}; };
} // namespace mozilla::dom } // namespace mozilla::dom

Просмотреть файл

@ -21,3 +21,5 @@ UNIFIED_SOURCES += [
] ]
FINAL_LIBRARY = "xul" FINAL_LIBRARY = "xul"
include("/ipc/chromium/chromium-config.mozbuild")

Просмотреть файл

@ -0,0 +1,43 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef DOM_WEBTRANSPORT_WEBTRANSPORTCHILD_H_
#define DOM_WEBTRANSPORT_WEBTRANSPORTCHILD_H_
#include "mozilla/dom/PWebTransportChild.h"
#include "nsISupportsImpl.h"
namespace mozilla::dom {
class WebTransportChild : public PWebTransportChild {
public:
NS_INLINE_DECL_REFCOUNTING(WebTransportChild)
virtual void CloseAll() {
// XXX need impl
}
virtual void Shutdown() {
if (!CanSend()) {
return;
}
Close();
}
::mozilla::ipc::IPCResult RecvCloseAll(CloseAllResolver&& aResolver) {
CloseAll();
aResolver(NS_OK);
return IPC_OK();
}
protected:
virtual ~WebTransportChild() = default;
};
} // namespace mozilla::dom
#endif // DOM_WEBTRANSPORT_WEBTRANSPORTCHILD_H_

Просмотреть файл

@ -0,0 +1,13 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXPORTS.mozilla.dom += [
"WebTransportChild.h",
]
FINAL_LIBRARY = "xul"
include("/ipc/chromium/chromium-config.mozbuild")

Просмотреть файл

@ -6,4 +6,8 @@
DIRS += [ DIRS += [
"api", "api",
"child",
"parent",
"shared",
"test",
] ]

Просмотреть файл

@ -0,0 +1,63 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "WebTransportParent.h"
#include "mozilla/StaticPrefs_network.h"
#include "mozilla/dom/WebTransportLog.h"
#include "mozilla/ipc/BackgroundParent.h"
using IPCResult = mozilla::ipc::IPCResult;
namespace mozilla::dom {
WebTransportParent::~WebTransportParent() {
LOG(("Destroying WebTransportParent %p", this));
}
bool WebTransportParent::Init(
const nsAString& aURL,
// WebTransportOptions aOptions,
Endpoint<PWebTransportParent>&& aParentEndpoint,
std::function<void(const nsresult&)>&& aResolver) {
LOG(("Created WebTransportParent %p %s", this,
NS_ConvertUTF16toUTF8(aURL).get()));
if (!StaticPrefs::network_webtransport_enabled()) {
aResolver(NS_ERROR_DOM_NOT_ALLOWED_ERR);
return false;
}
if (!aParentEndpoint.IsValid()) {
aResolver(NS_ERROR_INVALID_ARG);
return false;
}
if (!aParentEndpoint.Bind(this)) {
aResolver(NS_ERROR_FAILURE);
return false;
}
// XXX Send connection to the server
aResolver(NS_OK);
return true;
}
void WebTransportParent::ActorDestroy(ActorDestroyReason aWhy) {
LOG(("ActorDestroy WebTransportParent %d", aWhy));
}
// We may not receive this response if the child side is destroyed without
// `Close` or `Shutdown` being explicitly called.
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
Close();
return IPC_OK();
}
} // namespace mozilla::dom

Просмотреть файл

@ -0,0 +1,40 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef DOM_WEBTRANSPORT_PARENT_WEBTRANSPORTPARENT_H_
#define DOM_WEBTRANSPORT_PARENT_WEBTRANSPORTPARENT_H_
#include "ErrorList.h"
#include "mozilla/dom/FlippedOnce.h"
#include "mozilla/dom/PWebTransportParent.h"
#include "mozilla/ipc/Endpoint.h"
#include "nsISupports.h"
namespace mozilla::dom {
class WebTransportParent : public PWebTransportParent {
public:
WebTransportParent() = default;
// XXX Threadsafe??
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WebTransportParent, override)
bool Init(const nsAString& aURL, // WebTransportOptions aOptions,
Endpoint<PWebTransportParent>&& aParentEndpoint,
std::function<void(const nsresult&)>&& aResolver);
mozilla::ipc::IPCResult RecvClose(const uint32_t& aCode,
const nsACString& aReason);
void ActorDestroy(ActorDestroyReason aWhy) override;
protected:
virtual ~WebTransportParent();
};
} // namespace mozilla::dom
#endif // DOM_WEBTRANSPORT_PARENT_WEBTRANSPORTPARENT_H_

Просмотреть файл

@ -0,0 +1,17 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXPORTS.mozilla.dom += [
"WebTransportParent.h",
]
UNIFIED_SOURCES += [
"WebTransportParent.cpp",
]
FINAL_LIBRARY = "xul"
include("/ipc/chromium/chromium-config.mozbuild")

Просмотреть файл

@ -0,0 +1,26 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
using struct mozilla::void_t from "mozilla/ipc/IPCCore.h";
namespace mozilla {
namespace dom {
async protocol PWebTransport
{
parent:
/**
* TODO: documentation
*/
async Close(uint32_t code, nsCString reason);
child:
async CloseAll()
returns(nsresult rv);
};
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,13 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "WebTransportLog.h"
namespace mozilla {
LazyLogModule gWebTransportLog("WebTransport");
}

Просмотреть файл

@ -0,0 +1,25 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef DOM_WEBTRANSPORT_SHARED_WEBTRANSPORTLOG_H_
#define DOM_WEBTRANSPORT_SHARED_WEBTRANSPORTLOG_H_
#include "mozilla/Logging.h"
namespace mozilla {
extern LazyLogModule gWebTransportLog;
}
#define LOG(args) \
MOZ_LOG(mozilla::gWebTransportLog, mozilla::LogLevel::Debug, args)
#define LOG_VERBOSE(args) \
MOZ_LOG(mozilla::gWebTransportLog, mozilla::LogLevel::Verbose, args)
#define LOG_ENABLED() \
MOZ_LOG_TEST(mozilla::gWebTransportLog, mozilla::LogLevel::Debug)
#endif // DOM_WEBTRANSPORT_SHARED_WEBTRANSPORTLOG_H

Просмотреть файл

@ -0,0 +1,21 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXPORTS.mozilla.dom += [
"WebTransportLog.h",
]
UNIFIED_SOURCES += [
"WebTransportLog.cpp",
]
FINAL_LIBRARY = "xul"
IPDL_SOURCES += [
"PWebTransport.ipdl",
]
include("/ipc/chromium/chromium-config.mozbuild")

Просмотреть файл

@ -0,0 +1,9 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
TEST_DIRS += [
"xpcshell",
]

Просмотреть файл

@ -0,0 +1,9 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
XPCSHELL_TESTS_MANIFESTS += [
"xpcshell.ini",
]

Просмотреть файл

@ -0,0 +1,64 @@
//
// Simple WebTransport test
//
// keep eslint happy until it knows about WebTransport
/* global WebTransport:false */
"use strict";
var h3Port;
var host;
registerCleanupFunction(async () => {
Services.prefs.clearUserPref("network.dns.localDomains");
});
var { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
function readFile(file) {
let fstream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(
Ci.nsIFileInputStream
);
fstream.init(file, -1, 0, 0);
let data = NetUtil.readInputStreamToString(fstream, fstream.available());
fstream.close();
return data;
}
function addCertFromFile(certdb, filename, trustString) {
let certFile = do_get_file(filename, false);
let pem = readFile(certFile)
.replace(/-----BEGIN CERTIFICATE-----/, "")
.replace(/-----END CERTIFICATE-----/, "")
.replace(/[\r\n]/g, "");
certdb.addCertFromBase64(pem, trustString);
}
add_task(async function setup() {
Services.prefs.setCharPref("network.dns.localDomains", "foo.example.com");
h3Port = Services.env.get("MOZHTTP3_PORT");
Assert.notEqual(h3Port, null);
Assert.notEqual(h3Port, "");
host = "foo.example.com:" + h3Port;
do_get_profile();
let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService(
Ci.nsIX509CertDB
);
// `../unit/` so that unit_ipc tests can use as well
addCertFromFile(
certdb,
"../../../../netwerk/test/unit/http2-ca.pem",
"CTu,u,u"
);
});
add_task(async function test_webtransport_create() {
Services.prefs.setBoolPref("network.webtransport.enabled", true);
const wt = new WebTransport("https://" + host + "/success");
await wt.ready;
wt.close();
});

Просмотреть файл

@ -0,0 +1,7 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
[DEFAULT]
[test_close.js]

Просмотреть файл

@ -48,6 +48,7 @@
#include "mozilla/dom/StorageIPC.h" #include "mozilla/dom/StorageIPC.h"
#include "mozilla/dom/TemporaryIPCBlobParent.h" #include "mozilla/dom/TemporaryIPCBlobParent.h"
#include "mozilla/dom/WebAuthnTransactionParent.h" #include "mozilla/dom/WebAuthnTransactionParent.h"
#include "mozilla/dom/WebTransportParent.h"
#include "mozilla/dom/cache/ActorUtils.h" #include "mozilla/dom/cache/ActorUtils.h"
#include "mozilla/dom/indexedDB/ActorsParent.h" #include "mozilla/dom/indexedDB/ActorsParent.h"
#include "mozilla/dom/locks/LockManagerParent.h" #include "mozilla/dom/locks/LockManagerParent.h"
@ -502,6 +503,23 @@ mozilla::ipc::IPCResult BackgroundParentImpl::RecvCreateFileSystemManagerParent(
aPrincipalInfo, std::move(aParentEndpoint), std::move(aResolver)); aPrincipalInfo, std::move(aParentEndpoint), std::move(aResolver));
} }
mozilla::ipc::IPCResult BackgroundParentImpl::RecvCreateWebTransportParent(
const nsAString& aURL,
// WebTransportOptions aOptions,
Endpoint<PWebTransportParent>&& aParentEndpoint,
CreateWebTransportParentResolver&& aResolver) {
AssertIsInMainProcess();
AssertIsOnBackgroundThread();
RefPtr<mozilla::dom::WebTransportParent> webt =
new mozilla::dom::WebTransportParent();
if (!webt->Init(aURL, /*aOptions, */ std::move(aParentEndpoint),
std::move(aResolver))) {
webt->Close();
}
return IPC_OK();
}
already_AddRefed<PIdleSchedulerParent> already_AddRefed<PIdleSchedulerParent>
BackgroundParentImpl::AllocPIdleSchedulerParent() { BackgroundParentImpl::AllocPIdleSchedulerParent() {
AssertIsOnBackgroundThread(); AssertIsOnBackgroundThread();

Просмотреть файл

@ -137,6 +137,12 @@ class BackgroundParentImpl : public PBackgroundParent {
Endpoint<mozilla::dom::PFileSystemManagerParent>&& aParentEndpoint, Endpoint<mozilla::dom::PFileSystemManagerParent>&& aParentEndpoint,
CreateFileSystemManagerParentResolver&& aResolver) override; CreateFileSystemManagerParentResolver&& aResolver) override;
mozilla::ipc::IPCResult RecvCreateWebTransportParent(
const nsAString& aURL,
// WebTransportOptions aOptions,
Endpoint<PWebTransportParent>&& aParentEndpoint,
CreateWebTransportParentResolver&& aResolver) override;
already_AddRefed<PIdleSchedulerParent> AllocPIdleSchedulerParent() override; already_AddRefed<PIdleSchedulerParent> AllocPIdleSchedulerParent() override;
PTemporaryIPCBlobParent* AllocPTemporaryIPCBlobParent() override; PTemporaryIPCBlobParent* AllocPTemporaryIPCBlobParent() override;

Просмотреть файл

@ -52,6 +52,7 @@ include protocol PVerifySSLServerCert;
include protocol PVsync; include protocol PVsync;
include protocol PRemoteDecoderManager; include protocol PRemoteDecoderManager;
include protocol PWebSocketConnection; include protocol PWebSocketConnection;
include protocol PWebTransport;
include DOMTypes; include DOMTypes;
include IPCBlob; include IPCBlob;
@ -197,6 +198,15 @@ parent:
Endpoint<PFileSystemManagerParent> aParentEndpoint) Endpoint<PFileSystemManagerParent> aParentEndpoint)
returns(nsresult rv); returns(nsresult rv);
/**
* Finish the setup of a new PWebTransport top level protocol.
*/
async CreateWebTransportParent(
nsString aURL,
/* WebTransportOptions aOptions, */
Endpoint<PWebTransportParent> aParentEndpoint)
returns(nsresult rv);
async PVsync(); async PVsync();
async PCameras(); async PCameras();

Просмотреть файл

@ -63,7 +63,9 @@ promise_test(async t => {
const close_info = await wt.closed; const close_info = await wt.closed;
assert_equals(close_info.closeCode, 11, 'code'); assert_equals(close_info.closeCode, 11, 'code');
assert_equals(close_info.reason, reason, 'reason'); // This should be truncated to 1023 bytes!
const reason_truncated = 'あいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあいうえおあ';
assert_equals(close_info.reason, reason_truncated, 'reason');
await wait(10); await wait(10);
const data = await query(id); const data = await query(id);

Просмотреть файл

@ -92,4 +92,4 @@ async function readInto(reader, buffer) {
} }
return buffer; return buffer;
} }