tor-browser

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

HttpChannelParent.h (14344B)


      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 #ifndef mozilla_net_HttpChannelParent_h
      9 #define mozilla_net_HttpChannelParent_h
     10 
     11 #include "HttpBaseChannel.h"
     12 #include "nsHttp.h"
     13 #include "mozilla/net/PHttpChannelParent.h"
     14 #include "mozilla/net/NeckoCommon.h"
     15 #include "mozilla/net/NeckoParent.h"
     16 #include "mozilla/MozPromise.h"
     17 #include "nsIParentRedirectingChannel.h"
     18 #include "nsIProgressEventSink.h"
     19 #include "nsIChannelEventSink.h"
     20 #include "nsIRedirectResultListener.h"
     21 #include "nsHttpChannel.h"
     22 #include "mozilla/dom/ipc/IdType.h"
     23 #include "nsIMultiPartChannel.h"
     24 #include "nsIURI.h"
     25 
     26 class nsICacheEntry;
     27 
     28 #define HTTP_CHANNEL_PARENT_IID \
     29  {0x982b2372, 0x7aa5, 0x4e8a, {0xbd, 0x9f, 0x89, 0x74, 0xd7, 0xf0, 0x58, 0xeb}}
     30 
     31 namespace mozilla {
     32 
     33 namespace dom {
     34 class BrowserParent;
     35 }  // namespace dom
     36 
     37 namespace net {
     38 
     39 class HttpBackgroundChannelParent;
     40 class ParentChannelListener;
     41 class ChannelEventQueue;
     42 class CacheEntryWriteHandleParent;
     43 
     44 class HttpChannelParent final : public nsIInterfaceRequestor,
     45                                public PHttpChannelParent,
     46                                public nsIParentRedirectingChannel,
     47                                public nsIProgressEventSink,
     48                                public HttpChannelSecurityWarningReporter,
     49                                public nsIAsyncVerifyRedirectReadyCallback,
     50                                public nsIChannelEventSink,
     51                                public nsIRedirectResultListener,
     52                                public nsIMultiPartChannelListener {
     53  virtual ~HttpChannelParent();
     54 
     55 public:
     56  NS_DECL_ISUPPORTS
     57  NS_DECL_NSIREQUESTOBSERVER
     58  NS_DECL_NSISTREAMLISTENER
     59  NS_DECL_NSIPARENTCHANNEL
     60  NS_DECL_NSIPARENTREDIRECTINGCHANNEL
     61  NS_DECL_NSIPROGRESSEVENTSINK
     62  NS_DECL_NSIINTERFACEREQUESTOR
     63  NS_DECL_NSIASYNCVERIFYREDIRECTREADYCALLBACK
     64  NS_DECL_NSICHANNELEVENTSINK
     65  NS_DECL_NSIREDIRECTRESULTLISTENER
     66  NS_DECL_NSIMULTIPARTCHANNELLISTENER
     67 
     68  NS_INLINE_DECL_STATIC_IID(HTTP_CHANNEL_PARENT_IID)
     69 
     70  HttpChannelParent(dom::BrowserParent* iframeEmbedding,
     71                    nsILoadContext* aLoadContext,
     72                    PBOverrideStatus aOverrideStatus);
     73 
     74  [[nodiscard]] bool Init(const HttpChannelCreationArgs& aArgs);
     75 
     76  // Forwarded to nsHttpChannel::SetApplyConversion.
     77  void SetApplyConversion(bool aApplyConversion) {
     78    if (mChannel) {
     79      mChannel->SetApplyConversion(aApplyConversion);
     80    }
     81  }
     82 
     83  [[nodiscard]] nsresult OpenAlternativeOutputStream(
     84      const nsACString& type, int64_t predictedSize,
     85      nsIAsyncOutputStream** _retval);
     86 
     87  [[nodiscard]] CacheEntryWriteHandleParent* AllocCacheEntryWriteHandle();
     88 
     89  // Callbacks for each asynchronous tasks required in AsyncOpen
     90  // procedure, will call InvokeAsyncOpen when all the expected
     91  // tasks is finished successfully or when any failure happened.
     92  // @see mAsyncOpenBarrier.
     93  void TryInvokeAsyncOpen(nsresult aRv);
     94 
     95  void InvokeAsyncOpen(nsresult rv);
     96 
     97  void InvokeEarlyHintPreloader(nsresult rv, uint64_t aEarlyHintPreloaderId);
     98 
     99  // Calls SendSetPriority if mIPCClosed is false.
    100  void DoSendSetPriority(int16_t aValue);
    101 
    102  // Calls SendReportLNAToConsole if mIPCClosed is false.
    103  void DoSendReportLNAToConsole(const NetAddr& aPeerAddr,
    104                                const nsACString& aMessageType,
    105                                const nsACString& aPromptAction,
    106                                const nsACString& aTopLevelSite);
    107 
    108  // Callback while background channel is ready.
    109  void OnBackgroundParentReady(HttpBackgroundChannelParent* aBgParent);
    110  // Callback while background channel is destroyed.
    111  void OnBackgroundParentDestroyed();
    112 
    113  base::ProcessId OtherPid() const;
    114 
    115  // Inform the child actor that our referrer info was modified late during
    116  // BeginConnect.
    117  void OverrideReferrerInfoDuringBeginConnect(nsIReferrerInfo* aReferrerInfo);
    118 
    119  // Set the cookie changes triggered by the channel, which will be applied by
    120  // the child actor during PHttpBackgroundChannel::OnStartRequest. Note that
    121  // CookieService also sends the information to all actors via PContent, a main
    122  // thread IPC, which could be slower than background IPC
    123  // PHttpBackgroundChannel::OnStartRequest.
    124  void SetCookieChanges(nsTArray<CookieChange>&& aCookieChanges);
    125 
    126  using ChildEndpointPromise =
    127      MozPromise<ipc::Endpoint<extensions::PStreamFilterChild>, bool, true>;
    128  [[nodiscard]] RefPtr<ChildEndpointPromise> AttachStreamFilter(
    129      Endpoint<extensions::PStreamFilterParent>&& aParentEndpoint,
    130      Endpoint<extensions::PStreamFilterChild>&& aChildEndpoint);
    131  [[nodiscard]] RefPtr<GenericPromise> DetachStreamFilters();
    132 
    133  // Should only be called from EarlyHintPreloader. mChannel should be null at
    134  // the point of calling. Sets mChannel to aChannel. Used by the
    135  // EarlyHintPreloader to redirect the channel to this parent as soon as the
    136  // final channel becomes available after all http redirects.
    137  void SetHttpChannelFromEarlyHintPreloader(HttpBaseChannel* aChannel);
    138 
    139 protected:
    140  // used to connect redirected-to channel in parent with just created
    141  // ChildChannel.  Used during redirects.
    142  [[nodiscard]] bool ConnectChannel(const uint32_t& registrarId);
    143 
    144  [[nodiscard]] bool DoAsyncOpen(
    145      nsIURI* uri, nsIURI* originalUri, nsIURI* docUri,
    146      nsIReferrerInfo* aReferrerInfo, nsIURI* aAPIRedirectToURI,
    147      nsIURI* topWindowUri, const uint32_t& loadFlags,
    148      const RequestHeaderTuples& requestHeaders, const nsCString& requestMethod,
    149      const Maybe<IPCStream>& uploadStream, const bool& uploadStreamHasHeaders,
    150      const int16_t& priority, const ClassOfService& classOfService,
    151      const uint8_t& redirectionLimit, const bool& allowSTS,
    152      const uint32_t& thirdPartyFlags, const bool& doResumeAt,
    153      const uint64_t& startPos, const nsCString& entityID,
    154      const bool& allowSpdy, const bool& allowHttp3, const bool& allowAltSvc,
    155      const bool& beConservative, const bool& bypassProxy,
    156      const uint32_t& tlsFlags, const LoadInfoArgs& aLoadInfoArgs,
    157      const uint32_t& aCacheKey, const uint64_t& aRequestContextID,
    158      const Maybe<CorsPreflightArgs>& aCorsPreflightArgs,
    159      const uint32_t& aInitialRwin, const bool& aBlockAuthPrompt,
    160      const bool& aAllowStaleCacheContent,
    161      const bool& aPreferCacheLoadOverBypass, const nsCString& aContentTypeHint,
    162      const dom::RequestMode& aRequestMode, const uint32_t& aRedirectMode,
    163      const uint64_t& aChannelId, const uint64_t& aContentWindowId,
    164      const nsTArray<PreferredAlternativeDataTypeParams>&
    165          aPreferredAlternativeTypes,
    166      const uint64_t& aBrowserId, const TimeStamp& aLaunchServiceWorkerStart,
    167      const TimeStamp& aLaunchServiceWorkerEnd,
    168      const TimeStamp& aDispatchFetchEventStart,
    169      const TimeStamp& aDispatchFetchEventEnd,
    170      const TimeStamp& aHandleFetchEventStart,
    171      const TimeStamp& aHandleFetchEventEnd,
    172      const bool& aForceMainDocumentChannel,
    173      const TimeStamp& aNavigationStartTimeStamp,
    174      const uint64_t& aEarlyHintPreloaderId,
    175      const nsAString& aClassicScriptHintCharset,
    176      const nsAString& aDocumentCharacterSet,
    177      const bool& aIsUserAgentHeaderModified, const nsString& aInitiatorType);
    178 
    179  virtual mozilla::ipc::IPCResult RecvSetPriority(
    180      const int16_t& priority) override;
    181  virtual mozilla::ipc::IPCResult RecvSetClassOfService(
    182      const ClassOfService& cos) override;
    183  virtual mozilla::ipc::IPCResult RecvSuspend() override;
    184  virtual mozilla::ipc::IPCResult RecvResume() override;
    185  virtual mozilla::ipc::IPCResult RecvCancel(
    186      const nsresult& status, const uint32_t& requestBlockingReason,
    187      const nsACString& reason,
    188      const mozilla::Maybe<nsCString>& logString) override;
    189  virtual mozilla::ipc::IPCResult RecvRedirect2Verify(
    190      const nsresult& result, const RequestHeaderTuples& changedHeaders,
    191      const uint32_t& aSourceRequestBlockingReason,
    192      const Maybe<ChildLoadInfoForwarderArgs>& aTargetLoadInfoForwarder,
    193      const uint32_t& loadFlags, nsIReferrerInfo* aReferrerInfo,
    194      nsIURI* apiRedirectUri,
    195      const Maybe<CorsPreflightArgs>& aCorsPreflightArgs) override;
    196  virtual mozilla::ipc::IPCResult RecvDocumentChannelCleanup(
    197      const bool& clearCacheEntry) override;
    198  virtual mozilla::ipc::IPCResult RecvRemoveCorsPreflightCacheEntry(
    199      nsIURI* uri, const mozilla::ipc::PrincipalInfo& requestingPrincipal,
    200      const OriginAttributes& originAttributes) override;
    201  virtual mozilla::ipc::IPCResult RecvSetCookies(
    202      const nsACString& aBaseDomain, const OriginAttributes& aOriginAttributes,
    203      nsIURI* aHost, const bool& aFromHttp, const bool& aIsThirdParty,
    204      nsTArray<CookieStruct>&& aCookies) override;
    205  virtual mozilla::ipc::IPCResult RecvBytesRead(const int32_t& aCount) override;
    206  virtual mozilla::ipc::IPCResult RecvOpenOriginalCacheInputStream() override;
    207  virtual void ActorDestroy(ActorDestroyReason why) override;
    208 
    209  friend class ParentChannelListener;
    210  RefPtr<mozilla::dom::BrowserParent> mBrowserParent;
    211 
    212  [[nodiscard]] nsresult ReportSecurityMessage(
    213      const nsAString& aMessageTag, const nsAString& aMessageCategory) override;
    214  nsresult LogBlockedCORSRequest(const nsAString& aMessage,
    215                                 const nsACString& aCategory,
    216                                 bool aIsWarning = false) override;
    217  nsresult LogMimeTypeMismatch(const nsACString& aMessageName, bool aWarning,
    218                               const nsAString& aURL,
    219                               const nsAString& aContentType) override;
    220 
    221  // Calls SendDeleteSelf and sets mIPCClosed to true because we should not
    222  // send any more messages after that. Bug 1274886
    223  [[nodiscard]] bool DoSendDeleteSelf();
    224  // Called to notify the parent channel to not send any more IPC messages.
    225  virtual mozilla::ipc::IPCResult RecvDeletingChannel() override;
    226 
    227 private:
    228  already_AddRefed<nsITransportSecurityInfo> SecurityInfo();
    229 
    230  // final step for Redirect2Verify procedure, will be invoked while both
    231  // redirecting and redirected channel are ready or any error happened.
    232  // OnRedirectVerifyCallback will be invoked for finishing the async
    233  // redirect verification procedure.
    234  void ContinueRedirect2Verify(const nsresult& aResult);
    235 
    236  void AsyncOpenFailed(nsresult aRv);
    237 
    238  // Request to pair with a HttpBackgroundChannelParent with the same channel
    239  // id, a promise will be returned so the caller can append callbacks on it.
    240  // If called multiple times before mBgParent is available, the same promise
    241  // will be returned and the callbacks will be invoked in order.
    242  [[nodiscard]] RefPtr<GenericNonExclusivePromise> WaitForBgParent(
    243      uint64_t aChannelId);
    244 
    245  // Remove the association with background channel after main-thread IPC
    246  // is about to be destroyed or no further event is going to be sent, i.e.,
    247  // DocumentChannelCleanup.
    248  void CleanupBackgroundChannel();
    249 
    250  // Check if the channel needs to enable the flow control on the IPC channel.
    251  // That is, we may suspend the channel if the ODA-s to child process are not
    252  // consumed quickly enough. Otherwise, memory explosion could happen.
    253  bool NeedFlowControl();
    254 
    255  // Get the appropriate event target for background parent operations based on
    256  // channel's class of service flags: synchronous event target for urgent
    257  // channels, queued for others to balance responsiveness and prevent
    258  // head-of-line blocking.
    259  nsCOMPtr<nsISerialEventTarget> GetEventTargetForBgParentWait();
    260 
    261  bool IsRedirectDueToAuthRetry(uint32_t redirectFlags);
    262 
    263  int32_t mSendWindowSize;
    264 
    265  friend class HttpBackgroundChannelParent;
    266 
    267  uint64_t mEarlyHintPreloaderId{};
    268 
    269  RefPtr<HttpBaseChannel> mChannel;
    270  nsCOMPtr<nsICacheEntry> mCacheEntry;
    271 
    272  nsCOMPtr<nsIChannel> mRedirectChannel;
    273  nsCOMPtr<nsIAsyncVerifyRedirectCallback> mRedirectCallback;
    274 
    275  nsCOMPtr<nsILoadContext> mLoadContext;
    276  RefPtr<nsHttpHandler> mHttpHandler;
    277 
    278  RefPtr<ParentChannelListener> mParentListener;
    279 
    280  RefPtr<ChannelEventQueue> mEventQ;
    281 
    282  RefPtr<HttpBackgroundChannelParent> mBgParent;
    283 
    284  MozPromiseHolder<GenericNonExclusivePromise> mPromise;
    285  MozPromiseRequestHolder<GenericNonExclusivePromise> mRequest;
    286 
    287  // To calculate the delay caused by the e10s back-pressure suspension
    288  TimeStamp mResumedTimestamp;
    289 
    290  Atomic<bool> mIPCClosed;  // PHttpChannel actor has been Closed()
    291 
    292  // Corresponding redirect channel registrar Id. 0 means redirection is not
    293  // started.
    294  uint64_t mRedirectChannelId = 0;
    295 
    296  PBOverrideStatus mPBOverride;
    297 
    298  // Set to the canceled status value if the main channel was canceled.
    299  nsresult mStatus;
    300 
    301  // The referrer info, set during nsHttpChannel::BeginConnect, to override the
    302  // original one. This info will be sent in OnStartRequest.
    303  nsCOMPtr<nsIReferrerInfo> mOverrideReferrerInfo;
    304 
    305  // The cookie changes received while processing the Set-Cookie header. This
    306  // info will be sent in OnStartRequest.
    307  nsTArray<CookieChange> mCookieChanges;
    308 
    309  // OnStatus is always called before OnProgress.
    310  // Set true in OnStatus if next OnProgress can be ignored
    311  // since the information can be recontructed from ODA.
    312  uint8_t mIgnoreProgress : 1;
    313 
    314  uint8_t mHasSuspendedByBackPressure : 1;
    315 
    316  // Set if we get the result of and cache |mNeedFlowControl|
    317  uint8_t mCacheNeedFlowControlInitialized : 1;
    318  uint8_t mNeedFlowControl : 1;
    319  uint8_t mSuspendedForFlowControl : 1;
    320 
    321  // Defaults to false. Is set to true at the begining of OnStartRequest.
    322  // Used to ensure methods can't be called before OnStartRequest.
    323  uint8_t mAfterOnStartRequestBegun : 1;
    324 
    325  // Number of events to wait before actually invoking AsyncOpen on the main
    326  // channel. For each asynchronous step required before InvokeAsyncOpen, should
    327  // increase 1 to mAsyncOpenBarrier and invoke TryInvokeAsyncOpen after
    328  // finished. This attribute is main thread only.
    329  uint8_t mAsyncOpenBarrier = 0;
    330 
    331  // When true, ODAs are sent from the socket process to the child process
    332  // directly.
    333  uint8_t mDataSentToChildProcess : 1;
    334 };
    335 
    336 }  // namespace net
    337 }  // namespace mozilla
    338 
    339 #endif  // mozilla_net_HttpChannelParent_h