netwerk/protocol/http/HttpBaseChannel.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/netwerk/protocol/http/HttpBaseChannel.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,442 @@
     1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* vim: set sw=2 ts=8 et tw=80 : */
     1.6 +
     1.7 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.8 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.9 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    1.10 +
    1.11 +#ifndef mozilla_net_HttpBaseChannel_h
    1.12 +#define mozilla_net_HttpBaseChannel_h
    1.13 +
    1.14 +#include "nsHttp.h"
    1.15 +#include "nsAutoPtr.h"
    1.16 +#include "nsHashPropertyBag.h"
    1.17 +#include "nsProxyInfo.h"
    1.18 +#include "nsHttpRequestHead.h"
    1.19 +#include "nsHttpResponseHead.h"
    1.20 +#include "nsHttpConnectionInfo.h"
    1.21 +#include "nsIEncodedChannel.h"
    1.22 +#include "nsIHttpChannel.h"
    1.23 +#include "nsHttpHandler.h"
    1.24 +#include "nsIHttpChannelInternal.h"
    1.25 +#include "nsIUploadChannel.h"
    1.26 +#include "nsIUploadChannel2.h"
    1.27 +#include "nsIProgressEventSink.h"
    1.28 +#include "nsIURI.h"
    1.29 +#include "nsIEffectiveTLDService.h"
    1.30 +#include "nsIStringEnumerator.h"
    1.31 +#include "nsISupportsPriority.h"
    1.32 +#include "nsIApplicationCache.h"
    1.33 +#include "nsIResumableChannel.h"
    1.34 +#include "nsITraceableChannel.h"
    1.35 +#include "nsILoadContext.h"
    1.36 +#include "mozilla/net/NeckoCommon.h"
    1.37 +#include "nsThreadUtils.h"
    1.38 +#include "PrivateBrowsingChannel.h"
    1.39 +#include "mozilla/net/DNS.h"
    1.40 +#include "nsITimedChannel.h"
    1.41 +#include "nsISecurityConsoleMessage.h"
    1.42 +
    1.43 +extern PRLogModuleInfo *gHttpLog;
    1.44 +
    1.45 +namespace mozilla {
    1.46 +namespace net {
    1.47 +
    1.48 +/*
    1.49 + * This class is a partial implementation of nsIHttpChannel.  It contains code
    1.50 + * shared by nsHttpChannel and HttpChannelChild.
    1.51 + * - Note that this class has nothing to do with nsBaseChannel, which is an
    1.52 + *   earlier effort at a base class for channels that somehow never made it all
    1.53 + *   the way to the HTTP channel.
    1.54 + */
    1.55 +class HttpBaseChannel : public nsHashPropertyBag
    1.56 +                      , public nsIEncodedChannel
    1.57 +                      , public nsIHttpChannel
    1.58 +                      , public nsIHttpChannelInternal
    1.59 +                      , public nsIUploadChannel
    1.60 +                      , public nsIUploadChannel2
    1.61 +                      , public nsISupportsPriority
    1.62 +                      , public nsIResumableChannel
    1.63 +                      , public nsITraceableChannel
    1.64 +                      , public PrivateBrowsingChannel<HttpBaseChannel>
    1.65 +                      , public nsITimedChannel
    1.66 +{
    1.67 +public:
    1.68 +  NS_DECL_ISUPPORTS_INHERITED
    1.69 +  NS_DECL_NSIUPLOADCHANNEL
    1.70 +  NS_DECL_NSIUPLOADCHANNEL2
    1.71 +  NS_DECL_NSITRACEABLECHANNEL
    1.72 +  NS_DECL_NSITIMEDCHANNEL
    1.73 +
    1.74 +  HttpBaseChannel();
    1.75 +  virtual ~HttpBaseChannel();
    1.76 +
    1.77 +  virtual nsresult Init(nsIURI *aURI, uint32_t aCaps, nsProxyInfo *aProxyInfo,
    1.78 +                        uint32_t aProxyResolveFlags,
    1.79 +                        nsIURI *aProxyURI);
    1.80 +
    1.81 +  // nsIRequest
    1.82 +  NS_IMETHOD GetName(nsACString& aName);
    1.83 +  NS_IMETHOD IsPending(bool *aIsPending);
    1.84 +  NS_IMETHOD GetStatus(nsresult *aStatus);
    1.85 +  NS_IMETHOD GetLoadGroup(nsILoadGroup **aLoadGroup);
    1.86 +  NS_IMETHOD SetLoadGroup(nsILoadGroup *aLoadGroup);
    1.87 +  NS_IMETHOD GetLoadFlags(nsLoadFlags *aLoadFlags);
    1.88 +  NS_IMETHOD SetLoadFlags(nsLoadFlags aLoadFlags);
    1.89 +
    1.90 +  // nsIChannel
    1.91 +  NS_IMETHOD GetOriginalURI(nsIURI **aOriginalURI);
    1.92 +  NS_IMETHOD SetOriginalURI(nsIURI *aOriginalURI);
    1.93 +  NS_IMETHOD GetURI(nsIURI **aURI);
    1.94 +  NS_IMETHOD GetOwner(nsISupports **aOwner);
    1.95 +  NS_IMETHOD SetOwner(nsISupports *aOwner);
    1.96 +  NS_IMETHOD GetNotificationCallbacks(nsIInterfaceRequestor **aCallbacks);
    1.97 +  NS_IMETHOD SetNotificationCallbacks(nsIInterfaceRequestor *aCallbacks);
    1.98 +  NS_IMETHOD GetContentType(nsACString& aContentType);
    1.99 +  NS_IMETHOD SetContentType(const nsACString& aContentType);
   1.100 +  NS_IMETHOD GetContentCharset(nsACString& aContentCharset);
   1.101 +  NS_IMETHOD SetContentCharset(const nsACString& aContentCharset);
   1.102 +  NS_IMETHOD GetContentDisposition(uint32_t *aContentDisposition);
   1.103 +  NS_IMETHOD SetContentDisposition(uint32_t aContentDisposition);
   1.104 +  NS_IMETHOD GetContentDispositionFilename(nsAString& aContentDispositionFilename);
   1.105 +  NS_IMETHOD SetContentDispositionFilename(const nsAString& aContentDispositionFilename);
   1.106 +  NS_IMETHOD GetContentDispositionHeader(nsACString& aContentDispositionHeader);
   1.107 +  NS_IMETHOD GetContentLength(int64_t *aContentLength);
   1.108 +  NS_IMETHOD SetContentLength(int64_t aContentLength);
   1.109 +  NS_IMETHOD Open(nsIInputStream **aResult);
   1.110 +
   1.111 +  // nsIEncodedChannel
   1.112 +  NS_IMETHOD GetApplyConversion(bool *value);
   1.113 +  NS_IMETHOD SetApplyConversion(bool value);
   1.114 +  NS_IMETHOD GetContentEncodings(nsIUTF8StringEnumerator** aEncodings);
   1.115 +
   1.116 +  // HttpBaseChannel::nsIHttpChannel
   1.117 +  NS_IMETHOD GetRequestMethod(nsACString& aMethod);
   1.118 +  NS_IMETHOD SetRequestMethod(const nsACString& aMethod);
   1.119 +  NS_IMETHOD GetReferrer(nsIURI **referrer);
   1.120 +  NS_IMETHOD SetReferrer(nsIURI *referrer);
   1.121 +  NS_IMETHOD GetProxyURI(nsIURI **proxyURI);
   1.122 +  NS_IMETHOD GetRequestHeader(const nsACString& aHeader, nsACString& aValue);
   1.123 +  NS_IMETHOD SetRequestHeader(const nsACString& aHeader,
   1.124 +                              const nsACString& aValue, bool aMerge);
   1.125 +  NS_IMETHOD VisitRequestHeaders(nsIHttpHeaderVisitor *visitor);
   1.126 +  NS_IMETHOD GetResponseHeader(const nsACString &header, nsACString &value);
   1.127 +  NS_IMETHOD SetResponseHeader(const nsACString& header,
   1.128 +                               const nsACString& value, bool merge);
   1.129 +  NS_IMETHOD VisitResponseHeaders(nsIHttpHeaderVisitor *visitor);
   1.130 +  NS_IMETHOD GetAllowPipelining(bool *value);
   1.131 +  NS_IMETHOD SetAllowPipelining(bool value);
   1.132 +  NS_IMETHOD GetRedirectionLimit(uint32_t *value);
   1.133 +  NS_IMETHOD SetRedirectionLimit(uint32_t value);
   1.134 +  NS_IMETHOD IsNoStoreResponse(bool *value);
   1.135 +  NS_IMETHOD IsNoCacheResponse(bool *value);
   1.136 +  NS_IMETHOD GetResponseStatus(uint32_t *aValue);
   1.137 +  NS_IMETHOD GetResponseStatusText(nsACString& aValue);
   1.138 +  NS_IMETHOD GetRequestSucceeded(bool *aValue);
   1.139 +  NS_IMETHOD RedirectTo(nsIURI *newURI);
   1.140 +
   1.141 +  // nsIHttpChannelInternal
   1.142 +  NS_IMETHOD GetDocumentURI(nsIURI **aDocumentURI);
   1.143 +  NS_IMETHOD SetDocumentURI(nsIURI *aDocumentURI);
   1.144 +  NS_IMETHOD GetRequestVersion(uint32_t *major, uint32_t *minor);
   1.145 +  NS_IMETHOD GetResponseVersion(uint32_t *major, uint32_t *minor);
   1.146 +  NS_IMETHOD SetCookie(const char *aCookieHeader);
   1.147 +  NS_IMETHOD GetForceAllowThirdPartyCookie(bool *aForce);
   1.148 +  NS_IMETHOD SetForceAllowThirdPartyCookie(bool aForce);
   1.149 +  NS_IMETHOD GetCanceled(bool *aCanceled);
   1.150 +  NS_IMETHOD GetChannelIsForDownload(bool *aChannelIsForDownload);
   1.151 +  NS_IMETHOD SetChannelIsForDownload(bool aChannelIsForDownload);
   1.152 +  NS_IMETHOD SetCacheKeysRedirectChain(nsTArray<nsCString> *cacheKeys);
   1.153 +  NS_IMETHOD GetLocalAddress(nsACString& addr);
   1.154 +  NS_IMETHOD GetLocalPort(int32_t* port);
   1.155 +  NS_IMETHOD GetRemoteAddress(nsACString& addr);
   1.156 +  NS_IMETHOD GetRemotePort(int32_t* port);
   1.157 +  NS_IMETHOD GetAllowSpdy(bool *aAllowSpdy);
   1.158 +  NS_IMETHOD SetAllowSpdy(bool aAllowSpdy);
   1.159 +  NS_IMETHOD GetLoadAsBlocking(bool *aLoadAsBlocking);
   1.160 +  NS_IMETHOD SetLoadAsBlocking(bool aLoadAsBlocking);
   1.161 +  NS_IMETHOD GetLoadUnblocked(bool *aLoadUnblocked);
   1.162 +  NS_IMETHOD SetLoadUnblocked(bool aLoadUnblocked);
   1.163 +  NS_IMETHOD GetApiRedirectToURI(nsIURI * *aApiRedirectToURI);
   1.164 +  NS_IMETHOD AddSecurityMessage(const nsAString &aMessageTag, const nsAString &aMessageCategory);
   1.165 +  NS_IMETHOD TakeAllSecurityMessages(nsCOMArray<nsISecurityConsoleMessage> &aMessages);
   1.166 +  NS_IMETHOD GetResponseTimeoutEnabled(bool *aEnable);
   1.167 +  NS_IMETHOD SetResponseTimeoutEnabled(bool aEnable);
   1.168 +
   1.169 +  inline void CleanRedirectCacheChainIfNecessary()
   1.170 +  {
   1.171 +      mRedirectedCachekeys = nullptr;
   1.172 +  }
   1.173 +  NS_IMETHOD HTTPUpgrade(const nsACString & aProtocolName,
   1.174 +                         nsIHttpUpgradeListener *aListener);
   1.175 +
   1.176 +  // nsISupportsPriority
   1.177 +  NS_IMETHOD GetPriority(int32_t *value);
   1.178 +  NS_IMETHOD AdjustPriority(int32_t delta);
   1.179 +
   1.180 +  // nsIResumableChannel
   1.181 +  NS_IMETHOD GetEntityID(nsACString& aEntityID);
   1.182 +
   1.183 +  class nsContentEncodings : public nsIUTF8StringEnumerator
   1.184 +    {
   1.185 +    public:
   1.186 +        NS_DECL_ISUPPORTS
   1.187 +        NS_DECL_NSIUTF8STRINGENUMERATOR
   1.188 +
   1.189 +        nsContentEncodings(nsIHttpChannel* aChannel, const char* aEncodingHeader);
   1.190 +        virtual ~nsContentEncodings();
   1.191 +
   1.192 +    private:
   1.193 +        nsresult PrepareForNext(void);
   1.194 +
   1.195 +        // We do not own the buffer.  The channel owns it.
   1.196 +        const char* mEncodingHeader;
   1.197 +        const char* mCurStart;  // points to start of current header
   1.198 +        const char* mCurEnd;  // points to end of current header
   1.199 +
   1.200 +        // Hold a ref to our channel so that it can't go away and take the
   1.201 +        // header with it.
   1.202 +        nsCOMPtr<nsIHttpChannel> mChannel;
   1.203 +
   1.204 +        bool mReady;
   1.205 +    };
   1.206 +
   1.207 +    nsHttpResponseHead * GetResponseHead() const { return mResponseHead; }
   1.208 +    nsHttpRequestHead * GetRequestHead() { return &mRequestHead; }
   1.209 +
   1.210 +    const NetAddr& GetSelfAddr() { return mSelfAddr; }
   1.211 +    const NetAddr& GetPeerAddr() { return mPeerAddr; }
   1.212 +
   1.213 +public: /* Necko internal use only... */
   1.214 +
   1.215 +
   1.216 +    // Return whether upon a redirect code of httpStatus for method, the
   1.217 +    // request method should be rewritten to GET.
   1.218 +    static bool ShouldRewriteRedirectToGET(uint32_t httpStatus,
   1.219 +                                           nsHttpRequestHead::ParsedMethodType method);
   1.220 +
   1.221 +protected:
   1.222 +    nsCOMArray<nsISecurityConsoleMessage> mSecurityConsoleMessages;
   1.223 +
   1.224 +  // Handle notifying listener, removing from loadgroup if request failed.
   1.225 +  void     DoNotifyListener();
   1.226 +  virtual void DoNotifyListenerCleanup() = 0;
   1.227 +
   1.228 +  // drop reference to listener, its callbacks, and the progress sink
   1.229 +  void ReleaseListeners();
   1.230 +
   1.231 +  nsresult ApplyContentConversions();
   1.232 +
   1.233 +  void AddCookiesToRequest();
   1.234 +  virtual nsresult SetupReplacementChannel(nsIURI *,
   1.235 +                                           nsIChannel *,
   1.236 +                                           bool preserveMethod);
   1.237 +
   1.238 +  // bundle calling OMR observers and marking flag into one function
   1.239 +  inline void CallOnModifyRequestObservers() {
   1.240 +    gHttpHandler->OnModifyRequest(this);
   1.241 +    mRequestObserversCalled = true;
   1.242 +  }
   1.243 +
   1.244 +  // Helper function to simplify getting notification callbacks.
   1.245 +  template <class T>
   1.246 +  void GetCallback(nsCOMPtr<T> &aResult)
   1.247 +  {
   1.248 +    NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup,
   1.249 +                                  NS_GET_TEMPLATE_IID(T),
   1.250 +                                  getter_AddRefs(aResult));
   1.251 +  }
   1.252 +
   1.253 +  // Redirect tracking
   1.254 +  // Checks whether or not aURI and mOriginalURI share the same domain.
   1.255 +  bool SameOriginWithOriginalUri(nsIURI *aURI);
   1.256 +
   1.257 +  friend class PrivateBrowsingChannel<HttpBaseChannel>;
   1.258 +
   1.259 +  nsCOMPtr<nsIURI>                  mURI;
   1.260 +  nsCOMPtr<nsIURI>                  mOriginalURI;
   1.261 +  nsCOMPtr<nsIURI>                  mDocumentURI;
   1.262 +  nsCOMPtr<nsIStreamListener>       mListener;
   1.263 +  nsCOMPtr<nsISupports>             mListenerContext;
   1.264 +  nsCOMPtr<nsILoadGroup>            mLoadGroup;
   1.265 +  nsCOMPtr<nsISupports>             mOwner;
   1.266 +  nsCOMPtr<nsIInterfaceRequestor>   mCallbacks;
   1.267 +  nsCOMPtr<nsIProgressEventSink>    mProgressSink;
   1.268 +  nsCOMPtr<nsIURI>                  mReferrer;
   1.269 +  nsCOMPtr<nsIApplicationCache>     mApplicationCache;
   1.270 +
   1.271 +  nsHttpRequestHead                 mRequestHead;
   1.272 +  nsCOMPtr<nsIInputStream>          mUploadStream;
   1.273 +  nsAutoPtr<nsHttpResponseHead>     mResponseHead;
   1.274 +  nsRefPtr<nsHttpConnectionInfo>    mConnectionInfo;
   1.275 +  nsCOMPtr<nsIProxyInfo>            mProxyInfo;
   1.276 +
   1.277 +  nsCString                         mSpec; // ASCII encoded URL spec
   1.278 +  nsCString                         mContentTypeHint;
   1.279 +  nsCString                         mContentCharsetHint;
   1.280 +  nsCString                         mUserSetCookieHeader;
   1.281 +
   1.282 +  NetAddr                           mSelfAddr;
   1.283 +  NetAddr                           mPeerAddr;
   1.284 +
   1.285 +  // HTTP Upgrade Data
   1.286 +  nsCString                        mUpgradeProtocol;
   1.287 +  nsCOMPtr<nsIHttpUpgradeListener> mUpgradeProtocolCallback;
   1.288 +
   1.289 +  // Resumable channel specific data
   1.290 +  nsCString                         mEntityID;
   1.291 +  uint64_t                          mStartPos;
   1.292 +
   1.293 +  nsresult                          mStatus;
   1.294 +  uint32_t                          mLoadFlags;
   1.295 +  uint32_t                          mCaps;
   1.296 +  int16_t                           mPriority;
   1.297 +  uint8_t                           mRedirectionLimit;
   1.298 +
   1.299 +  uint32_t                          mApplyConversion            : 1;
   1.300 +  uint32_t                          mCanceled                   : 1;
   1.301 +  uint32_t                          mIsPending                  : 1;
   1.302 +  uint32_t                          mWasOpened                  : 1;
   1.303 +  // if 1 all "http-on-{opening|modify|etc}-request" observers have been called
   1.304 +  uint32_t                          mRequestObserversCalled     : 1;
   1.305 +  uint32_t                          mResponseHeadersModified    : 1;
   1.306 +  uint32_t                          mAllowPipelining            : 1;
   1.307 +  uint32_t                          mForceAllowThirdPartyCookie : 1;
   1.308 +  uint32_t                          mUploadStreamHasHeaders     : 1;
   1.309 +  uint32_t                          mInheritApplicationCache    : 1;
   1.310 +  uint32_t                          mChooseApplicationCache     : 1;
   1.311 +  uint32_t                          mLoadedFromApplicationCache : 1;
   1.312 +  uint32_t                          mChannelIsForDownload       : 1;
   1.313 +  uint32_t                          mTracingEnabled             : 1;
   1.314 +  // True if timing collection is enabled
   1.315 +  uint32_t                          mTimingEnabled              : 1;
   1.316 +  uint32_t                          mAllowSpdy                  : 1;
   1.317 +  uint32_t                          mLoadAsBlocking             : 1;
   1.318 +  uint32_t                          mLoadUnblocked              : 1;
   1.319 +  uint32_t                          mResponseTimeoutEnabled     : 1;
   1.320 +  // A flag that should be false only if a cross-domain redirect occurred
   1.321 +  uint32_t                          mAllRedirectsSameOrigin     : 1;
   1.322 +
   1.323 +  // Current suspension depth for this channel object
   1.324 +  uint32_t                          mSuspendCount;
   1.325 +
   1.326 +  nsCOMPtr<nsIURI>                  mAPIRedirectToURI;
   1.327 +  nsAutoPtr<nsTArray<nsCString> >   mRedirectedCachekeys;
   1.328 +
   1.329 +  uint32_t                          mProxyResolveFlags;
   1.330 +  nsCOMPtr<nsIURI>                  mProxyURI;
   1.331 +
   1.332 +  uint32_t                          mContentDispositionHint;
   1.333 +  nsAutoPtr<nsString>               mContentDispositionFilename;
   1.334 +
   1.335 +  nsRefPtr<nsHttpHandler>           mHttpHandler;  // keep gHttpHandler alive
   1.336 +
   1.337 +  // Performance tracking
   1.338 +  // The initiator type (for this resource) - how was the resource referenced in
   1.339 +  // the HTML file.
   1.340 +  nsString                          mInitiatorType;
   1.341 +  // Number of redirects that has occurred.
   1.342 +  int16_t                           mRedirectCount;
   1.343 +  // A time value equal to the starting time of the fetch that initiates the
   1.344 +  // redirect.
   1.345 +  mozilla::TimeStamp                mRedirectStartTimeStamp;
   1.346 +  // A time value equal to the time immediately after receiving the last byte of
   1.347 +  // the response of the last redirect.
   1.348 +  mozilla::TimeStamp                mRedirectEndTimeStamp;
   1.349 +
   1.350 +  PRTime                            mChannelCreationTime;
   1.351 +  TimeStamp                         mChannelCreationTimestamp;
   1.352 +  TimeStamp                         mAsyncOpenTime;
   1.353 +  TimeStamp                         mCacheReadStart;
   1.354 +  TimeStamp                         mCacheReadEnd;
   1.355 +  // copied from the transaction before we null out mTransaction
   1.356 +  // so that the timing can still be queried from OnStopRequest
   1.357 +  TimingStruct                      mTransactionTimings;
   1.358 +};
   1.359 +
   1.360 +// Share some code while working around C++'s absurd inability to handle casting
   1.361 +// of member functions between base/derived types.
   1.362 +// - We want to store member function pointer to call at resume time, but one
   1.363 +//   such function--HandleAsyncAbort--we want to share between the
   1.364 +//   nsHttpChannel/HttpChannelChild.  Can't define it in base class, because
   1.365 +//   then we'd have to cast member function ptr between base/derived class
   1.366 +//   types.  Sigh...
   1.367 +template <class T>
   1.368 +class HttpAsyncAborter
   1.369 +{
   1.370 +public:
   1.371 +  HttpAsyncAborter(T *derived) : mThis(derived), mCallOnResume(0) {}
   1.372 +
   1.373 +  // Aborts channel: calls OnStart/Stop with provided status, removes channel
   1.374 +  // from loadGroup.
   1.375 +  nsresult AsyncAbort(nsresult status);
   1.376 +
   1.377 +  // Does most the actual work.
   1.378 +  void HandleAsyncAbort();
   1.379 +
   1.380 +  // AsyncCall calls a member function asynchronously (via an event).
   1.381 +  // retval isn't refcounted and is set only when event was successfully
   1.382 +  // posted, the event is returned for the purpose of cancelling when needed
   1.383 +  nsresult AsyncCall(void (T::*funcPtr)(),
   1.384 +                     nsRunnableMethod<T> **retval = nullptr);
   1.385 +private:
   1.386 +  T *mThis;
   1.387 +
   1.388 +protected:
   1.389 +  // Function to be called at resume time
   1.390 +  void (T::* mCallOnResume)(void);
   1.391 +};
   1.392 +
   1.393 +template <class T>
   1.394 +nsresult HttpAsyncAborter<T>::AsyncAbort(nsresult status)
   1.395 +{
   1.396 +  PR_LOG(gHttpLog, 4,
   1.397 +         ("HttpAsyncAborter::AsyncAbort [this=%p status=%x]\n", mThis, status));
   1.398 +
   1.399 +  mThis->mStatus = status;
   1.400 +  mThis->mIsPending = false;
   1.401 +
   1.402 +  // if this fails?  Callers ignore our return value anyway....
   1.403 +  return AsyncCall(&T::HandleAsyncAbort);
   1.404 +}
   1.405 +
   1.406 +// Each subclass needs to define its own version of this (which just calls this
   1.407 +// base version), else we wind up casting base/derived member function ptrs
   1.408 +template <class T>
   1.409 +inline void HttpAsyncAborter<T>::HandleAsyncAbort()
   1.410 +{
   1.411 +  NS_PRECONDITION(!mCallOnResume, "How did that happen?");
   1.412 +
   1.413 +  if (mThis->mSuspendCount) {
   1.414 +    PR_LOG(gHttpLog, 4,
   1.415 +           ("Waiting until resume to do async notification [this=%p]\n", mThis));
   1.416 +    mCallOnResume = &T::HandleAsyncAbort;
   1.417 +    return;
   1.418 +  }
   1.419 +
   1.420 +  mThis->DoNotifyListener();
   1.421 +
   1.422 +  // finally remove ourselves from the load group.
   1.423 +  if (mThis->mLoadGroup)
   1.424 +    mThis->mLoadGroup->RemoveRequest(mThis, nullptr, mThis->mStatus);
   1.425 +}
   1.426 +
   1.427 +template <class T>
   1.428 +nsresult HttpAsyncAborter<T>::AsyncCall(void (T::*funcPtr)(),
   1.429 +                                   nsRunnableMethod<T> **retval)
   1.430 +{
   1.431 +  nsresult rv;
   1.432 +
   1.433 +  nsRefPtr<nsRunnableMethod<T> > event = NS_NewRunnableMethod(mThis, funcPtr);
   1.434 +  rv = NS_DispatchToCurrentThread(event);
   1.435 +  if (NS_SUCCEEDED(rv) && retval) {
   1.436 +    *retval = event;
   1.437 +  }
   1.438 +
   1.439 +  return rv;
   1.440 +}
   1.441 +
   1.442 +} // namespace net
   1.443 +} // namespace mozilla
   1.444 +
   1.445 +#endif // mozilla_net_HttpBaseChannel_h

mercurial