netwerk/base/src/nsPACMan.h

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:1da802bc7b7a
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/. */
6
7 #ifndef nsPACMan_h__
8 #define nsPACMan_h__
9
10 #include "nsIStreamLoader.h"
11 #include "nsIInterfaceRequestor.h"
12 #include "nsIChannelEventSink.h"
13 #include "ProxyAutoConfig.h"
14 #include "nsThreadUtils.h"
15 #include "nsIURI.h"
16 #include "nsCOMPtr.h"
17 #include "nsString.h"
18 #include "mozilla/Attributes.h"
19 #include "mozilla/LinkedList.h"
20 #include "nsAutoPtr.h"
21 #include "mozilla/TimeStamp.h"
22 #include "prlog.h"
23
24 class nsPACMan;
25 class nsISystemProxySettings;
26 class nsIThread;
27 class WaitForThreadShutdown;
28
29 /**
30 * This class defines a callback interface used by AsyncGetProxyForChannel.
31 */
32 class NS_NO_VTABLE nsPACManCallback : public nsISupports
33 {
34 public:
35 /**
36 * This method is invoked on the same thread that called AsyncGetProxyForChannel.
37 *
38 * @param status
39 * This parameter indicates whether or not the PAC query succeeded.
40 * @param pacString
41 * This parameter holds the value of the PAC string. It is empty when
42 * status is a failure code.
43 * @param newPACURL
44 * This parameter holds the URL of a new PAC file that should be loaded
45 * before the query is evaluated again. At least one of pacString and
46 * newPACURL should be 0 length.
47 */
48 virtual void OnQueryComplete(nsresult status,
49 const nsCString &pacString,
50 const nsCString &newPACURL) = 0;
51 };
52
53 class PendingPACQuery MOZ_FINAL : public nsRunnable,
54 public mozilla::LinkedListElement<PendingPACQuery>
55 {
56 public:
57 PendingPACQuery(nsPACMan *pacMan, nsIURI *uri,
58 nsPACManCallback *callback, bool mainThreadResponse);
59
60 // can be called from either thread
61 void Complete(nsresult status, const nsCString &pacString);
62 void UseAlternatePACFile(const nsCString &pacURL);
63
64 nsCString mSpec;
65 nsCString mScheme;
66 nsCString mHost;
67 int32_t mPort;
68
69 NS_IMETHOD Run(void); /* nsRunnable */
70
71 private:
72 nsPACMan *mPACMan; // weak reference
73 nsRefPtr<nsPACManCallback> mCallback;
74 bool mOnMainThreadOnly;
75 };
76
77 /**
78 * This class provides an abstraction layer above the PAC thread. The methods
79 * defined on this class are intended to be called on the main thread only.
80 */
81
82 class nsPACMan MOZ_FINAL : public nsIStreamLoaderObserver
83 , public nsIInterfaceRequestor
84 , public nsIChannelEventSink
85 {
86 public:
87 NS_DECL_THREADSAFE_ISUPPORTS
88
89 nsPACMan();
90
91 /**
92 * This method may be called to shutdown the PAC manager. Any async queries
93 * that have not yet completed will either finish normally or be canceled by
94 * the time this method returns.
95 */
96 void Shutdown();
97
98 /**
99 * This method queries a PAC result asynchronously. The callback runs on the
100 * calling thread. If the PAC file has not yet been loaded, then this method
101 * will queue up the request, and complete it once the PAC file has been
102 * loaded.
103 *
104 * @param channel
105 * The channel to query.
106 * @param callback
107 * The callback to run once the PAC result is available.
108 * @param mustCallbackOnMainThread
109 * If set to false the callback can be made from the PAC thread
110 */
111 nsresult AsyncGetProxyForChannel(nsIChannel *channel, nsPACManCallback *callback,
112 bool mustCallbackOnMainThread);
113
114 /**
115 * This method may be called to reload the PAC file. While we are loading
116 * the PAC file, any asynchronous PAC queries will be queued up to be
117 * processed once the PAC file finishes loading.
118 *
119 * @param pacSpec
120 * The non normalized uri spec of this URI used for comparison with
121 * system proxy settings to determine if the PAC uri has changed.
122 */
123 nsresult LoadPACFromURI(const nsCString &pacSpec);
124
125 /**
126 * Returns true if we are currently loading the PAC file.
127 */
128 bool IsLoading() { return mLoader != nullptr; }
129
130 /**
131 * Returns true if the given URI matches the URI of our PAC file or the
132 * URI it has been redirected to. In the case of a chain of redirections
133 * only the current one being followed and the original are considered
134 * becuase this information is used, respectively, to determine if we
135 * should bypass the proxy (to fetch the pac file) or if the pac
136 * configuration has changed (and we should reload the pac file)
137 */
138 bool IsPACURI(const nsACString &spec)
139 {
140 return mPACURISpec.Equals(spec) || mPACURIRedirectSpec.Equals(spec) ||
141 mNormalPACURISpec.Equals(spec);
142 }
143
144 bool IsPACURI(nsIURI *uri) {
145 if (mPACURISpec.IsEmpty() && mPACURIRedirectSpec.IsEmpty())
146 return false;
147
148 nsAutoCString tmp;
149 uri->GetSpec(tmp);
150 return IsPACURI(tmp);
151 }
152
153 NS_HIDDEN_(nsresult) Init(nsISystemProxySettings *);
154 static nsPACMan *sInstance;
155
156 // PAC thread operations only
157 void ProcessPendingQ();
158 void CancelPendingQ(nsresult);
159
160 private:
161 NS_DECL_NSISTREAMLOADEROBSERVER
162 NS_DECL_NSIINTERFACEREQUESTOR
163 NS_DECL_NSICHANNELEVENTSINK
164
165 friend class PendingPACQuery;
166 friend class PACLoadComplete;
167 friend class ExecutePACThreadAction;
168 friend class WaitForThreadShutdown;
169
170 ~nsPACMan();
171
172 /**
173 * Cancel any existing load if any.
174 */
175 void CancelExistingLoad();
176
177 /**
178 * Start loading the PAC file.
179 */
180 void StartLoading();
181
182 /**
183 * Reload the PAC file if there is reason to.
184 */
185 void MaybeReloadPAC();
186
187 /**
188 * Called when we fail to load the PAC file.
189 */
190 void OnLoadFailure();
191
192 /**
193 * PostQuery() only runs on the PAC thread and it is used to
194 * place a pendingPACQuery into the queue and potentially
195 * execute the queue if it was otherwise empty
196 */
197 nsresult PostQuery(PendingPACQuery *query);
198
199 // PAC thread operations only
200 void PostProcessPendingQ();
201 void PostCancelPendingQ(nsresult);
202 bool ProcessPending();
203 void NamePACThread();
204
205 private:
206 mozilla::net::ProxyAutoConfig mPAC;
207 nsCOMPtr<nsIThread> mPACThread;
208 nsCOMPtr<nsISystemProxySettings> mSystemProxySettings;
209
210 mozilla::LinkedList<PendingPACQuery> mPendingQ; /* pac thread only */
211
212 // These specs are not nsIURI so that they can be used off the main thread.
213 // The non-normalized versions are directly from the configuration, the
214 // normalized version has been extracted from an nsIURI
215 nsCString mPACURISpec;
216 nsCString mPACURIRedirectSpec;
217 nsCString mNormalPACURISpec;
218
219 nsCOMPtr<nsIStreamLoader> mLoader;
220 bool mLoadPending;
221 bool mShutdown;
222 mozilla::TimeStamp mScheduledReload;
223 uint32_t mLoadFailureCount;
224
225 bool mInProgress;
226 };
227
228 namespace mozilla {
229 namespace net {
230 PRLogModuleInfo* GetProxyLog();
231 }
232 }
233
234 #endif // nsPACMan_h__

mercurial