mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 13:51:41 +00:00
Backed out changeset e1be97ce43d1 (bug 1622451
) for failures on browser_download_canceled.js. CLOSED TREE
This commit is contained in:
parent
42b619b62e
commit
83cd8858fc
@ -6,8 +6,6 @@ include IPCStream;
|
||||
include ChannelInfo;
|
||||
include PBackgroundSharedTypes;
|
||||
|
||||
include protocol PIPCBlobInputStream;
|
||||
|
||||
using HeadersGuardEnum from "mozilla/dom/FetchIPCTypes.h";
|
||||
using ReferrerPolicy from "mozilla/dom/FetchIPCTypes.h";
|
||||
using RequestCache from "mozilla/dom/FetchIPCTypes.h";
|
||||
@ -15,7 +13,6 @@ using RequestCredentials from "mozilla/dom/FetchIPCTypes.h";
|
||||
using RequestMode from "mozilla/dom/FetchIPCTypes.h";
|
||||
using RequestRedirect from "mozilla/dom/FetchIPCTypes.h";
|
||||
using ResponseType from "mozilla/dom/FetchIPCTypes.h";
|
||||
using struct nsID from "nsID.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -25,31 +22,12 @@ struct HeadersEntry {
|
||||
nsCString value;
|
||||
};
|
||||
|
||||
struct ParentToParentStream {
|
||||
// Used as a key for IPCBlobInputStreamStorage
|
||||
nsID uuid;
|
||||
};
|
||||
|
||||
struct ParentToChildStream {
|
||||
PIPCBlobInputStream actor;
|
||||
};
|
||||
|
||||
struct ChildToParentStream {
|
||||
IPCStream stream;
|
||||
};
|
||||
|
||||
union BodyStreamVariant {
|
||||
ParentToParentStream;
|
||||
ParentToChildStream;
|
||||
ChildToParentStream;
|
||||
};
|
||||
|
||||
struct IPCInternalRequest {
|
||||
nsCString method;
|
||||
nsCString[] urlList;
|
||||
HeadersGuardEnum headersGuard;
|
||||
HeadersEntry[] headers;
|
||||
BodyStreamVariant? body;
|
||||
IPCStream? body;
|
||||
int64_t bodySize;
|
||||
nsCString preferredAlternativeDataType;
|
||||
uint32_t contentPolicyType;
|
||||
@ -71,11 +49,11 @@ struct IPCInternalResponse {
|
||||
nsCString statusText;
|
||||
HeadersGuardEnum headersGuard;
|
||||
HeadersEntry[] headers;
|
||||
BodyStreamVariant? body;
|
||||
IPCStream? body;
|
||||
int64_t bodySize;
|
||||
nsresult errorCode;
|
||||
nsCString alternativeDataType;
|
||||
BodyStreamVariant? alternativeBody;
|
||||
IPCStream? alternativeBody;
|
||||
IPCChannelInfo channelInfo;
|
||||
PrincipalInfo? principalInfo;
|
||||
};
|
||||
|
@ -6,17 +6,18 @@
|
||||
|
||||
#include "InternalRequest.h"
|
||||
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "nsIContentPolicy.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "nsStreamUtils.h"
|
||||
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/dom/FetchTypes.h"
|
||||
#include "mozilla/dom/IPCBlobInputStreamChild.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
|
||||
#include "mozilla/dom/WorkerCommon.h"
|
||||
#include "mozilla/dom/WorkerPrivate.h"
|
||||
#include "mozilla/ipc/IPCStreamUtils.h"
|
||||
#include "mozilla/ipc/PBackgroundChild.h"
|
||||
#include "nsIContentPolicy.h"
|
||||
#include "nsStreamUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -145,6 +146,7 @@ InternalRequest::InternalRequest(const IPCInternalRequest& aIPCRequest)
|
||||
mURLList(aIPCRequest.urlList()),
|
||||
mHeaders(new InternalHeaders(aIPCRequest.headers(),
|
||||
aIPCRequest.headersGuard())),
|
||||
mBodyStream(mozilla::ipc::DeserializeIPCStream(aIPCRequest.body())),
|
||||
mBodyLength(aIPCRequest.bodySize()),
|
||||
mPreferredAlternativeDataType(aIPCRequest.preferredAlternativeDataType()),
|
||||
mContentPolicyType(
|
||||
@ -161,21 +163,49 @@ InternalRequest::InternalRequest(const IPCInternalRequest& aIPCRequest)
|
||||
mPrincipalInfo = MakeUnique<mozilla::ipc::PrincipalInfo>(
|
||||
aIPCRequest.principalInfo().ref());
|
||||
}
|
||||
|
||||
const Maybe<BodyStreamVariant>& body = aIPCRequest.body();
|
||||
|
||||
// This constructor is (currently) only used for parent -> child communication
|
||||
// (constructed on the child side).
|
||||
if (body) {
|
||||
MOZ_ASSERT(body->type() == BodyStreamVariant::TParentToChildStream);
|
||||
mBodyStream = static_cast<IPCBlobInputStreamChild*>(
|
||||
body->get_ParentToChildStream().actorChild())
|
||||
->CreateStream();
|
||||
}
|
||||
}
|
||||
|
||||
InternalRequest::~InternalRequest() = default;
|
||||
|
||||
template void InternalRequest::ToIPC<mozilla::ipc::PBackgroundChild>(
|
||||
IPCInternalRequest* aIPCRequest, mozilla::ipc::PBackgroundChild* aManager,
|
||||
UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoStream);
|
||||
|
||||
template <typename M>
|
||||
void InternalRequest::ToIPC(
|
||||
IPCInternalRequest* aIPCRequest, M* aManager,
|
||||
UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoStream) {
|
||||
MOZ_ASSERT(aIPCRequest);
|
||||
MOZ_ASSERT(aManager);
|
||||
MOZ_ASSERT(!mURLList.IsEmpty());
|
||||
|
||||
aIPCRequest->method() = mMethod;
|
||||
aIPCRequest->urlList() = mURLList;
|
||||
mHeaders->ToIPC(aIPCRequest->headers(), aIPCRequest->headersGuard());
|
||||
|
||||
if (mBodyStream) {
|
||||
aAutoStream.reset(new mozilla::ipc::AutoIPCStream(aIPCRequest->body()));
|
||||
DebugOnly<bool> ok = aAutoStream->Serialize(mBodyStream, aManager);
|
||||
MOZ_ASSERT(ok);
|
||||
}
|
||||
|
||||
aIPCRequest->bodySize() = mBodyLength;
|
||||
aIPCRequest->preferredAlternativeDataType() = mPreferredAlternativeDataType;
|
||||
aIPCRequest->contentPolicyType() = static_cast<uint32_t>(mContentPolicyType);
|
||||
aIPCRequest->referrer() = mReferrer;
|
||||
aIPCRequest->referrerPolicy() = mReferrerPolicy;
|
||||
aIPCRequest->requestMode() = mMode;
|
||||
aIPCRequest->requestCredentials() = mCredentialsMode;
|
||||
aIPCRequest->cacheMode() = mCacheMode;
|
||||
aIPCRequest->requestRedirect() = mRedirectMode;
|
||||
aIPCRequest->integrity() = mIntegrity;
|
||||
aIPCRequest->fragment() = mFragment;
|
||||
|
||||
if (mPrincipalInfo) {
|
||||
aIPCRequest->principalInfo().emplace(*mPrincipalInfo);
|
||||
}
|
||||
}
|
||||
|
||||
void InternalRequest::SetContentPolicyType(
|
||||
nsContentPolicyType aContentPolicyType) {
|
||||
mContentPolicyType = aContentPolicyType;
|
||||
|
@ -25,6 +25,7 @@ namespace mozilla {
|
||||
|
||||
namespace ipc {
|
||||
class PrincipalInfo;
|
||||
class AutoIPCStream;
|
||||
} // namespace ipc
|
||||
|
||||
namespace dom {
|
||||
@ -89,6 +90,10 @@ class InternalRequest final {
|
||||
|
||||
explicit InternalRequest(const IPCInternalRequest& aIPCRequest);
|
||||
|
||||
template <typename M>
|
||||
void ToIPC(IPCInternalRequest* aIPCRequest, M* aManager,
|
||||
UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoStream);
|
||||
|
||||
already_AddRefed<InternalRequest> Clone();
|
||||
|
||||
void GetMethod(nsCString& aMethod) const { aMethod.Assign(mMethod); }
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/dom/FetchTypes.h"
|
||||
#include "mozilla/dom/IPCBlobInputStreamStorage.h"
|
||||
#include "mozilla/dom/InternalHeaders.h"
|
||||
#include "mozilla/dom/cache/CacheTypes.h"
|
||||
#include "mozilla/ipc/PBackgroundSharedTypes.h"
|
||||
@ -27,22 +26,6 @@ namespace {
|
||||
// XXX This will be tweaked to something more meaningful in Bug 1383656.
|
||||
const uint32_t kMaxRandomNumber = 102400;
|
||||
|
||||
nsCOMPtr<nsIInputStream> TakeStreamFromStorage(
|
||||
const BodyStreamVariant& aVariant, int64_t aBodySize) {
|
||||
MOZ_ASSERT(aVariant.type() == BodyStreamVariant::TParentToParentStream);
|
||||
const auto& uuid = aVariant.get_ParentToParentStream().uuid();
|
||||
|
||||
IPCBlobInputStreamStorage* storage = IPCBlobInputStreamStorage::Get();
|
||||
|
||||
nsCOMPtr<nsIInputStream> body;
|
||||
storage->GetStream(uuid, 0, aBodySize, getter_AddRefs(body));
|
||||
MOZ_DIAGNOSTIC_ASSERT(body);
|
||||
|
||||
storage->ForgetStream(uuid);
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
InternalResponse::InternalResponse(uint16_t aStatus,
|
||||
@ -70,20 +53,15 @@ InternalResponse::InternalResponse(uint16_t aStatus,
|
||||
response->mHeaders =
|
||||
new InternalHeaders(aIPCResponse.headers(), aIPCResponse.headersGuard());
|
||||
|
||||
if (aIPCResponse.body()) {
|
||||
auto bodySize = aIPCResponse.bodySize();
|
||||
nsCOMPtr<nsIInputStream> body =
|
||||
TakeStreamFromStorage(*aIPCResponse.body(), bodySize);
|
||||
response->SetBody(body, bodySize);
|
||||
}
|
||||
nsCOMPtr<nsIInputStream> body =
|
||||
mozilla::ipc::DeserializeIPCStream(aIPCResponse.body());
|
||||
response->SetBody(body, aIPCResponse.bodySize());
|
||||
|
||||
response->SetAlternativeDataType(aIPCResponse.alternativeDataType());
|
||||
|
||||
if (aIPCResponse.alternativeBody()) {
|
||||
nsCOMPtr<nsIInputStream> alternativeBody = TakeStreamFromStorage(
|
||||
*aIPCResponse.alternativeBody(), UNKNOWN_BODY_SIZE);
|
||||
response->SetAlternativeBody(alternativeBody);
|
||||
}
|
||||
nsCOMPtr<nsIInputStream> alternativeBody =
|
||||
mozilla::ipc::DeserializeIPCStream(aIPCResponse.alternativeBody());
|
||||
response->SetAlternativeBody(alternativeBody);
|
||||
|
||||
response->InitChannelInfo(aIPCResponse.channelInfo());
|
||||
|
||||
@ -118,50 +96,54 @@ InternalResponse::InternalResponse(uint16_t aStatus,
|
||||
|
||||
InternalResponse::~InternalResponse() = default;
|
||||
|
||||
void InternalResponse::ToIPC(
|
||||
template void InternalResponse::ToIPC<mozilla::ipc::PBackgroundChild>(
|
||||
IPCInternalResponse* aIPCResponse, mozilla::ipc::PBackgroundChild* aManager,
|
||||
UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoBodyStream,
|
||||
UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoAlternativeBodyStream);
|
||||
|
||||
template <typename M>
|
||||
void InternalResponse::ToIPC(
|
||||
IPCInternalResponse* aIPCResponse, M* aManager,
|
||||
UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoBodyStream,
|
||||
UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoAlternativeBodyStream) {
|
||||
nsTArray<HeadersEntry> headers;
|
||||
HeadersGuardEnum headersGuard;
|
||||
UnfilteredHeaders()->ToIPC(headers, headersGuard);
|
||||
MOZ_ASSERT(aIPCResponse);
|
||||
|
||||
Maybe<mozilla::ipc::PrincipalInfo> principalInfo =
|
||||
mPrincipalInfo ? Some(*mPrincipalInfo) : Nothing();
|
||||
|
||||
// Note: all the arguments are copied rather than moved, which would be more
|
||||
// efficient, because there's no move-friendly constructor generated.
|
||||
*aIPCResponse =
|
||||
IPCInternalResponse(mType, GetUnfilteredURLList(), GetUnfilteredStatus(),
|
||||
GetUnfilteredStatusText(), headersGuard, headers,
|
||||
Nothing(), static_cast<uint64_t>(UNKNOWN_BODY_SIZE),
|
||||
mErrorCode, GetAlternativeDataType(), Nothing(),
|
||||
mChannelInfo.AsIPCChannelInfo(), principalInfo);
|
||||
aIPCResponse->type() = mType;
|
||||
GetUnfilteredURLList(aIPCResponse->urlList());
|
||||
aIPCResponse->status() = GetUnfilteredStatus();
|
||||
aIPCResponse->statusText() = GetUnfilteredStatusText();
|
||||
UnfilteredHeaders()->ToIPC(aIPCResponse->headers(),
|
||||
aIPCResponse->headersGuard());
|
||||
|
||||
nsCOMPtr<nsIInputStream> body;
|
||||
int64_t bodySize;
|
||||
GetUnfilteredBody(getter_AddRefs(body), &bodySize);
|
||||
|
||||
if (body) {
|
||||
aIPCResponse->body().emplace(ChildToParentStream());
|
||||
aIPCResponse->bodySize() = bodySize;
|
||||
|
||||
aAutoBodyStream.reset(new mozilla::ipc::AutoIPCStream(
|
||||
aIPCResponse->body()->get_ChildToParentStream().stream()));
|
||||
aAutoBodyStream.reset(
|
||||
new mozilla::ipc::AutoIPCStream(aIPCResponse->body()));
|
||||
DebugOnly<bool> ok = aAutoBodyStream->Serialize(body, aManager);
|
||||
MOZ_ASSERT(ok);
|
||||
}
|
||||
|
||||
aIPCResponse->bodySize() = bodySize;
|
||||
aIPCResponse->errorCode() = mErrorCode;
|
||||
aIPCResponse->alternativeDataType() = GetAlternativeDataType();
|
||||
|
||||
nsCOMPtr<nsIInputStream> alternativeBody = TakeAlternativeBody();
|
||||
if (alternativeBody) {
|
||||
aIPCResponse->alternativeBody().emplace(ChildToParentStream());
|
||||
|
||||
aAutoAlternativeBodyStream.reset(new mozilla::ipc::AutoIPCStream(
|
||||
aIPCResponse->alternativeBody()->get_ChildToParentStream().stream()));
|
||||
aAutoAlternativeBodyStream.reset(
|
||||
new mozilla::ipc::AutoIPCStream(aIPCResponse->alternativeBody()));
|
||||
DebugOnly<bool> ok =
|
||||
aAutoAlternativeBodyStream->Serialize(alternativeBody, aManager);
|
||||
MOZ_ASSERT(ok);
|
||||
}
|
||||
|
||||
aIPCResponse->channelInfo() = mChannelInfo.AsIPCChannelInfo();
|
||||
|
||||
if (mPrincipalInfo) {
|
||||
aIPCResponse->principalInfo().emplace(*mPrincipalInfo);
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<InternalResponse> InternalResponse::Clone(
|
||||
|
@ -20,9 +20,8 @@
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
class AutoIPCStream;
|
||||
class PBackgroundChild;
|
||||
class PrincipalInfo;
|
||||
class AutoIPCStream;
|
||||
} // namespace ipc
|
||||
|
||||
namespace dom {
|
||||
@ -43,10 +42,9 @@ class InternalResponse final {
|
||||
static RefPtr<InternalResponse> FromIPC(
|
||||
const IPCInternalResponse& aIPCResponse);
|
||||
|
||||
// Note: the AutoIPCStreams must outlive the IPCInternalResponse.
|
||||
template <typename M>
|
||||
void ToIPC(
|
||||
IPCInternalResponse* aIPCResponse,
|
||||
mozilla::ipc::PBackgroundChild* aManager,
|
||||
IPCInternalResponse* aIPCResponse, M* aManager,
|
||||
UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoBodyStream,
|
||||
UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoAlternativeBodyStream);
|
||||
|
||||
@ -113,12 +111,6 @@ class InternalResponse final {
|
||||
return GetURLList(aURLList);
|
||||
}
|
||||
|
||||
nsTArray<nsCString> GetUnfilteredURLList() const {
|
||||
nsTArray<nsCString> list;
|
||||
GetUnfilteredURLList(list);
|
||||
return list;
|
||||
}
|
||||
|
||||
void SetURLList(const nsTArray<nsCString>& aURLList) {
|
||||
mURLList.Assign(aURLList);
|
||||
|
||||
|
@ -31,6 +31,10 @@ NS_INTERFACE_MAP_END
|
||||
NS_IMPL_ADDREF(IPCBlobInputStreamStorage)
|
||||
NS_IMPL_RELEASE(IPCBlobInputStreamStorage)
|
||||
|
||||
IPCBlobInputStreamStorage::IPCBlobInputStreamStorage() = default;
|
||||
|
||||
IPCBlobInputStreamStorage::~IPCBlobInputStreamStorage() = default;
|
||||
|
||||
/* static */
|
||||
IPCBlobInputStreamStorage* IPCBlobInputStreamStorage::Get() { return gStorage; }
|
||||
|
||||
|
@ -46,8 +46,8 @@ class IPCBlobInputStreamStorage final : public nsIObserver {
|
||||
const nsID& aID);
|
||||
|
||||
private:
|
||||
IPCBlobInputStreamStorage() = default;
|
||||
~IPCBlobInputStreamStorage() = default;
|
||||
IPCBlobInputStreamStorage();
|
||||
~IPCBlobInputStreamStorage();
|
||||
|
||||
struct StreamData {
|
||||
nsCOMPtr<nsIInputStream> mInputStream;
|
||||
|
@ -135,14 +135,6 @@ nsresult SerializeInputStream(nsIInputStream* aInputStream, uint64_t aSize,
|
||||
aActorParent, aManager);
|
||||
}
|
||||
|
||||
nsresult SerializeInputStream(nsIInputStream* aInputStream, uint64_t aSize,
|
||||
PIPCBlobInputStreamParent*& aActorParent,
|
||||
PBackgroundParent* aManager) {
|
||||
return SerializeInputStreamParent(aInputStream, aSize,
|
||||
BackgroundParent::GetChildID(aManager),
|
||||
aActorParent, aManager);
|
||||
}
|
||||
|
||||
nsresult SerializeInputStream(nsIInputStream* aInputStream, uint64_t aSize,
|
||||
IPCBlobStream& aIPCBlob,
|
||||
ContentParent* aManager) {
|
||||
|
@ -255,10 +255,6 @@ nsresult SerializeInputStream(nsIInputStream* aInputStream, uint64_t aSize,
|
||||
PIPCBlobInputStreamParent*& aActorParent,
|
||||
ContentParent* aManager);
|
||||
|
||||
nsresult SerializeInputStream(nsIInputStream* aInputStream, uint64_t aSize,
|
||||
PIPCBlobInputStreamParent*& aActorParent,
|
||||
mozilla::ipc::PBackgroundParent* aManager);
|
||||
|
||||
// WARNING: If you pass any actor which does not have P{Content,Background} as
|
||||
// its toplevel protocol, this method will MOZ_CRASH.
|
||||
nsresult SerializeUntyped(BlobImpl* aBlobImpl, mozilla::ipc::IProtocol* aActor,
|
||||
|
@ -16,6 +16,8 @@
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIConsoleReportCollector.h"
|
||||
#include "nsIContentPolicy.h"
|
||||
#include "nsIHttpChannelInternal.h"
|
||||
#include "nsIHttpHeaderVisitor.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsILoadInfo.h"
|
||||
#include "nsINetworkInterceptController.h"
|
||||
@ -23,6 +25,7 @@
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIUploadChannel2.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsProxyRelease.h"
|
||||
#include "nsTArray.h"
|
||||
@ -37,6 +40,7 @@
|
||||
#include "mozilla/Unused.h"
|
||||
#include "mozilla/ipc/BackgroundChild.h"
|
||||
#include "mozilla/dom/InternalHeaders.h"
|
||||
#include "mozilla/dom/InternalRequest.h"
|
||||
#include "mozilla/dom/InternalResponse.h"
|
||||
#include "mozilla/dom/PRemoteWorkerControllerChild.h"
|
||||
#include "mozilla/dom/ServiceWorkerRegistrationInfo.h"
|
||||
@ -181,6 +185,168 @@ class SynthesizeResponseWatcher final : public nsIInterceptedBodyCallback {
|
||||
|
||||
NS_IMPL_ISUPPORTS(SynthesizeResponseWatcher, nsIInterceptedBodyCallback)
|
||||
|
||||
class HeaderFiller final : public nsIHttpHeaderVisitor {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
explicit HeaderFiller(HeadersGuardEnum aGuard)
|
||||
: mInternalHeaders(new InternalHeaders(aGuard)) {
|
||||
MOZ_ASSERT(mInternalHeaders);
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
VisitHeader(const nsACString& aHeader, const nsACString& aValue) override {
|
||||
ErrorResult result;
|
||||
mInternalHeaders->Append(aHeader, aValue, result);
|
||||
|
||||
if (NS_WARN_IF(result.Failed())) {
|
||||
return result.StealNSResult();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
RefPtr<InternalHeaders> Extract() {
|
||||
return RefPtr<InternalHeaders>(std::move(mInternalHeaders));
|
||||
}
|
||||
|
||||
private:
|
||||
~HeaderFiller() = default;
|
||||
|
||||
RefPtr<InternalHeaders> mInternalHeaders;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(HeaderFiller, nsIHttpHeaderVisitor)
|
||||
|
||||
nsresult GetIPCInternalRequest(nsIInterceptedChannel* aChannel,
|
||||
IPCInternalRequest* aOutRequest,
|
||||
UniquePtr<AutoIPCStream>& aAutoStream) {
|
||||
AssertIsOnMainThread();
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = aChannel->GetSecureUpgradedChannelURI(getter_AddRefs(uri));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIURI> uriNoFragment;
|
||||
rv = NS_GetURIWithoutRef(uri, getter_AddRefs(uriNoFragment));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIChannel> underlyingChannel;
|
||||
rv = aChannel->GetChannel(getter_AddRefs(underlyingChannel));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(underlyingChannel);
|
||||
MOZ_ASSERT(httpChannel, "How come we don't have an HTTP channel?");
|
||||
|
||||
nsCOMPtr<nsIHttpChannelInternal> internalChannel =
|
||||
do_QueryInterface(httpChannel);
|
||||
NS_ENSURE_TRUE(internalChannel, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
nsCOMPtr<nsICacheInfoChannel> cacheInfoChannel =
|
||||
do_QueryInterface(underlyingChannel);
|
||||
|
||||
nsAutoCString spec;
|
||||
rv = uriNoFragment->GetSpec(spec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoCString fragment;
|
||||
rv = uri->GetRef(fragment);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoCString method;
|
||||
rv = httpChannel->GetRequestMethod(method);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// This is safe due to static_asserts in ServiceWorkerManager.cpp
|
||||
uint32_t cacheModeInt;
|
||||
rv = internalChannel->GetFetchCacheMode(&cacheModeInt);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
RequestCache cacheMode = static_cast<RequestCache>(cacheModeInt);
|
||||
|
||||
RequestMode requestMode =
|
||||
InternalRequest::MapChannelToRequestMode(underlyingChannel);
|
||||
|
||||
// This is safe due to static_asserts in ServiceWorkerManager.cpp
|
||||
uint32_t redirectMode;
|
||||
rv = internalChannel->GetRedirectMode(&redirectMode);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
RequestRedirect requestRedirect = static_cast<RequestRedirect>(redirectMode);
|
||||
|
||||
RequestCredentials requestCredentials =
|
||||
InternalRequest::MapChannelToRequestCredentials(underlyingChannel);
|
||||
|
||||
nsAutoString referrer;
|
||||
ReferrerPolicy referrerPolicy = ReferrerPolicy::_empty;
|
||||
|
||||
nsCOMPtr<nsIReferrerInfo> referrerInfo = httpChannel->GetReferrerInfo();
|
||||
if (referrerInfo) {
|
||||
referrerPolicy = referrerInfo->ReferrerPolicy();
|
||||
Unused << referrerInfo->GetComputedReferrerSpec(referrer);
|
||||
}
|
||||
|
||||
uint32_t loadFlags;
|
||||
rv = underlyingChannel->GetLoadFlags(&loadFlags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsILoadInfo> loadInfo;
|
||||
rv = underlyingChannel->GetLoadInfo(getter_AddRefs(loadInfo));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_STATE(loadInfo);
|
||||
|
||||
nsContentPolicyType contentPolicyType = loadInfo->InternalContentPolicyType();
|
||||
|
||||
nsAutoString integrity;
|
||||
rv = internalChannel->GetIntegrityMetadata(integrity);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
RefPtr<HeaderFiller> headerFiller =
|
||||
MakeRefPtr<HeaderFiller>(HeadersGuardEnum::Request);
|
||||
rv = httpChannel->VisitNonDefaultRequestHeaders(headerFiller);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
RefPtr<InternalHeaders> internalHeaders = headerFiller->Extract();
|
||||
|
||||
ErrorResult result;
|
||||
internalHeaders->SetGuard(HeadersGuardEnum::Immutable, result);
|
||||
if (NS_WARN_IF(result.Failed())) {
|
||||
return result.StealNSResult();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIUploadChannel2> uploadChannel = do_QueryInterface(httpChannel);
|
||||
nsCOMPtr<nsIInputStream> uploadStream;
|
||||
int64_t uploadStreamContentLength = -1;
|
||||
if (uploadChannel) {
|
||||
rv = uploadChannel->CloneUploadStream(&uploadStreamContentLength,
|
||||
getter_AddRefs(uploadStream));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
RefPtr<InternalRequest> internalRequest = new InternalRequest(
|
||||
spec, fragment, method, internalHeaders.forget(), cacheMode, requestMode,
|
||||
requestRedirect, requestCredentials, referrer, referrerPolicy,
|
||||
contentPolicyType, integrity);
|
||||
internalRequest->SetBody(uploadStream, uploadStreamContentLength);
|
||||
|
||||
nsAutoCString alternativeDataType;
|
||||
if (cacheInfoChannel &&
|
||||
!cacheInfoChannel->PreferredAlternativeDataTypes().IsEmpty()) {
|
||||
// TODO: the internal request probably needs all the preferred types.
|
||||
alternativeDataType.Assign(
|
||||
cacheInfoChannel->PreferredAlternativeDataTypes()[0].type());
|
||||
internalRequest->SetPreferredAlternativeDataType(alternativeDataType);
|
||||
}
|
||||
|
||||
PBackgroundChild* bgChild = BackgroundChild::GetForCurrentThread();
|
||||
|
||||
if (NS_WARN_IF(!bgChild)) {
|
||||
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||
}
|
||||
|
||||
internalRequest->ToIPC(aOutRequest, bgChild, aAutoStream);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/* static */ RefPtr<GenericPromise> FetchEventOpChild::SendFetchEvent(
|
||||
@ -198,7 +364,28 @@ NS_IMPL_ISUPPORTS(SynthesizeResponseWatcher, nsIInterceptedBodyCallback)
|
||||
std::move(aArgs), std::move(aInterceptedChannel),
|
||||
std::move(aRegistration), std::move(aKeepAliveToken));
|
||||
|
||||
// autoStream will contain a pointer into the IPCInternalRequest passed into
|
||||
// GetIPCInternalRequest, so autoStream shouldn't outlive that
|
||||
// IPCInternalRequest or the containing FetchEventOpChild.
|
||||
auto autoStream = MakeUnique<AutoIPCStream>();
|
||||
|
||||
// const_cast-ing the IPCInternalRequest is okay because this is conceptually
|
||||
// part of initializing actor->mArgs, and `autoStream` needs its
|
||||
// IPCStream (physically part of actor->mArgs.internalRequest()) to be in its
|
||||
// final location in memory, so actor->mArgs must be created before this call.
|
||||
nsresult rv = GetIPCInternalRequest(
|
||||
actor->mInterceptedChannel,
|
||||
const_cast<IPCInternalRequest*>(&actor->mArgs.internalRequest()),
|
||||
autoStream);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
// `actor` must be manually delete-d before the actor tree can manage its
|
||||
// lifetime starting with SendPFetchEventOpConstructor.
|
||||
delete actor;
|
||||
return GenericPromise::CreateAndReject(rv, __func__);
|
||||
}
|
||||
|
||||
Unused << aManager->SendPFetchEventOpConstructor(actor, actor->mArgs);
|
||||
autoStream->TakeOptionalValue();
|
||||
|
||||
return actor->mPromiseHolder.Ensure(__func__);
|
||||
}
|
||||
|
@ -120,14 +120,8 @@ void FetchEventOpProxyChild::Initialize(
|
||||
}
|
||||
|
||||
Unused << self->SendRespondWith(ipcArgs);
|
||||
|
||||
if (ipcArgs.internalResponse().body()) {
|
||||
autoBodyStream->TakeValue();
|
||||
}
|
||||
|
||||
if (ipcArgs.internalResponse().alternativeBody()) {
|
||||
autoAlternativeBodyStream->TakeValue();
|
||||
}
|
||||
autoBodyStream->TakeOptionalValue();
|
||||
autoAlternativeBodyStream->TakeOptionalValue();
|
||||
} else if (result.is<ResetInterceptionArgs>()) {
|
||||
Unused << self->SendRespondWith(
|
||||
result.extract<ResetInterceptionArgs>());
|
||||
@ -145,7 +139,7 @@ RefPtr<InternalRequest> FetchEventOpProxyChild::ExtractInternalRequest() {
|
||||
MOZ_ASSERT(IsCurrentThreadRunningWorker());
|
||||
MOZ_ASSERT(mInternalRequest);
|
||||
|
||||
return std::move(mInternalRequest);
|
||||
return RefPtr<InternalRequest>(std::move(mInternalRequest));
|
||||
}
|
||||
|
||||
void FetchEventOpProxyChild::ActorDestroy(ActorDestroyReason) {
|
||||
|
@ -9,18 +9,13 @@
|
||||
#include <utility>
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIInputStream.h"
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/Result.h"
|
||||
#include "mozilla/ResultExtensions.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "mozilla/dom/FetchEventOpParent.h"
|
||||
#include "mozilla/dom/IPCBlobInputStreamStorage.h"
|
||||
#include "mozilla/dom/IPCBlobUtils.h"
|
||||
#include "mozilla/ipc/BackgroundParent.h"
|
||||
#include "mozilla/ipc/IPCStreamUtils.h"
|
||||
|
||||
@ -32,25 +27,20 @@ namespace dom {
|
||||
|
||||
namespace {
|
||||
|
||||
nsresult MaybeDeserializeAndWrapForMainThread(
|
||||
const Maybe<BodyStreamVariant>& aSource, int64_t aBodyStreamSize,
|
||||
Maybe<BodyStreamVariant>& aSink, PBackgroundParent* aManager) {
|
||||
if (aSource.isNothing()) {
|
||||
return NS_OK;
|
||||
void MaybeDeserializeAndReserialize(const Maybe<IPCStream>& aDeserialize,
|
||||
Maybe<IPCStream>& aReserialize,
|
||||
UniquePtr<AutoIPCStream>& aAutoStream,
|
||||
PBackgroundParent* aManager) {
|
||||
nsCOMPtr<nsIInputStream> maybeDeserialized =
|
||||
DeserializeIPCStream(aDeserialize);
|
||||
|
||||
if (!maybeDeserialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInputStream> deserialized =
|
||||
DeserializeIPCStream(aSource->get_ChildToParentStream().stream());
|
||||
|
||||
aSink = Some(ParentToParentStream());
|
||||
auto& uuid = aSink->get_ParentToParentStream().uuid();
|
||||
|
||||
MOZ_TRY(nsContentUtils::GenerateUUIDInPlace(uuid));
|
||||
|
||||
IPCBlobInputStreamStorage::Get()->AddStream(deserialized, uuid,
|
||||
aBodyStreamSize, 0);
|
||||
|
||||
return NS_OK;
|
||||
aAutoStream.reset(new AutoIPCStream(aReserialize));
|
||||
DebugOnly<bool> ok = aAutoStream->Serialize(maybeDeserialized, aManager);
|
||||
MOZ_ASSERT(ok);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
@ -74,30 +64,15 @@ nsresult MaybeDeserializeAndWrapForMainThread(
|
||||
ServiceWorkerFetchEventOpArgs copyArgs = aArgs;
|
||||
IPCInternalRequest& copyRequest = copyArgs.internalRequest();
|
||||
|
||||
if (copyRequest.body().ref().type() ==
|
||||
BodyStreamVariant::TParentToParentStream) {
|
||||
nsCOMPtr<nsIInputStream> stream;
|
||||
auto streamLength = copyRequest.bodySize();
|
||||
const auto& uuid =
|
||||
copyRequest.body().ref().get_ParentToParentStream().uuid();
|
||||
IPCBlobInputStreamStorage* storage = IPCBlobInputStreamStorage::Get();
|
||||
PBackgroundParent* bgParent = aManager->Manager();
|
||||
MOZ_ASSERT(bgParent);
|
||||
|
||||
storage->GetStream(uuid, 0, streamLength, getter_AddRefs(stream));
|
||||
storage->ForgetStream(uuid);
|
||||
|
||||
MOZ_DIAGNOSTIC_ASSERT(stream);
|
||||
|
||||
PBackgroundParent* bgParent = aManager->Manager();
|
||||
MOZ_ASSERT(bgParent);
|
||||
|
||||
copyRequest.body() = Some(ParentToChildStream());
|
||||
MOZ_ALWAYS_SUCCEEDS(IPCBlobUtils::SerializeInputStream(
|
||||
stream, streamLength,
|
||||
copyRequest.body().ref().get_ParentToChildStream().actorParent(),
|
||||
bgParent));
|
||||
}
|
||||
UniquePtr<AutoIPCStream> autoBodyStream = MakeUnique<AutoIPCStream>();
|
||||
MaybeDeserializeAndReserialize(aArgs.internalRequest().body(),
|
||||
copyRequest.body(), autoBodyStream, bgParent);
|
||||
|
||||
Unused << aManager->SendPFetchEventOpProxyConstructor(actor, copyArgs);
|
||||
autoBodyStream->TakeOptionalValue();
|
||||
}
|
||||
|
||||
FetchEventOpProxyParent::~FetchEventOpProxyParent() {
|
||||
@ -150,14 +125,20 @@ mozilla::ipc::IPCResult FetchEventOpProxyParent::RecvRespondWith(
|
||||
PBackgroundParent* bgParent = manager->Manager();
|
||||
MOZ_ASSERT(bgParent);
|
||||
|
||||
MOZ_ALWAYS_SUCCEEDS(MaybeDeserializeAndWrapForMainThread(
|
||||
originalResponse.body(), copyResponse.bodySize(), copyResponse.body(),
|
||||
bgParent));
|
||||
MOZ_ALWAYS_SUCCEEDS(MaybeDeserializeAndWrapForMainThread(
|
||||
originalResponse.alternativeBody(), InternalResponse::UNKNOWN_BODY_SIZE,
|
||||
copyResponse.alternativeBody(), bgParent));
|
||||
UniquePtr<AutoIPCStream> autoBodyStream = MakeUnique<AutoIPCStream>();
|
||||
UniquePtr<AutoIPCStream> autoAlternativeBodyStream =
|
||||
MakeUnique<AutoIPCStream>();
|
||||
|
||||
MaybeDeserializeAndReserialize(originalResponse.body(), copyResponse.body(),
|
||||
autoBodyStream, bgParent);
|
||||
MaybeDeserializeAndReserialize(originalResponse.alternativeBody(),
|
||||
copyResponse.alternativeBody(),
|
||||
autoAlternativeBodyStream, bgParent);
|
||||
|
||||
Unused << mReal->SendRespondWith(copyArgs);
|
||||
|
||||
autoBodyStream->TakeOptionalValue();
|
||||
autoAlternativeBodyStream->TakeOptionalValue();
|
||||
} else {
|
||||
Unused << mReal->SendRespondWith(aResult);
|
||||
}
|
||||
|
@ -14,13 +14,10 @@
|
||||
#include "nsDebug.h"
|
||||
#include "nsError.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIHttpChannelInternal.h"
|
||||
#include "nsIHttpHeaderVisitor.h"
|
||||
#include "nsINetworkInterceptController.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIUploadChannel2.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
#include "ServiceWorkerManager.h"
|
||||
@ -28,8 +25,6 @@
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/Result.h"
|
||||
#include "mozilla/ResultExtensions.h"
|
||||
#include "mozilla/ScopeExit.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/StaticPrefs_dom.h"
|
||||
@ -37,9 +32,7 @@
|
||||
#include "mozilla/dom/ClientIPCTypes.h"
|
||||
#include "mozilla/dom/DOMTypes.h"
|
||||
#include "mozilla/dom/FetchEventOpChild.h"
|
||||
#include "mozilla/dom/IPCBlobInputStreamStorage.h"
|
||||
#include "mozilla/dom/InternalHeaders.h"
|
||||
#include "mozilla/dom/InternalRequest.h"
|
||||
#include "mozilla/dom/ReferrerInfo.h"
|
||||
#include "mozilla/dom/RemoteWorkerControllerChild.h"
|
||||
#include "mozilla/dom/ServiceWorkerBinding.h"
|
||||
@ -581,189 +574,12 @@ ServiceWorkerPrivateImpl::PendingFetchEvent::~PendingFetchEvent() {
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class HeaderFiller final : public nsIHttpHeaderVisitor {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
explicit HeaderFiller(HeadersGuardEnum aGuard)
|
||||
: mInternalHeaders(new InternalHeaders(aGuard)) {
|
||||
MOZ_ASSERT(mInternalHeaders);
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
VisitHeader(const nsACString& aHeader, const nsACString& aValue) override {
|
||||
ErrorResult result;
|
||||
mInternalHeaders->Append(aHeader, aValue, result);
|
||||
|
||||
if (NS_WARN_IF(result.Failed())) {
|
||||
return result.StealNSResult();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
RefPtr<InternalHeaders> Extract() {
|
||||
return RefPtr<InternalHeaders>(std::move(mInternalHeaders));
|
||||
}
|
||||
|
||||
private:
|
||||
~HeaderFiller() = default;
|
||||
|
||||
RefPtr<InternalHeaders> mInternalHeaders;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(HeaderFiller, nsIHttpHeaderVisitor)
|
||||
|
||||
Result<IPCInternalRequest, nsresult> GetIPCInternalRequest(
|
||||
nsIInterceptedChannel* aChannel) {
|
||||
AssertIsOnMainThread();
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
MOZ_TRY(aChannel->GetSecureUpgradedChannelURI(getter_AddRefs(uri)));
|
||||
|
||||
nsCOMPtr<nsIURI> uriNoFragment;
|
||||
MOZ_TRY(NS_GetURIWithoutRef(uri, getter_AddRefs(uriNoFragment)));
|
||||
|
||||
nsCOMPtr<nsIChannel> underlyingChannel;
|
||||
MOZ_TRY(aChannel->GetChannel(getter_AddRefs(underlyingChannel)));
|
||||
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(underlyingChannel);
|
||||
MOZ_ASSERT(httpChannel, "How come we don't have an HTTP channel?");
|
||||
|
||||
nsCOMPtr<nsIHttpChannelInternal> internalChannel =
|
||||
do_QueryInterface(httpChannel);
|
||||
NS_ENSURE_TRUE(internalChannel, Err(NS_ERROR_NOT_AVAILABLE));
|
||||
|
||||
nsCOMPtr<nsICacheInfoChannel> cacheInfoChannel =
|
||||
do_QueryInterface(underlyingChannel);
|
||||
|
||||
nsAutoCString spec;
|
||||
MOZ_TRY(uriNoFragment->GetSpec(spec));
|
||||
|
||||
nsAutoCString fragment;
|
||||
MOZ_TRY(uri->GetRef(fragment));
|
||||
|
||||
nsAutoCString method;
|
||||
MOZ_TRY(httpChannel->GetRequestMethod(method));
|
||||
|
||||
// This is safe due to static_asserts in ServiceWorkerManager.cpp
|
||||
uint32_t cacheModeInt;
|
||||
MOZ_ALWAYS_SUCCEEDS(internalChannel->GetFetchCacheMode(&cacheModeInt));
|
||||
RequestCache cacheMode = static_cast<RequestCache>(cacheModeInt);
|
||||
|
||||
RequestMode requestMode =
|
||||
InternalRequest::MapChannelToRequestMode(underlyingChannel);
|
||||
|
||||
// This is safe due to static_asserts in ServiceWorkerManager.cpp
|
||||
uint32_t redirectMode;
|
||||
MOZ_ALWAYS_SUCCEEDS(internalChannel->GetRedirectMode(&redirectMode));
|
||||
RequestRedirect requestRedirect = static_cast<RequestRedirect>(redirectMode);
|
||||
|
||||
RequestCredentials requestCredentials =
|
||||
InternalRequest::MapChannelToRequestCredentials(underlyingChannel);
|
||||
|
||||
nsAutoString referrer;
|
||||
ReferrerPolicy referrerPolicy = ReferrerPolicy::_empty;
|
||||
|
||||
nsCOMPtr<nsIReferrerInfo> referrerInfo = httpChannel->GetReferrerInfo();
|
||||
if (referrerInfo) {
|
||||
referrerPolicy = referrerInfo->ReferrerPolicy();
|
||||
Unused << referrerInfo->GetComputedReferrerSpec(referrer);
|
||||
}
|
||||
|
||||
uint32_t loadFlags;
|
||||
MOZ_TRY(underlyingChannel->GetLoadFlags(&loadFlags));
|
||||
|
||||
nsCOMPtr<nsILoadInfo> loadInfo;
|
||||
MOZ_TRY(underlyingChannel->GetLoadInfo(getter_AddRefs(loadInfo)));
|
||||
MOZ_ASSERT(loadInfo);
|
||||
|
||||
nsContentPolicyType contentPolicyType = loadInfo->InternalContentPolicyType();
|
||||
|
||||
nsAutoString integrity;
|
||||
MOZ_TRY(internalChannel->GetIntegrityMetadata(integrity));
|
||||
|
||||
RefPtr<HeaderFiller> headerFiller =
|
||||
MakeRefPtr<HeaderFiller>(HeadersGuardEnum::Request);
|
||||
MOZ_TRY(httpChannel->VisitNonDefaultRequestHeaders(headerFiller));
|
||||
|
||||
RefPtr<InternalHeaders> internalHeaders = headerFiller->Extract();
|
||||
|
||||
ErrorResult result;
|
||||
internalHeaders->SetGuard(HeadersGuardEnum::Immutable, result);
|
||||
if (NS_WARN_IF(result.Failed())) {
|
||||
return Err(result.StealNSResult());
|
||||
}
|
||||
|
||||
nsTArray<HeadersEntry> ipcHeaders;
|
||||
HeadersGuardEnum ipcHeadersGuard;
|
||||
internalHeaders->ToIPC(ipcHeaders, ipcHeadersGuard);
|
||||
|
||||
nsAutoCString alternativeDataType;
|
||||
if (cacheInfoChannel &&
|
||||
!cacheInfoChannel->PreferredAlternativeDataTypes().IsEmpty()) {
|
||||
// TODO: the internal request probably needs all the preferred types.
|
||||
alternativeDataType.Assign(
|
||||
cacheInfoChannel->PreferredAlternativeDataTypes()[0].type());
|
||||
}
|
||||
|
||||
Maybe<PrincipalInfo> principalInfo;
|
||||
|
||||
if (loadInfo->TriggeringPrincipal()) {
|
||||
principalInfo.emplace();
|
||||
MOZ_ALWAYS_SUCCEEDS(PrincipalToPrincipalInfo(
|
||||
loadInfo->TriggeringPrincipal(), principalInfo.ptr()));
|
||||
}
|
||||
|
||||
// Note: all the arguments are copied rather than moved, which would be more
|
||||
// efficient, because there's no move-friendly constructor generated.
|
||||
return IPCInternalRequest(
|
||||
method, {spec}, ipcHeadersGuard, ipcHeaders, Nothing(), -1,
|
||||
alternativeDataType, contentPolicyType, referrer, referrerPolicy,
|
||||
requestMode, requestCredentials, cacheMode, requestRedirect, integrity,
|
||||
fragment, principalInfo);
|
||||
}
|
||||
|
||||
nsresult MaybeStoreStreamForBackgroundThread(nsIInterceptedChannel* aChannel,
|
||||
IPCInternalRequest& aIPCRequest) {
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
MOZ_ALWAYS_SUCCEEDS(aChannel->GetChannel(getter_AddRefs(channel)));
|
||||
|
||||
Maybe<BodyStreamVariant> body;
|
||||
int64_t bodySize = -1;
|
||||
nsCOMPtr<nsIUploadChannel2> uploadChannel = do_QueryInterface(channel);
|
||||
|
||||
if (uploadChannel) {
|
||||
nsCOMPtr<nsIInputStream> uploadStream;
|
||||
MOZ_TRY(uploadChannel->CloneUploadStream(&aIPCRequest.bodySize(),
|
||||
getter_AddRefs(uploadStream)));
|
||||
|
||||
if (uploadStream) {
|
||||
Maybe<BodyStreamVariant>& body = aIPCRequest.body();
|
||||
body.emplace(ParentToParentStream());
|
||||
|
||||
MOZ_TRY(nsContentUtils::GenerateUUIDInPlace(
|
||||
body->get_ParentToParentStream().uuid()));
|
||||
|
||||
IPCBlobInputStreamStorage::Get()->AddStream(
|
||||
uploadStream, body->get_ParentToParentStream().uuid(), bodySize, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
nsresult ServiceWorkerPrivateImpl::SendFetchEvent(
|
||||
RefPtr<ServiceWorkerRegistrationInfo> aRegistration,
|
||||
nsCOMPtr<nsIInterceptedChannel> aChannel, const nsAString& aClientId,
|
||||
const nsAString& aResultingClientId) {
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(mOuter);
|
||||
MOZ_ASSERT(mOuter->mInfo);
|
||||
MOZ_ASSERT(aRegistration);
|
||||
MOZ_ASSERT(aChannel);
|
||||
|
||||
@ -773,15 +589,19 @@ nsresult ServiceWorkerPrivateImpl::SendFetchEvent(
|
||||
});
|
||||
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
MOZ_TRY(aChannel->GetChannel(getter_AddRefs(channel)));
|
||||
nsresult rv = aChannel->GetChannel(getter_AddRefs(channel));
|
||||
|
||||
IPCInternalRequest request;
|
||||
MOZ_TRY_VAR(request, GetIPCInternalRequest(aChannel));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
scopeExit.release();
|
||||
|
||||
MOZ_ASSERT(mOuter->mInfo);
|
||||
|
||||
// FetchEventOpChild will fill in the IPCInternalRequest.
|
||||
ServiceWorkerFetchEventOpArgs args(
|
||||
mOuter->mInfo->ScriptSpec(), std::move(request), nsString(aClientId),
|
||||
mOuter->mInfo->ScriptSpec(), IPCInternalRequest(), nsString(aClientId),
|
||||
nsString(aResultingClientId),
|
||||
nsContentUtils::IsNonSubresourceRequest(channel));
|
||||
|
||||
@ -814,9 +634,11 @@ nsresult ServiceWorkerPrivateImpl::SendFetchEventInternal(
|
||||
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||
}
|
||||
|
||||
MOZ_TRY(SpawnWorkerIfNeeded());
|
||||
MOZ_TRY(
|
||||
MaybeStoreStreamForBackgroundThread(aChannel, aArgs.internalRequest()));
|
||||
nsresult rv = SpawnWorkerIfNeeded();
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
scopeExit.release();
|
||||
|
||||
|
@ -1,14 +1,7 @@
|
||||
self.skipWaiting();
|
||||
|
||||
addEventListener("fetch", event => {
|
||||
const url = new URL(event.request.url);
|
||||
const params = new URLSearchParams(url.search);
|
||||
|
||||
if (params.get("clone") === "1") {
|
||||
event.respondWith(fetch(event.request.clone()));
|
||||
} else {
|
||||
event.respondWith(fetch(event.request));
|
||||
}
|
||||
event.respondWith(fetch(event.request));
|
||||
});
|
||||
|
||||
addEventListener("activate", function(event) {
|
||||
|
@ -14,12 +14,6 @@
|
||||
<input id="input" type="file">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
function GetFormData(file) {
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
return formData;
|
||||
}
|
||||
|
||||
async function onOpened(message) {
|
||||
let input = document.getElementById("input");
|
||||
SpecialPowers.wrap(input).mozSetFileArray([message.file]);
|
||||
@ -30,22 +24,13 @@ async function onOpened(message) {
|
||||
let serviceWorker = reg.installing || reg.waiting || reg.active;
|
||||
await waitForState(serviceWorker, 'activated');
|
||||
|
||||
let res = await fetch('server_file_upload.sjs?clone=0', {
|
||||
let res = await fetch('server_file_upload.sjs', {
|
||||
method: 'POST',
|
||||
body: input.files[0],
|
||||
});
|
||||
|
||||
let data = await res.clone().text();
|
||||
ok(data.length > 0, "We have data for an uncloned request!");
|
||||
|
||||
res = await fetch('server_file_upload.sjs?clone=1', {
|
||||
method: 'POST',
|
||||
// Make sure the underlying stream is a file stream
|
||||
body: GetFormData(input.files[0]),
|
||||
});
|
||||
|
||||
data = await res.clone().text();
|
||||
ok(data.length > 0, "We have data for a file-stream-backed cloned request!");
|
||||
ok(data.length > 0, "We have data!");
|
||||
|
||||
await reg.unregister();
|
||||
SimpleTest.finish();
|
||||
|
Loading…
Reference in New Issue
Block a user