/* -*- 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/. */
// make a copy because ProcessURL strips the fragmet
nsAutoCString url(aUrl);
TypeUtils::ProcessURL(url, &validScheme, nullptr, nullptr, aRv); if (aRv.Failed()) { returnfalse;
}
if (!validScheme) { // `url` has been modified, so don't use it here.
aRv.ThrowTypeError<MSG_INVALID_URL_SCHEME>("Request", aUrl); returnfalse;
}
staticbool IsValidPutRequestMethod(const RequestOrUTF8String& aRequest,
ErrorResult& aRv) { // If the provided request is a string URL, then it will default to // a valid http method automatically. if (!aRequest.IsRequest()) { returntrue;
} return IsValidPutRequestMethod(aRequest.GetAsRequest(), aRv);
}
// Helper class to wait for Add()/AddAll() fetch requests to complete and // then perform a PutAll() with the responses. This class holds a WorkerRef // to keep the Worker thread alive. This is mainly to ensure that Add/AddAll // act the same as other Cache operations that directly create a CacheOpChild // actor. class Cache::FetchHandler final : public PromiseNativeHandler { public:
FetchHandler(SafeRefPtr<CacheWorkerRef> aWorkerRef, Cache* aCache,
nsTArray<SafeRefPtr<Request>>&& aRequestList, Promise* aPromise)
: mWorkerRef(std::move(aWorkerRef)),
mCache(aCache),
mRequestList(std::move(aRequestList)),
mPromise(aPromise) {
MOZ_ASSERT_IF(!NS_IsMainThread(), mWorkerRef);
MOZ_DIAGNOSTIC_ASSERT(mCache);
MOZ_DIAGNOSTIC_ASSERT(mPromise);
}
// Stop holding the worker alive when we leave this method. const SafeRefPtr<CacheWorkerRef> workerRef = std::move(mWorkerRef);
// Promise::All() passed an array of fetch() Promises should give us // an Array of Response objects. The following code unwraps these // JS values back to an nsTArray<RefPtr<Response>>.
// Do not allow the convenience methods .add()/.addAll() to store failed // or invalid responses. A consequence of this is that these methods // cannot be used to store opaque or opaqueredirect responses since they // always expose a 0 status value.
ErrorResult errorResult; if (!IsValidPutResponseStatus(*response, PutStatusPolicy::RequireOK,
errorResult)) { // TODO: abort the fetch requests we have running (bug 1157434)
mPromise->MaybeReject(std::move(errorResult)); return;
}
// Now store the unwrapped Response list in the Cache.
ErrorResult result; // TODO: Here we use the JSContext as received by the ResolvedCallback, and // its state could be the wrong one. The spec doesn't say anything // about it, yet (bug 1384006)
RefPtr<Promise> put =
mCache->PutAll(aCx, mRequestList, responseList, result);
result.WouldReportJSException(); if (NS_WARN_IF(result.Failed())) { // TODO: abort the fetch requests we have running (bug 1157434)
mPromise->MaybeReject(std::move(result)); return;
}
// Chain the Cache::Put() promise to the original promise returned to // the content script.
mPromise->MaybeResolve(put);
}
nsTArray<SafeRefPtr<Request>> requestList(aRequestList.Length()); for (uint32_t i = 0; i < aRequestList.Length(); ++i) {
RequestOrUTF8String requestOrString;
if (aRequestList[i].IsRequest()) {
requestOrString.SetAsRequest() = aRequestList[i].GetAsRequest(); if (NS_WARN_IF(
!IsValidPutRequestMethod(requestOrString.GetAsRequest(), aRv))) { return nullptr;
}
} else {
requestOrString.SetAsUTF8String().ShareOrDependUpon(
aRequestList[i].GetAsUTF8String());
}
if (NS_WARN_IF(!IsValidPutRequestMethod(aRequest, aRv))) { return nullptr;
}
if (!IsValidPutResponseStatus(aResponse, PutStatusPolicy::Default, aRv)) { return nullptr;
}
if (NS_WARN_IF(aResponse.GetPrincipalInfo() &&
aResponse.GetPrincipalInfo()->type() ==
mozilla::ipc::PrincipalInfo::TExpandedPrincipalInfo)) { // WebExtensions Content Scripts can currently run fetch from their global // which will end up to have an expanded principal, but we require that the // contents of Cache storage for the content origin to be same-origin, and // never an expanded principal (See Bug 1753810).
aRv.ThrowSecurityError("Disallowed on WebExtension ContentScript Request"); return nullptr;
}
SafeRefPtr<InternalRequest> ir =
ToInternalRequest(aCx, aRequest, ReadBody, aRv); if (NS_WARN_IF(aRv.Failed())) { return nullptr;
}
Cache::~Cache() {
NS_ASSERT_OWNINGTHREAD(Cache); if (mActor) {
mActor->StartDestroyFromListener(); // DestroyInternal() is called synchronously by StartDestroyFromListener(). // So we should have already cleared the mActor.
MOZ_DIAGNOSTIC_ASSERT(!mActor);
}
}
// If there is no work to do, then resolve immediately if (aRequestList.IsEmpty()) {
RefPtr<Promise> promise = Promise::Create(mGlobal, aRv); if (NS_WARN_IF(!promise)) { return nullptr;
}
// Begin fetching each request in parallel. For now, if an error occurs just // abandon our previous fetch calls. In theory we could cancel them in the // future once fetch supports it.
for (uint32_t i = 0; i < aRequestList.Length(); ++i) {
RequestOrUTF8String requestOrString;
requestOrString.SetAsRequest() = aRequestList[i].unsafeGetRawPtr();
RootedDictionary<RequestInit> requestInit(aGlobal.Context());
RefPtr<Promise> fetch =
FetchRequest(mGlobal, requestOrString, requestInit, aCallerType, aRv); if (NS_WARN_IF(aRv.Failed())) { return nullptr;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.