tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

DocumentChannelParent.cpp (6269B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set sw=2 ts=8 et tw=80 : */
      3 
      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/. */
      7 
      8 #include "DocumentChannelParent.h"
      9 
     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"
     16 
     17 extern mozilla::LazyLogModule gDocumentChannelLog;
     18 #define LOG(fmt) MOZ_LOG(gDocumentChannelLog, mozilla::LogLevel::Verbose, fmt)
     19 
     20 using namespace mozilla::dom;
     21 
     22 namespace mozilla {
     23 namespace net {
     24 
     25 DocumentChannelParent::DocumentChannelParent() {
     26  LOG(("DocumentChannelParent ctor [this=%p]", this));
     27 }
     28 
     29 DocumentChannelParent::~DocumentChannelParent() {
     30  LOG(("DocumentChannelParent dtor [this=%p]", this));
     31 }
     32 
     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);
     42  }
     43 
     44  ContentParent* contentParent =
     45      static_cast<ContentParent*>(Manager()->Manager());
     46 
     47  RefPtr<DocumentLoadListener::OpenPromise> promise;
     48  if (loadState->GetChannelInitialized()) {
     49    promise = DocumentLoadListener::ClaimParentLoad(
     50        getter_AddRefs(mDocumentLoadListener), loadState->GetLoadIdentifier(),
     51        Some(aArgs.channelId()));
     52  }
     53  if (!promise) {
     54    bool isDocumentLoad =
     55        aArgs.elementCreationArgs().type() ==
     56        DocumentChannelElementCreationArgs::TDocumentCreationArgs;
     57    mDocumentLoadListener = new DocumentLoadListener(aContext, isDocumentLoad);
     58 
     59    Maybe<ClientInfo> clientInfo;
     60    if (aArgs.initialClientInfo().isSome()) {
     61      clientInfo.emplace(ClientInfo(aArgs.initialClientInfo().ref()));
     62    }
     63 
     64    nsresult rv = NS_ERROR_UNEXPECTED;
     65 
     66    if (isDocumentLoad) {
     67      const DocumentCreationArgs& docArgs = aArgs.elementCreationArgs();
     68 
     69      promise = mDocumentLoadListener->OpenDocument(
     70          loadState, docArgs.loadFlags(), aArgs.cacheKey(),
     71          Some(aArgs.channelId()), aArgs.asyncOpenTime(), aArgs.timing(),
     72          std::move(clientInfo), docArgs.uriModified(),
     73          Some(docArgs.isEmbeddingBlockedError()), contentParent, &rv);
     74    } else {
     75      const ObjectCreationArgs& objectArgs = aArgs.elementCreationArgs();
     76 
     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);
     83    }
     84 
     85    if (NS_FAILED(rv)) {
     86      MOZ_ASSERT(!promise);
     87      return SendFailedAsyncOpen(rv);
     88    }
     89  }
     90 
     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;
    106      },
    107      [self](DocumentLoadListener::OpenPromiseFailedType&& aRejectValue) {
    108        if (self->CanSend()) {
    109          (void)self->SendDisconnectChildListeners(
    110              aRejectValue.mStatus, aRejectValue.mLoadGroupStatus,
    111              aRejectValue.mContinueNavigating);
    112        }
    113        self->mDocumentLoadListener = nullptr;
    114      });
    115 
    116  return true;
    117 }
    118 
    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__);
    128        }
    129 
    130        return ObjectUpgradePromise::CreateAndResolve(
    131            aValue.ResolveValue().get_canonical(), __func__);
    132      });
    133 }
    134 
    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__);
    143  }
    144 
    145  ContentParent* cp = static_cast<ContentParent*>(Manager()->Manager());
    146  nsTArray<EarlyHintConnectArgs> earlyHints;
    147  mDocumentLoadListener->RegisterEarlyHintLinksAndGetConnectArgs(cp->ChildID(),
    148                                                                 earlyHints);
    149 
    150  RedirectToRealChannelArgs args;
    151  mDocumentLoadListener->SerializeRedirectData(
    152      args, false, aRedirectFlags, aLoadFlags, std::move(earlyHints),
    153      aEarlyHintLinkType);
    154  return SendRedirectToRealChannel(args, std::move(aStreamFilterEndpoints));
    155 }
    156 
    157 }  // namespace net
    158 }  // namespace mozilla
    159 
    160 #undef LOG