Bug 1920487 - QM: Rename helpers for resolving nsresult type; r=dom-storage-reviewers...
[gecko.git] / netwerk / ipc / DocumentChannelParent.cpp
bloba9483f9055eaf84ed1ecae3cba443e14f5b8ac0c
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set sw=2 ts=8 et tw=80 : */
4 /* This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 #include "DocumentChannelParent.h"
10 #include "mozilla/dom/BrowserParent.h"
11 #include "mozilla/dom/CanonicalBrowsingContext.h"
12 #include "mozilla/dom/ClientInfo.h"
13 #include "mozilla/dom/ContentParent.h"
14 #include "mozilla/net/NeckoChannelParams.h"
15 #include "nsDocShellLoadState.h"
17 extern mozilla::LazyLogModule gDocumentChannelLog;
18 #define LOG(fmt) MOZ_LOG(gDocumentChannelLog, mozilla::LogLevel::Verbose, fmt)
20 using namespace mozilla::dom;
22 namespace mozilla {
23 namespace net {
25 DocumentChannelParent::DocumentChannelParent() {
26 LOG(("DocumentChannelParent ctor [this=%p]", this));
29 DocumentChannelParent::~DocumentChannelParent() {
30 LOG(("DocumentChannelParent dtor [this=%p]", this));
33 bool DocumentChannelParent::Init(dom::CanonicalBrowsingContext* aContext,
34 const DocumentChannelCreationArgs& aArgs) {
35 RefPtr<nsDocShellLoadState> loadState = aArgs.loadState();
36 LOG(("DocumentChannelParent Init [this=%p, uri=%s]", this,
37 loadState->URI()->GetSpecOrDefault().get()));
38 if (aArgs.parentInitiatedNavigationEpoch() <
39 aContext->GetParentInitiatedNavigationEpoch()) {
40 nsresult rv = NS_BINDING_ABORTED;
41 return SendFailedAsyncOpen(rv);
44 ContentParent* contentParent =
45 static_cast<ContentParent*>(Manager()->Manager());
47 RefPtr<DocumentLoadListener::OpenPromise> promise;
48 if (loadState->GetChannelInitialized()) {
49 promise = DocumentLoadListener::ClaimParentLoad(
50 getter_AddRefs(mDocumentLoadListener), loadState->GetLoadIdentifier(),
51 Some(aArgs.channelId()));
53 if (!promise) {
54 bool isDocumentLoad =
55 aArgs.elementCreationArgs().type() ==
56 DocumentChannelElementCreationArgs::TDocumentCreationArgs;
57 mDocumentLoadListener = new DocumentLoadListener(aContext, isDocumentLoad);
59 Maybe<ClientInfo> clientInfo;
60 if (aArgs.initialClientInfo().isSome()) {
61 clientInfo.emplace(ClientInfo(aArgs.initialClientInfo().ref()));
64 nsresult rv = NS_ERROR_UNEXPECTED;
66 if (isDocumentLoad) {
67 const DocumentCreationArgs& docArgs = aArgs.elementCreationArgs();
69 promise = mDocumentLoadListener->OpenDocument(
70 loadState, aArgs.cacheKey(), Some(aArgs.channelId()),
71 aArgs.asyncOpenTime(), aArgs.timing(), std::move(clientInfo),
72 docArgs.uriModified(), Some(docArgs.isEmbeddingBlockedError()),
73 contentParent, &rv);
74 } else {
75 const ObjectCreationArgs& objectArgs = aArgs.elementCreationArgs();
77 promise = mDocumentLoadListener->OpenObject(
78 loadState, aArgs.cacheKey(), Some(aArgs.channelId()),
79 aArgs.asyncOpenTime(), aArgs.timing(), std::move(clientInfo),
80 objectArgs.embedderInnerWindowId(), objectArgs.loadFlags(),
81 objectArgs.contentPolicyType(), objectArgs.isUrgentStart(),
82 contentParent, this /* ObjectUpgradeHandler */, &rv);
85 if (NS_FAILED(rv)) {
86 MOZ_ASSERT(!promise);
87 return SendFailedAsyncOpen(rv);
91 RefPtr<DocumentChannelParent> self = this;
92 promise->Then(
93 GetCurrentSerialEventTarget(), __func__,
94 [self](DocumentLoadListener::OpenPromiseSucceededType&& aResolveValue) {
95 // The DLL is waiting for us to resolve the
96 // PDocumentChannel::RedirectToRealChannelPromise given as parameter.
97 auto promise = self->RedirectToRealChannel(
98 std::move(aResolveValue.mStreamFilterEndpoints),
99 aResolveValue.mRedirectFlags, aResolveValue.mLoadFlags,
100 aResolveValue.mEarlyHintLinkType);
101 // We chain the promise the DLL is waiting on to the one returned by
102 // RedirectToRealChannel. As soon as the promise returned is resolved
103 // or rejected, so will the DLL's promise.
104 promise->ChainTo(aResolveValue.mPromise.forget(), __func__);
105 self->mDocumentLoadListener = nullptr;
107 [self](DocumentLoadListener::OpenPromiseFailedType&& aRejectValue) {
108 if (self->CanSend()) {
109 Unused << self->SendDisconnectChildListeners(
110 aRejectValue.mStatus, aRejectValue.mLoadGroupStatus,
111 aRejectValue.mContinueNavigating);
113 self->mDocumentLoadListener = nullptr;
116 return true;
119 auto DocumentChannelParent::UpgradeObjectLoad()
120 -> RefPtr<ObjectUpgradePromise> {
121 return SendUpgradeObjectLoad()->Then(
122 GetCurrentSerialEventTarget(), __func__,
123 [](const UpgradeObjectLoadPromise::ResolveOrRejectValue& aValue) {
124 if (!aValue.IsResolve() || aValue.ResolveValue().IsNullOrDiscarded()) {
125 LOG(("DocumentChannelParent object load upgrade failed"));
126 return ObjectUpgradePromise::CreateAndReject(NS_ERROR_FAILURE,
127 __func__);
130 return ObjectUpgradePromise::CreateAndResolve(
131 aValue.ResolveValue().get_canonical(), __func__);
135 RefPtr<PDocumentChannelParent::RedirectToRealChannelPromise>
136 DocumentChannelParent::RedirectToRealChannel(
137 nsTArray<ipc::Endpoint<extensions::PStreamFilterParent>>&&
138 aStreamFilterEndpoints,
139 uint32_t aRedirectFlags, uint32_t aLoadFlags, uint32_t aEarlyHintLinkType) {
140 if (!CanSend()) {
141 return PDocumentChannelParent::RedirectToRealChannelPromise::
142 CreateAndReject(ResponseRejectReason::ChannelClosed, __func__);
145 ContentParent* cp = static_cast<ContentParent*>(Manager()->Manager());
146 nsTArray<EarlyHintConnectArgs> earlyHints;
147 mDocumentLoadListener->RegisterEarlyHintLinksAndGetConnectArgs(cp->ChildID(),
148 earlyHints);
150 RedirectToRealChannelArgs args;
151 mDocumentLoadListener->SerializeRedirectData(
152 args, false, aRedirectFlags, aLoadFlags, std::move(earlyHints),
153 aEarlyHintLinkType);
154 return SendRedirectToRealChannel(args, std::move(aStreamFilterEndpoints));
157 } // namespace net
158 } // namespace mozilla
160 #undef LOG