mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Bug 1279493 - Use blob URLs exclusively rather than having mediastream and mediasource URLs, r=smaug
This commit is contained in:
parent
b23e6a33e4
commit
8183e57459
@ -25,7 +25,9 @@
|
||||
#include "nsIUUIDGenerator.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
using mozilla::DOMMediaStream;
|
||||
using mozilla::dom::BlobImpl;
|
||||
using mozilla::dom::MediaSource;
|
||||
using mozilla::ErrorResult;
|
||||
using mozilla::net::LoadInfo;
|
||||
|
||||
@ -33,8 +35,36 @@ using mozilla::net::LoadInfo;
|
||||
// Hash table
|
||||
struct DataInfo
|
||||
{
|
||||
// mObject is expected to be an BlobImpl, DOMMediaStream, or MediaSource
|
||||
nsCOMPtr<nsISupports> mObject;
|
||||
enum ObjectType {
|
||||
eBlobImpl,
|
||||
eMediaStream,
|
||||
eMediaSource
|
||||
};
|
||||
|
||||
DataInfo(BlobImpl* aBlobImpl, nsIPrincipal* aPrincipal)
|
||||
: mObjectType(eBlobImpl)
|
||||
, mBlobImpl(aBlobImpl)
|
||||
, mPrincipal(aPrincipal)
|
||||
{}
|
||||
|
||||
DataInfo(DOMMediaStream* aMediaStream, nsIPrincipal* aPrincipal)
|
||||
: mObjectType(eMediaStream)
|
||||
, mMediaStream(aMediaStream)
|
||||
, mPrincipal(aPrincipal)
|
||||
{}
|
||||
|
||||
DataInfo(MediaSource* aMediaSource, nsIPrincipal* aPrincipal)
|
||||
: mObjectType(eMediaSource)
|
||||
, mMediaSource(aMediaSource)
|
||||
, mPrincipal(aPrincipal)
|
||||
{}
|
||||
|
||||
ObjectType mObjectType;
|
||||
|
||||
RefPtr<BlobImpl> mBlobImpl;
|
||||
RefPtr<DOMMediaStream> mMediaStream;
|
||||
RefPtr<MediaSource> mMediaSource;
|
||||
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
nsCString mStack;
|
||||
};
|
||||
@ -71,6 +101,21 @@ GetDataInfo(const nsACString& aUri)
|
||||
|
||||
return res;
|
||||
}
|
||||
static DataInfo*
|
||||
GetDataInfoFromURI(nsIURI* aURI)
|
||||
{
|
||||
if (!aURI) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCString spec;
|
||||
nsresult rv = aURI->GetSpec(spec);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return GetDataInfo(spec);
|
||||
}
|
||||
|
||||
// Memory reporting for the hash table.
|
||||
namespace mozilla {
|
||||
@ -150,18 +195,24 @@ class BlobURLsReporter final : public nsIMemoryReporter
|
||||
|
||||
// Determine number of URLs per BlobImpl, to handle the case where it's > 1.
|
||||
for (auto iter = gDataTable->Iter(); !iter.Done(); iter.Next()) {
|
||||
nsCOMPtr<BlobImpl> blobImpl = do_QueryInterface(iter.UserData()->mObject);
|
||||
if (blobImpl) {
|
||||
refCounts.Put(blobImpl, refCounts.Get(blobImpl) + 1);
|
||||
if (iter.UserData()->mObjectType != DataInfo::eBlobImpl) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BlobImpl* blobImpl = iter.UserData()->mBlobImpl;
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
refCounts.Put(blobImpl, refCounts.Get(blobImpl) + 1);
|
||||
}
|
||||
|
||||
for (auto iter = gDataTable->Iter(); !iter.Done(); iter.Next()) {
|
||||
nsCStringHashKey::KeyType key = iter.Key();
|
||||
DataInfo* info = iter.UserData();
|
||||
|
||||
nsCOMPtr<BlobImpl> blobImpl = do_QueryInterface(iter.UserData()->mObject);
|
||||
if (blobImpl) {
|
||||
if (iter.UserData()->mObjectType == DataInfo::eBlobImpl) {
|
||||
BlobImpl* blobImpl = iter.UserData()->mBlobImpl;
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
NS_NAMED_LITERAL_CSTRING(desc,
|
||||
"A blob URL allocated with URL.createObjectURL; the referenced "
|
||||
"blob cannot be freed until all URLs for it have been explicitly "
|
||||
@ -234,27 +285,22 @@ class BlobURLsReporter final : public nsIMemoryReporter
|
||||
descString,
|
||||
aData);
|
||||
}
|
||||
} else {
|
||||
// Just report the path for the DOMMediaStream or MediaSource.
|
||||
nsCOMPtr<mozilla::dom::MediaSource>
|
||||
ms(do_QueryInterface(info->mObject));
|
||||
nsAutoCString path;
|
||||
path = ms ? "media-source-urls/" : "dom-media-stream-urls/";
|
||||
BuildPath(path, key, info, aAnonymize);
|
||||
|
||||
NS_NAMED_LITERAL_CSTRING(desc,
|
||||
"An object URL allocated with URL.createObjectURL; the referenced "
|
||||
"data cannot be freed until all URLs for it have been explicitly "
|
||||
"invalidated with URL.revokeObjectURL.");
|
||||
|
||||
aCallback->Callback(EmptyCString(),
|
||||
path,
|
||||
KIND_OTHER,
|
||||
UNITS_COUNT,
|
||||
1,
|
||||
desc,
|
||||
aData);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Just report the path for the DOMMediaStream or MediaSource.
|
||||
nsAutoCString path;
|
||||
path = iter.UserData()->mObjectType == DataInfo::eMediaSource
|
||||
? "media-source-urls/" : "dom-media-stream-urls/";
|
||||
BuildPath(path, key, info, aAnonymize);
|
||||
|
||||
NS_NAMED_LITERAL_CSTRING(desc,
|
||||
"An object URL allocated with URL.createObjectURL; the referenced "
|
||||
"data cannot be freed until all URLs for it have been explicitly "
|
||||
"invalidated with URL.revokeObjectURL.");
|
||||
|
||||
aCallback->Callback(EmptyCString(), path, KIND_OTHER, UNITS_COUNT, 1,
|
||||
desc, aData);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -370,6 +416,22 @@ NS_IMPL_ISUPPORTS(BlobURLsReporter, nsIMemoryReporter)
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
template<typename T>
|
||||
static nsresult
|
||||
AddDataEntryInternal(const nsACString& aURI, T aObject,
|
||||
nsIPrincipal* aPrincipal)
|
||||
{
|
||||
if (!gDataTable) {
|
||||
gDataTable = new nsClassHashtable<nsCStringHashKey, DataInfo>;
|
||||
}
|
||||
|
||||
DataInfo* info = new DataInfo(aObject, aPrincipal);
|
||||
mozilla::BlobURLsReporter::GetJSStackForBlob(info);
|
||||
|
||||
gDataTable->Put(aURI, info);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsHostObjectProtocolHandler::Init(void)
|
||||
{
|
||||
@ -387,56 +449,61 @@ nsHostObjectProtocolHandler::nsHostObjectProtocolHandler()
|
||||
Init();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHostObjectProtocolHandler::AddDataEntry(const nsACString& aScheme,
|
||||
nsISupports* aObject,
|
||||
/* static */ nsresult
|
||||
nsHostObjectProtocolHandler::AddDataEntry(BlobImpl* aBlobImpl,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsACString& aUri)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
{
|
||||
nsCOMPtr<BlobImpl> blobImpl(do_QueryInterface(aObject));
|
||||
nsCOMPtr<MediaSource> mediaSource(do_QueryInterface(aObject));
|
||||
nsCOMPtr<DOMMediaStream> mediaStream(do_QueryInterface(aObject));
|
||||
|
||||
// We support only these types.
|
||||
MOZ_ASSERT(blobImpl || mediaSource || mediaStream);
|
||||
}
|
||||
#endif
|
||||
|
||||
Init();
|
||||
|
||||
nsresult rv = GenerateURIString(aScheme, aPrincipal, aUri);
|
||||
nsresult rv = GenerateURIStringForBlobURL(aPrincipal, aUri);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = AddDataEntry(aUri, aObject, aPrincipal);
|
||||
rv = AddDataEntryInternal(aUri, aBlobImpl, aPrincipal);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<BlobImpl> blobImpl = do_QueryInterface(aObject);
|
||||
if (blobImpl) {
|
||||
BroadcastBlobURLRegistration(aUri, blobImpl, aPrincipal);
|
||||
}
|
||||
BroadcastBlobURLRegistration(aUri, aBlobImpl, aPrincipal);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */ nsresult
|
||||
nsHostObjectProtocolHandler::AddDataEntry(DOMMediaStream* aMediaStream,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsACString& aUri)
|
||||
{
|
||||
Init();
|
||||
|
||||
nsresult rv = GenerateURIStringForBlobURL(aPrincipal, aUri);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = AddDataEntryInternal(aUri, aMediaStream, aPrincipal);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */ nsresult
|
||||
nsHostObjectProtocolHandler::AddDataEntry(MediaSource* aMediaSource,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsACString& aUri)
|
||||
{
|
||||
Init();
|
||||
|
||||
nsresult rv = GenerateURIStringForBlobURL(aPrincipal, aUri);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = AddDataEntryInternal(aUri, aMediaSource, aPrincipal);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */ nsresult
|
||||
nsHostObjectProtocolHandler::AddDataEntry(const nsACString& aURI,
|
||||
nsISupports* aObject,
|
||||
nsIPrincipal* aPrincipal)
|
||||
nsIPrincipal* aPrincipal,
|
||||
mozilla::dom::BlobImpl* aBlobImpl)
|
||||
{
|
||||
if (!gDataTable) {
|
||||
gDataTable = new nsClassHashtable<nsCStringHashKey, DataInfo>;
|
||||
}
|
||||
|
||||
DataInfo* info = new DataInfo;
|
||||
|
||||
info->mObject = aObject;
|
||||
info->mPrincipal = aPrincipal;
|
||||
mozilla::BlobURLsReporter::GetJSStackForBlob(info);
|
||||
|
||||
gDataTable->Put(aURI, info);
|
||||
return NS_OK;
|
||||
return AddDataEntryInternal(aURI, aBlobImpl, aPrincipal);
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
@ -453,12 +520,12 @@ nsHostObjectProtocolHandler::GetAllBlobURLEntries(nsTArray<BlobURLRegistrationDa
|
||||
DataInfo* info = iter.UserData();
|
||||
MOZ_ASSERT(info);
|
||||
|
||||
nsCOMPtr<BlobImpl> blobImpl = do_QueryInterface(info->mObject);
|
||||
if (!blobImpl) {
|
||||
if (info->mObjectType != DataInfo::eBlobImpl) {
|
||||
continue;
|
||||
}
|
||||
|
||||
PBlobParent* blobParent = aCP->GetOrCreateActorForBlobImpl(blobImpl);
|
||||
MOZ_ASSERT(info->mBlobImpl);
|
||||
PBlobParent* blobParent = aCP->GetOrCreateActorForBlobImpl(info->mBlobImpl);
|
||||
if (!blobParent) {
|
||||
return false;
|
||||
}
|
||||
@ -484,11 +551,8 @@ nsHostObjectProtocolHandler::RemoveDataEntry(const nsACString& aUri,
|
||||
return;
|
||||
}
|
||||
|
||||
if (aBroadcastToOtherProcesses) {
|
||||
nsCOMPtr<BlobImpl> blobImpl = do_QueryInterface(info->mObject);
|
||||
if (blobImpl) {
|
||||
BroadcastBlobURLUnregistration(aUri, info);
|
||||
}
|
||||
if (aBroadcastToOtherProcesses && info->mObjectType == DataInfo::eBlobImpl) {
|
||||
BroadcastBlobURLUnregistration(aUri, info);
|
||||
}
|
||||
|
||||
gDataTable->Remove(aUri);
|
||||
@ -548,6 +612,14 @@ nsHostObjectProtocolHandler::GenerateURIString(const nsACString &aScheme,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHostObjectProtocolHandler::GenerateURIStringForBlobURL(nsIPrincipal* aPrincipal,
|
||||
nsACString& aUri)
|
||||
{
|
||||
return
|
||||
GenerateURIString(NS_LITERAL_CSTRING(BLOBURI_SCHEME), aPrincipal, aUri);
|
||||
}
|
||||
|
||||
nsIPrincipal*
|
||||
nsHostObjectProtocolHandler::GetDataEntryPrincipal(const nsACString& aUri)
|
||||
{
|
||||
@ -578,23 +650,14 @@ nsHostObjectProtocolHandler::Traverse(const nsACString& aUri,
|
||||
return;
|
||||
}
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCallback, "HostObjectProtocolHandler DataInfo.mObject");
|
||||
aCallback.NoteXPCOMChild(res->mObject);
|
||||
}
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCallback, "HostObjectProtocolHandler DataInfo.mBlobImpl");
|
||||
aCallback.NoteXPCOMChild(res->mBlobImpl);
|
||||
|
||||
static nsISupports*
|
||||
GetDataObjectForSpec(const nsACString& aSpec)
|
||||
{
|
||||
DataInfo* info = GetDataInfo(aSpec);
|
||||
return info ? info->mObject : nullptr;
|
||||
}
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCallback, "HostObjectProtocolHandler DataInfo.mMediaSource");
|
||||
aCallback.NoteXPCOMChild(res->mMediaSource);
|
||||
|
||||
static nsISupports*
|
||||
GetDataObject(nsIURI* aURI)
|
||||
{
|
||||
nsCString spec;
|
||||
aURI->GetSpec(spec);
|
||||
return GetDataObjectForSpec(spec);
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCallback, "HostObjectProtocolHandler DataInfo.mMediaStream");
|
||||
aCallback.NoteXPCOMChild(res->mMediaStream);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
@ -629,9 +692,9 @@ nsHostObjectProtocolHandler::NewURI(const nsACString& aSpec,
|
||||
DataInfo* info = GetDataInfo(aSpec);
|
||||
|
||||
RefPtr<nsHostObjectURI> uri;
|
||||
if (info) {
|
||||
nsCOMPtr<BlobImpl> blob = do_QueryInterface(info->mObject);
|
||||
uri = new nsHostObjectURI(info->mPrincipal, blob);
|
||||
if (info && info->mObjectType == DataInfo::eBlobImpl) {
|
||||
MOZ_ASSERT(info->mBlobImpl);
|
||||
uri = new nsHostObjectURI(info->mPrincipal, info->mBlobImpl);
|
||||
} else {
|
||||
uri = new nsHostObjectURI(nullptr, nullptr);
|
||||
}
|
||||
@ -665,10 +728,7 @@ nsHostObjectProtocolHandler::NewChannel2(nsIURI* uri,
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
nsCString spec;
|
||||
uri->GetSpec(spec);
|
||||
|
||||
DataInfo* info = GetDataInfo(spec);
|
||||
DataInfo* info = GetDataInfoFromURI(uri);
|
||||
|
||||
// Info can be null, in case this blob URL has been revoked already.
|
||||
if (info) {
|
||||
@ -742,20 +802,6 @@ nsBlobProtocolHandler::GetScheme(nsACString &result)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMediaStreamProtocolHandler::GetScheme(nsACString &result)
|
||||
{
|
||||
result.AssignLiteral(MEDIASTREAMURI_SCHEME);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMediaSourceProtocolHandler::GetScheme(nsACString &result)
|
||||
{
|
||||
result.AssignLiteral(MEDIASOURCEURI_SCHEME);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFontTableProtocolHandler::GetScheme(nsACString &result)
|
||||
{
|
||||
@ -770,11 +816,12 @@ NS_GetBlobForBlobURI(nsIURI* aURI, BlobImpl** aBlob)
|
||||
|
||||
*aBlob = nullptr;
|
||||
|
||||
nsCOMPtr<BlobImpl> blob = do_QueryInterface(GetDataObject(aURI));
|
||||
if (!blob) {
|
||||
DataInfo* info = GetDataInfoFromURI(aURI);
|
||||
if (!info || info->mObjectType != DataInfo::eBlobImpl) {
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
|
||||
RefPtr<BlobImpl> blob = info->mBlobImpl;
|
||||
blob.forget(aBlob);
|
||||
return NS_OK;
|
||||
}
|
||||
@ -784,11 +831,12 @@ NS_GetBlobForBlobURISpec(const nsACString& aSpec, BlobImpl** aBlob)
|
||||
{
|
||||
*aBlob = nullptr;
|
||||
|
||||
nsCOMPtr<BlobImpl> blob = do_QueryInterface(GetDataObjectForSpec(aSpec));
|
||||
if (!blob) {
|
||||
DataInfo* info = GetDataInfo(aSpec);
|
||||
if (!info || info->mObjectType != DataInfo::eBlobImpl) {
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
|
||||
RefPtr<BlobImpl> blob = info->mBlobImpl;
|
||||
blob.forget(aBlob);
|
||||
return NS_OK;
|
||||
}
|
||||
@ -816,13 +864,14 @@ NS_GetStreamForMediaStreamURI(nsIURI* aURI, mozilla::DOMMediaStream** aStream)
|
||||
{
|
||||
NS_ASSERTION(IsMediaStreamURI(aURI), "Only call this with mediastream URIs");
|
||||
|
||||
nsISupports* dataObject = GetDataObject(aURI);
|
||||
if (!dataObject) {
|
||||
DataInfo* info = GetDataInfoFromURI(aURI);
|
||||
if (!info || info->mObjectType != DataInfo::eMediaStream) {
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
|
||||
*aStream = nullptr;
|
||||
return CallQueryInterface(dataObject, aStream);
|
||||
RefPtr<DOMMediaStream> mediaStream = info->mMediaStream;
|
||||
mediaStream.forget(aStream);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -865,12 +914,13 @@ NS_GetSourceForMediaSourceURI(nsIURI* aURI, mozilla::dom::MediaSource** aSource)
|
||||
|
||||
*aSource = nullptr;
|
||||
|
||||
nsCOMPtr<mozilla::dom::MediaSource> source = do_QueryInterface(GetDataObject(aURI));
|
||||
if (!source) {
|
||||
DataInfo* info = GetDataInfoFromURI(aURI);
|
||||
if (!info || info->mObjectType != DataInfo::eMediaSource) {
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
|
||||
source.forget(aSource);
|
||||
RefPtr<MediaSource> mediaSource = info->mMediaSource;
|
||||
mediaSource.forget(aSource);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -878,40 +928,24 @@ NS_GetSourceForMediaSourceURI(nsIURI* aURI, mozilla::dom::MediaSource** aSource)
|
||||
{ 0xb43964aa, 0xa078, 0x44b2, \
|
||||
{ 0xb0, 0x6b, 0xfd, 0x4d, 0x1b, 0x17, 0x2e, 0x66 } }
|
||||
|
||||
#define NS_MEDIASTREAMPROTOCOLHANDLER_CID \
|
||||
{ 0x27d1fa24, 0x2b73, 0x4db3, \
|
||||
{ 0xab, 0x48, 0xb9, 0x83, 0x83, 0x40, 0xe0, 0x81 } }
|
||||
|
||||
#define NS_MEDIASOURCEPROTOCOLHANDLER_CID \
|
||||
{ 0x12ef31fc, 0xa8fb, 0x4661, \
|
||||
{ 0x9a, 0x63, 0xfb, 0x61, 0x04,0x5d, 0xb8, 0x61 } }
|
||||
|
||||
#define NS_FONTTABLEPROTOCOLHANDLER_CID \
|
||||
{ 0x3fc8f04e, 0xd719, 0x43ca, \
|
||||
{ 0x9a, 0xd0, 0x18, 0xee, 0x32, 0x02, 0x11, 0xf2 } }
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsBlobProtocolHandler)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMediaStreamProtocolHandler)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMediaSourceProtocolHandler)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsFontTableProtocolHandler)
|
||||
|
||||
NS_DEFINE_NAMED_CID(NS_BLOBPROTOCOLHANDLER_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_MEDIASTREAMPROTOCOLHANDLER_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_MEDIASOURCEPROTOCOLHANDLER_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_FONTTABLEPROTOCOLHANDLER_CID);
|
||||
|
||||
static const mozilla::Module::CIDEntry kHostObjectProtocolHandlerCIDs[] = {
|
||||
{ &kNS_BLOBPROTOCOLHANDLER_CID, false, nullptr, nsBlobProtocolHandlerConstructor },
|
||||
{ &kNS_MEDIASTREAMPROTOCOLHANDLER_CID, false, nullptr, nsMediaStreamProtocolHandlerConstructor },
|
||||
{ &kNS_MEDIASOURCEPROTOCOLHANDLER_CID, false, nullptr, nsMediaSourceProtocolHandlerConstructor },
|
||||
{ &kNS_FONTTABLEPROTOCOLHANDLER_CID, false, nullptr, nsFontTableProtocolHandlerConstructor },
|
||||
{ nullptr }
|
||||
};
|
||||
|
||||
static const mozilla::Module::ContractIDEntry kHostObjectProtocolHandlerContracts[] = {
|
||||
{ NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX BLOBURI_SCHEME, &kNS_BLOBPROTOCOLHANDLER_CID },
|
||||
{ NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX MEDIASTREAMURI_SCHEME, &kNS_MEDIASTREAMPROTOCOLHANDLER_CID },
|
||||
{ NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX MEDIASOURCEURI_SCHEME, &kNS_MEDIASOURCEPROTOCOLHANDLER_CID },
|
||||
{ NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX FONTTABLEURI_SCHEME, &kNS_FONTTABLEPROTOCOLHANDLER_CID },
|
||||
{ nullptr }
|
||||
};
|
||||
@ -924,3 +958,27 @@ static const mozilla::Module kHostObjectProtocolHandlerModule = {
|
||||
|
||||
NSMODULE_DEFN(HostObjectProtocolHandler) = &kHostObjectProtocolHandlerModule;
|
||||
|
||||
bool IsType(nsIURI* aUri, DataInfo::ObjectType aType)
|
||||
{
|
||||
DataInfo* info = GetDataInfoFromURI(aUri);
|
||||
if (!info) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return info->mObjectType == aType;
|
||||
}
|
||||
|
||||
bool IsBlobURI(nsIURI* aUri)
|
||||
{
|
||||
return IsType(aUri, DataInfo::eBlobImpl);
|
||||
}
|
||||
|
||||
bool IsMediaStreamURI(nsIURI* aUri)
|
||||
{
|
||||
return IsType(aUri, DataInfo::eMediaStream);
|
||||
}
|
||||
|
||||
bool IsMediaSourceURI(nsIURI* aUri)
|
||||
{
|
||||
return IsType(aUri, DataInfo::eMediaSource);
|
||||
}
|
||||
|
@ -15,14 +15,13 @@
|
||||
#include "nsTArray.h"
|
||||
|
||||
#define BLOBURI_SCHEME "blob"
|
||||
#define MEDIASTREAMURI_SCHEME "mediastream"
|
||||
#define MEDIASOURCEURI_SCHEME "mediasource"
|
||||
#define FONTTABLEURI_SCHEME "moz-fonttable"
|
||||
#define RTSPURI_SCHEME "rtsp"
|
||||
|
||||
class nsIPrincipal;
|
||||
|
||||
namespace mozilla {
|
||||
class BlobURLsReporter;
|
||||
class DOMMediaStream;
|
||||
namespace dom {
|
||||
class BlobImpl;
|
||||
@ -51,13 +50,25 @@ public:
|
||||
static nsresult GenerateURIString(const nsACString &aScheme,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsACString &aUri);
|
||||
static nsresult GenerateURIStringForBlobURL(nsIPrincipal* aPrincipal,
|
||||
nsACString &aUri);
|
||||
|
||||
// Methods for managing uri->object mapping
|
||||
// AddDataEntry creates the URI with the given scheme and returns it in aUri
|
||||
static nsresult AddDataEntry(const nsACString& aScheme,
|
||||
nsISupports* aObject,
|
||||
static nsresult AddDataEntry(mozilla::dom::BlobImpl* aBlobImpl,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsACString& aUri);
|
||||
static nsresult AddDataEntry(mozilla::DOMMediaStream* aMediaStream,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsACString& aUri);
|
||||
static nsresult AddDataEntry(mozilla::dom::MediaSource* aMediaSource,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsACString& aUri);
|
||||
// IPC only
|
||||
static nsresult AddDataEntry(const nsACString& aURI,
|
||||
nsIPrincipal* aPrincipal,
|
||||
mozilla::dom::BlobImpl* aBlobImpl);
|
||||
|
||||
static void RemoveDataEntry(const nsACString& aUri,
|
||||
bool aBroadcastToOTherProcesses = true);
|
||||
|
||||
@ -67,10 +78,6 @@ public:
|
||||
static nsIPrincipal* GetDataEntryPrincipal(const nsACString& aUri);
|
||||
static void Traverse(const nsACString& aUri, nsCycleCollectionTraversalCallback& aCallback);
|
||||
|
||||
// IPC or internal use only
|
||||
static nsresult AddDataEntry(const nsACString& aURI,
|
||||
nsISupports* aObject,
|
||||
nsIPrincipal* aPrincipal);
|
||||
static bool
|
||||
GetAllBlobURLEntries(nsTArray<mozilla::dom::BlobURLRegistrationData>& aRegistrations,
|
||||
mozilla::dom::ContentParent* aCP);
|
||||
@ -88,12 +95,6 @@ public:
|
||||
NS_IMETHOD GetScheme(nsACString &result) override;
|
||||
};
|
||||
|
||||
class nsMediaStreamProtocolHandler : public nsHostObjectProtocolHandler
|
||||
{
|
||||
public:
|
||||
NS_IMETHOD GetScheme(nsACString &result) override;
|
||||
};
|
||||
|
||||
class nsMediaSourceProtocolHandler : public nsHostObjectProtocolHandler
|
||||
{
|
||||
public:
|
||||
@ -107,11 +108,9 @@ public:
|
||||
NS_IMETHOD NewURI(const nsACString & aSpec, const char * aOriginCharset, nsIURI *aBaseURI, nsIURI * *_retval);
|
||||
};
|
||||
|
||||
inline bool IsBlobURI(nsIURI* aUri)
|
||||
{
|
||||
bool isBlob;
|
||||
return NS_SUCCEEDED(aUri->SchemeIs(BLOBURI_SCHEME, &isBlob)) && isBlob;
|
||||
}
|
||||
bool IsBlobURI(nsIURI* aUri);
|
||||
bool IsMediaStreamURI(nsIURI* aUri);
|
||||
bool IsMediaSourceURI(nsIURI* aUri);
|
||||
|
||||
inline bool IsRtspURI(nsIURI* aUri)
|
||||
{
|
||||
@ -119,18 +118,6 @@ inline bool IsRtspURI(nsIURI* aUri)
|
||||
return NS_SUCCEEDED(aUri->SchemeIs(RTSPURI_SCHEME, &isRtsp)) && isRtsp;
|
||||
}
|
||||
|
||||
inline bool IsMediaStreamURI(nsIURI* aUri)
|
||||
{
|
||||
bool isStream;
|
||||
return NS_SUCCEEDED(aUri->SchemeIs(MEDIASTREAMURI_SCHEME, &isStream)) && isStream;
|
||||
}
|
||||
|
||||
inline bool IsMediaSourceURI(nsIURI* aUri)
|
||||
{
|
||||
bool isMediaSource;
|
||||
return NS_SUCCEEDED(aUri->SchemeIs(MEDIASOURCEURI_SCHEME, &isMediaSource)) && isMediaSource;
|
||||
}
|
||||
|
||||
inline bool IsFontTableURI(nsIURI* aUri)
|
||||
{
|
||||
bool isFont;
|
||||
|
@ -1500,9 +1500,15 @@ nsresult HTMLMediaElement::LoadResource()
|
||||
mCORSMode = AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
|
||||
|
||||
#ifdef MOZ_EME
|
||||
bool isBlob = false;
|
||||
if (mMediaKeys &&
|
||||
!IsMediaSourceURI(mLoadingSrc) &&
|
||||
Preferences::GetBool("media.eme.mse-only", true)) {
|
||||
Preferences::GetBool("media.eme.mse-only", true) &&
|
||||
// We only want mediaSource URLs, but they are BlobURL, so we have to
|
||||
// check the schema and if they are not MediaStream or real Blob.
|
||||
(NS_FAILED(mLoadingSrc->SchemeIs(BLOBURI_SCHEME, &isBlob)) ||
|
||||
!isBlob ||
|
||||
IsMediaStreamURI(mLoadingSrc) ||
|
||||
IsBlobURI(mLoadingSrc))) {
|
||||
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
||||
}
|
||||
#endif
|
||||
|
@ -2644,8 +2644,9 @@ ContentChild::RecvInitBlobURLs(nsTArray<BlobURLRegistrationData>&& aRegistration
|
||||
static_cast<BlobChild*>(registration.blobChild())->GetBlobImpl();
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
nsHostObjectProtocolHandler::AddDataEntry(registration.url(), blobImpl,
|
||||
registration.principal());
|
||||
nsHostObjectProtocolHandler::AddDataEntry(registration.url(),
|
||||
registration.principal(),
|
||||
blobImpl);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -3396,7 +3397,7 @@ ContentChild::RecvBlobURLRegistration(const nsCString& aURI, PBlobChild* aBlobCh
|
||||
RefPtr<BlobImpl> blobImpl = static_cast<BlobChild*>(aBlobChild)->GetBlobImpl();
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
nsHostObjectProtocolHandler::AddDataEntry(aURI, blobImpl, aPrincipal);
|
||||
nsHostObjectProtocolHandler::AddDataEntry(aURI, aPrincipal, blobImpl);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -5749,8 +5749,8 @@ ContentParent::RecvStoreAndBroadcastBlobURLRegistration(const nsCString& aURI,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(nsHostObjectProtocolHandler::AddDataEntry(aURI, blobImpl,
|
||||
aPrincipal))) {
|
||||
if (NS_SUCCEEDED(nsHostObjectProtocolHandler::AddDataEntry(aURI, aPrincipal,
|
||||
blobImpl))) {
|
||||
BroadcastBlobURLRegistration(aURI, blobImpl, aPrincipal, this);
|
||||
|
||||
// We want to store this blobURL, so we can unregister it if the child
|
||||
|
@ -34,6 +34,30 @@ namespace dom {
|
||||
|
||||
namespace {
|
||||
|
||||
template<typename T>
|
||||
void
|
||||
CreateObjectURLInternal(const GlobalObject& aGlobal, T aObject,
|
||||
nsAString& aResult, ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
|
||||
if (NS_WARN_IF(!global)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal =
|
||||
nsContentUtils::ObjectPrincipal(aGlobal.Get());
|
||||
|
||||
nsAutoCString url;
|
||||
aRv = nsHostObjectProtocolHandler::AddDataEntry(aObject, principal, url);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
global->RegisterHostObjectURI(url);
|
||||
CopyASCIItoUTF16(url, aResult);
|
||||
}
|
||||
|
||||
// The URL implementation for the main-thread
|
||||
class URLMainThread final : public URL
|
||||
{
|
||||
@ -60,9 +84,7 @@ public:
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
CreateObjectURLInternal(aGlobal, aBlob.Impl(),
|
||||
NS_LITERAL_CSTRING(BLOBURI_SCHEME), aOptions,
|
||||
aResult, aRv);
|
||||
CreateObjectURLInternal(aGlobal, aBlob.Impl(), aResult, aRv);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -71,9 +93,7 @@ public:
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
CreateObjectURLInternal(aGlobal, &aStream,
|
||||
NS_LITERAL_CSTRING(MEDIASTREAMURI_SCHEME), aOptions,
|
||||
aResult, aRv);
|
||||
CreateObjectURLInternal(aGlobal, &aStream, aResult, aRv);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -81,12 +101,6 @@ public:
|
||||
const objectURLOptions& aOptions, nsAString& aResult,
|
||||
ErrorResult& aRv);
|
||||
|
||||
static void
|
||||
CreateObjectURLInternal(const GlobalObject& aGlobal, nsISupports* aObject,
|
||||
const nsACString& aScheme,
|
||||
const objectURLOptions& aOptions,
|
||||
nsAString& aResult, ErrorResult& aRv);
|
||||
|
||||
static void
|
||||
RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aURL,
|
||||
ErrorResult& aRv);
|
||||
@ -246,9 +260,7 @@ URLMainThread::CreateObjectURL(const GlobalObject& aGlobal,
|
||||
nsContentUtils::ObjectPrincipal(aGlobal.Get());
|
||||
|
||||
nsAutoCString url;
|
||||
aRv = nsHostObjectProtocolHandler::
|
||||
AddDataEntry(NS_LITERAL_CSTRING(MEDIASOURCEURI_SCHEME),
|
||||
&aSource, principal, url);
|
||||
aRv = nsHostObjectProtocolHandler::AddDataEntry(&aSource, principal, url);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
@ -263,34 +275,6 @@ URLMainThread::CreateObjectURL(const GlobalObject& aGlobal,
|
||||
CopyASCIItoUTF16(url, aResult);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
URLMainThread::CreateObjectURLInternal(const GlobalObject& aGlobal,
|
||||
nsISupports* aObject,
|
||||
const nsACString& aScheme,
|
||||
const objectURLOptions& aOptions,
|
||||
nsAString& aResult, ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
|
||||
if (!global) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal =
|
||||
nsContentUtils::ObjectPrincipal(aGlobal.Get());
|
||||
|
||||
nsAutoCString url;
|
||||
nsresult rv = nsHostObjectProtocolHandler::AddDataEntry(aScheme, aObject,
|
||||
principal, url);
|
||||
if (NS_FAILED(rv)) {
|
||||
aRv.Throw(rv);
|
||||
return;
|
||||
}
|
||||
|
||||
global->RegisterHostObjectURI(url);
|
||||
CopyASCIItoUTF16(url, aResult);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
URLMainThread::RevokeObjectURL(const GlobalObject& aGlobal,
|
||||
const nsAString& aURL, ErrorResult& aRv)
|
||||
@ -826,9 +810,8 @@ public:
|
||||
nsCOMPtr<nsIPrincipal> principal = mWorkerPrivate->GetPrincipal();
|
||||
|
||||
nsAutoCString url;
|
||||
nsresult rv = nsHostObjectProtocolHandler::AddDataEntry(
|
||||
NS_LITERAL_CSTRING(BLOBURI_SCHEME),
|
||||
mBlobImpl, principal, url);
|
||||
nsresult rv =
|
||||
nsHostObjectProtocolHandler::AddDataEntry(mBlobImpl, principal, url);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to add data entry for the blob!");
|
||||
|
@ -1,6 +0,0 @@
|
||||
[URL-createObjectURL.html]
|
||||
type: testharness
|
||||
prefs: [media.mediasource.enabled:true]
|
||||
[URL.createObjectURL(mediaSource) should return a unique Blob URI.]
|
||||
expected: FAIL
|
||||
|
Loading…
Reference in New Issue
Block a user