Bug 1312410 - Fetch API should use MutableBlobStorage to store big Blobs on disk, r=qdot

This commit is contained in:
Andrea Marchesini
2016-10-26 09:07:25 +02:00
parent 87820057a6
commit 0ce4aeb4a5
10 changed files with 383 additions and 73 deletions

View File

@@ -316,7 +316,6 @@ public:
{ {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mBlobStorage); MOZ_ASSERT(mBlobStorage);
MOZ_ASSERT(aParent);
MOZ_ASSERT(aCallback); MOZ_ASSERT(aCallback);
} }
@@ -373,7 +372,6 @@ MutableBlobStorage::GetBlobWhenReady(nsISupports* aParent,
MutableBlobStorageCallback* aCallback) MutableBlobStorageCallback* aCallback)
{ {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aParent);
MOZ_ASSERT(aCallback); MOZ_ASSERT(aCallback);
// GetBlob can be called just once. // GetBlob can be called just once.

View File

@@ -0,0 +1,102 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 "MutableBlobStreamListener.h"
#include "MutableBlobStorage.h"
namespace mozilla {
namespace dom {
MutableBlobStreamListener::MutableBlobStreamListener(MutableBlobStorage::MutableBlobStorageType aStorageType,
nsISupports* aParent,
const nsACString& aContentType,
MutableBlobStorageCallback* aCallback)
: mCallback(aCallback)
, mParent(aParent)
, mStorageType(aStorageType)
, mContentType(aContentType)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aCallback);
}
MutableBlobStreamListener::~MutableBlobStreamListener()
{
MOZ_ASSERT(NS_IsMainThread());
}
NS_IMPL_ISUPPORTS(MutableBlobStreamListener,
nsIStreamListener,
nsIRequestObserver)
NS_IMETHODIMP
MutableBlobStreamListener::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!mStorage);
mStorage = new MutableBlobStorage(mStorageType);
return NS_OK;
}
NS_IMETHODIMP
MutableBlobStreamListener::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
nsresult aStatus)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mStorage);
// Resetting mStorage to nullptr.
RefPtr<MutableBlobStorage> storage;
storage.swap(mStorage);
// Let's propagate the error simulating a failure of the storage.
if (NS_FAILED(aStatus)) {
mCallback->BlobStoreCompleted(storage, nullptr, aStatus);
return NS_OK;
}
storage->GetBlobWhenReady(mParent, mContentType, mCallback);
return NS_OK;
}
NS_IMETHODIMP
MutableBlobStreamListener::OnDataAvailable(nsIRequest* aRequest,
nsISupports* aContext,
nsIInputStream* aStream,
uint64_t aSourceOffset,
uint32_t aCount)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mStorage);
uint32_t countRead;
return aStream->ReadSegments(WriteSegmentFun, this, aCount, &countRead);
}
nsresult
MutableBlobStreamListener::WriteSegmentFun(nsIInputStream* aWriterStream,
void* aClosure,
const char* aFromSegment,
uint32_t aToOffset,
uint32_t aCount,
uint32_t* aWriteCount)
{
MOZ_ASSERT(NS_IsMainThread());
MutableBlobStreamListener* self = static_cast<MutableBlobStreamListener*>(aClosure);
MOZ_ASSERT(self->mStorage);
nsresult rv = self->mStorage->Append(aFromSegment, aCount);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
*aWriteCount = aCount;
return NS_OK;
}
} // namespace net
} // namespace mozilla

View File

