tor-browser

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

nsAsyncRedirectVerifyHelper.h (3581B)


      1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 #ifndef nsAsyncRedirectVerifyHelper_h
      7 #define nsAsyncRedirectVerifyHelper_h
      8 
      9 #include "nsIRunnable.h"
     10 #include "nsIChannelEventSink.h"
     11 #include "nsIAsyncVerifyRedirectCallback.h"
     12 #include "nsINamed.h"
     13 #include "nsCOMPtr.h"
     14 #include "nsCycleCollectionParticipant.h"
     15 
     16 class nsIChannel;
     17 
     18 namespace mozilla {
     19 namespace net {
     20 
     21 /**
     22 * This class simplifies call of OnChannelRedirect of IOService and
     23 * the sink bound with the channel being redirected while the result of
     24 * redirect decision is returned through the callback.
     25 */
     26 class nsAsyncRedirectVerifyHelper final
     27    : public nsIRunnable,
     28      public nsINamed,
     29      public nsIAsyncVerifyRedirectCallback {
     30  NS_DECL_THREADSAFE_ISUPPORTS
     31  NS_DECL_NSIRUNNABLE
     32  NS_DECL_NSINAMED
     33  NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK
     34 
     35 public:
     36  nsAsyncRedirectVerifyHelper() = default;
     37 
     38  /*
     39   * Calls AsyncOnChannelRedirect() on the given sink with the given
     40   * channels and flags. Keeps track of number of async callbacks to expect.
     41   */
     42  nsresult DelegateOnChannelRedirect(nsIChannelEventSink* sink,
     43                                     nsIChannel* oldChannel,
     44                                     nsIChannel* newChannel, uint32_t flags);
     45 
     46  /**
     47   * Initialize and run the chain of AsyncOnChannelRedirect calls. OldChannel
     48   * is QI'ed for nsIAsyncVerifyRedirectCallback. The result of the redirect
     49   * decision is passed through this interface back to the oldChannel.
     50   *
     51   * @param oldChan
     52   *    channel being redirected, MUST implement
     53   *    nsIAsyncVerifyRedirectCallback
     54   * @param newChan
     55   *    target of the redirect channel
     56   * @param flags
     57   *    redirect flags
     58   * @param mainThreadEventTarget
     59   *    a labeled event target for dispatching runnables
     60   * @param synchronize
     61   *    set to TRUE if you want the Init method wait synchronously for
     62   *    all redirect callbacks
     63   */
     64  nsresult Init(nsIChannel* oldChan, nsIChannel* newChan, uint32_t flags,
     65                nsIEventTarget* mainThreadEventTarget,
     66                bool synchronize = false);
     67 
     68 protected:
     69  nsCOMPtr<nsIChannel> mOldChan;
     70  nsCOMPtr<nsIChannel> mNewChan;
     71  uint32_t mFlags{0};
     72  bool mWaitingForRedirectCallback{false};
     73  nsCOMPtr<nsIEventTarget> mCallbackEventTarget;
     74  bool mCallbackInitiated{false};
     75  int32_t mExpectedCallbacks{0};
     76  nsresult mResult{NS_OK};  // value passed to callback
     77 
     78  void InitCallback();
     79 
     80  /**
     81   * Calls back to |oldChan| as described in Init()
     82   */
     83  void ExplicitCallback(nsresult result);
     84 
     85 private:
     86  ~nsAsyncRedirectVerifyHelper();
     87 
     88  bool IsOldChannelCanceled();
     89 };
     90 
     91 /*
     92 * Helper to make the call-stack handle some control-flow for us
     93 */
     94 class nsAsyncRedirectAutoCallback {
     95 public:
     96  explicit nsAsyncRedirectAutoCallback(
     97      nsIAsyncVerifyRedirectCallback* aCallback)
     98      : mCallback(aCallback) {
     99    mResult = NS_OK;
    100  }
    101  ~nsAsyncRedirectAutoCallback() {
    102    if (mCallback) mCallback->OnRedirectVerifyCallback(mResult);
    103  }
    104  /*
    105   * Call this is you want it to call back with a different result-code
    106   */
    107  void SetResult(nsresult aRes) { mResult = aRes; }
    108  /*
    109   * Call this is you want to avoid the callback
    110   */
    111  void DontCallback() { mCallback = nullptr; }
    112 
    113 private:
    114  nsIAsyncVerifyRedirectCallback* mCallback;
    115  nsresult mResult;
    116 };
    117 
    118 }  // namespace net
    119 }  // namespace mozilla
    120 #endif