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