@@ -0,0 +1,48 @@
/* -*- 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 mozilla_dom_MutableBlobStreamListener_h
#define mozilla_dom_MutableBlobStreamListener_h
#include "nsIStreamListener.h"
#include "mozilla/dom/MutableBlobStorage.h"
namespace mozilla {
namespace dom {
// This class is main-thread only.
class MutableBlobStreamListener final : public nsIStreamListener
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIREQUESTOBSERVER
MutableBlobStreamListener(MutableBlobStorage::MutableBlobStorageType aType,
nsISupports* aParent,
const nsACString& aContentType,
MutableBlobStorageCallback* aCallback);
private:
~MutableBlobStreamListener();
static nsresult
WriteSegmentFun(nsIInputStream* aWriter, void* aClosure,
const char* aFromSegment, uint32_t aOffset,
uint32_t aCount, uint32_t* aWriteCount);
RefPtr<MutableBlobStorage> mStorage;
RefPtr<MutableBlobStorageCallback> mCallback;
nsCOMPtr<nsISupports> mParent;
MutableBlobStorage::MutableBlobStorageType mStorageType;
nsCString mContentType;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_MutableBlobStreamListener_h

View File

@@ -188,6 +188,7 @@ EXPORTS.mozilla.dom += [
'Link.h', 'Link.h',
'Location.h', 'Location.h',
'MutableBlobStorage.h', 'MutableBlobStorage.h',
'MutableBlobStreamListener.h',
'NameSpaceConstants.h', 'NameSpaceConstants.h',
'Navigator.h', 'Navigator.h',
'NodeInfo.h', 'NodeInfo.h',
@@ -251,6 +252,7 @@ UNIFIED_SOURCES += [
'Location.cpp', 'Location.cpp',
'MultipartBlobImpl.cpp', 'MultipartBlobImpl.cpp',
'MutableBlobStorage.cpp', 'MutableBlobStorage.cpp',
'MutableBlobStreamListener.cpp',
'Navigator.cpp', 'Navigator.cpp',
'NodeInfo.cpp', 'NodeInfo.cpp',
'NodeIterator.cpp', 'NodeIterator.cpp',

View File

@@ -28,6 +28,7 @@
#include "mozilla/dom/File.h" #include "mozilla/dom/File.h"
#include "mozilla/dom/FormData.h" #include "mozilla/dom/FormData.h"
#include "mozilla/dom/Headers.h" #include "mozilla/dom/Headers.h"
#include "mozilla/dom/MutableBlobStreamListener.h"
#include "mozilla/dom/Promise.h" #include "mozilla/dom/Promise.h"
#include "mozilla/dom/PromiseWorkerProxy.h" #include "mozilla/dom/PromiseWorkerProxy.h"
#include "mozilla/dom/Request.h" #include "mozilla/dom/Request.h"
@@ -170,10 +171,7 @@ public:
// ...but release it before calling Fetch, because mResolver's callback can // ...but release it before calling Fetch, because mResolver's callback can
// be called synchronously and they want the mutex, too. // be called synchronously and they want the mutex, too.
fetch->Fetch(mResolver); return fetch->Fetch(mResolver);
// FetchDriver::Fetch never directly fails
return NS_OK;
} }
}; };
@@ -709,6 +707,36 @@ public:
} }
}; };
/*
* Called on successfully reading the complete stream for Blob.
*/
template <class Derived>
class ContinueConsumeBlobBodyRunnable final : public MainThreadWorkerRunnable
{
// This has been addrefed before this runnable is dispatched,
// released in WorkerRun().
FetchBody<Derived>* mFetchBody;
RefPtr<BlobImpl> mBlobImpl;
public:
ContinueConsumeBlobBodyRunnable(FetchBody<Derived>* aFetchBody,
BlobImpl* aBlobImpl)
: MainThreadWorkerRunnable(aFetchBody->mWorkerPrivate)
, mFetchBody(aFetchBody)
, mBlobImpl(aBlobImpl)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mBlobImpl);
}
bool
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
{
mFetchBody->ContinueConsumeBlobBody(mBlobImpl);
return true;
}
};
// OnStreamComplete always adopts the buffer, utility class to release it in // OnStreamComplete always adopts the buffer, utility class to release it in
// a couple of places. // a couple of places.
class MOZ_STACK_CLASS AutoFreeBuffer final { class MOZ_STACK_CLASS AutoFreeBuffer final {
@@ -789,6 +817,7 @@ public:
template <class Derived> template <class Derived>
class ConsumeBodyDoneObserver : public nsIStreamLoaderObserver class ConsumeBodyDoneObserver : public nsIStreamLoaderObserver
, public MutableBlobStorageCallback
{ {
FetchBody<Derived>* mFetchBody; FetchBody<Derived>* mFetchBody;
@@ -836,6 +865,31 @@ public:
return NS_SUCCESS_ADOPTED_DATA; return NS_SUCCESS_ADOPTED_DATA;
} }
virtual void BlobStoreCompleted(MutableBlobStorage* aBlobStorage,
Blob* aBlob,
nsresult aRv) override
{
// On error.
if (NS_FAILED(aRv)) {
OnStreamComplete(nullptr, nullptr, aRv, 0, nullptr);
return;
}
MOZ_ASSERT(aBlob);
if (mFetchBody->mWorkerPrivate) {
RefPtr<ContinueConsumeBlobBodyRunnable<Derived>> r =
new ContinueConsumeBlobBodyRunnable<Derived>(mFetchBody, aBlob->Impl());
if (!r->Dispatch()) {
NS_WARNING("Could not dispatch ConsumeBlobBodyRunnable");
return;
}
} else {
mFetchBody->ContinueConsumeBlobBody(aBlob->Impl());
}
}
private: private:
virtual ~ConsumeBodyDoneObserver() virtual ~ConsumeBodyDoneObserver()
{ } { }
@@ -1074,13 +1128,35 @@ FetchBody<Derived>::BeginConsumeBodyMainThread()
} }
RefPtr<ConsumeBodyDoneObserver<Derived>> p = new ConsumeBodyDoneObserver<Derived>(this); RefPtr<ConsumeBodyDoneObserver<Derived>> p = new ConsumeBodyDoneObserver<Derived>(this);
nsCOMPtr<nsIStreamLoader> loader;
rv = NS_NewStreamLoader(getter_AddRefs(loader), p); nsCOMPtr<nsIStreamListener> listener;
if (NS_WARN_IF(NS_FAILED(rv))) { if (mConsumeType == CONSUME_BLOB) {
return; MutableBlobStorage::MutableBlobStorageType type =
MutableBlobStorage::eOnlyInMemory;
const mozilla::UniquePtr<mozilla::ipc::PrincipalInfo>& principalInfo =
DerivedClass()->GetPrincipalInfo();
// We support temporary file for blobs only if the principal is known and
// it's system or content not in private Browsing.
if (principalInfo &&
(principalInfo->type() == mozilla::ipc::PrincipalInfo::TSystemPrincipalInfo ||
(principalInfo->type() == mozilla::ipc::PrincipalInfo::TContentPrincipalInfo &&
principalInfo->get_ContentPrincipalInfo().attrs().mPrivateBrowsingId == 0))) {
type = MutableBlobStorage::eCouldBeInTemporaryFile;
}
listener = new MutableBlobStreamListener(type, nullptr, mMimeType, p);
} else {
nsCOMPtr<nsIStreamLoader> loader;
rv = NS_NewStreamLoader(getter_AddRefs(loader), p);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
listener = loader;
} }
rv = pump->AsyncRead(loader, nullptr); rv = pump->AsyncRead(listener, nullptr);
if (NS_WARN_IF(NS_FAILED(rv))) { if (NS_WARN_IF(NS_FAILED(rv))) {
return; return;
} }
@@ -1195,14 +1271,7 @@ FetchBody<Derived>::ContinueConsumeBody(nsresult aStatus, uint32_t aResultLength
break; break;
} }
case CONSUME_BLOB: { case CONSUME_BLOB: {
RefPtr<dom::Blob> blob = BodyUtil::ConsumeBlob( MOZ_CRASH("This should not happen.");
derivedClass->GetParentObject(), NS_ConvertUTF8toUTF16(mMimeType),
aResultLength, aResult, error);
if (!error.Failed()) {
localPromise->MaybeResolve(blob);
// File takes over ownership.
autoFree.Reset();
}
break; break;
} }
case CONSUME_FORMDATA: { case CONSUME_FORMDATA: {
@@ -1245,6 +1314,38 @@ FetchBody<Derived>::ContinueConsumeBody(nsresult aStatus, uint32_t aResultLength
} }
} }
template <class Derived>
void
FetchBody<Derived>::ContinueConsumeBlobBody(BlobImpl* aBlobImpl)
{
AssertIsOnTargetThread();
// Just a precaution to ensure ContinueConsumeBody is not called out of
// sync with a body read.
MOZ_ASSERT(mBodyUsed);
MOZ_ASSERT(!mReadDone);
MOZ_ASSERT(mConsumeType == CONSUME_BLOB);
MOZ_ASSERT_IF(mWorkerPrivate, mWorkerHolder);
#ifdef DEBUG
mReadDone = true;
#endif
MOZ_ASSERT(mConsumePromise);
RefPtr<Promise> localPromise = mConsumePromise.forget();
RefPtr<Derived> derivedClass = DerivedClass();
ReleaseObject();
// Release the pump and then early exit if there was an error.
// Uses NS_ProxyRelease internally, so this is safe.
mConsumeBodyPump = nullptr;
RefPtr<dom::Blob> blob =
dom::Blob::Create(derivedClass->GetParentObject(), aBlobImpl);
MOZ_ASSERT(blob);
localPromise->MaybeResolve(blob);
}
template <class Derived> template <class Derived>
already_AddRefed<Promise> already_AddRefed<Promise>
FetchBody<Derived>::ConsumeBody(ConsumeType aType, ErrorResult& aRv) FetchBody<Derived>::ConsumeBody(ConsumeType aType, ErrorResult& aRv)

