diff options
Diffstat (limited to 'dom/webtransport/api')
-rw-r--r-- | dom/webtransport/api/WebTransport.cpp | 306 | ||||
-rw-r--r-- | dom/webtransport/api/WebTransport.h | 102 | ||||
-rw-r--r-- | dom/webtransport/api/WebTransportBidirectionalStream.cpp | 34 | ||||
-rw-r--r-- | dom/webtransport/api/WebTransportBidirectionalStream.h | 52 | ||||
-rw-r--r-- | dom/webtransport/api/WebTransportDatagramDuplexStream.cpp | 35 | ||||
-rw-r--r-- | dom/webtransport/api/WebTransportDatagramDuplexStream.h | 78 | ||||
-rw-r--r-- | dom/webtransport/api/WebTransportError.cpp | 30 | ||||
-rw-r--r-- | dom/webtransport/api/WebTransportError.h | 34 | ||||
-rw-r--r-- | dom/webtransport/api/WebTransportReceiveStream.h | 39 | ||||
-rw-r--r-- | dom/webtransport/api/WebTransportSendStream.h | 39 | ||||
-rw-r--r-- | dom/webtransport/api/moz.build | 25 |
11 files changed, 774 insertions, 0 deletions
diff --git a/dom/webtransport/api/WebTransport.cpp b/dom/webtransport/api/WebTransport.cpp new file mode 100644 index 0000000000..5915827f62 --- /dev/null +++ b/dom/webtransport/api/WebTransport.cpp @@ -0,0 +1,306 @@ +/* -*- 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 "WebTransport.h" + +#include "nsUTF8Utils.h" +#include "nsIURL.h" +#include "mozilla/Assertions.h" +#include "mozilla/dom/Promise.h" +#include "mozilla/dom/PWebTransport.h" +#include "mozilla/dom/ReadableStream.h" +#include "mozilla/dom/WebTransportDatagramDuplexStream.h" +#include "mozilla/dom/WebTransportLog.h" +#include "mozilla/dom/WritableStream.h" +#include "mozilla/ipc/BackgroundChild.h" +#include "mozilla/ipc/Endpoint.h" +#include "mozilla/ipc/PBackgroundChild.h" + +namespace mozilla::dom { + +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WebTransport, mGlobal, + mIncomingUnidirectionalStreams, + mIncomingBidirectionalStreams, + mSendStreams, mReceiveStreams, mDatagrams, + mReady, mClosed) + +NS_IMPL_CYCLE_COLLECTING_ADDREF(WebTransport) +NS_IMPL_CYCLE_COLLECTING_RELEASE(WebTransport) +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebTransport) + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY + NS_INTERFACE_MAP_ENTRY(nsISupports) +NS_INTERFACE_MAP_END + +WebTransport::WebTransport(nsIGlobalObject* aGlobal) + : mGlobal(aGlobal), + mState(WebTransportState::CONNECTING), + mReliability(WebTransportReliabilityMode::Pending) { + LOG(("Creating WebTransport %p", this)); +} + +// WebIDL Boilerplate + +nsIGlobalObject* WebTransport::GetParentObject() const { return mGlobal; } + +JSObject* WebTransport::WrapObject(JSContext* aCx, + JS::Handle<JSObject*> aGivenProto) { + return WebTransport_Binding::Wrap(aCx, this, aGivenProto); +} + +// WebIDL Interface + +/* static */ +already_AddRefed<WebTransport> WebTransport::Constructor( + const GlobalObject& aGlobal, const nsAString& aURL, + const WebTransportOptions& aOptions, ErrorResult& aError) { + 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; + } + + mClosed = 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; + } + + nsCOMPtr<nsIPrincipal> principal = nsContentUtils::GetSystemPrincipal(); + // 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())); + + // Parse string for validity and Throw a SyntaxError if it isn't + if (!ParseURL(aURL)) { + aError.ThrowSyntaxError("Invalid WebTransport URL"); + return false; + } + bool dedicated = + !aOptions.mAllowPooling; // spec language, optimizer will eliminate this + bool requireUnreliable = aOptions.mRequireUnreliable; + WebTransportCongestionControl congestionControl = aOptions.mCongestionControl; + if (aOptions.mServerCertificateHashes.WasPassed()) { + // XXX bug 1806693 + aError.ThrowNotSupportedError("No support for serverCertificateHashes yet"); + // XXX if dedicated is false and serverCertificateHashes is non-null, then + // throw a TypeError. Also should enforce in parent + return false; + } + + // https://w3c.github.io/webtransport/#webtransport-constructor Spec 5.2 + backgroundChild + ->SendCreateWebTransportParent(aURL, principal, dedicated, + requireUnreliable, + (uint32_t)congestionControl, + // XXX serverCertHashes, + std::move(parentEndpoint)) + ->Then(GetCurrentSerialEventTarget(), __func__, + [self = RefPtr{this}, + child](PBackgroundChild::CreateWebTransportParentPromise:: + ResolveOrRejectValue&& aResult) { + // aResult is a Tuple<nsresult, uint8_t> + // TODO: is there a better/more-spec-compliant error in the + // reject case? Which begs the question, why would we get a + // reject? + nsresult rv = aResult.IsReject() + ? NS_ERROR_FAILURE + : Get<0>(aResult.ResolveValue()); + if (NS_FAILED(rv)) { + self->RejectWaitingConnection(rv); + } else { + // This will process anything waiting for the connection to + // complete; + self->ResolveWaitingConnection( + static_cast<WebTransportReliabilityMode>( + Get<1>(aResult.ResolveValue())), + child); + } + }); + + return true; +} + +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; + mReliability = aReliability; + + 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", (uint32_t)aRv)); + + // https://w3c.github.io/webtransport/#webtransport-internal-slots + // "Reliability returns "pending" until a connection is established" so + // we leave it pending + mReady->MaybeReject(aRv); +} + +bool WebTransport::ParseURL(const nsAString& aURL) const { + NS_ENSURE_TRUE(!aURL.IsEmpty(), false); + + // 5.4 = https://w3c.github.io/webtransport/#webtransport-constructor + // 5.4 #1 and #2 + nsCOMPtr<nsIURI> uri; + nsresult rv = NS_NewURI(getter_AddRefs(uri), aURL); + NS_ENSURE_SUCCESS(rv, false); + + // 5.4 #3 + if (!uri->SchemeIs("https")) { + return false; + } + + // 5.4 #4 no fragments + bool hasRef; + rv = uri->GetHasRef(&hasRef); + NS_ENSURE_TRUE(NS_SUCCEEDED(rv) && !hasRef, false); + + return true; +} + +already_AddRefed<Promise> WebTransport::GetStats(ErrorResult& aError) { + aError.Throw(NS_ERROR_NOT_IMPLEMENTED); + return nullptr; +} + +already_AddRefed<Promise> WebTransport::Ready() { return do_AddRef(mReady); } + +WebTransportReliabilityMode WebTransport::Reliability() { return mReliability; } + +WebTransportCongestionControl WebTransport::CongestionControl() { + // XXX not implemented + return WebTransportCongestionControl::Default; +} + +already_AddRefed<Promise> WebTransport::Closed() { + ErrorResult error; + RefPtr<Promise> promise = Promise::Create(GetParentObject(), error); + if (error.Failed()) { + return nullptr; + } + promise->MaybeResolve(mState == WebTransportState::CLOSED); + return promise.forget(); +} + +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 + // doesn’t 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() { + LOG(("Datagrams() called")); + // XXX not implemented + return nullptr; +} + +already_AddRefed<Promise> WebTransport::CreateBidirectionalStream( + ErrorResult& aError) { + LOG(("CreateBidirectionalStream() called")); + aError.Throw(NS_ERROR_NOT_IMPLEMENTED); + return nullptr; +} + +already_AddRefed<ReadableStream> WebTransport::IncomingBidirectionalStreams() { + return do_AddRef(mIncomingBidirectionalStreams); +} + +already_AddRefed<Promise> WebTransport::CreateUnidirectionalStream( + ErrorResult& aError) { + LOG(("CreateUnidirectionalStream() called")); + aError.Throw(NS_ERROR_NOT_IMPLEMENTED); + return nullptr; +} + +already_AddRefed<ReadableStream> WebTransport::IncomingUnidirectionalStreams() { + return do_AddRef(mIncomingUnidirectionalStreams); +} + +} // namespace mozilla::dom diff --git a/dom/webtransport/api/WebTransport.h b/dom/webtransport/api/WebTransport.h new file mode 100644 index 0000000000..803a370676 --- /dev/null +++ b/dom/webtransport/api/WebTransport.h @@ -0,0 +1,102 @@ +/* -*- 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_API_WEBTRANSPORT__H_ +#define DOM_WEBTRANSPORT_API_WEBTRANSPORT__H_ + +#include "nsCOMPtr.h" +#include "nsISupports.h" +#include "nsWrapperCache.h" +#include "mozilla/dom/WebTransportBinding.h" +#include "mozilla/dom/WebTransportChild.h" + +namespace mozilla::dom { + +class WebTransportDatagramDuplexStream; +class ReadableStream; +class WritableStream; + +class WebTransport final : public nsISupports, public nsWrapperCache { + public: + explicit WebTransport(nsIGlobalObject* aGlobal); + + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + 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(WebTransportReliabilityMode aReliability, + WebTransportChild* aChild); + void RejectWaitingConnection(nsresult aRv); + bool ParseURL(const nsAString& aURL) const; + + // WebIDL Boilerplate + nsIGlobalObject* GetParentObject() const; + + JSObject* WrapObject(JSContext* aCx, + JS::Handle<JSObject*> aGivenProto) override; + + // WebIDL Interface + static already_AddRefed<WebTransport> Constructor( + const GlobalObject& aGlobal, const nsAString& aUrl, + const WebTransportOptions& aOptions, ErrorResult& aRv); + + already_AddRefed<Promise> GetStats(ErrorResult& aError); + + already_AddRefed<Promise> Ready(); + WebTransportReliabilityMode Reliability(); + WebTransportCongestionControl CongestionControl(); + already_AddRefed<Promise> Closed(); + void Close(const WebTransportCloseInfo& aOptions); + already_AddRefed<WebTransportDatagramDuplexStream> Datagrams(); + already_AddRefed<Promise> CreateBidirectionalStream(ErrorResult& aError); + already_AddRefed<ReadableStream> IncomingBidirectionalStreams(); + already_AddRefed<Promise> CreateUnidirectionalStream(ErrorResult& aError); + already_AddRefed<ReadableStream> IncomingUnidirectionalStreams(); + + void Shutdown() {} + + private: + ~WebTransport() { + // Should be empty by this point, because we should always have run cleanup: + // https://w3c.github.io/webtransport/#webtransport-procedures + MOZ_ASSERT(mSendStreams.IsEmpty()); + MOZ_ASSERT(mReceiveStreams.IsEmpty()); + // If this WebTransport was destroyed without being closed properly, make + // sure to clean up the channel. + if (mChild) { + mChild->Shutdown(); + } + } + + nsCOMPtr<nsIGlobalObject> mGlobal; + RefPtr<WebTransportChild> mChild; + + // Spec-defined slots: + // ordered sets, but we can't have duplicates, and this spec only appends. + // Order is visible due to + // https://w3c.github.io/webtransport/#webtransport-procedures step 10: "For + // each sendStream in sendStreams, error sendStream with error." + // XXX Use nsTArray.h for now, but switch to OrderHashSet/Table for release to + // improve remove performance (if needed) + nsTArray<RefPtr<WritableStream>> mSendStreams; + nsTArray<RefPtr<ReadableStream>> mReceiveStreams; + + WebTransportState mState; + RefPtr<Promise> mReady; + WebTransportReliabilityMode mReliability; + // These are created in the constructor + RefPtr<ReadableStream> mIncomingUnidirectionalStreams; + RefPtr<ReadableStream> mIncomingBidirectionalStreams; + RefPtr<WebTransportDatagramDuplexStream> mDatagrams; + RefPtr<Promise> mClosed; +}; + +} // namespace mozilla::dom + +#endif diff --git a/dom/webtransport/api/WebTransportBidirectionalStream.cpp b/dom/webtransport/api/WebTransportBidirectionalStream.cpp new file mode 100644 index 0000000000..60f202cd03 --- /dev/null +++ b/dom/webtransport/api/WebTransportBidirectionalStream.cpp @@ -0,0 +1,34 @@ +/* -*- 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 "WebTransportBidirectionalStream.h" +#include "mozilla/dom/Promise.h" + +namespace mozilla::dom { + +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WebTransportBidirectionalStream, mGlobal) + +NS_IMPL_CYCLE_COLLECTING_ADDREF(WebTransportBidirectionalStream) +NS_IMPL_CYCLE_COLLECTING_RELEASE(WebTransportBidirectionalStream) +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebTransportBidirectionalStream) + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY + NS_INTERFACE_MAP_ENTRY(nsISupports) +NS_INTERFACE_MAP_END + +// WebIDL Boilerplate + +nsIGlobalObject* WebTransportBidirectionalStream::GetParentObject() const { + return mGlobal; +} + +JSObject* WebTransportBidirectionalStream::WrapObject( + JSContext* aCx, JS::Handle<JSObject*> aGivenProto) { + return WebTransportBidirectionalStream_Binding::Wrap(aCx, this, aGivenProto); +} + +// WebIDL Interface + +} // namespace mozilla::dom diff --git a/dom/webtransport/api/WebTransportBidirectionalStream.h b/dom/webtransport/api/WebTransportBidirectionalStream.h new file mode 100644 index 0000000000..0f9e90f767 --- /dev/null +++ b/dom/webtransport/api/WebTransportBidirectionalStream.h @@ -0,0 +1,52 @@ +/* -*- 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_API_WEBTRANSPORTBIDIRECTIONALSTREAM__H_ +#define DOM_WEBTRANSPORT_API_WEBTRANSPORTBIDIRECTIONALSTREAM__H_ + +#include "nsCOMPtr.h" +#include "nsISupports.h" +#include "nsWrapperCache.h" +#include "mozilla/dom/Promise.h" +#include "mozilla/dom/ReadableStream.h" +#include "mozilla/dom/WritableStream.h" +#include "mozilla/dom/WebTransportSendReceiveStreamBinding.h" + +// #include "mozilla/dom/WebTransportReceiveStream.h" +// #include "mozilla/dom/WebTransportSendStream.h" + +namespace mozilla::dom { +class WebTransportBidirectionalStream final : public nsISupports, + public nsWrapperCache { + public: + explicit WebTransportBidirectionalStream(nsIGlobalObject* aGlobal) + : mGlobal(aGlobal) {} + + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(WebTransportBidirectionalStream) + + // WebIDL Boilerplate + nsIGlobalObject* GetParentObject() const; + + JSObject* WrapObject(JSContext* aCx, + JS::Handle<JSObject*> aGivenProto) override; + + // WebIDL Interface + // XXX spec says these should be WebTransportReceiveStream and + // WebTransportSendStream + // XXX Not implemented + already_AddRefed<ReadableStream> Readable() { return nullptr; } + already_AddRefed<WritableStream> Writable() { return nullptr; } + + private: + ~WebTransportBidirectionalStream() = default; + + nsCOMPtr<nsIGlobalObject> mGlobal; +}; + +} // namespace mozilla::dom + +#endif diff --git a/dom/webtransport/api/WebTransportDatagramDuplexStream.cpp b/dom/webtransport/api/WebTransportDatagramDuplexStream.cpp new file mode 100644 index 0000000000..e4fac822e5 --- /dev/null +++ b/dom/webtransport/api/WebTransportDatagramDuplexStream.cpp @@ -0,0 +1,35 @@ +/* -*- 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 "WebTransportDatagramDuplexStream.h" +#include "mozilla/dom/Promise.h" + +namespace mozilla::dom { + +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WebTransportDatagramDuplexStream, mGlobal, + mReadable, mWritable) + +NS_IMPL_CYCLE_COLLECTING_ADDREF(WebTransportDatagramDuplexStream) +NS_IMPL_CYCLE_COLLECTING_RELEASE(WebTransportDatagramDuplexStream) +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebTransportDatagramDuplexStream) + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY + NS_INTERFACE_MAP_ENTRY(nsISupports) +NS_INTERFACE_MAP_END + +// WebIDL Boilerplate + +nsIGlobalObject* WebTransportDatagramDuplexStream::GetParentObject() const { + return mGlobal; +} + +JSObject* WebTransportDatagramDuplexStream::WrapObject( + JSContext* aCx, JS::Handle<JSObject*> aGivenProto) { + return WebTransportDatagramDuplexStream_Binding::Wrap(aCx, this, aGivenProto); +} + +// WebIDL Interface + +} // namespace mozilla::dom diff --git a/dom/webtransport/api/WebTransportDatagramDuplexStream.h b/dom/webtransport/api/WebTransportDatagramDuplexStream.h new file mode 100644 index 0000000000..1aa895cd53 --- /dev/null +++ b/dom/webtransport/api/WebTransportDatagramDuplexStream.h @@ -0,0 +1,78 @@ +/* -*- 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_API_WEBTRANSPORTDATAGRAMDUPLEXSTREAM__H_ +#define DOM_WEBTRANSPORT_API_WEBTRANSPORTDATAGRAMDUPLEXSTREAM__H_ + +#include "nsCOMPtr.h" +#include "nsISupports.h" +#include "nsWrapperCache.h" +#include "mozilla/dom/Promise.h" +#include "mozilla/dom/ReadableStream.h" +#include "mozilla/dom/WritableStream.h" +#include "mozilla/dom/WebTransportDatagramDuplexStreamBinding.h" + +namespace mozilla::dom { + +class WebTransportDatagramDuplexStream final : public nsISupports, + public nsWrapperCache { + public: + explicit WebTransportDatagramDuplexStream(nsIGlobalObject* aGlobal) + : mGlobal(aGlobal) {} + + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(WebTransportDatagramDuplexStream) + + // WebIDL Boilerplate + nsIGlobalObject* GetParentObject() const; + + JSObject* WrapObject(JSContext* aCx, + JS::Handle<JSObject*> aGivenProto) override; + + // WebIDL Interface + already_AddRefed<ReadableStream> Readable() const { + RefPtr<ReadableStream> result(mReadable); + return result.forget(); + } + already_AddRefed<WritableStream> Writable() { + RefPtr<WritableStream> result(mWritable); + return result.forget(); + } + // XXX not implemented + uint64_t MaxDatagramSize() const { return 1500; } + Nullable<double> GetIncomingMaxAge() const { return mIncomingMaxAge; } + void SetIncomingMaxAge(const Nullable<double>& aMaxAge) { + mIncomingMaxAge = aMaxAge; + } + Nullable<double> GetOutgoingMaxAge() const { return mOutgoingMaxAge; } + void SetOutgoingMaxAge(const Nullable<double>& aMaxAge) { + mOutgoingMaxAge = aMaxAge; + } + int64_t IncomingHighWaterMark() const { return mIncomingHighWaterMark; } + void SetIncomingHighWaterMark(int64_t aWaterMark) { + mIncomingHighWaterMark = aWaterMark; + } + int64_t OutgoingHighWaterMark() const { return mOutgoingHighWaterMark; } + void SetOutgoingHighWaterMark(int64_t aWaterMark) { + mOutgoingHighWaterMark = aWaterMark; + } + + private: + ~WebTransportDatagramDuplexStream() = default; + + nsCOMPtr<nsIGlobalObject> mGlobal; + RefPtr<ReadableStream> mReadable; + RefPtr<WritableStream> mWritable; + + Nullable<double> mIncomingMaxAge; + Nullable<double> mOutgoingMaxAge; + int64_t mIncomingHighWaterMark = 0; + int64_t mOutgoingHighWaterMark = 0; +}; + +} // namespace mozilla::dom + +#endif diff --git a/dom/webtransport/api/WebTransportError.cpp b/dom/webtransport/api/WebTransportError.cpp new file mode 100644 index 0000000000..142d98d2b9 --- /dev/null +++ b/dom/webtransport/api/WebTransportError.cpp @@ -0,0 +1,30 @@ +/* -*- 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 "WebTransportError.h" + +namespace mozilla::dom { + +/* static */ +already_AddRefed<WebTransportError> WebTransportError::Constructor( + const GlobalObject& aGlobal, const WebTransportErrorInit& aInit) { + nsCString message(""_ns); + if (aInit.mMessage.WasPassed()) { + CopyUTF16toUTF8(aInit.mMessage.Value(), message); + } + RefPtr<WebTransportError> error(new WebTransportError(message)); + if (aInit.mStreamErrorCode.WasPassed()) { + error->mStreamErrorCode = aInit.mStreamErrorCode.Value(); + } + return error.forget(); +} + +WebTransportErrorSource WebTransportError::Source() { + // XXX Not implemented + return WebTransportErrorSource::Stream; +} + +} // namespace mozilla::dom diff --git a/dom/webtransport/api/WebTransportError.h b/dom/webtransport/api/WebTransportError.h new file mode 100644 index 0000000000..96b195ca0e --- /dev/null +++ b/dom/webtransport/api/WebTransportError.h @@ -0,0 +1,34 @@ +/* -*- 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_API_WEBTRANSPORTERROR__H_ +#define DOM_WEBTRANSPORT_API_WEBTRANSPORTERROR__H_ + +#include "mozilla/dom/DOMException.h" +#include "mozilla/dom/WebTransportErrorBinding.h" + +namespace mozilla::dom { +class WebTransportError final : public DOMException { + protected: + explicit WebTransportError(const nsACString& aMessage) + : DOMException(NS_OK, aMessage, "stream"_ns, 0) {} + + public: + static already_AddRefed<WebTransportError> Constructor( + const GlobalObject& aGlobal, const WebTransportErrorInit& aInit); + + WebTransportErrorSource Source(); + Nullable<uint8_t> GetStreamErrorCode() const { + return Nullable<uint8_t>(mStreamErrorCode); + } + + private: + uint8_t mStreamErrorCode = 0; +}; + +} // namespace mozilla::dom + +#endif diff --git a/dom/webtransport/api/WebTransportReceiveStream.h b/dom/webtransport/api/WebTransportReceiveStream.h new file mode 100644 index 0000000000..013af43424 --- /dev/null +++ b/dom/webtransport/api/WebTransportReceiveStream.h @@ -0,0 +1,39 @@ +/* -*- 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_API_WEBTRANSPORTSENDSTREAM__H_ +#define DOM_WEBTRANSPORT_API_WEBTRANSPORTSENDSTREAM__H_ + +#include "mozilla/dom/ReadableStream.h" + +#if WEBTRANSPORT_STREAM_IMPLEMENTED +namespace mozilla::dom { +class WebTransportReceiveStream final : public ReadableStream { + protected: + WebTransportReceiveStream(); + + public: + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(WebTransportReceiveStream, + ReadableStream) + + already_AddRefed<Promise> GetStats(); +}; +#else +namespace mozilla::dom { +class WebTransportReceiveStream final : public nsISupports { + protected: + WebTransportReceiveStream(); + + public: + NS_DECL_ISUPPORTS + + already_AddRefed<Promise> GetStats(); +}; +#endif +} + +#endif diff --git a/dom/webtransport/api/WebTransportSendStream.h b/dom/webtransport/api/WebTransportSendStream.h new file mode 100644 index 0000000000..0de62208b4 --- /dev/null +++ b/dom/webtransport/api/WebTransportSendStream.h @@ -0,0 +1,39 @@ +/* -*- 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_API_WEBTRANSPORTSENDSTREAM__H_ +#define DOM_WEBTRANSPORT_API_WEBTRANSPORTSENDSTREAM__H_ + +#include "mozilla/dom/WritableStream.h" + +#if WEBTRANSPORT_STREAM_IMPLEMENTED +namespace mozilla::dom { +class WebTransportSendStream final : public WritableStream { + protected: + WebTransportSendStream(); + + public: + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(WebTransportSendStream, + WritableStream) + + already_AddRefed<Promise> GetStats(); +}; +#else +namespace mozilla::dom { +class WebTransportSendStream final : public nsISupports { + protected: + WebTransportSendStream(); + + public: + NS_DECL_ISUPPORTS + + already_AddRefed<Promise> GetStats(); +}; +#endif +} + +#endif diff --git a/dom/webtransport/api/moz.build b/dom/webtransport/api/moz.build new file mode 100644 index 0000000000..c456fb16d0 --- /dev/null +++ b/dom/webtransport/api/moz.build @@ -0,0 +1,25 @@ +# -*- 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 += [ + "WebTransport.h", + "WebTransportBidirectionalStream.h", + "WebTransportDatagramDuplexStream.h", + "WebTransportError.h", + "WebTransportReceiveStream.h", + "WebTransportSendStream.h", +] + +UNIFIED_SOURCES += [ + "WebTransport.cpp", + "WebTransportBidirectionalStream.cpp", + "WebTransportDatagramDuplexStream.cpp", + "WebTransportError.cpp", +] + +FINAL_LIBRARY = "xul" + +include("/ipc/chromium/chromium-config.mozbuild") |