diff --git a/dom/file/nsHostObjectProtocolHandler.cpp b/dom/file/nsHostObjectProtocolHandler.cpp index d69d0d7e6065..a3e2546b6ebf 100644 --- a/dom/file/nsHostObjectProtocolHandler.cpp +++ b/dom/file/nsHostObjectProtocolHandler.cpp @@ -892,20 +892,23 @@ nsHostObjectProtocolHandler::NewURI(const nsACString& aSpec, DataInfo* info = GetDataInfo(aSpec); + nsCOMPtr principal; + RefPtr blob; + if (info && info->mObjectType == DataInfo::eBlobImpl) { + MOZ_ASSERT(info->mBlobImpl); + principal = info->mPrincipal; + blob = info->mBlobImpl; + } + nsCOMPtr uri; rv = NS_MutateURI(new nsHostObjectURI::Mutator()) .SetSpec(aSpec) + .Apply(&nsIBlobURIMutator::SetBlobImpl, blob) + .Apply(&nsIPrincipalURIMutator::SetPrincipal, principal) .Finalize(uri); NS_ENSURE_SUCCESS(rv, rv); - RefPtr hostURI = static_cast(uri.get()); - if (info && info->mObjectType == DataInfo::eBlobImpl) { - MOZ_ASSERT(info->mBlobImpl); - hostURI->mPrincipal = info->mPrincipal; - hostURI->mBlobImpl = info->mBlobImpl; - } - - NS_TryToSetImmutable(hostURI); + NS_TryToSetImmutable(uri); uri.forget(aResult); if (info && info->mObjectType == DataInfo::eBlobImpl) { diff --git a/dom/file/nsHostObjectURI.cpp b/dom/file/nsHostObjectURI.cpp index 8be9f50eb8d6..9a84c3aa9b83 100644 --- a/dom/file/nsHostObjectURI.cpp +++ b/dom/file/nsHostObjectURI.cpp @@ -230,7 +230,7 @@ nsHostObjectURI::EqualsInternal(nsIURI* aOther, return NS_OK; } -NS_IMPL_ISUPPORTS(nsHostObjectURI::Mutator, nsIURISetters, nsIURIMutator) +NS_IMPL_ISUPPORTS(nsHostObjectURI::Mutator, nsIURISetters, nsIURIMutator, nsIBlobURIMutator, nsIPrincipalURIMutator) NS_IMETHODIMP nsHostObjectURI::Mutate(nsIURIMutator** aMutator) diff --git a/dom/file/nsHostObjectURI.h b/dom/file/nsHostObjectURI.h index 3a9a7b63aa47..c7e12680b28d 100644 --- a/dom/file/nsHostObjectURI.h +++ b/dom/file/nsHostObjectURI.h @@ -81,11 +81,33 @@ public: class Mutator : public nsIURIMutator , public BaseURIMutator + , public nsIBlobURIMutator + , public nsIPrincipalURIMutator { NS_DECL_ISUPPORTS NS_FORWARD_SAFE_NSIURISETTERS_RET(mURI) NS_DEFINE_NSIMUTATOR_COMMON + MOZ_MUST_USE NS_IMETHOD + SetBlobImpl(mozilla::dom::BlobImpl *aBlobImpl) override + { + if (!mURI) { + return NS_ERROR_NULL_POINTER; + } + mURI->mBlobImpl = aBlobImpl; + return NS_OK; + } + + MOZ_MUST_USE NS_IMETHOD + SetPrincipal(nsIPrincipal *aPrincipal) override + { + if (!mURI) { + return NS_ERROR_NULL_POINTER; + } + mURI->mPrincipal = aPrincipal; + return NS_OK; + } + explicit Mutator() { } private: virtual ~Mutator() { } diff --git a/netwerk/base/nsIURIMutator.idl b/netwerk/base/nsIURIMutator.idl index 687a691a83c1..63e70187ee18 100644 --- a/netwerk/base/nsIURIMutator.idl +++ b/netwerk/base/nsIURIMutator.idl @@ -369,6 +369,32 @@ public: return *this; } + /** + * This method allows consumers to call the methods declared in other + * interfaces implemented by the mutator object. + * + * Example: + * nsCOMPtr uri; + * nsresult rv = NS_MutateURI(new URIClass::Mutator()) + * .SetSpec(aSpec) + * .Apply(&SomeInterface::Method, arg1, arg2) + * .Finalize(uri); + * + * If mMutator does not implement SomeInterface, do_QueryInterface will fail + * and the method will not be called. + * If aMethod does not exist, or if there is a mismatch between argument + * types, or the number of arguments, then there will be a compile error. + */ + template + NS_MutateURI& Apply(Method aMethod, Args ...aArgs) + { + NS_ENSURE_SUCCESS(mStatus, *this); + nsCOMPtr target = do_QueryInterface(mMutator, &mStatus); + NS_ENSURE_SUCCESS(mStatus, *this); + mStatus = (target->*aMethod)(aArgs...); + return *this; + } + template MOZ_MUST_USE nsresult Finalize(nsCOMPtr& aURI) { diff --git a/netwerk/base/nsIURIWithBlobImpl.idl b/netwerk/base/nsIURIWithBlobImpl.idl index e76c12c7ed26..1a3832e4a57b 100644 --- a/netwerk/base/nsIURIWithBlobImpl.idl +++ b/netwerk/base/nsIURIWithBlobImpl.idl @@ -6,6 +6,15 @@ interface nsIURI; +%{C++ +namespace mozilla { +namespace dom { + class BlobImpl; +}} +%} + +[ptr] native BlobImplPtr(mozilla::dom::BlobImpl); + /** * nsIURIWithBlobImpl is implemented by URIs which are associated with a * specific BlobImpl. @@ -18,3 +27,14 @@ interface nsIURIWithBlobImpl : nsISupports */ readonly attribute nsISupports blobImpl; }; + +[builtinclass, uuid(d3e8c9fa-ff07-47cc-90dc-0cc5445ddb59)] +interface nsIBlobURIMutator : nsISupports +{ + /** + * Associates a blobImpl to the mutated URI. + * Would normally return nsIURIMutator, but since it only gets called + * from C++, there is no need for that. + */ + [must_use, noscript] void setBlobImpl(in BlobImplPtr blobImpl); +}; diff --git a/netwerk/base/nsIURIWithPrincipal.idl b/netwerk/base/nsIURIWithPrincipal.idl index 912225c90972..bd130b2b5282 100644 --- a/netwerk/base/nsIURIWithPrincipal.idl +++ b/netwerk/base/nsIURIWithPrincipal.idl @@ -6,6 +6,7 @@ interface nsIPrincipal; interface nsIURI; +interface nsIURIMutator; /** * nsIURIWithPrincipal is implemented by URIs which are associated with a @@ -25,3 +26,14 @@ interface nsIURIWithPrincipal : nsISupports */ readonly attribute nsIURI principalUri; }; + +[builtinclass, uuid(fa138a89-c76e-4b7f-95ec-c7b56ded5ef5)] +interface nsIPrincipalURIMutator : nsISupports +{ + /** + * Associates a principal to the mutated URI. + * Would normally return nsIURIMutator, but since it only gets called + * from C++, there is no need for that. + */ + [must_use, noscript] void setPrincipal(in nsIPrincipal aPrincipal); +};