зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset e1be97ce43d1 (bug 1622451
) for failures on browser_download_canceled.js. CLOSED TREE
This commit is contained in:
Родитель
42b619b62e
Коммит
83cd8858fc
|
@ -6,8 +6,6 @@ include IPCStream;
|
||||||
include ChannelInfo;
|
include ChannelInfo;
|
||||||
include PBackgroundSharedTypes;
|
include PBackgroundSharedTypes;
|
||||||
|
|
||||||
include protocol PIPCBlobInputStream;
|
|
||||||
|
|
||||||
using HeadersGuardEnum from "mozilla/dom/FetchIPCTypes.h";
|
using HeadersGuardEnum from "mozilla/dom/FetchIPCTypes.h";
|
||||||
using ReferrerPolicy from "mozilla/dom/FetchIPCTypes.h";
|
using ReferrerPolicy from "mozilla/dom/FetchIPCTypes.h";
|
||||||
using RequestCache 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 RequestMode from "mozilla/dom/FetchIPCTypes.h";
|
||||||
using RequestRedirect from "mozilla/dom/FetchIPCTypes.h";
|
using RequestRedirect from "mozilla/dom/FetchIPCTypes.h";
|
||||||
using ResponseType from "mozilla/dom/FetchIPCTypes.h";
|
using ResponseType from "mozilla/dom/FetchIPCTypes.h";
|
||||||
using struct nsID from "nsID.h";
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
@ -25,31 +22,12 @@ struct HeadersEntry {
|
||||||
nsCString value;
|
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 {
|
struct IPCInternalRequest {
|
||||||
nsCString method;
|
nsCString method;
|
||||||
nsCString[] urlList;
|
nsCString[] urlList;
|
||||||
HeadersGuardEnum headersGuard;
|
HeadersGuardEnum headersGuard;
|
||||||
HeadersEntry[] headers;
|
HeadersEntry[] headers;
|
||||||
BodyStreamVariant? body;
|
IPCStream? body;
|
||||||
int64_t bodySize;
|
int64_t bodySize;
|
||||||
nsCString preferredAlternativeDataType;
|
nsCString preferredAlternativeDataType;
|
||||||
uint32_t contentPolicyType;
|
uint32_t contentPolicyType;
|
||||||
|
@ -71,11 +49,11 @@ struct IPCInternalResponse {
|
||||||
nsCString statusText;
|
nsCString statusText;
|
||||||
HeadersGuardEnum headersGuard;
|
HeadersGuardEnum headersGuard;
|
||||||
HeadersEntry[] headers;
|
HeadersEntry[] headers;
|
||||||
BodyStreamVariant? body;
|
IPCStream? body;
|
||||||
int64_t bodySize;
|
int64_t bodySize;
|
||||||
nsresult errorCode;
|
nsresult errorCode;
|
||||||
nsCString alternativeDataType;
|
nsCString alternativeDataType;
|
||||||
BodyStreamVariant? alternativeBody;
|
IPCStream? alternativeBody;
|
||||||
IPCChannelInfo channelInfo;
|
IPCChannelInfo channelInfo;
|
||||||
PrincipalInfo? principalInfo;
|
PrincipalInfo? principalInfo;
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,17 +6,18 @@
|
||||||
|
|
||||||
#include "InternalRequest.h"
|
#include "InternalRequest.h"
|
||||||
|
|
||||||
#include "mozilla/ErrorResult.h"
|
#include "nsIContentPolicy.h"
|
||||||
#include "mozilla/dom/Document.h"
|
#include "mozilla/dom/Document.h"
|
||||||
|
#include "nsStreamUtils.h"
|
||||||
|
|
||||||
|
#include "mozilla/ErrorResult.h"
|
||||||
#include "mozilla/dom/FetchTypes.h"
|
#include "mozilla/dom/FetchTypes.h"
|
||||||
#include "mozilla/dom/IPCBlobInputStreamChild.h"
|
|
||||||
#include "mozilla/dom/ScriptSettings.h"
|
#include "mozilla/dom/ScriptSettings.h"
|
||||||
|
|
||||||
#include "mozilla/dom/WorkerCommon.h"
|
#include "mozilla/dom/WorkerCommon.h"
|
||||||
#include "mozilla/dom/WorkerPrivate.h"
|
#include "mozilla/dom/WorkerPrivate.h"
|
||||||
#include "mozilla/ipc/IPCStreamUtils.h"
|
#include "mozilla/ipc/IPCStreamUtils.h"
|
||||||
#include "mozilla/ipc/PBackgroundChild.h"
|
#include "mozilla/ipc/PBackgroundChild.h"
|
||||||
#include "nsIContentPolicy.h"
|
|
||||||
#include "nsStreamUtils.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
@ -145,6 +146,7 @@ InternalRequest::InternalRequest(const IPCInternalRequest& aIPCRequest)
|
||||||
mURLList(aIPCRequest.urlList()),
|
mURLList(aIPCRequest.urlList()),
|
||||||
mHeaders(new InternalHeaders(aIPCRequest.headers(),
|
mHeaders(new InternalHeaders(aIPCRequest.headers(),
|
||||||
aIPCRequest.headersGuard())),
|
aIPCRequest.headersGuard())),
|
||||||
|
mBodyStream(mozilla::ipc::DeserializeIPCStream(aIPCRequest.body())),
|
||||||
mBodyLength(aIPCRequest.bodySize()),
|
mBodyLength(aIPCRequest.bodySize()),
|
||||||
mPreferredAlternativeDataType(aIPCRequest.preferredAlternativeDataType()),
|
mPreferredAlternativeDataType(aIPCRequest.preferredAlternativeDataType()),
|
||||||
mContentPolicyType(
|
mContentPolicyType(
|
||||||
|
@ -161,21 +163,49 @@ InternalRequest::InternalRequest(const IPCInternalRequest& aIPCRequest)
|
||||||
mPrincipalInfo = MakeUnique<mozilla::ipc::PrincipalInfo>(
|
mPrincipalInfo = MakeUnique<mozilla::ipc::PrincipalInfo>(
|
||||||
aIPCRequest.principalInfo().ref());
|
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;
|
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(
|
void InternalRequest::SetContentPolicyType(
|
||||||
nsContentPolicyType aContentPolicyType) {
|
nsContentPolicyType aContentPolicyType) {
|
||||||
mContentPolicyType = aContentPolicyType;
|
mContentPolicyType = aContentPolicyType;
|
||||||
|
|
|
@ -25,6 +25,7 @@ namespace mozilla {
|
||||||
|
|
||||||
namespace ipc {
|
namespace ipc {
|
||||||
class PrincipalInfo;
|
class PrincipalInfo;
|
||||||
|
class AutoIPCStream;
|
||||||
} // namespace ipc
|
} // namespace ipc
|
||||||
|
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
@ -89,6 +90,10 @@ class InternalRequest final {
|
||||||
|
|
||||||
explicit InternalRequest(const IPCInternalRequest& aIPCRequest);
|
explicit InternalRequest(const IPCInternalRequest& aIPCRequest);
|
||||||
|
|
||||||
|
template <typename M>
|
||||||
|
void ToIPC(IPCInternalRequest* aIPCRequest, M* aManager,
|
||||||
|
UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoStream);
|
||||||
|
|
||||||
already_AddRefed<InternalRequest> Clone();
|
already_AddRefed<InternalRequest> Clone();
|
||||||
|
|
||||||
void GetMethod(nsCString& aMethod) const { aMethod.Assign(mMethod); }
|
void GetMethod(nsCString& aMethod) const { aMethod.Assign(mMethod); }
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
#include "mozilla/Assertions.h"
|
#include "mozilla/Assertions.h"
|
||||||
#include "mozilla/RefPtr.h"
|
#include "mozilla/RefPtr.h"
|
||||||
#include "mozilla/dom/FetchTypes.h"
|
#include "mozilla/dom/FetchTypes.h"
|
||||||
#include "mozilla/dom/IPCBlobInputStreamStorage.h"
|
|
||||||
#include "mozilla/dom/InternalHeaders.h"
|
#include "mozilla/dom/InternalHeaders.h"
|
||||||
#include "mozilla/dom/cache/CacheTypes.h"
|
#include "mozilla/dom/cache/CacheTypes.h"
|
||||||
#include "mozilla/ipc/PBackgroundSharedTypes.h"
|
#include "mozilla/ipc/PBackgroundSharedTypes.h"
|
||||||
|
@ -27,22 +26,6 @@ namespace {
|
||||||
// XXX This will be tweaked to something more meaningful in Bug 1383656.
|
// XXX This will be tweaked to something more meaningful in Bug 1383656.
|
||||||
const uint32_t kMaxRandomNumber = 102400;
|
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
|
} // namespace
|
||||||
|
|
||||||
InternalResponse::InternalResponse(uint16_t aStatus,
|
InternalResponse::InternalResponse(uint16_t aStatus,
|
||||||
|
@ -70,20 +53,15 @@ InternalResponse::InternalResponse(uint16_t aStatus,
|
||||||
response->mHeaders =
|
response->mHeaders =
|
||||||
new InternalHeaders(aIPCResponse.headers(), aIPCResponse.headersGuard());
|
new InternalHeaders(aIPCResponse.headers(), aIPCResponse.headersGuard());
|
||||||
|
|
||||||
if (aIPCResponse.body()) {
|
nsCOMPtr<nsIInputStream> body =
|
||||||
auto bodySize = aIPCResponse.bodySize();
|
mozilla::ipc::DeserializeIPCStream(aIPCResponse.body());
|
||||||
nsCOMPtr<nsIInputStream> body =
|
response->SetBody(body, aIPCResponse.bodySize());
|
||||||
TakeStreamFromStorage(*aIPCResponse.body(), bodySize);
|
|
||||||
response->SetBody(body, bodySize);
|
|
||||||
}
|
|
||||||
|
|
||||||
response->SetAlternativeDataType(aIPCResponse.alternativeDataType());
|
response->SetAlternativeDataType(aIPCResponse.alternativeDataType());
|
||||||
|
|
||||||
if (aIPCResponse.alternativeBody()) {
|
nsCOMPtr<nsIInputStream> alternativeBody =
|
||||||
nsCOMPtr<nsIInputStream> alternativeBody = TakeStreamFromStorage(
|
mozilla::ipc::DeserializeIPCStream(aIPCResponse.alternativeBody());
|
||||||
*aIPCResponse.alternativeBody(), UNKNOWN_BODY_SIZE);
|
response->SetAlternativeBody(alternativeBody);
|
||||||
response->SetAlternativeBody(alternativeBody);
|
|
||||||
}
|
|
||||||
|
|
||||||
response->InitChannelInfo(aIPCResponse.channelInfo());
|
response->InitChannelInfo(aIPCResponse.channelInfo());
|
||||||
|
|
||||||
|
@ -118,50 +96,54 @@ InternalResponse::InternalResponse(uint16_t aStatus,
|
||||||
|
|
||||||
InternalResponse::~InternalResponse() = default;
|
InternalResponse::~InternalResponse() = default;
|
||||||
|
|
||||||
void InternalResponse::ToIPC(
|
template void InternalResponse::ToIPC<mozilla::ipc::PBackgroundChild>(
|
||||||
IPCInternalResponse* aIPCResponse, mozilla::ipc::PBackgroundChild* aManager,
|
IPCInternalResponse* aIPCResponse, mozilla::ipc::PBackgroundChild* aManager,
|
||||||
UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoBodyStream,
|
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) {
|
UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoAlternativeBodyStream) {
|
||||||
nsTArray<HeadersEntry> headers;
|
MOZ_ASSERT(aIPCResponse);
|
||||||
HeadersGuardEnum headersGuard;
|
|
||||||
UnfilteredHeaders()->ToIPC(headers, headersGuard);
|
|
||||||
|
|
||||||
Maybe<mozilla::ipc::PrincipalInfo> principalInfo =
|
aIPCResponse->type() = mType;
|
||||||
mPrincipalInfo ? Some(*mPrincipalInfo) : Nothing();
|
GetUnfilteredURLList(aIPCResponse->urlList());
|
||||||
|
aIPCResponse->status() = GetUnfilteredStatus();
|
||||||
// Note: all the arguments are copied rather than moved, which would be more
|
aIPCResponse->statusText() = GetUnfilteredStatusText();
|
||||||
// efficient, because there's no move-friendly constructor generated.
|
UnfilteredHeaders()->ToIPC(aIPCResponse->headers(),
|
||||||
*aIPCResponse =
|
aIPCResponse->headersGuard());
|
||||||
IPCInternalResponse(mType, GetUnfilteredURLList(), GetUnfilteredStatus(),
|
|
||||||
GetUnfilteredStatusText(), headersGuard, headers,
|
|
||||||
Nothing(), static_cast<uint64_t>(UNKNOWN_BODY_SIZE),
|
|
||||||
mErrorCode, GetAlternativeDataType(), Nothing(),
|
|
||||||
mChannelInfo.AsIPCChannelInfo(), principalInfo);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIInputStream> body;
|
nsCOMPtr<nsIInputStream> body;
|
||||||
int64_t bodySize;
|
int64_t bodySize;
|
||||||
GetUnfilteredBody(getter_AddRefs(body), &bodySize);
|
GetUnfilteredBody(getter_AddRefs(body), &bodySize);
|
||||||
|
|
||||||
if (body) {
|
if (body) {
|
||||||
aIPCResponse->body().emplace(ChildToParentStream());
|
aAutoBodyStream.reset(
|
||||||
aIPCResponse->bodySize() = bodySize;
|
new mozilla::ipc::AutoIPCStream(aIPCResponse->body()));
|
||||||
|
|
||||||
aAutoBodyStream.reset(new mozilla::ipc::AutoIPCStream(
|
|
||||||
aIPCResponse->body()->get_ChildToParentStream().stream()));
|
|
||||||
DebugOnly<bool> ok = aAutoBodyStream->Serialize(body, aManager);
|
DebugOnly<bool> ok = aAutoBodyStream->Serialize(body, aManager);
|
||||||
MOZ_ASSERT(ok);
|
MOZ_ASSERT(ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
aIPCResponse->bodySize() = bodySize;
|
||||||
|
aIPCResponse->errorCode() = mErrorCode;
|
||||||
|
aIPCResponse->alternativeDataType() = GetAlternativeDataType();
|
||||||
|
|
||||||
nsCOMPtr<nsIInputStream> alternativeBody = TakeAlternativeBody();
|
nsCOMPtr<nsIInputStream> alternativeBody = TakeAlternativeBody();
|
||||||
if (alternativeBody) {
|
if (alternativeBody) {
|
||||||
aIPCResponse->alternativeBody().emplace(ChildToParentStream());
|
aAutoAlternativeBodyStream.reset(
|
||||||
|
new mozilla::ipc::AutoIPCStream(aIPCResponse->alternativeBody()));
|
||||||
aAutoAlternativeBodyStream.reset(new mozilla::ipc::AutoIPCStream(
|
|
||||||
aIPCResponse->alternativeBody()->get_ChildToParentStream().stream()));
|
|
||||||
DebugOnly<bool> ok =
|
DebugOnly<bool> ok =
|
||||||
aAutoAlternativeBodyStream->Serialize(alternativeBody, aManager);
|
aAutoAlternativeBodyStream->Serialize(alternativeBody, aManager);
|
||||||
MOZ_ASSERT(ok);
|
MOZ_ASSERT(ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
aIPCResponse->channelInfo() = mChannelInfo.AsIPCChannelInfo();
|
||||||
|
|
||||||
|
if (mPrincipalInfo) {
|
||||||
|
aIPCResponse->principalInfo().emplace(*mPrincipalInfo);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<InternalResponse> InternalResponse::Clone(
|
already_AddRefed<InternalResponse> InternalResponse::Clone(
|
||||||
|
|
|
@ -20,9 +20,8 @@
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace ipc {
|
namespace ipc {
|
||||||
class AutoIPCStream;
|
|
||||||
class PBackgroundChild;
|
|
||||||
class PrincipalInfo;
|
class PrincipalInfo;
|
||||||
|
class AutoIPCStream;
|
||||||
} // namespace ipc
|
} // namespace ipc
|
||||||
|
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
@ -43,10 +42,9 @@ class InternalResponse final {
|
||||||
static RefPtr<InternalResponse> FromIPC(
|
static RefPtr<InternalResponse> FromIPC(
|
||||||
const IPCInternalResponse& aIPCResponse);
|
const IPCInternalResponse& aIPCResponse);
|
||||||
|
|
||||||
// Note: the AutoIPCStreams must outlive the IPCInternalResponse.
|
template <typename M>
|
||||||
void ToIPC(
|
void ToIPC(
|
||||||
IPCInternalResponse* aIPCResponse,
|
IPCInternalResponse* aIPCResponse, M* aManager,
|
||||||
mozilla::ipc::PBackgroundChild* aManager,
|
|
||||||
UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoBodyStream,
|
UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoBodyStream,
|
||||||
UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoAlternativeBodyStream);
|
UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoAlternativeBodyStream);
|
||||||
|
|
||||||
|
@ -113,12 +111,6 @@ class InternalResponse final {
|
||||||
return GetURLList(aURLList);
|
return GetURLList(aURLList);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsTArray<nsCString> GetUnfilteredURLList() const {
|
|
||||||
nsTArray<nsCString> list;
|
|
||||||
GetUnfilteredURLList(list);
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetURLList(const nsTArray<nsCString>& aURLList) {
|
void SetURLList(const nsTArray<nsCString>& aURLList) {
|
||||||
mURLList.Assign(aURLList);
|
mURLList.Assign(aURLList);
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,10 @@ NS_INTERFACE_MAP_END
|
||||||
NS_IMPL_ADDREF(IPCBlobInputStreamStorage)
|
NS_IMPL_ADDREF(IPCBlobInputStreamStorage)
|
||||||
NS_IMPL_RELEASE(IPCBlobInputStreamStorage)
|
NS_IMPL_RELEASE(IPCBlobInputStreamStorage)
|
||||||
|
|
||||||
|
IPCBlobInputStreamStorage::IPCBlobInputStreamStorage() = default;
|
||||||
|
|
||||||
|
IPCBlobInputStreamStorage::~IPCBlobInputStreamStorage() = default;
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
IPCBlobInputStreamStorage* IPCBlobInputStreamStorage::Get() { return gStorage; }
|
IPCBlobInputStreamStorage* IPCBlobInputStreamStorage::Get() { return gStorage; }
|
||||||
|
|
||||||
|
|
|
@ -46,8 +46,8 @@ class IPCBlobInputStreamStorage final : public nsIObserver {
|
||||||
const nsID& aID);
|
const nsID& aID);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IPCBlobInputStreamStorage() = default;
|
IPCBlobInputStreamStorage();
|
||||||
~IPCBlobInputStreamStorage() = default;
|
~IPCBlobInputStreamStorage();
|
||||||
|
|
||||||
struct StreamData {
|
struct StreamData {
|
||||||
nsCOMPtr<nsIInputStream> mInputStream;
|
nsCOMPtr<nsIInputStream> mInputStream;
|
||||||
|
|
|
@ -135,14 +135,6 @@ nsresult SerializeInputStream(nsIInputStream* aInputStream, uint64_t aSize,
|
||||||
aActorParent, aManager);
|
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,
|
nsresult SerializeInputStream(nsIInputStream* aInputStream, uint64_t aSize,
|
||||||
IPCBlobStream& aIPCBlob,
|
IPCBlobStream& aIPCBlob,
|
||||||
ContentParent* aManager) {
|
ContentParent* aManager) {
|
||||||
|
|
|
@ -255,10 +255,6 @@ nsresult SerializeInputStream(nsIInputStream* aInputStream, uint64_t aSize,
|
||||||
PIPCBlobInputStreamParent*& aActorParent,
|
PIPCBlobInputStreamParent*& aActorParent,
|
||||||
ContentParent* aManager);
|
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
|
// WARNING: If you pass any actor which does not have P{Content,Background} as
|
||||||
// its toplevel protocol, this method will MOZ_CRASH.
|
// its toplevel protocol, this method will MOZ_CRASH.
|
||||||
nsresult SerializeUntyped(BlobImpl* aBlobImpl, mozilla::ipc::IProtocol* aActor,
|
nsresult SerializeUntyped(BlobImpl* aBlobImpl, mozilla::ipc::IProtocol* aActor,
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
#include "nsIChannel.h"
|
#include "nsIChannel.h"
|
||||||
#include "nsIConsoleReportCollector.h"
|
#include "nsIConsoleReportCollector.h"
|
||||||
#include "nsIContentPolicy.h"
|
#include "nsIContentPolicy.h"
|
||||||
|
#include "nsIHttpChannelInternal.h"
|
||||||
|
#include "nsIHttpHeaderVisitor.h"
|
||||||
#include "nsIInputStream.h"
|
#include "nsIInputStream.h"
|
||||||
#include "nsILoadInfo.h"
|
#include "nsILoadInfo.h"
|
||||||
#include "nsINetworkInterceptController.h"
|
#include "nsINetworkInterceptController.h"
|
||||||
|
@ -23,6 +25,7 @@
|
||||||
#include "nsIScriptError.h"
|
#include "nsIScriptError.h"
|
||||||
#include "nsISupportsImpl.h"
|
#include "nsISupportsImpl.h"
|
||||||
#include "nsIURI.h"
|
#include "nsIURI.h"
|
||||||
|
#include "nsIUploadChannel2.h"
|
||||||
#include "nsNetUtil.h"
|
#include "nsNetUtil.h"
|
||||||
#include "nsProxyRelease.h"
|
#include "nsProxyRelease.h"
|
||||||
#include "nsTArray.h"
|
#include "nsTArray.h"
|
||||||
|
@ -37,6 +40,7 @@
|
||||||
#include "mozilla/Unused.h"
|
#include "mozilla/Unused.h"
|
||||||
#include "mozilla/ipc/BackgroundChild.h"
|
#include "mozilla/ipc/BackgroundChild.h"
|
||||||
#include "mozilla/dom/InternalHeaders.h"
|
#include "mozilla/dom/InternalHeaders.h"
|
||||||
|
#include "mozilla/dom/InternalRequest.h"
|
||||||
#include "mozilla/dom/InternalResponse.h"
|
#include "mozilla/dom/InternalResponse.h"
|
||||||
#include "mozilla/dom/PRemoteWorkerControllerChild.h"
|
#include "mozilla/dom/PRemoteWorkerControllerChild.h"
|
||||||
#include "mozilla/dom/ServiceWorkerRegistrationInfo.h"
|
#include "mozilla/dom/ServiceWorkerRegistrationInfo.h"
|
||||||
|
@ -181,6 +185,168 @@ class SynthesizeResponseWatcher final : public nsIInterceptedBodyCallback {
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS(SynthesizeResponseWatcher, 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
|
} // anonymous namespace
|
||||||
|
|
||||||
/* static */ RefPtr<GenericPromise> FetchEventOpChild::SendFetchEvent(
|
/* static */ RefPtr<GenericPromise> FetchEventOpChild::SendFetchEvent(
|
||||||
|
@ -198,7 +364,28 @@ NS_IMPL_ISUPPORTS(SynthesizeResponseWatcher, nsIInterceptedBodyCallback)
|
||||||
std::move(aArgs), std::move(aInterceptedChannel),
|
std::move(aArgs), std::move(aInterceptedChannel),
|
||||||
std::move(aRegistration), std::move(aKeepAliveToken));
|
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);
|
Unused << aManager->SendPFetchEventOpConstructor(actor, actor->mArgs);
|
||||||
|
autoStream->TakeOptionalValue();
|
||||||
|
|
||||||
return actor->mPromiseHolder.Ensure(__func__);
|
return actor->mPromiseHolder.Ensure(__func__);
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,14 +120,8 @@ void FetchEventOpProxyChild::Initialize(
|
||||||
}
|
}
|
||||||
|
|
||||||
Unused << self->SendRespondWith(ipcArgs);
|
Unused << self->SendRespondWith(ipcArgs);
|
||||||
|
autoBodyStream->TakeOptionalValue();
|
||||||
if (ipcArgs.internalResponse().body()) {
|
autoAlternativeBodyStream->TakeOptionalValue();
|
||||||
autoBodyStream->TakeValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ipcArgs.internalResponse().alternativeBody()) {
|
|
||||||
autoAlternativeBodyStream->TakeValue();
|
|
||||||
}
|
|
||||||
} else if (result.is<ResetInterceptionArgs>()) {
|
} else if (result.is<ResetInterceptionArgs>()) {
|
||||||
Unused << self->SendRespondWith(
|
Unused << self->SendRespondWith(
|
||||||
result.extract<ResetInterceptionArgs>());
|
result.extract<ResetInterceptionArgs>());
|
||||||
|
@ -145,7 +139,7 @@ RefPtr<InternalRequest> FetchEventOpProxyChild::ExtractInternalRequest() {
|
||||||
MOZ_ASSERT(IsCurrentThreadRunningWorker());
|
MOZ_ASSERT(IsCurrentThreadRunningWorker());
|
||||||
MOZ_ASSERT(mInternalRequest);
|
MOZ_ASSERT(mInternalRequest);
|
||||||
|
|
||||||
return std::move(mInternalRequest);
|
return RefPtr<InternalRequest>(std::move(mInternalRequest));
|
||||||
}
|
}
|
||||||
|
|
||||||
void FetchEventOpProxyChild::ActorDestroy(ActorDestroyReason) {
|
void FetchEventOpProxyChild::ActorDestroy(ActorDestroyReason) {
|
||||||
|
|
|
@ -9,18 +9,13 @@
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsContentUtils.h"
|
|
||||||
#include "nsIInputStream.h"
|
#include "nsIInputStream.h"
|
||||||
|
|
||||||
#include "mozilla/Assertions.h"
|
#include "mozilla/Assertions.h"
|
||||||
#include "mozilla/DebugOnly.h"
|
#include "mozilla/DebugOnly.h"
|
||||||
#include "mozilla/Result.h"
|
|
||||||
#include "mozilla/ResultExtensions.h"
|
|
||||||
#include "mozilla/UniquePtr.h"
|
#include "mozilla/UniquePtr.h"
|
||||||
#include "mozilla/Unused.h"
|
#include "mozilla/Unused.h"
|
||||||
#include "mozilla/dom/FetchEventOpParent.h"
|
#include "mozilla/dom/FetchEventOpParent.h"
|
||||||
#include "mozilla/dom/IPCBlobInputStreamStorage.h"
|
|
||||||
#include "mozilla/dom/IPCBlobUtils.h"
|
|
||||||
#include "mozilla/ipc/BackgroundParent.h"
|
#include "mozilla/ipc/BackgroundParent.h"
|
||||||
#include "mozilla/ipc/IPCStreamUtils.h"
|
#include "mozilla/ipc/IPCStreamUtils.h"
|
||||||
|
|
||||||
|
@ -32,25 +27,20 @@ namespace dom {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
nsresult MaybeDeserializeAndWrapForMainThread(
|
void MaybeDeserializeAndReserialize(const Maybe<IPCStream>& aDeserialize,
|
||||||
const Maybe<BodyStreamVariant>& aSource, int64_t aBodyStreamSize,
|
Maybe<IPCStream>& aReserialize,
|
||||||
Maybe<BodyStreamVariant>& aSink, PBackgroundParent* aManager) {
|
UniquePtr<AutoIPCStream>& aAutoStream,
|
||||||
if (aSource.isNothing()) {
|
PBackgroundParent* aManager) {
|
||||||
return NS_OK;
|
nsCOMPtr<nsIInputStream> maybeDeserialized =
|
||||||
|
DeserializeIPCStream(aDeserialize);
|
||||||
|
|
||||||
|
if (!maybeDeserialized) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIInputStream> deserialized =
|
aAutoStream.reset(new AutoIPCStream(aReserialize));
|
||||||
DeserializeIPCStream(aSource->get_ChildToParentStream().stream());
|
DebugOnly<bool> ok = aAutoStream->Serialize(maybeDeserialized, aManager);
|
||||||
|
MOZ_ASSERT(ok);
|
||||||
aSink = Some(ParentToParentStream());
|
|
||||||
auto& uuid = aSink->get_ParentToParentStream().uuid();
|
|
||||||
|
|
||||||
MOZ_TRY(nsContentUtils::GenerateUUIDInPlace(uuid));
|
|
||||||
|
|
||||||
IPCBlobInputStreamStorage::Get()->AddStream(deserialized, uuid,
|
|
||||||
aBodyStreamSize, 0);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
@ -74,30 +64,15 @@ nsresult MaybeDeserializeAndWrapForMainThread(
|
||||||
ServiceWorkerFetchEventOpArgs copyArgs = aArgs;
|
ServiceWorkerFetchEventOpArgs copyArgs = aArgs;
|
||||||
IPCInternalRequest& copyRequest = copyArgs.internalRequest();
|
IPCInternalRequest& copyRequest = copyArgs.internalRequest();
|
||||||
|
|
||||||
if (copyRequest.body().ref().type() ==
|
PBackgroundParent* bgParent = aManager->Manager();
|
||||||
BodyStreamVariant::TParentToParentStream) {
|
MOZ_ASSERT(bgParent);
|
||||||
nsCOMPtr<nsIInputStream> stream;
|
|
||||||
auto streamLength = copyRequest.bodySize();
|
|
||||||
const auto& uuid =
|
|
||||||
copyRequest.body().ref().get_ParentToParentStream().uuid();
|
|
||||||
IPCBlobInputStreamStorage* storage = IPCBlobInputStreamStorage::Get();
|
|
||||||
|
|
||||||
storage->GetStream(uuid, 0, streamLength, getter_AddRefs(stream));
|
UniquePtr<AutoIPCStream> autoBodyStream = MakeUnique<AutoIPCStream>();
|
||||||
storage->ForgetStream(uuid);
|
MaybeDeserializeAndReserialize(aArgs.internalRequest().body(),
|
||||||
|
copyRequest.body(), autoBodyStream, bgParent);
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
Unused << aManager->SendPFetchEventOpProxyConstructor(actor, copyArgs);
|
Unused << aManager->SendPFetchEventOpProxyConstructor(actor, copyArgs);
|
||||||
|
autoBodyStream->TakeOptionalValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
FetchEventOpProxyParent::~FetchEventOpProxyParent() {
|
FetchEventOpProxyParent::~FetchEventOpProxyParent() {
|
||||||
|
@ -150,14 +125,20 @@ mozilla::ipc::IPCResult FetchEventOpProxyParent::RecvRespondWith(
|
||||||
PBackgroundParent* bgParent = manager->Manager();
|
PBackgroundParent* bgParent = manager->Manager();
|
||||||
MOZ_ASSERT(bgParent);
|
MOZ_ASSERT(bgParent);
|
||||||
|
|
||||||
MOZ_ALWAYS_SUCCEEDS(MaybeDeserializeAndWrapForMainThread(
|
UniquePtr<AutoIPCStream> autoBodyStream = MakeUnique<AutoIPCStream>();
|
||||||
originalResponse.body(), copyResponse.bodySize(), copyResponse.body(),
|
UniquePtr<AutoIPCStream> autoAlternativeBodyStream =
|
||||||
bgParent));
|
MakeUnique<AutoIPCStream>();
|
||||||
MOZ_ALWAYS_SUCCEEDS(MaybeDeserializeAndWrapForMainThread(
|
|
||||||
originalResponse.alternativeBody(), InternalResponse::UNKNOWN_BODY_SIZE,
|
MaybeDeserializeAndReserialize(originalResponse.body(), copyResponse.body(),
|
||||||
copyResponse.alternativeBody(), bgParent));
|
autoBodyStream, bgParent);
|
||||||
|
MaybeDeserializeAndReserialize(originalResponse.alternativeBody(),
|
||||||
|
copyResponse.alternativeBody(),
|
||||||
|
autoAlternativeBodyStream, bgParent);
|
||||||
|
|
||||||
Unused << mReal->SendRespondWith(copyArgs);
|
Unused << mReal->SendRespondWith(copyArgs);
|
||||||
|
|
||||||
|
autoBodyStream->TakeOptionalValue();
|
||||||
|
autoAlternativeBodyStream->TakeOptionalValue();
|
||||||
} else {
|
} else {
|
||||||
Unused << mReal->SendRespondWith(aResult);
|
Unused << mReal->SendRespondWith(aResult);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,13 +14,10 @@
|
||||||
#include "nsDebug.h"
|
#include "nsDebug.h"
|
||||||
#include "nsError.h"
|
#include "nsError.h"
|
||||||
#include "nsIChannel.h"
|
#include "nsIChannel.h"
|
||||||
#include "nsIHttpChannelInternal.h"
|
|
||||||
#include "nsIHttpHeaderVisitor.h"
|
|
||||||
#include "nsINetworkInterceptController.h"
|
#include "nsINetworkInterceptController.h"
|
||||||
#include "nsIObserverService.h"
|
#include "nsIObserverService.h"
|
||||||
#include "nsIScriptError.h"
|
#include "nsIScriptError.h"
|
||||||
#include "nsIURI.h"
|
#include "nsIURI.h"
|
||||||
#include "nsIUploadChannel2.h"
|
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
|
|
||||||
#include "ServiceWorkerManager.h"
|
#include "ServiceWorkerManager.h"
|
||||||
|
@ -28,8 +25,6 @@
|
||||||
#include "mozilla/Assertions.h"
|
#include "mozilla/Assertions.h"
|
||||||
#include "mozilla/ErrorResult.h"
|
#include "mozilla/ErrorResult.h"
|
||||||
#include "mozilla/Maybe.h"
|
#include "mozilla/Maybe.h"
|
||||||
#include "mozilla/Result.h"
|
|
||||||
#include "mozilla/ResultExtensions.h"
|
|
||||||
#include "mozilla/ScopeExit.h"
|
#include "mozilla/ScopeExit.h"
|
||||||
#include "mozilla/Services.h"
|
#include "mozilla/Services.h"
|
||||||
#include "mozilla/StaticPrefs_dom.h"
|
#include "mozilla/StaticPrefs_dom.h"
|
||||||
|
@ -37,9 +32,7 @@
|
||||||
#include "mozilla/dom/ClientIPCTypes.h"
|
#include "mozilla/dom/ClientIPCTypes.h"
|
||||||
#include "mozilla/dom/DOMTypes.h"
|
#include "mozilla/dom/DOMTypes.h"
|
||||||
#include "mozilla/dom/FetchEventOpChild.h"
|
#include "mozilla/dom/FetchEventOpChild.h"
|
||||||
#include "mozilla/dom/IPCBlobInputStreamStorage.h"
|
|
||||||
#include "mozilla/dom/InternalHeaders.h"
|
#include "mozilla/dom/InternalHeaders.h"
|
||||||
#include "mozilla/dom/InternalRequest.h"
|
|
||||||
#include "mozilla/dom/ReferrerInfo.h"
|
#include "mozilla/dom/ReferrerInfo.h"
|
||||||
#include "mozilla/dom/RemoteWorkerControllerChild.h"
|
#include "mozilla/dom/RemoteWorkerControllerChild.h"
|
||||||
#include "mozilla/dom/ServiceWorkerBinding.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(
|
nsresult ServiceWorkerPrivateImpl::SendFetchEvent(
|
||||||
RefPtr<ServiceWorkerRegistrationInfo> aRegistration,
|
RefPtr<ServiceWorkerRegistrationInfo> aRegistration,
|
||||||
nsCOMPtr<nsIInterceptedChannel> aChannel, const nsAString& aClientId,
|
nsCOMPtr<nsIInterceptedChannel> aChannel, const nsAString& aClientId,
|
||||||
const nsAString& aResultingClientId) {
|
const nsAString& aResultingClientId) {
|
||||||
AssertIsOnMainThread();
|
AssertIsOnMainThread();
|
||||||
MOZ_ASSERT(mOuter);
|
MOZ_ASSERT(mOuter);
|
||||||
MOZ_ASSERT(mOuter->mInfo);
|
|
||||||
MOZ_ASSERT(aRegistration);
|
MOZ_ASSERT(aRegistration);
|
||||||
MOZ_ASSERT(aChannel);
|
MOZ_ASSERT(aChannel);
|
||||||
|
|
||||||
|
@ -773,15 +589,19 @@ nsresult ServiceWorkerPrivateImpl::SendFetchEvent(
|
||||||
});
|
});
|
||||||
|
|
||||||
nsCOMPtr<nsIChannel> channel;
|
nsCOMPtr<nsIChannel> channel;
|
||||||
MOZ_TRY(aChannel->GetChannel(getter_AddRefs(channel)));
|
nsresult rv = aChannel->GetChannel(getter_AddRefs(channel));
|
||||||
|
|
||||||
IPCInternalRequest request;
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
MOZ_TRY_VAR(request, GetIPCInternalRequest(aChannel));
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
scopeExit.release();
|
scopeExit.release();
|
||||||
|
|
||||||
|
MOZ_ASSERT(mOuter->mInfo);
|
||||||
|
|
||||||
|
// FetchEventOpChild will fill in the IPCInternalRequest.
|
||||||
ServiceWorkerFetchEventOpArgs args(
|
ServiceWorkerFetchEventOpArgs args(
|
||||||
mOuter->mInfo->ScriptSpec(), std::move(request), nsString(aClientId),
|
mOuter->mInfo->ScriptSpec(), IPCInternalRequest(), nsString(aClientId),
|
||||||
nsString(aResultingClientId),
|
nsString(aResultingClientId),
|
||||||
nsContentUtils::IsNonSubresourceRequest(channel));
|
nsContentUtils::IsNonSubresourceRequest(channel));
|
||||||
|
|
||||||
|
@ -814,9 +634,11 @@ nsresult ServiceWorkerPrivateImpl::SendFetchEventInternal(
|
||||||
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_TRY(SpawnWorkerIfNeeded());
|
nsresult rv = SpawnWorkerIfNeeded();
|
||||||
MOZ_TRY(
|
|
||||||
MaybeStoreStreamForBackgroundThread(aChannel, aArgs.internalRequest()));
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
scopeExit.release();
|
scopeExit.release();
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,7 @@
|
||||||
self.skipWaiting();
|
self.skipWaiting();
|
||||||
|
|
||||||
addEventListener("fetch", event => {
|
addEventListener("fetch", event => {
|
||||||
const url = new URL(event.request.url);
|
event.respondWith(fetch(event.request));
|
||||||
const params = new URLSearchParams(url.search);
|
|
||||||
|
|
||||||
if (params.get("clone") === "1") {
|
|
||||||
event.respondWith(fetch(event.request.clone()));
|
|
||||||
} else {
|
|
||||||
event.respondWith(fetch(event.request));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
addEventListener("activate", function(event) {
|
addEventListener("activate", function(event) {
|
||||||
|
|
|
@ -14,12 +14,6 @@
|
||||||
<input id="input" type="file">
|
<input id="input" type="file">
|
||||||
<script class="testbody" type="text/javascript">
|
<script class="testbody" type="text/javascript">
|
||||||
|
|
||||||
function GetFormData(file) {
|
|
||||||
const formData = new FormData();
|
|
||||||
formData.append('file', file);
|
|
||||||
return formData;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function onOpened(message) {
|
async function onOpened(message) {
|
||||||
let input = document.getElementById("input");
|
let input = document.getElementById("input");
|
||||||
SpecialPowers.wrap(input).mozSetFileArray([message.file]);
|
SpecialPowers.wrap(input).mozSetFileArray([message.file]);
|
||||||
|
@ -30,22 +24,13 @@ async function onOpened(message) {
|
||||||
let serviceWorker = reg.installing || reg.waiting || reg.active;
|
let serviceWorker = reg.installing || reg.waiting || reg.active;
|
||||||
await waitForState(serviceWorker, 'activated');
|
await waitForState(serviceWorker, 'activated');
|
||||||
|
|
||||||
let res = await fetch('server_file_upload.sjs?clone=0', {
|
let res = await fetch('server_file_upload.sjs', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: input.files[0],
|
body: input.files[0],
|
||||||
});
|
});
|
||||||
|
|
||||||
let data = await res.clone().text();
|
let data = await res.clone().text();
|
||||||
ok(data.length > 0, "We have data for an uncloned request!");
|
ok(data.length > 0, "We have data!");
|
||||||
|
|
||||||
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!");
|
|
||||||
|
|
||||||
await reg.unregister();
|
await reg.unregister();
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
|
|
Загрузка…
Ссылка в новой задаче