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