netwerk/base/src/nsPACMan.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/netwerk/base/src/nsPACMan.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,234 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* vim:set ts=2 sw=2 sts=2 et cindent: */
     1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +#ifndef nsPACMan_h__
    1.11 +#define nsPACMan_h__
    1.12 +
    1.13 +#include "nsIStreamLoader.h"
    1.14 +#include "nsIInterfaceRequestor.h"
    1.15 +#include "nsIChannelEventSink.h"
    1.16 +#include "ProxyAutoConfig.h"
    1.17 +#include "nsThreadUtils.h"
    1.18 +#include "nsIURI.h"
    1.19 +#include "nsCOMPtr.h"
    1.20 +#include "nsString.h"
    1.21 +#include "mozilla/Attributes.h"
    1.22 +#include "mozilla/LinkedList.h"
    1.23 +#include "nsAutoPtr.h"
    1.24 +#include "mozilla/TimeStamp.h"
    1.25 +#include "prlog.h"
    1.26 +
    1.27 +class nsPACMan;
    1.28 +class nsISystemProxySettings;
    1.29 +class nsIThread;
    1.30 +class WaitForThreadShutdown;
    1.31 +
    1.32 +/**
    1.33 + * This class defines a callback interface used by AsyncGetProxyForChannel.
    1.34 + */
    1.35 +class NS_NO_VTABLE nsPACManCallback : public nsISupports
    1.36 +{
    1.37 +public:
    1.38 +  /**
    1.39 +   * This method is invoked on the same thread that called AsyncGetProxyForChannel.
    1.40 +   *
    1.41 +   * @param status
    1.42 +   *        This parameter indicates whether or not the PAC query succeeded.
    1.43 +   * @param pacString
    1.44 +   *        This parameter holds the value of the PAC string.  It is empty when
    1.45 +   *        status is a failure code.
    1.46 +   * @param newPACURL
    1.47 +   *        This parameter holds the URL of a new PAC file that should be loaded
    1.48 +   *        before the query is evaluated again. At least one of pacString and
    1.49 +   *        newPACURL should be 0 length.
    1.50 +   */
    1.51 +  virtual void OnQueryComplete(nsresult status,
    1.52 +                               const nsCString &pacString,
    1.53 +                               const nsCString &newPACURL) = 0;
    1.54 +};
    1.55 +
    1.56 +class PendingPACQuery MOZ_FINAL : public nsRunnable,
    1.57 +                                  public mozilla::LinkedListElement<PendingPACQuery>
    1.58 +{
    1.59 +public:
    1.60 +  PendingPACQuery(nsPACMan *pacMan, nsIURI *uri,
    1.61 +                  nsPACManCallback *callback, bool mainThreadResponse);
    1.62 +
    1.63 +  // can be called from either thread
    1.64 +  void Complete(nsresult status, const nsCString &pacString);
    1.65 +  void UseAlternatePACFile(const nsCString &pacURL);
    1.66 +
    1.67 +  nsCString                  mSpec;
    1.68 +  nsCString                  mScheme;
    1.69 +  nsCString                  mHost;
    1.70 +  int32_t                    mPort;
    1.71 +
    1.72 +  NS_IMETHOD Run(void);     /* nsRunnable */
    1.73 +
    1.74 +private:
    1.75 +  nsPACMan                  *mPACMan;  // weak reference
    1.76 +  nsRefPtr<nsPACManCallback> mCallback;
    1.77 +  bool                       mOnMainThreadOnly;
    1.78 +};
    1.79 +
    1.80 +/**
    1.81 + * This class provides an abstraction layer above the PAC thread.  The methods
    1.82 + * defined on this class are intended to be called on the main thread only.
    1.83 + */
    1.84 +
    1.85 +class nsPACMan MOZ_FINAL : public nsIStreamLoaderObserver
    1.86 +                         , public nsIInterfaceRequestor
    1.87 +                         , public nsIChannelEventSink
    1.88 +{
    1.89 +public:
    1.90 +  NS_DECL_THREADSAFE_ISUPPORTS
    1.91 +
    1.92 +  nsPACMan();
    1.93 +
    1.94 +  /**
    1.95 +   * This method may be called to shutdown the PAC manager.  Any async queries
    1.96 +   * that have not yet completed will either finish normally or be canceled by
    1.97 +   * the time this method returns.
    1.98 +   */
    1.99 +  void Shutdown();
   1.100 +
   1.101 +  /**
   1.102 +   * This method queries a PAC result asynchronously.  The callback runs on the
   1.103 +   * calling thread.  If the PAC file has not yet been loaded, then this method
   1.104 +   * will queue up the request, and complete it once the PAC file has been
   1.105 +   * loaded.
   1.106 +   * 
   1.107 +   * @param channel
   1.108 +   *        The channel to query.
   1.109 +   * @param callback
   1.110 +   *        The callback to run once the PAC result is available.
   1.111 +   * @param mustCallbackOnMainThread
   1.112 +   *        If set to false the callback can be made from the PAC thread
   1.113 +   */
   1.114 +  nsresult AsyncGetProxyForChannel(nsIChannel *channel, nsPACManCallback *callback,
   1.115 +                               bool mustCallbackOnMainThread);
   1.116 +
   1.117 +  /**
   1.118 +   * This method may be called to reload the PAC file.  While we are loading
   1.119 +   * the PAC file, any asynchronous PAC queries will be queued up to be
   1.120 +   * processed once the PAC file finishes loading.
   1.121 +   *
   1.122 +   * @param pacSpec
   1.123 +   *        The non normalized uri spec of this URI used for comparison with
   1.124 +   *        system proxy settings to determine if the PAC uri has changed.
   1.125 +   */
   1.126 +  nsresult LoadPACFromURI(const nsCString &pacSpec);
   1.127 +
   1.128 +  /**
   1.129 +   * Returns true if we are currently loading the PAC file.
   1.130 +   */
   1.131 +  bool IsLoading() { return mLoader != nullptr; }
   1.132 +
   1.133 +  /**
   1.134 +   * Returns true if the given URI matches the URI of our PAC file or the
   1.135 +   * URI it has been redirected to. In the case of a chain of redirections
   1.136 +   * only the current one being followed and the original are considered
   1.137 +   * becuase this information is used, respectively, to determine if we
   1.138 +   * should bypass the proxy (to fetch the pac file) or if the pac
   1.139 +   * configuration has changed (and we should reload the pac file)
   1.140 +   */
   1.141 +  bool IsPACURI(const nsACString &spec)
   1.142 +  {
   1.143 +    return mPACURISpec.Equals(spec) || mPACURIRedirectSpec.Equals(spec) ||
   1.144 +      mNormalPACURISpec.Equals(spec);
   1.145 +  }
   1.146 +
   1.147 +  bool IsPACURI(nsIURI *uri) {
   1.148 +    if (mPACURISpec.IsEmpty() && mPACURIRedirectSpec.IsEmpty())
   1.149 +      return false;
   1.150 +
   1.151 +    nsAutoCString tmp;
   1.152 +    uri->GetSpec(tmp);
   1.153 +    return IsPACURI(tmp);
   1.154 +  }
   1.155 +
   1.156 +  NS_HIDDEN_(nsresult) Init(nsISystemProxySettings *);
   1.157 +  static nsPACMan *sInstance;
   1.158 +
   1.159 +  // PAC thread operations only
   1.160 +  void ProcessPendingQ();
   1.161 +  void CancelPendingQ(nsresult);
   1.162 +
   1.163 +private:
   1.164 +  NS_DECL_NSISTREAMLOADEROBSERVER
   1.165 +  NS_DECL_NSIINTERFACEREQUESTOR
   1.166 +  NS_DECL_NSICHANNELEVENTSINK
   1.167 +
   1.168 +  friend class PendingPACQuery;
   1.169 +  friend class PACLoadComplete;
   1.170 +  friend class ExecutePACThreadAction;
   1.171 +  friend class WaitForThreadShutdown;
   1.172 +
   1.173 +  ~nsPACMan();
   1.174 +
   1.175 +  /**
   1.176 +   * Cancel any existing load if any.
   1.177 +   */
   1.178 +  void CancelExistingLoad();
   1.179 +
   1.180 +  /**
   1.181 +   * Start loading the PAC file.
   1.182 +   */
   1.183 +  void StartLoading();
   1.184 +
   1.185 +  /**
   1.186 +   * Reload the PAC file if there is reason to.
   1.187 +   */
   1.188 +  void MaybeReloadPAC();
   1.189 +
   1.190 +  /**
   1.191 +   * Called when we fail to load the PAC file.
   1.192 +   */
   1.193 +  void OnLoadFailure();
   1.194 +
   1.195 +  /**
   1.196 +   * PostQuery() only runs on the PAC thread and it is used to
   1.197 +   * place a pendingPACQuery into the queue and potentially
   1.198 +   * execute the queue if it was otherwise empty
   1.199 +   */
   1.200 +  nsresult PostQuery(PendingPACQuery *query);
   1.201 +
   1.202 +  // PAC thread operations only
   1.203 +  void PostProcessPendingQ();
   1.204 +  void PostCancelPendingQ(nsresult);
   1.205 +  bool ProcessPending();
   1.206 +  void NamePACThread();
   1.207 +
   1.208 +private:
   1.209 +  mozilla::net::ProxyAutoConfig mPAC;
   1.210 +  nsCOMPtr<nsIThread>           mPACThread;
   1.211 +  nsCOMPtr<nsISystemProxySettings> mSystemProxySettings;
   1.212 +
   1.213 +  mozilla::LinkedList<PendingPACQuery> mPendingQ; /* pac thread only */
   1.214 +
   1.215 +  // These specs are not nsIURI so that they can be used off the main thread.
   1.216 +  // The non-normalized versions are directly from the configuration, the
   1.217 +  // normalized version has been extracted from an nsIURI
   1.218 +  nsCString                    mPACURISpec;
   1.219 +  nsCString                    mPACURIRedirectSpec;
   1.220 +  nsCString                    mNormalPACURISpec;
   1.221 +
   1.222 +  nsCOMPtr<nsIStreamLoader>    mLoader;
   1.223 +  bool                         mLoadPending;
   1.224 +  bool                         mShutdown;
   1.225 +  mozilla::TimeStamp           mScheduledReload;
   1.226 +  uint32_t                     mLoadFailureCount;
   1.227 +
   1.228 +  bool                         mInProgress;
   1.229 +};
   1.230 +
   1.231 +namespace mozilla {
   1.232 +namespace net {
   1.233 +PRLogModuleInfo* GetProxyLog();
   1.234 +}
   1.235 +}
   1.236 +
   1.237 +#endif  // nsPACMan_h__

mercurial