Merge mozilla-central to autoland. CLOSED TREE
[gecko.git] / netwerk / base / nsPACMan.h
blobdd7d6edb8c366f1f47aa59d30f1161414e94ce45
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef nsPACMan_h__
8 #define nsPACMan_h__
10 #include "mozilla/Atomics.h"
11 #include "mozilla/Attributes.h"
12 #include "mozilla/DataMutex.h"
13 #include "mozilla/LinkedList.h"
14 #include "mozilla/Logging.h"
15 #include "mozilla/net/NeckoTargetHolder.h"
16 #include "mozilla/TimeStamp.h"
17 #include "nsCOMPtr.h"
18 #include "nsIChannelEventSink.h"
19 #include "nsIInterfaceRequestor.h"
20 #include "nsIStreamLoader.h"
21 #include "nsThreadUtils.h"
22 #include "nsIURI.h"
23 #include "nsString.h"
24 #include "ProxyAutoConfig.h"
26 class nsISystemProxySettings;
27 class nsIDHCPClient;
28 class nsIThread;
30 namespace mozilla {
31 namespace net {
33 class nsPACMan;
34 class WaitForThreadShutdown;
36 /**
37 * This class defines a callback interface used by AsyncGetProxyForURI.
39 class NS_NO_VTABLE nsPACManCallback : public nsISupports {
40 public:
41 /**
42 * This method is invoked on the same thread that called AsyncGetProxyForURI.
44 * @param status
45 * This parameter indicates whether or not the PAC query succeeded.
46 * @param pacString
47 * This parameter holds the value of the PAC string. It is empty when
48 * status is a failure code.
49 * @param newPACURL
50 * This parameter holds the URL of a new PAC file that should be loaded
51 * before the query is evaluated again. At least one of pacString and
52 * newPACURL should be 0 length.
54 virtual void OnQueryComplete(nsresult status, const nsACString& pacString,
55 const nsACString& newPACURL) = 0;
58 class PendingPACQuery final : public Runnable,
59 public LinkedListElement<PendingPACQuery> {
60 public:
61 PendingPACQuery(nsPACMan* pacMan, nsIURI* uri, nsPACManCallback* callback,
62 uint32_t flags, bool mainThreadResponse);
64 // can be called from either thread
65 void Complete(nsresult status, const nsACString& pacString);
66 void UseAlternatePACFile(const nsACString& pacURL);
68 nsCString mSpec;
69 nsCString mScheme;
70 nsCString mHost;
71 int32_t mPort;
72 uint32_t mFlags;
74 NS_IMETHOD Run(void) override; /* Runnable */
76 private:
77 nsPACMan* mPACMan; // weak reference
79 private:
80 RefPtr<nsPACManCallback> mCallback;
81 bool mOnMainThreadOnly;
84 /**
85 * This class provides an abstraction layer above the PAC thread. The methods
86 * defined on this class are intended to be called on the main thread only.
89 class nsPACMan final : public nsIStreamLoaderObserver,
90 public nsIInterfaceRequestor,
91 public nsIChannelEventSink,
92 public NeckoTargetHolder {
93 public:
94 NS_DECL_THREADSAFE_ISUPPORTS
96 explicit nsPACMan(nsISerialEventTarget* mainThreadEventTarget);
98 /**
99 * This method may be called to shutdown the PAC manager. Any async queries
100 * that have not yet completed will either finish normally or be canceled by
101 * the time this method returns.
103 void Shutdown();
106 * This method queries a PAC result asynchronously. The callback runs on the
107 * calling thread. If the PAC file has not yet been loaded, then this method
108 * will queue up the request, and complete it once the PAC file has been
109 * loaded.
111 * @param uri
112 * The URI to query.
113 * @param callback
114 * The callback to run once the PAC result is available.
115 * @param flags
116 * A bit-wise combination of the RESOLVE_ flags defined above. Pass
117 * 0 to specify the default behavior.
118 * @param mustCallbackOnMainThread
119 * If set to false the callback can be made from the PAC thread
121 nsresult AsyncGetProxyForURI(nsIURI* uri, nsPACManCallback* callback,
122 uint32_t flags, bool mainThreadResponse);
125 * This method may be called to reload the PAC file. While we are loading
126 * the PAC file, any asynchronous PAC queries will be queued up to be
127 * processed once the PAC file finishes loading.
129 * @param aSpec
130 * The non normalized uri spec of this URI used for comparison with
131 * system proxy settings to determine if the PAC uri has changed.
133 nsresult LoadPACFromURI(const nsACString& aSpec);
136 * Returns true if we are currently loading the PAC file.
138 bool IsLoading() {
139 auto loader = mLoader.Lock();
140 return loader.ref() != nullptr;
144 * Returns true if the given URI matches the URI of our PAC file or the
145 * URI it has been redirected to. In the case of a chain of redirections
146 * only the current one being followed and the original are considered
147 * becuase this information is used, respectively, to determine if we
148 * should bypass the proxy (to fetch the pac file) or if the pac
149 * configuration has changed (and we should reload the pac file)
151 bool IsPACURI(const nsACString& spec) {
152 return mPACURISpec.Equals(spec) || mPACURIRedirectSpec.Equals(spec) ||
153 mNormalPACURISpec.Equals(spec);
156 bool IsPACURI(nsIURI* uri) {
157 if (mPACURISpec.IsEmpty() && mPACURIRedirectSpec.IsEmpty()) {
158 return false;
161 nsAutoCString tmp;
162 nsresult rv = uri->GetSpec(tmp);
163 if (NS_FAILED(rv)) {
164 return false;
167 return IsPACURI(tmp);
170 bool IsUsingWPAD() { return mAutoDetect; }
172 nsresult Init(nsISystemProxySettings*);
173 static nsPACMan* sInstance;
175 // PAC thread operations only
176 void ProcessPendingQ();
177 void CancelPendingQ(nsresult, bool aShutdown);
179 void SetWPADOverDHCPEnabled(bool aValue) { mWPADOverDHCPEnabled = aValue; }
181 private:
182 NS_DECL_NSISTREAMLOADEROBSERVER
183 NS_DECL_NSIINTERFACEREQUESTOR
184 NS_DECL_NSICHANNELEVENTSINK
186 friend class PendingPACQuery;
187 friend class PACLoadComplete;
188 friend class ConfigureWPADComplete;
189 friend class ExecutePACThreadAction;
190 friend class WaitForThreadShutdown;
191 friend class TestPACMan;
193 ~nsPACMan();
196 * Cancel any existing load if any.
198 void CancelExistingLoad();
201 * Start loading the PAC file.
203 void StartLoading();
206 * Continue loading the PAC file.
208 void ContinueLoadingAfterPACUriKnown();
211 * This method may be called to reload the PAC file. While we are loading
212 * the PAC file, any asynchronous PAC queries will be queued up to be
213 * processed once the PAC file finishes loading.
215 * @param aSpec
216 * The non normalized uri spec of this URI used for comparison with
217 * system proxy settings to determine if the PAC uri has changed.
218 * @param aResetLoadFailureCount
219 * A flag saying whether the exponential back-off for attempting to
220 * reload the PAC should be reset.
222 nsresult LoadPACFromURI(const nsACString& aSpec, bool aResetLoadFailureCount);
225 * Reload the PAC file if there is reason to.
227 void MaybeReloadPAC();
230 * Called when we fail to load the PAC file.
232 void OnLoadFailure();
235 * PostQuery() only runs on the PAC thread and it is used to
236 * place a pendingPACQuery into the queue and potentially
237 * execute the queue if it was otherwise empty
239 nsresult PostQuery(PendingPACQuery* query);
241 // Having found the PAC URI on the PAC thread, copy it to a string which
242 // can be altered on the main thread.
243 void AssignPACURISpec(const nsACString& aSpec);
245 // PAC thread operations only
246 void PostProcessPendingQ();
247 void PostCancelPendingQ(nsresult, bool aShutdown = false);
248 bool ProcessPending();
249 nsresult GetPACFromDHCP(nsACString& aSpec);
250 nsresult ConfigureWPAD(nsACString& aSpec);
252 private:
254 * Dispatches a runnable to the PAC processing thread. Handles lazy
255 * instantiation of the thread.
257 * @param aEvent The event to disptach.
258 * @param aSync Whether or not this should be synchronous dispatch.
260 nsresult DispatchToPAC(already_AddRefed<nsIRunnable> aEvent,
261 bool aSync = false);
263 UniquePtr<ProxyAutoConfigBase> mPAC;
264 nsCOMPtr<nsIThread> mPACThread;
265 nsCOMPtr<nsISystemProxySettings> mSystemProxySettings;
266 nsCOMPtr<nsIDHCPClient> mDHCPClient;
268 LinkedList<PendingPACQuery> mPendingQ; /* pac thread only */
270 // These specs are not nsIURI so that they can be used off the main thread.
271 // The non-normalized versions are directly from the configuration, the
272 // normalized version has been extracted from an nsIURI
273 nsCString mPACURISpec;
274 nsCString mPACURIRedirectSpec;
275 nsCString mNormalPACURISpec;
277 DataMutex<nsCOMPtr<nsIStreamLoader>> mLoader;
278 bool mLoadPending;
279 Atomic<bool, Relaxed> mShutdown;
280 TimeStamp mScheduledReload;
281 Atomic<uint32_t, Relaxed> mLoadFailureCount;
283 bool mInProgress;
284 bool mIncludePath;
285 bool mAutoDetect;
286 bool mWPADOverDHCPEnabled;
287 int32_t mProxyConfigType;
290 extern LazyLogModule gProxyLog;
292 } // namespace net
293 } // namespace mozilla
295 #endif // nsPACMan_h__