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