View File

@@ -28,6 +28,7 @@ namespace mozilla {
namespace dom { namespace dom {
class ArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams; class ArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams;
class BlobImpl;
class InternalRequest; class InternalRequest;
class OwningArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams; class OwningArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams;
class RequestOrUSVString; class RequestOrUSVString;
@@ -141,6 +142,9 @@ public:
void void
ContinueConsumeBody(nsresult aStatus, uint32_t aLength, uint8_t* aResult); ContinueConsumeBody(nsresult aStatus, uint32_t aLength, uint8_t* aResult);
void
ContinueConsumeBlobBody(BlobImpl* aBlobImpl);
void void
CancelPump(); CancelPump();

View File

@@ -31,6 +31,7 @@
#include "mozilla/dom/File.h" #include "mozilla/dom/File.h"
#include "mozilla/dom/workers/Workers.h" #include "mozilla/dom/workers/Workers.h"
#include "mozilla/ipc/PBackgroundSharedTypes.h"
#include "mozilla/Unused.h" #include "mozilla/Unused.h"
#include "Fetch.h" #include "Fetch.h"
@@ -54,6 +55,8 @@ FetchDriver::FetchDriver(InternalRequest* aRequest, nsIPrincipal* aPrincipal,
, mFetchCalled(false) , mFetchCalled(false)
#endif #endif
{ {
MOZ_ASSERT(aRequest);
MOZ_ASSERT(aPrincipal);
} }
FetchDriver::~FetchDriver() FetchDriver::~FetchDriver()
@@ -82,6 +85,14 @@ FetchDriver::Fetch(FetchDriverObserver* aObserver)
MOZ_RELEASE_ASSERT(!mRequest->IsSynchronous(), MOZ_RELEASE_ASSERT(!mRequest->IsSynchronous(),
"Synchronous fetch not supported"); "Synchronous fetch not supported");
UniquePtr<mozilla::ipc::PrincipalInfo> principalInfo(new mozilla::ipc::PrincipalInfo());
nsresult rv = PrincipalToPrincipalInfo(mPrincipal, principalInfo.get());
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
mRequest->SetPrincipalInfo(Move(principalInfo));
if (NS_FAILED(HttpFetch())) { if (NS_FAILED(HttpFetch())) {
FailWithNetworkError(); FailWithNetworkError();
} }

View File

@@ -79,6 +79,72 @@ InternalRequest::Clone()
return clone.forget(); return clone.forget();
} }
InternalRequest::InternalRequest(const nsACString& aURL)
: mMethod("GET")
, mHeaders(new InternalHeaders(HeadersGuardEnum::None))
, mContentPolicyType(nsIContentPolicy::TYPE_FETCH)
, mReferrer(NS_LITERAL_STRING(kFETCH_CLIENT_REFERRER_STR))
, mReferrerPolicy(ReferrerPolicy::_empty)
, mEnvironmentReferrerPolicy(net::RP_Default)
, mMode(RequestMode::No_cors)
, mCredentialsMode(RequestCredentials::Omit)
, mResponseTainting(LoadTainting::Basic)
, mCacheMode(RequestCache::Default)
, mRedirectMode(RequestRedirect::Follow)
, mAuthenticationFlag(false)
, mForceOriginHeader(false)
, mPreserveContentCodings(false)
// FIXME(nsm): This should be false by default, but will lead to the
// algorithm never loading data: URLs right now. See Bug 1018872 about
// how certain contexts will override it to set it to true. Fetch
// specification does not handle this yet.
, mSameOriginDataURL(true)
, mSkipServiceWorker(false)
, mSynchronous(false)
, mUnsafeRequest(false)
, mUseURLCredentials(false)
{
MOZ_ASSERT(!aURL.IsEmpty());
AddURL(aURL);
}
InternalRequest::InternalRequest(const nsACString& aURL,
const nsACString& aMethod,
already_AddRefed<InternalHeaders> aHeaders,
RequestCache aCacheMode,
RequestMode aMode,
RequestRedirect aRequestRedirect,
RequestCredentials aRequestCredentials,
const nsAString& aReferrer,
ReferrerPolicy aReferrerPolicy,
nsContentPolicyType aContentPolicyType,
const nsAString& aIntegrity)
: mMethod(aMethod)
, mHeaders(aHeaders)
, mContentPolicyType(aContentPolicyType)
, mReferrer(aReferrer)
, mReferrerPolicy(aReferrerPolicy)
, mEnvironmentReferrerPolicy(net::RP_Default)
, mMode(aMode)
, mCredentialsMode(aRequestCredentials)
, mResponseTainting(LoadTainting::Basic)
, mCacheMode(aCacheMode)
, mRedirectMode(aRequestRedirect)
, mIntegrity(aIntegrity)
, mAuthenticationFlag(false)
, mForceOriginHeader(false)
, mPreserveContentCodings(false)
// FIXME See the above comment in the default constructor.
, mSameOriginDataURL(true)
, mSkipServiceWorker(false)
, mSynchronous(false)
, mUnsafeRequest(false)
, mUseURLCredentials(false)
{
MOZ_ASSERT(!aURL.IsEmpty());
AddURL(aURL);
}
InternalRequest::InternalRequest(const InternalRequest& aOther) InternalRequest::InternalRequest(const InternalRequest& aOther)
: mMethod(aOther.mMethod) : mMethod(aOther.mMethod)
, mURLList(aOther.mURLList) , mURLList(aOther.mURLList)
@@ -422,5 +488,11 @@ InternalRequest::MaybeSkipCacheIfPerformingRevalidation()
} }
} }
void
InternalRequest::SetPrincipalInfo(UniquePtr<mozilla::ipc::PrincipalInfo> aPrincipalInfo)
{
mPrincipalInfo = Move(aPrincipalInfo);
}
} // namespace dom } // namespace dom
} // namespace mozilla } // namespace mozilla

