summaryrefslogtreecommitdiffstats
path: root/dom/base/nsHostObjectURI.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/base/nsHostObjectURI.cpp')
-rw-r--r--dom/base/nsHostObjectURI.cpp292
1 files changed, 292 insertions, 0 deletions
diff --git a/dom/base/nsHostObjectURI.cpp b/dom/base/nsHostObjectURI.cpp
new file mode 100644
index 000000000..0d505c0ef
--- /dev/null
+++ b/dom/base/nsHostObjectURI.cpp
@@ -0,0 +1,292 @@
+/* -*- 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 "nsHostObjectURI.h"
+
+#include "nsIObjectInputStream.h"
+#include "nsIObjectOutputStream.h"
+#include "nsHostObjectProtocolHandler.h"
+
+#include "mozilla/ipc/BackgroundUtils.h"
+#include "mozilla/ipc/URIUtils.h"
+
+static NS_DEFINE_CID(kHOSTOBJECTURICID, NS_HOSTOBJECTURI_CID);
+
+static NS_DEFINE_CID(kThisSimpleURIImplementationCID,
+ NS_THIS_SIMPLEURI_IMPLEMENTATION_CID);
+
+NS_IMPL_ADDREF_INHERITED(nsHostObjectURI, mozilla::net::nsSimpleURI)
+NS_IMPL_RELEASE_INHERITED(nsHostObjectURI, mozilla::net::nsSimpleURI)
+
+NS_INTERFACE_MAP_BEGIN(nsHostObjectURI)
+ NS_INTERFACE_MAP_ENTRY(nsIURIWithBlobImpl)
+ NS_INTERFACE_MAP_ENTRY(nsIURIWithPrincipal)
+ NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
+ if (aIID.Equals(kHOSTOBJECTURICID))
+ foundInterface = static_cast<nsIURI*>(this);
+ else if (aIID.Equals(kThisSimpleURIImplementationCID)) {
+ // Need to return explicitly here, because if we just set foundInterface
+ // to null the NS_INTERFACE_MAP_END_INHERITING will end up calling into
+ // nsSimplURI::QueryInterface and finding something for this CID.
+ *aInstancePtr = nullptr;
+ return NS_NOINTERFACE;
+ }
+ else
+NS_INTERFACE_MAP_END_INHERITING(mozilla::net::nsSimpleURI)
+
+// nsIURIWithBlobImpl methods:
+
+NS_IMETHODIMP
+nsHostObjectURI::GetBlobImpl(nsISupports** aBlobImpl)
+{
+ RefPtr<mozilla::dom::BlobImpl> blobImpl(mBlobImpl);
+ blobImpl.forget(aBlobImpl);
+ return NS_OK;
+}
+
+// nsIURIWithPrincipal methods:
+
+NS_IMETHODIMP
+nsHostObjectURI::GetPrincipal(nsIPrincipal** aPrincipal)
+{
+ NS_IF_ADDREF(*aPrincipal = mPrincipal);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsHostObjectURI::GetPrincipalUri(nsIURI** aUri)
+{
+ if (mPrincipal) {
+ mPrincipal->GetURI(aUri);
+ }
+ else {
+ *aUri = nullptr;
+ }
+
+ return NS_OK;
+}
+
+// nsISerializable methods:
+
+NS_IMETHODIMP
+nsHostObjectURI::Read(nsIObjectInputStream* aStream)
+{
+ nsresult rv = mozilla::net::nsSimpleURI::Read(aStream);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsISupports> supports;
+ rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(supports));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ mPrincipal = do_QueryInterface(supports, &rv);
+ return rv;
+}
+
+NS_IMETHODIMP
+nsHostObjectURI::Write(nsIObjectOutputStream* aStream)
+{
+ nsresult rv = mozilla::net::nsSimpleURI::Write(aStream);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return NS_WriteOptionalCompoundObject(aStream, mPrincipal,
+ NS_GET_IID(nsIPrincipal),
+ true);
+}
+
+// nsIIPCSerializableURI methods:
+void
+nsHostObjectURI::Serialize(mozilla::ipc::URIParams& aParams)
+{
+ using namespace mozilla::ipc;
+
+ HostObjectURIParams hostParams;
+ URIParams simpleParams;
+
+ mozilla::net::nsSimpleURI::Serialize(simpleParams);
+ hostParams.simpleParams() = simpleParams;
+
+ if (mPrincipal) {
+ PrincipalInfo info;
+ nsresult rv = PrincipalToPrincipalInfo(mPrincipal, &info);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return;
+ }
+
+ hostParams.principal() = info;
+ } else {
+ hostParams.principal() = mozilla::void_t();
+ }
+
+ aParams = hostParams;
+}
+
+bool
+nsHostObjectURI::Deserialize(const mozilla::ipc::URIParams& aParams)
+{
+ using namespace mozilla::ipc;
+
+ if (aParams.type() != URIParams::THostObjectURIParams) {
+ NS_ERROR("Received unknown parameters from the other process!");
+ return false;
+ }
+
+ const HostObjectURIParams& hostParams = aParams.get_HostObjectURIParams();
+
+ if (!mozilla::net::nsSimpleURI::Deserialize(hostParams.simpleParams())) {
+ return false;
+ }
+
+ if (hostParams.principal().type() == OptionalPrincipalInfo::Tvoid_t) {
+ return true;
+ }
+
+ mPrincipal = PrincipalInfoToPrincipal(hostParams.principal().get_PrincipalInfo());
+ if (!mPrincipal) {
+ return false;
+ }
+
+ // If this fails, we still want to complete the operation. Probably this
+ // blobURL has been revoked in the meantime.
+ NS_GetBlobForBlobURI(this, getter_AddRefs(mBlobImpl));
+
+ return true;
+}
+
+NS_IMETHODIMP
+nsHostObjectURI::SetScheme(const nsACString& aScheme)
+{
+ // Disallow setting the scheme, since that could cause us to be associated
+ // with a different protocol handler that doesn't expect us to be carrying
+ // around a principal with nsIURIWithPrincipal.
+ return NS_ERROR_FAILURE;
+}
+
+// nsIURI methods:
+nsresult
+nsHostObjectURI::CloneInternal(mozilla::net::nsSimpleURI::RefHandlingEnum aRefHandlingMode,
+ const nsACString& newRef,
+ nsIURI** aClone)
+{
+ nsCOMPtr<nsIURI> simpleClone;
+ nsresult rv =
+ mozilla::net::nsSimpleURI::CloneInternal(aRefHandlingMode, newRef, getter_AddRefs(simpleClone));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+#ifdef DEBUG
+ RefPtr<nsHostObjectURI> uriCheck;
+ rv = simpleClone->QueryInterface(kHOSTOBJECTURICID, getter_AddRefs(uriCheck));
+ MOZ_ASSERT(NS_SUCCEEDED(rv) && uriCheck);
+#endif
+
+ nsHostObjectURI* u = static_cast<nsHostObjectURI*>(simpleClone.get());
+
+ u->mPrincipal = mPrincipal;
+ u->mBlobImpl = mBlobImpl;
+
+ simpleClone.forget(aClone);
+ return NS_OK;
+}
+
+/* virtual */ nsresult
+nsHostObjectURI::EqualsInternal(nsIURI* aOther,
+ mozilla::net::nsSimpleURI::RefHandlingEnum aRefHandlingMode,
+ bool* aResult)
+{
+ if (!aOther) {
+ *aResult = false;
+ return NS_OK;
+ }
+
+ RefPtr<nsHostObjectURI> otherUri;
+ aOther->QueryInterface(kHOSTOBJECTURICID, getter_AddRefs(otherUri));
+ if (!otherUri) {
+ *aResult = false;
+ return NS_OK;
+ }
+
+ // Compare the member data that our base class knows about.
+ if (!mozilla::net::nsSimpleURI::EqualsInternal(otherUri, aRefHandlingMode)) {
+ *aResult = false;
+ return NS_OK;
+ }
+
+ // Compare the piece of additional member data that we add to base class,
+ // but we cannot compare BlobImpl. This should not be a problem, because we
+ // don't support changing the underlying mBlobImpl.
+
+ if (mPrincipal && otherUri->mPrincipal) {
+ // Both of us have mPrincipals. Compare them.
+ return mPrincipal->Equals(otherUri->mPrincipal, aResult);
+ }
+ // else, at least one of us lacks a principal; only equal if *both* lack it.
+ *aResult = (!mPrincipal && !otherUri->mPrincipal);
+ return NS_OK;
+}
+
+// nsIClassInfo methods:
+NS_IMETHODIMP
+nsHostObjectURI::GetInterfaces(uint32_t *count, nsIID * **array)
+{
+ *count = 0;
+ *array = nullptr;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsHostObjectURI::GetScriptableHelper(nsIXPCScriptable **_retval)
+{
+ *_retval = nullptr;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsHostObjectURI::GetContractID(char * *aContractID)
+{
+ // Make sure to modify any subclasses as needed if this ever
+ // changes.
+ *aContractID = nullptr;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsHostObjectURI::GetClassDescription(char * *aClassDescription)
+{
+ *aClassDescription = nullptr;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsHostObjectURI::GetClassID(nsCID * *aClassID)
+{
+ // Make sure to modify any subclasses as needed if this ever
+ // changes to not call the virtual GetClassIDNoAlloc.
+ *aClassID = (nsCID*) moz_xmalloc(sizeof(nsCID));
+ NS_ENSURE_TRUE(*aClassID, NS_ERROR_OUT_OF_MEMORY);
+
+ return GetClassIDNoAlloc(*aClassID);
+}
+
+NS_IMETHODIMP
+nsHostObjectURI::GetFlags(uint32_t *aFlags)
+{
+ *aFlags = nsIClassInfo::MAIN_THREAD_ONLY;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsHostObjectURI::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
+{
+ *aClassIDNoAlloc = kHOSTOBJECTURICID;
+ return NS_OK;
+}
+
+void
+nsHostObjectURI::ForgetBlobImpl()
+{
+ MOZ_ASSERT(mBlobImpl);
+ mBlobImpl = nullptr;
+}