diff --git a/dom/fetch/FetchTypes.ipdlh b/dom/fetch/FetchTypes.ipdlh index 19f47a0a7fac..e3d92c844589 100644 --- a/dom/fetch/FetchTypes.ipdlh +++ b/dom/fetch/FetchTypes.ipdlh @@ -7,15 +7,57 @@ include ChannelInfo; include PBackgroundSharedTypes; using HeadersGuardEnum from "mozilla/dom/FetchIPCTypes.h"; +using ReferrerPolicy from "mozilla/dom/FetchIPCTypes.h"; +using RequestCache from "mozilla/dom/FetchIPCTypes.h"; +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"; namespace mozilla { namespace dom { -struct HeadersEntry -{ +struct HeadersEntry { nsCString name; nsCString value; }; +struct IPCInternalRequest { + nsCString method; + nsCString[] urlList; + HeadersGuardEnum headersGuard; + HeadersEntry[] headers; + IPCStream? body; + int64_t bodySize; + nsCString preferredAlternativeDataType; + uint32_t contentPolicyType; + nsString referrer; + ReferrerPolicy referrerPolicy; + RequestMode requestMode; + RequestCredentials requestCredentials; + RequestCache cacheMode; + RequestRedirect requestRedirect; + nsString integrity; + nsCString fragment; + bool createdByFetchEvent; + PrincipalInfo? principalInfo; +}; + +struct IPCInternalResponse { + ResponseType type; + nsCString[] urlList; + uint16_t status; + nsCString statusText; + HeadersGuardEnum headersGuard; + HeadersEntry[] headers; + IPCStream? body; + int64_t bodySize; + nsresult errorCode; + nsCString alternativeDataType; + IPCStream? alternativeBody; + IPCChannelInfo channelInfo; + PrincipalInfo? principalInfo; +}; + } // namespace ipc } // namespace mozilla diff --git a/dom/fetch/InternalRequest.cpp b/dom/fetch/InternalRequest.cpp index 6456fe55c9aa..cf457016a2a4 100644 --- a/dom/fetch/InternalRequest.cpp +++ b/dom/fetch/InternalRequest.cpp @@ -16,6 +16,8 @@ #include "mozilla/dom/WorkerCommon.h" #include "mozilla/dom/WorkerPrivate.h" +#include "mozilla/ipc/IPCStreamUtils.h" +#include "mozilla/ipc/PBackgroundChild.h" namespace mozilla { namespace dom { @@ -171,8 +173,73 @@ InternalRequest::InternalRequest(const InternalRequest& aOther) // NOTE: does not copy body stream... use the fallible Clone() for that } +InternalRequest::InternalRequest(const IPCInternalRequest& aIPCRequest) + : mMethod(aIPCRequest.method()), + mURLList(aIPCRequest.urlList()), + mHeaders(new InternalHeaders(aIPCRequest.headers(), + aIPCRequest.headersGuard())), + mBodyStream(mozilla::ipc::DeserializeIPCStream(aIPCRequest.body())), + mBodyLength(aIPCRequest.bodySize()), + mPreferredAlternativeDataType(aIPCRequest.preferredAlternativeDataType()), + mContentPolicyType( + static_cast(aIPCRequest.contentPolicyType())), + mReferrer(aIPCRequest.referrer()), + mReferrerPolicy(aIPCRequest.referrerPolicy()), + mMode(aIPCRequest.requestMode()), + mCredentialsMode(aIPCRequest.requestCredentials()), + mCacheMode(aIPCRequest.cacheMode()), + mRedirectMode(aIPCRequest.requestRedirect()), + mIntegrity(aIPCRequest.integrity()), + mFragment(aIPCRequest.fragment()), + mCreatedByFetchEvent(aIPCRequest.createdByFetchEvent()) { + if (aIPCRequest.principalInfo()) { + mPrincipalInfo = MakeUnique( + aIPCRequest.principalInfo().ref()); + } +} + InternalRequest::~InternalRequest() {} +template void InternalRequest::ToIPC( + IPCInternalRequest* aIPCRequest, mozilla::ipc::PBackgroundChild* aManager, + UniquePtr& aAutoStream); + +template +void InternalRequest::ToIPC( + IPCInternalRequest* aIPCRequest, M* aManager, + UniquePtr& 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 ok = aAutoStream->Serialize(mBodyStream, aManager); + MOZ_ASSERT(ok); + } + + aIPCRequest->bodySize() = mBodyLength; + aIPCRequest->preferredAlternativeDataType() = mPreferredAlternativeDataType; + aIPCRequest->contentPolicyType() = static_cast(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; + aIPCRequest->createdByFetchEvent() = mCreatedByFetchEvent; + + if (mPrincipalInfo) { + aIPCRequest->principalInfo().emplace(*mPrincipalInfo); + } +} + void InternalRequest::SetContentPolicyType( nsContentPolicyType aContentPolicyType) { mContentPolicyType = aContentPolicyType; diff --git a/dom/fetch/InternalRequest.h b/dom/fetch/InternalRequest.h index e9e0b1fab9bb..a5755bfdf083 100644 --- a/dom/fetch/InternalRequest.h +++ b/dom/fetch/InternalRequest.h @@ -12,6 +12,7 @@ #include "mozilla/dom/RequestBinding.h" #include "mozilla/LoadTainting.h" #include "mozilla/net/ReferrerPolicy.h" +#include "mozilla/UniquePtr.h" #include "nsIContentPolicy.h" #include "nsIInputStream.h" @@ -26,6 +27,7 @@ namespace mozilla { namespace ipc { class PrincipalInfo; +class AutoIPCStream; } // namespace ipc namespace dom { @@ -68,6 +70,7 @@ namespace dom { * */ +class IPCInternalRequest; class Request; #define kFETCH_CLIENT_REFERRER_STR "about:client" @@ -87,6 +90,12 @@ class InternalRequest final { nsContentPolicyType aContentPolicyType, const nsAString& aIntegrity); + explicit InternalRequest(const IPCInternalRequest& aIPCRequest); + + template + void ToIPC(IPCInternalRequest* aIPCRequest, M* aManager, + UniquePtr& aAutoStream); + already_AddRefed Clone(); void GetMethod(nsCString& aMethod) const { aMethod.Assign(mMethod); } diff --git a/dom/fetch/InternalResponse.cpp b/dom/fetch/InternalResponse.cpp index 922ade82767c..5cbd7eb0cc3e 100644 --- a/dom/fetch/InternalResponse.cpp +++ b/dom/fetch/InternalResponse.cpp @@ -7,6 +7,8 @@ #include "InternalResponse.h" #include "mozilla/Assertions.h" +#include "mozilla/RefPtr.h" +#include "mozilla/dom/FetchTypes.h" #include "mozilla/dom/InternalHeaders.h" #include "mozilla/dom/cache/CacheTypes.h" #include "mozilla/ipc/PBackgroundSharedTypes.h" @@ -39,8 +41,112 @@ InternalResponse::InternalResponse(uint16_t aStatus, mErrorCode(NS_OK), mCredentialsMode(aCredentialsMode) {} +/* static */ RefPtr InternalResponse::FromIPC( + const IPCInternalResponse& aIPCResponse) { + if (aIPCResponse.type() == ResponseType::Error) { + return InternalResponse::NetworkError(aIPCResponse.errorCode()); + } + + RefPtr response = + new InternalResponse(aIPCResponse.status(), aIPCResponse.statusText()); + + response->SetURLList(aIPCResponse.urlList()); + response->mHeaders = + new InternalHeaders(aIPCResponse.headers(), aIPCResponse.headersGuard()); + + nsCOMPtr body = + mozilla::ipc::DeserializeIPCStream(aIPCResponse.body()); + response->SetBody(body, aIPCResponse.bodySize()); + + response->SetAlternativeDataType(aIPCResponse.alternativeDataType()); + + nsCOMPtr alternativeBody = + mozilla::ipc::DeserializeIPCStream(aIPCResponse.alternativeBody()); + response->SetAlternativeBody(alternativeBody); + + response->InitChannelInfo(aIPCResponse.channelInfo()); + + if (aIPCResponse.principalInfo()) { + response->SetPrincipalInfo(MakeUnique( + aIPCResponse.principalInfo().ref())); + } + + switch (aIPCResponse.type()) { + case ResponseType::Basic: + response = response->BasicResponse(); + break; + case ResponseType::Cors: + response = response->CORSResponse(); + break; + case ResponseType::Default: + break; + case ResponseType::Opaque: + response = response->OpaqueResponse(); + break; + case ResponseType::Opaqueredirect: + response = response->OpaqueRedirectResponse(); + break; + default: + MOZ_CRASH("Unexpected ResponseType!"); + } + + MOZ_ASSERT(response); + + return response; +} + InternalResponse::~InternalResponse() {} +template void InternalResponse::ToIPC( + IPCInternalResponse* aIPCResponse, mozilla::ipc::PBackgroundChild* aManager, + UniquePtr& aAutoBodyStream, + UniquePtr& aAutoAlternativeBodyStream); + +template +void InternalResponse::ToIPC( + IPCInternalResponse* aIPCResponse, M* aManager, + UniquePtr& aAutoBodyStream, + UniquePtr& aAutoAlternativeBodyStream) { + MOZ_ASSERT(aIPCResponse); + + aIPCResponse->type() = mType; + GetUnfilteredURLList(aIPCResponse->urlList()); + aIPCResponse->status() = GetUnfilteredStatus(); + aIPCResponse->statusText() = GetUnfilteredStatusText(); + UnfilteredHeaders()->ToIPC(aIPCResponse->headers(), + aIPCResponse->headersGuard()); + + nsCOMPtr body; + int64_t bodySize; + GetUnfilteredBody(getter_AddRefs(body), &bodySize); + + if (body) { + aAutoBodyStream.reset( + new mozilla::ipc::AutoIPCStream(aIPCResponse->body())); + DebugOnly ok = aAutoBodyStream->Serialize(body, aManager); + MOZ_ASSERT(ok); + } + + aIPCResponse->bodySize() = bodySize; + aIPCResponse->errorCode() = mErrorCode; + aIPCResponse->alternativeDataType() = GetAlternativeDataType(); + + nsCOMPtr alternativeBody = TakeAlternativeBody(); + if (alternativeBody) { + aAutoAlternativeBodyStream.reset( + new mozilla::ipc::AutoIPCStream(aIPCResponse->alternativeBody())); + DebugOnly ok = + aAutoAlternativeBodyStream->Serialize(alternativeBody, aManager); + MOZ_ASSERT(ok); + } + + aIPCResponse->channelInfo() = mChannelInfo.AsIPCChannelInfo(); + + if (mPrincipalInfo) { + aIPCResponse->principalInfo().emplace(*mPrincipalInfo); + } +} + already_AddRefed InternalResponse::Clone( CloneType aCloneType) { RefPtr clone = CreateIncompleteCopy(); diff --git a/dom/fetch/InternalResponse.h b/dom/fetch/InternalResponse.h index 408f18e02ec7..b1e1c81d899f 100644 --- a/dom/fetch/InternalResponse.h +++ b/dom/fetch/InternalResponse.h @@ -26,6 +26,7 @@ class AutoIPCStream; namespace dom { +class IPCInternalResponse; class InternalHeaders; class InternalResponse final { @@ -38,6 +39,15 @@ class InternalResponse final { uint16_t aStatus, const nsACString& aStatusText, RequestCredentials aCredentialsMode = RequestCredentials::Omit); + static RefPtr FromIPC( + const IPCInternalResponse& aIPCResponse); + + template + void ToIPC( + IPCInternalResponse* aIPCResponse, M* aManager, + UniquePtr& aAutoBodyStream, + UniquePtr& aAutoAlternativeBodyStream); + enum CloneType { eCloneInputStream, eDontCloneInputStream, @@ -211,6 +221,24 @@ class InternalResponse final { void SetPaddingSize(int64_t aPaddingSize); + void SetAlternativeDataType(const nsACString& aAltDataType) { + if (mWrappedResponse) { + return mWrappedResponse->SetAlternativeDataType(aAltDataType); + } + + MOZ_DIAGNOSTIC_ASSERT(mAlternativeDataType.IsEmpty()); + + mAlternativeDataType.Assign(aAltDataType); + } + + const nsCString& GetAlternativeDataType() { + if (mWrappedResponse) { + return mWrappedResponse->GetAlternativeDataType(); + } + + return mAlternativeDataType; + } + void SetAlternativeBody(nsIInputStream* aAlternativeBody) { if (mWrappedResponse) { return mWrappedResponse->SetAlternativeBody(aAlternativeBody); @@ -323,6 +351,7 @@ class InternalResponse final { RequestCredentials mCredentialsMode; // For alternative data such as JS Bytecode cached in the HTTP cache. + nsCString mAlternativeDataType; nsCOMPtr mAlternativeBody; nsMainThreadPtrHandle mCacheInfoChannel;