View File

@@ -23,6 +23,11 @@
#endif #endif
namespace mozilla { namespace mozilla {
namespace ipc {
class PrincipalInfo;
} // namespace ipc
namespace dom { namespace dom {
/* /*
@@ -90,34 +95,7 @@ class InternalRequest final
public: public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(InternalRequest) NS_INLINE_DECL_THREADSAFE_REFCOUNTING(InternalRequest)
explicit InternalRequest(const nsACString& aURL) explicit InternalRequest(const nsACString& aURL);
: mMethod("GET")
, mHeaders(new InternalHeaders(HeadersGuardEnum::None))
, mContentPolicyType(nsIContentPolicy::TYPE_FETCH)
, mReferrer(NS_LITERAL_STRING(kFETCH_CLIENT_REFERRER_STR))
, mReferrerPolicy(ReferrerPolicy::_empty)
, mEnvironmentReferrerPolicy(net::RP_Default)
, mMode(RequestMode::No_cors)
, mCredentialsMode(RequestCredentials::Omit)
, mResponseTainting(LoadTainting::Basic)
, mCacheMode(RequestCache::Default)
, mRedirectMode(RequestRedirect::Follow)
, mAuthenticationFlag(false)
, mForceOriginHeader(false)
, mPreserveContentCodings(false)
// FIXME(nsm): This should be false by default, but will lead to the
// algorithm never loading data: URLs right now. See Bug 1018872 about
// how certain contexts will override it to set it to true. Fetch
// specification does not handle this yet.
, mSameOriginDataURL(true)
, mSkipServiceWorker(false)
, mSynchronous(false)
, mUnsafeRequest(false)
, mUseURLCredentials(false)
{
MOZ_ASSERT(!aURL.IsEmpty());
AddURL(aURL);
}
InternalRequest(const nsACString& aURL, InternalRequest(const nsACString& aURL,
const nsACString& aMethod, const nsACString& aMethod,
@@ -129,32 +107,7 @@ public:
const nsAString& aReferrer, const nsAString& aReferrer,
ReferrerPolicy aReferrerPolicy, ReferrerPolicy aReferrerPolicy,
nsContentPolicyType aContentPolicyType, nsContentPolicyType aContentPolicyType,
const nsAString& aIntegrity) const nsAString& aIntegrity);
: mMethod(aMethod)
, mHeaders(aHeaders)
, mContentPolicyType(aContentPolicyType)
, mReferrer(aReferrer)
, mReferrerPolicy(aReferrerPolicy)
, mEnvironmentReferrerPolicy(net::RP_Default)
, mMode(aMode)
, mCredentialsMode(aRequestCredentials)
, mResponseTainting(LoadTainting::Basic)
, mCacheMode(aCacheMode)
, mRedirectMode(aRequestRedirect)
, mIntegrity(aIntegrity)
, mAuthenticationFlag(false)
, mForceOriginHeader(false)
, mPreserveContentCodings(false)
// FIXME See the above comment in the default constructor.
, mSameOriginDataURL(true)
, mSkipServiceWorker(false)
, mSynchronous(false)
, mUnsafeRequest(false)
, mUseURLCredentials(false)
{
MOZ_ASSERT(!aURL.IsEmpty());
AddURL(aURL);
}
explicit InternalRequest(const IPCInternalRequest& aIPCRequest); explicit InternalRequest(const IPCInternalRequest& aIPCRequest);
@@ -493,6 +446,16 @@ public:
static RequestCredentials static RequestCredentials
MapChannelToRequestCredentials(nsIChannel* aChannel); MapChannelToRequestCredentials(nsIChannel* aChannel);
// Takes ownership of the principal info.
void
SetPrincipalInfo(UniquePtr<mozilla::ipc::PrincipalInfo> aPrincipalInfo);
const UniquePtr<mozilla::ipc::PrincipalInfo>&
GetPrincipalInfo() const
{
return mPrincipalInfo;
}
private: private:
// Does not copy mBodyStream. Use fallible Clone() for complete copy. // Does not copy mBodyStream. Use fallible Clone() for complete copy.
explicit InternalRequest(const InternalRequest& aOther); explicit InternalRequest(const InternalRequest& aOther);
@@ -553,6 +516,8 @@ private:
// It is illegal to pass such a Request object to a fetch() method unless // It is illegal to pass such a Request object to a fetch() method unless
// if the caller has chrome privileges. // if the caller has chrome privileges.
bool mContentPolicyTypeOverridden = false; bool mContentPolicyTypeOverridden = false;
UniquePtr<mozilla::ipc::PrincipalInfo> mPrincipalInfo;
}; };
} // namespace dom } // namespace dom

View File

@@ -145,6 +145,13 @@ public:
already_AddRefed<InternalRequest> already_AddRefed<InternalRequest>
GetInternalRequest(); GetInternalRequest();
const UniquePtr<mozilla::ipc::PrincipalInfo>&
GetPrincipalInfo() const
{
return mRequest->GetPrincipalInfo();
}
private: private:
~Request(); ~Request();