123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* vim:set ts=2 sw=2 sts=2 et cindent: */
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- #ifndef nsPACMan_h__
- #define nsPACMan_h__
- #include "nsIStreamLoader.h"
- #include "nsIInterfaceRequestor.h"
- #include "nsIChannelEventSink.h"
- #include "ProxyAutoConfig.h"
- #include "nsThreadUtils.h"
- #include "nsIURI.h"
- #include "nsCOMPtr.h"
- #include "nsString.h"
- #include "mozilla/Attributes.h"
- #include "mozilla/LinkedList.h"
- #include "nsAutoPtr.h"
- #include "mozilla/TimeStamp.h"
- #include "mozilla/Logging.h"
- #include "mozilla/Atomics.h"
- class nsISystemProxySettings;
- class nsIThread;
- namespace mozilla {
- namespace net {
- class nsPACMan;
- class WaitForThreadShutdown;
- /**
- * This class defines a callback interface used by AsyncGetProxyForURI.
- */
- class NS_NO_VTABLE nsPACManCallback : public nsISupports
- {
- public:
- /**
- * This method is invoked on the same thread that called AsyncGetProxyForURI.
- *
- * @param status
- * This parameter indicates whether or not the PAC query succeeded.
- * @param pacString
- * This parameter holds the value of the PAC string. It is empty when
- * status is a failure code.
- * @param newPACURL
- * This parameter holds the URL of a new PAC file that should be loaded
- * before the query is evaluated again. At least one of pacString and
- * newPACURL should be 0 length.
- */
- virtual void OnQueryComplete(nsresult status,
- const nsCString &pacString,
- const nsCString &newPACURL) = 0;
- };
- class PendingPACQuery final : public Runnable,
- public LinkedListElement<PendingPACQuery>
- {
- public:
- PendingPACQuery(nsPACMan *pacMan, nsIURI *uri,
- nsPACManCallback *callback,
- bool mainThreadResponse);
- // can be called from either thread
- void Complete(nsresult status, const nsCString &pacString);
- void UseAlternatePACFile(const nsCString &pacURL);
- nsCString mSpec;
- nsCString mScheme;
- nsCString mHost;
- int32_t mPort;
- NS_IMETHOD Run(void); /* Runnable */
- private:
- nsPACMan *mPACMan; // weak reference
- private:
- RefPtr<nsPACManCallback> mCallback;
- bool mOnMainThreadOnly;
- };
- /**
- * This class provides an abstraction layer above the PAC thread. The methods
- * defined on this class are intended to be called on the main thread only.
- */
- class nsPACMan final : public nsIStreamLoaderObserver
- , public nsIInterfaceRequestor
- , public nsIChannelEventSink
- {
- public:
- NS_DECL_THREADSAFE_ISUPPORTS
- nsPACMan();
- /**
- * This method may be called to shutdown the PAC manager. Any async queries
- * that have not yet completed will either finish normally or be canceled by
- * the time this method returns.
- */
- void Shutdown();
- /**
- * This method queries a PAC result asynchronously. The callback runs on the
- * calling thread. If the PAC file has not yet been loaded, then this method
- * will queue up the request, and complete it once the PAC file has been
- * loaded.
- *
- * @param uri
- * The URI to query.
- * @param callback
- * The callback to run once the PAC result is available.
- * @param mustCallbackOnMainThread
- * If set to false the callback can be made from the PAC thread
- */
- nsresult AsyncGetProxyForURI(nsIURI *uri,
- nsPACManCallback *callback,
- bool mustCallbackOnMainThread);
- /**
- * This method may be called to reload the PAC file. While we are loading
- * the PAC file, any asynchronous PAC queries will be queued up to be
- * processed once the PAC file finishes loading.
- *
- * @param pacSpec
- * The non normalized uri spec of this URI used for comparison with
- * system proxy settings to determine if the PAC uri has changed.
- */
- nsresult LoadPACFromURI(const nsCString &pacSpec);
- /**
- * Returns true if we are currently loading the PAC file.
- */
- bool IsLoading() { return mLoader != nullptr; }
- /**
- * Returns true if the given URI matches the URI of our PAC file or the
- * URI it has been redirected to. In the case of a chain of redirections
- * only the current one being followed and the original are considered
- * becuase this information is used, respectively, to determine if we
- * should bypass the proxy (to fetch the pac file) or if the pac
- * configuration has changed (and we should reload the pac file)
- */
- bool IsPACURI(const nsACString &spec)
- {
- return mPACURISpec.Equals(spec) || mPACURIRedirectSpec.Equals(spec) ||
- mNormalPACURISpec.Equals(spec);
- }
- bool IsPACURI(nsIURI *uri) {
- if (mPACURISpec.IsEmpty() && mPACURIRedirectSpec.IsEmpty()) {
- return false;
- }
- nsAutoCString tmp;
- nsresult rv = uri->GetSpec(tmp);
- if (NS_FAILED(rv)) {
- return false;
- }
- return IsPACURI(tmp);
- }
- nsresult Init(nsISystemProxySettings *);
- static nsPACMan *sInstance;
- // PAC thread operations only
- void ProcessPendingQ();
- void CancelPendingQ(nsresult);
- private:
- NS_DECL_NSISTREAMLOADEROBSERVER
- NS_DECL_NSIINTERFACEREQUESTOR
- NS_DECL_NSICHANNELEVENTSINK
- friend class PendingPACQuery;
- friend class PACLoadComplete;
- friend class ExecutePACThreadAction;
- friend class WaitForThreadShutdown;
- ~nsPACMan();
- /**
- * Cancel any existing load if any.
- */
- void CancelExistingLoad();
- /**
- * Start loading the PAC file.
- */
- void StartLoading();
- /**
- * Reload the PAC file if there is reason to.
- */
- void MaybeReloadPAC();
- /**
- * Called when we fail to load the PAC file.
- */
- void OnLoadFailure();
- /**
- * PostQuery() only runs on the PAC thread and it is used to
- * place a pendingPACQuery into the queue and potentially
- * execute the queue if it was otherwise empty
- */
- nsresult PostQuery(PendingPACQuery *query);
- // PAC thread operations only
- void PostProcessPendingQ();
- void PostCancelPendingQ(nsresult);
- bool ProcessPending();
- void NamePACThread();
- private:
- ProxyAutoConfig mPAC;
- nsCOMPtr<nsIThread> mPACThread;
- nsCOMPtr<nsISystemProxySettings> mSystemProxySettings;
- LinkedList<PendingPACQuery> mPendingQ; /* pac thread only */
- // These specs are not nsIURI so that they can be used off the main thread.
- // The non-normalized versions are directly from the configuration, the
- // normalized version has been extracted from an nsIURI
- nsCString mPACURISpec;
- nsCString mPACURIRedirectSpec;
- nsCString mNormalPACURISpec;
- nsCOMPtr<nsIStreamLoader> mLoader;
- bool mLoadPending;
- Atomic<bool, Relaxed> mShutdown;
- TimeStamp mScheduledReload;
- uint32_t mLoadFailureCount;
- bool mInProgress;
- bool mIncludePath;
- };
- extern LazyLogModule gProxyLog;
- } // namespace net
- } // namespace mozilla
- #endif // nsPACMan_h__
|