Bug 1312410 - Fetch API should use MutableBlobStorage to store big Blobs on disk, r=qdot
This commit is contained in:
@@ -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.
|
||||||
|
|||||||
102
dom/base/MutableBlobStreamListener.cpp
Normal file
102
dom/base/MutableBlobStreamListener.cpp
Normal 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
|
||||||
48
dom/base/MutableBlobStreamListener.h
Normal file
48
dom/base/MutableBlobStreamListener.h
Normal 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
|
||||||
@@ -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',
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user