Bug 1619953 - P6 - BlobURLChannel creates BlobURLInputStream only when content stream is opened r=baku

Additionally, BlobURLChannel holds no strong reference to BlobURLInputStream. This is to avoid circular dependency.

Differential Revision: https://phabricator.services.mozilla.com/D81452
This commit is contained in:
ssengupta 2020-08-05 17:06:04 +00:00
Родитель 8d095d15bf
Коммит fd9c765041
3 изменённых файлов: 18 добавлений и 50 удалений

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

@ -13,7 +13,7 @@
using namespace mozilla::dom;
BlobURLChannel::BlobURLChannel(nsIURI* aURI, nsILoadInfo* aLoadInfo)
: mInitialized(false) {
: mContentStreamOpened(false) {
SetURI(aURI);
SetOriginalURI(aURI);
SetLoadInfo(aLoadInfo);
@ -27,26 +27,24 @@ BlobURLChannel::BlobURLChannel(nsIURI* aURI, nsILoadInfo* aLoadInfo)
BlobURLChannel::~BlobURLChannel() = default;
void BlobURLChannel::InitFailed() {
MOZ_ASSERT(!mInitialized);
MOZ_ASSERT(!mInputStream);
mInitialized = true;
}
nsresult BlobURLChannel::OpenContentStream(bool aAsync,
nsIInputStream** aResult,
nsIChannel** aChannel) {
if (mContentStreamOpened) {
return NS_ERROR_ALREADY_OPENED;
}
void BlobURLChannel::Initialize() {
MOZ_ASSERT(!mInitialized);
auto cleanupOnEarlyExit = MakeScopeExit([&] { InitFailed(); });
mContentStreamOpened = true;
nsCOMPtr<nsIURI> uri;
nsresult rv = GetURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS_VOID(rv);
NS_ENSURE_SUCCESS(rv, NS_ERROR_MALFORMED_URI);
RefPtr<BlobURL> blobURL;
rv = uri->QueryInterface(kHOSTOBJECTURICID, getter_AddRefs(blobURL));
if (NS_WARN_IF(NS_FAILED(rv)) || NS_WARN_IF(!blobURL)) {
return;
return NS_ERROR_MALFORMED_URI;
}
if (blobURL->Revoked()) {
@ -56,36 +54,22 @@ void BlobURLChannel::Initialize() {
// if the channel was not triggered by the system principal,
// then we return here because the URL had been revoked
if (loadInfo && !loadInfo->TriggeringPrincipal()->IsSystemPrincipal()) {
return;
return NS_ERROR_MALFORMED_URI;
}
#else
return;
return NS_ERROR_MALFORMED_URI;
#endif
}
mInputStream = BlobURLInputStream::Create(this, blobURL);
if (NS_WARN_IF(!mInputStream)) {
return;
}
cleanupOnEarlyExit.release();
mInitialized = true;
}
nsresult BlobURLChannel::OpenContentStream(bool aAsync,
nsIInputStream** aResult,
nsIChannel** aChannel) {
MOZ_ASSERT(mInitialized);
if (!mInputStream) {
nsCOMPtr<nsIInputStream> inputStream =
BlobURLInputStream::Create(this, blobURL);
if (NS_WARN_IF(!inputStream)) {
return NS_ERROR_MALFORMED_URI;
}
EnableSynthesizedProgressEvents(true);
nsCOMPtr<nsIInputStream> stream = mInputStream;
stream.forget(aResult);
inputStream.forget(aResult);
return NS_OK;
}
void BlobURLChannel::OnChannelDone() { mInputStream = nullptr; }
}

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

@ -22,28 +22,13 @@ class BlobURLChannel final : public nsBaseChannel {
public:
BlobURLChannel(nsIURI* aURI, nsILoadInfo* aLoadInfo);
// This method is called when there is not a valid BlobImpl for this channel.
// This method will make ::OpenContentStream to return NS_ERROR_MALFORMED_URI.
void InitFailed();
// There is a valid BlobImpl for the channel. The blob's inputStream will be
// used when ::OpenContentStream is called.
void Initialize();
private:
~BlobURLChannel();
nsresult OpenContentStream(bool aAsync, nsIInputStream** aResult,
nsIChannel** aChannel) override;
void OnChannelDone() override;
// If Initialize() is called, this will contain the blob's inputStream.
nsCOMPtr<nsIInputStream> mInputStream;
// This boolean is used to check that InitFailed() or Initialize() are called
// just once.
bool mInitialized;
bool mContentStreamOpened;
};
} // namespace dom

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

@ -783,7 +783,6 @@ BlobURLProtocolHandler::NewChannel(nsIURI* aURI, nsILoadInfo* aLoadInfo,
if (!channel) {
return NS_ERROR_NOT_INITIALIZED;
}
channel->Initialize();
channel.forget(aResult);
return NS_OK;
}