nsPACMan.h 7.2 KB

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