netwerk/protocol/http/HttpBaseChannel.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

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: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* vim: set sw=2 ts=8 et tw=80 : */
michael@0 3
michael@0 4 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 5 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 7
michael@0 8 #ifndef mozilla_net_HttpBaseChannel_h
michael@0 9 #define mozilla_net_HttpBaseChannel_h
michael@0 10
michael@0 11 #include "nsHttp.h"
michael@0 12 #include "nsAutoPtr.h"
michael@0 13 #include "nsHashPropertyBag.h"
michael@0 14 #include "nsProxyInfo.h"
michael@0 15 #include "nsHttpRequestHead.h"
michael@0 16 #include "nsHttpResponseHead.h"
michael@0 17 #include "nsHttpConnectionInfo.h"
michael@0 18 #include "nsIEncodedChannel.h"
michael@0 19 #include "nsIHttpChannel.h"
michael@0 20 #include "nsHttpHandler.h"
michael@0 21 #include "nsIHttpChannelInternal.h"
michael@0 22 #include "nsIUploadChannel.h"
michael@0 23 #include "nsIUploadChannel2.h"
michael@0 24 #include "nsIProgressEventSink.h"
michael@0 25 #include "nsIURI.h"
michael@0 26 #include "nsIEffectiveTLDService.h"
michael@0 27 #include "nsIStringEnumerator.h"
michael@0 28 #include "nsISupportsPriority.h"
michael@0 29 #include "nsIApplicationCache.h"
michael@0 30 #include "nsIResumableChannel.h"
michael@0 31 #include "nsITraceableChannel.h"
michael@0 32 #include "nsILoadContext.h"
michael@0 33 #include "mozilla/net/NeckoCommon.h"
michael@0 34 #include "nsThreadUtils.h"
michael@0 35 #include "PrivateBrowsingChannel.h"
michael@0 36 #include "mozilla/net/DNS.h"
michael@0 37 #include "nsITimedChannel.h"
michael@0 38 #include "nsISecurityConsoleMessage.h"
michael@0 39
michael@0 40 extern PRLogModuleInfo *gHttpLog;
michael@0 41
michael@0 42 namespace mozilla {
michael@0 43 namespace net {
michael@0 44
michael@0 45 /*
michael@0 46 * This class is a partial implementation of nsIHttpChannel. It contains code
michael@0 47 * shared by nsHttpChannel and HttpChannelChild.
michael@0 48 * - Note that this class has nothing to do with nsBaseChannel, which is an
michael@0 49 * earlier effort at a base class for channels that somehow never made it all
michael@0 50 * the way to the HTTP channel.
michael@0 51 */
michael@0 52 class HttpBaseChannel : public nsHashPropertyBag
michael@0 53 , public nsIEncodedChannel
michael@0 54 , public nsIHttpChannel
michael@0 55 , public nsIHttpChannelInternal
michael@0 56 , public nsIUploadChannel
michael@0 57 , public nsIUploadChannel2
michael@0 58 , public nsISupportsPriority
michael@0 59 , public nsIResumableChannel
michael@0 60 , public nsITraceableChannel
michael@0 61 , public PrivateBrowsingChannel<HttpBaseChannel>
michael@0 62 , public nsITimedChannel
michael@0 63 {
michael@0 64 public:
michael@0 65 NS_DECL_ISUPPORTS_INHERITED
michael@0 66 NS_DECL_NSIUPLOADCHANNEL
michael@0 67 NS_DECL_NSIUPLOADCHANNEL2
michael@0 68 NS_DECL_NSITRACEABLECHANNEL
michael@0 69 NS_DECL_NSITIMEDCHANNEL
michael@0 70
michael@0 71 HttpBaseChannel();
michael@0 72 virtual ~HttpBaseChannel();
michael@0 73
michael@0 74 virtual nsresult Init(nsIURI *aURI, uint32_t aCaps, nsProxyInfo *aProxyInfo,
michael@0 75 uint32_t aProxyResolveFlags,
michael@0 76 nsIURI *aProxyURI);
michael@0 77
michael@0 78 // nsIRequest
michael@0 79 NS_IMETHOD GetName(nsACString& aName);
michael@0 80 NS_IMETHOD IsPending(bool *aIsPending);
michael@0 81 NS_IMETHOD GetStatus(nsresult *aStatus);
michael@0 82 NS_IMETHOD GetLoadGroup(nsILoadGroup **aLoadGroup);
michael@0 83 NS_IMETHOD SetLoadGroup(nsILoadGroup *aLoadGroup);
michael@0 84 NS_IMETHOD GetLoadFlags(nsLoadFlags *aLoadFlags);
michael@0 85 NS_IMETHOD SetLoadFlags(nsLoadFlags aLoadFlags);
michael@0 86
michael@0 87 // nsIChannel
michael@0 88 NS_IMETHOD GetOriginalURI(nsIURI **aOriginalURI);
michael@0 89 NS_IMETHOD SetOriginalURI(nsIURI *aOriginalURI);
michael@0 90 NS_IMETHOD GetURI(nsIURI **aURI);
michael@0 91 NS_IMETHOD GetOwner(nsISupports **aOwner);
michael@0 92 NS_IMETHOD SetOwner(nsISupports *aOwner);
michael@0 93 NS_IMETHOD GetNotificationCallbacks(nsIInterfaceRequestor **aCallbacks);
michael@0 94 NS_IMETHOD SetNotificationCallbacks(nsIInterfaceRequestor *aCallbacks);
michael@0 95 NS_IMETHOD GetContentType(nsACString& aContentType);
michael@0 96 NS_IMETHOD SetContentType(const nsACString& aContentType);
michael@0 97 NS_IMETHOD GetContentCharset(nsACString& aContentCharset);
michael@0 98 NS_IMETHOD SetContentCharset(const nsACString& aContentCharset);
michael@0 99 NS_IMETHOD GetContentDisposition(uint32_t *aContentDisposition);
michael@0 100 NS_IMETHOD SetContentDisposition(uint32_t aContentDisposition);
michael@0 101 NS_IMETHOD GetContentDispositionFilename(nsAString& aContentDispositionFilename);
michael@0 102 NS_IMETHOD SetContentDispositionFilename(const nsAString& aContentDispositionFilename);
michael@0 103 NS_IMETHOD GetContentDispositionHeader(nsACString& aContentDispositionHeader);
michael@0 104 NS_IMETHOD GetContentLength(int64_t *aContentLength);
michael@0 105 NS_IMETHOD SetContentLength(int64_t aContentLength);
michael@0 106 NS_IMETHOD Open(nsIInputStream **aResult);
michael@0 107
michael@0 108 // nsIEncodedChannel
michael@0 109 NS_IMETHOD GetApplyConversion(bool *value);
michael@0 110 NS_IMETHOD SetApplyConversion(bool value);
michael@0 111 NS_IMETHOD GetContentEncodings(nsIUTF8StringEnumerator** aEncodings);
michael@0 112
michael@0 113 // HttpBaseChannel::nsIHttpChannel
michael@0 114 NS_IMETHOD GetRequestMethod(nsACString& aMethod);
michael@0 115 NS_IMETHOD SetRequestMethod(const nsACString& aMethod);
michael@0 116 NS_IMETHOD GetReferrer(nsIURI **referrer);
michael@0 117 NS_IMETHOD SetReferrer(nsIURI *referrer);
michael@0 118 NS_IMETHOD GetProxyURI(nsIURI **proxyURI);
michael@0 119 NS_IMETHOD GetRequestHeader(const nsACString& aHeader, nsACString& aValue);
michael@0 120 NS_IMETHOD SetRequestHeader(const nsACString& aHeader,
michael@0 121 const nsACString& aValue, bool aMerge);
michael@0 122 NS_IMETHOD VisitRequestHeaders(nsIHttpHeaderVisitor *visitor);
michael@0 123 NS_IMETHOD GetResponseHeader(const nsACString &header, nsACString &value);
michael@0 124 NS_IMETHOD SetResponseHeader(const nsACString& header,
michael@0 125 const nsACString& value, bool merge);
michael@0 126 NS_IMETHOD VisitResponseHeaders(nsIHttpHeaderVisitor *visitor);
michael@0 127 NS_IMETHOD GetAllowPipelining(bool *value);
michael@0 128 NS_IMETHOD SetAllowPipelining(bool value);
michael@0 129 NS_IMETHOD GetRedirectionLimit(uint32_t *value);
michael@0 130 NS_IMETHOD SetRedirectionLimit(uint32_t value);
michael@0 131 NS_IMETHOD IsNoStoreResponse(bool *value);
michael@0 132 NS_IMETHOD IsNoCacheResponse(bool *value);
michael@0 133 NS_IMETHOD GetResponseStatus(uint32_t *aValue);
michael@0 134 NS_IMETHOD GetResponseStatusText(nsACString& aValue);
michael@0 135 NS_IMETHOD GetRequestSucceeded(bool *aValue);
michael@0 136 NS_IMETHOD RedirectTo(nsIURI *newURI);
michael@0 137
michael@0 138 // nsIHttpChannelInternal
michael@0 139 NS_IMETHOD GetDocumentURI(nsIURI **aDocumentURI);
michael@0 140 NS_IMETHOD SetDocumentURI(nsIURI *aDocumentURI);
michael@0 141 NS_IMETHOD GetRequestVersion(uint32_t *major, uint32_t *minor);
michael@0 142 NS_IMETHOD GetResponseVersion(uint32_t *major, uint32_t *minor);
michael@0 143 NS_IMETHOD SetCookie(const char *aCookieHeader);
michael@0 144 NS_IMETHOD GetForceAllowThirdPartyCookie(bool *aForce);
michael@0 145 NS_IMETHOD SetForceAllowThirdPartyCookie(bool aForce);
michael@0 146 NS_IMETHOD GetCanceled(bool *aCanceled);
michael@0 147 NS_IMETHOD GetChannelIsForDownload(bool *aChannelIsForDownload);
michael@0 148 NS_IMETHOD SetChannelIsForDownload(bool aChannelIsForDownload);
michael@0 149 NS_IMETHOD SetCacheKeysRedirectChain(nsTArray<nsCString> *cacheKeys);
michael@0 150 NS_IMETHOD GetLocalAddress(nsACString& addr);
michael@0 151 NS_IMETHOD GetLocalPort(int32_t* port);
michael@0 152 NS_IMETHOD GetRemoteAddress(nsACString& addr);
michael@0 153 NS_IMETHOD GetRemotePort(int32_t* port);
michael@0 154 NS_IMETHOD GetAllowSpdy(bool *aAllowSpdy);
michael@0 155 NS_IMETHOD SetAllowSpdy(bool aAllowSpdy);
michael@0 156 NS_IMETHOD GetLoadAsBlocking(bool *aLoadAsBlocking);
michael@0 157 NS_IMETHOD SetLoadAsBlocking(bool aLoadAsBlocking);
michael@0 158 NS_IMETHOD GetLoadUnblocked(bool *aLoadUnblocked);
michael@0 159 NS_IMETHOD SetLoadUnblocked(bool aLoadUnblocked);
michael@0 160 NS_IMETHOD GetApiRedirectToURI(nsIURI * *aApiRedirectToURI);
michael@0 161 NS_IMETHOD AddSecurityMessage(const nsAString &aMessageTag, const nsAString &aMessageCategory);
michael@0 162 NS_IMETHOD TakeAllSecurityMessages(nsCOMArray<nsISecurityConsoleMessage> &aMessages);
michael@0 163 NS_IMETHOD GetResponseTimeoutEnabled(bool *aEnable);
michael@0 164 NS_IMETHOD SetResponseTimeoutEnabled(bool aEnable);
michael@0 165
michael@0 166 inline void CleanRedirectCacheChainIfNecessary()
michael@0 167 {
michael@0 168 mRedirectedCachekeys = nullptr;
michael@0 169 }
michael@0 170 NS_IMETHOD HTTPUpgrade(const nsACString & aProtocolName,
michael@0 171 nsIHttpUpgradeListener *aListener);
michael@0 172
michael@0 173 // nsISupportsPriority
michael@0 174 NS_IMETHOD GetPriority(int32_t *value);
michael@0 175 NS_IMETHOD AdjustPriority(int32_t delta);
michael@0 176
michael@0 177 // nsIResumableChannel
michael@0 178 NS_IMETHOD GetEntityID(nsACString& aEntityID);
michael@0 179
michael@0 180 class nsContentEncodings : public nsIUTF8StringEnumerator
michael@0 181 {
michael@0 182 public:
michael@0 183 NS_DECL_ISUPPORTS
michael@0 184 NS_DECL_NSIUTF8STRINGENUMERATOR
michael@0 185
michael@0 186 nsContentEncodings(nsIHttpChannel* aChannel, const char* aEncodingHeader);
michael@0 187 virtual ~nsContentEncodings();
michael@0 188
michael@0 189 private:
michael@0 190 nsresult PrepareForNext(void);
michael@0 191
michael@0 192 // We do not own the buffer. The channel owns it.
michael@0 193 const char* mEncodingHeader;
michael@0 194 const char* mCurStart; // points to start of current header
michael@0 195 const char* mCurEnd; // points to end of current header
michael@0 196
michael@0 197 // Hold a ref to our channel so that it can't go away and take the
michael@0 198 // header with it.
michael@0 199 nsCOMPtr<nsIHttpChannel> mChannel;
michael@0 200
michael@0 201 bool mReady;
michael@0 202 };
michael@0 203
michael@0 204 nsHttpResponseHead * GetResponseHead() const { return mResponseHead; }
michael@0 205 nsHttpRequestHead * GetRequestHead() { return &mRequestHead; }
michael@0 206
michael@0 207 const NetAddr& GetSelfAddr() { return mSelfAddr; }
michael@0 208 const NetAddr& GetPeerAddr() { return mPeerAddr; }
michael@0 209
michael@0 210 public: /* Necko internal use only... */
michael@0 211
michael@0 212
michael@0 213 // Return whether upon a redirect code of httpStatus for method, the
michael@0 214 // request method should be rewritten to GET.
michael@0 215 static bool ShouldRewriteRedirectToGET(uint32_t httpStatus,
michael@0 216 nsHttpRequestHead::ParsedMethodType method);
michael@0 217
michael@0 218 protected:
michael@0 219 nsCOMArray<nsISecurityConsoleMessage> mSecurityConsoleMessages;
michael@0 220
michael@0 221 // Handle notifying listener, removing from loadgroup if request failed.
michael@0 222 void DoNotifyListener();
michael@0 223 virtual void DoNotifyListenerCleanup() = 0;
michael@0 224
michael@0 225 // drop reference to listener, its callbacks, and the progress sink
michael@0 226 void ReleaseListeners();
michael@0 227
michael@0 228 nsresult ApplyContentConversions();
michael@0 229
michael@0 230 void AddCookiesToRequest();
michael@0 231 virtual nsresult SetupReplacementChannel(nsIURI *,
michael@0 232 nsIChannel *,
michael@0 233 bool preserveMethod);
michael@0 234
michael@0 235 // bundle calling OMR observers and marking flag into one function
michael@0 236 inline void CallOnModifyRequestObservers() {
michael@0 237 gHttpHandler->OnModifyRequest(this);
michael@0 238 mRequestObserversCalled = true;
michael@0 239 }
michael@0 240
michael@0 241 // Helper function to simplify getting notification callbacks.
michael@0 242 template <class T>
michael@0 243 void GetCallback(nsCOMPtr<T> &aResult)
michael@0 244 {
michael@0 245 NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup,
michael@0 246 NS_GET_TEMPLATE_IID(T),
michael@0 247 getter_AddRefs(aResult));
michael@0 248 }
michael@0 249
michael@0 250 // Redirect tracking
michael@0 251 // Checks whether or not aURI and mOriginalURI share the same domain.
michael@0 252 bool SameOriginWithOriginalUri(nsIURI *aURI);
michael@0 253
michael@0 254 friend class PrivateBrowsingChannel<HttpBaseChannel>;
michael@0 255
michael@0 256 nsCOMPtr<nsIURI> mURI;
michael@0 257 nsCOMPtr<nsIURI> mOriginalURI;
michael@0 258 nsCOMPtr<nsIURI> mDocumentURI;
michael@0 259 nsCOMPtr<nsIStreamListener> mListener;
michael@0 260 nsCOMPtr<nsISupports> mListenerContext;
michael@0 261 nsCOMPtr<nsILoadGroup> mLoadGroup;
michael@0 262 nsCOMPtr<nsISupports> mOwner;
michael@0 263 nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
michael@0 264 nsCOMPtr<nsIProgressEventSink> mProgressSink;
michael@0 265 nsCOMPtr<nsIURI> mReferrer;
michael@0 266 nsCOMPtr<nsIApplicationCache> mApplicationCache;
michael@0 267
michael@0 268 nsHttpRequestHead mRequestHead;
michael@0 269 nsCOMPtr<nsIInputStream> mUploadStream;
michael@0 270 nsAutoPtr<nsHttpResponseHead> mResponseHead;
michael@0 271 nsRefPtr<nsHttpConnectionInfo> mConnectionInfo;
michael@0 272 nsCOMPtr<nsIProxyInfo> mProxyInfo;
michael@0 273
michael@0 274 nsCString mSpec; // ASCII encoded URL spec
michael@0 275 nsCString mContentTypeHint;
michael@0 276 nsCString mContentCharsetHint;
michael@0 277 nsCString mUserSetCookieHeader;
michael@0 278
michael@0 279 NetAddr mSelfAddr;
michael@0 280 NetAddr mPeerAddr;
michael@0 281
michael@0 282 // HTTP Upgrade Data
michael@0 283 nsCString mUpgradeProtocol;
michael@0 284 nsCOMPtr<nsIHttpUpgradeListener> mUpgradeProtocolCallback;
michael@0 285
michael@0 286 // Resumable channel specific data
michael@0 287 nsCString mEntityID;
michael@0 288 uint64_t mStartPos;
michael@0 289
michael@0 290 nsresult mStatus;
michael@0 291 uint32_t mLoadFlags;
michael@0 292 uint32_t mCaps;
michael@0 293 int16_t mPriority;
michael@0 294 uint8_t mRedirectionLimit;
michael@0 295
michael@0 296 uint32_t mApplyConversion : 1;
michael@0 297 uint32_t mCanceled : 1;
michael@0 298 uint32_t mIsPending : 1;
michael@0 299 uint32_t mWasOpened : 1;
michael@0 300 // if 1 all "http-on-{opening|modify|etc}-request" observers have been called
michael@0 301 uint32_t mRequestObserversCalled : 1;
michael@0 302 uint32_t mResponseHeadersModified : 1;
michael@0 303 uint32_t mAllowPipelining : 1;
michael@0 304 uint32_t mForceAllowThirdPartyCookie : 1;
michael@0 305 uint32_t mUploadStreamHasHeaders : 1;
michael@0 306 uint32_t mInheritApplicationCache : 1;
michael@0 307 uint32_t mChooseApplicationCache : 1;
michael@0 308 uint32_t mLoadedFromApplicationCache : 1;
michael@0 309 uint32_t mChannelIsForDownload : 1;
michael@0 310 uint32_t mTracingEnabled : 1;
michael@0 311 // True if timing collection is enabled
michael@0 312 uint32_t mTimingEnabled : 1;
michael@0 313 uint32_t mAllowSpdy : 1;
michael@0 314 uint32_t mLoadAsBlocking : 1;
michael@0 315 uint32_t mLoadUnblocked : 1;
michael@0 316 uint32_t mResponseTimeoutEnabled : 1;
michael@0 317 // A flag that should be false only if a cross-domain redirect occurred
michael@0 318 uint32_t mAllRedirectsSameOrigin : 1;
michael@0 319
michael@0 320 // Current suspension depth for this channel object
michael@0 321 uint32_t mSuspendCount;
michael@0 322
michael@0 323 nsCOMPtr<nsIURI> mAPIRedirectToURI;
michael@0 324 nsAutoPtr<nsTArray<nsCString> > mRedirectedCachekeys;
michael@0 325
michael@0 326 uint32_t mProxyResolveFlags;
michael@0 327 nsCOMPtr<nsIURI> mProxyURI;
michael@0 328
michael@0 329 uint32_t mContentDispositionHint;
michael@0 330 nsAutoPtr<nsString> mContentDispositionFilename;
michael@0 331
michael@0 332 nsRefPtr<nsHttpHandler> mHttpHandler; // keep gHttpHandler alive
michael@0 333
michael@0 334 // Performance tracking
michael@0 335 // The initiator type (for this resource) - how was the resource referenced in
michael@0 336 // the HTML file.
michael@0 337 nsString mInitiatorType;
michael@0 338 // Number of redirects that has occurred.
michael@0 339 int16_t mRedirectCount;
michael@0 340 // A time value equal to the starting time of the fetch that initiates the
michael@0 341 // redirect.
michael@0 342 mozilla::TimeStamp mRedirectStartTimeStamp;
michael@0 343 // A time value equal to the time immediately after receiving the last byte of
michael@0 344 // the response of the last redirect.
michael@0 345 mozilla::TimeStamp mRedirectEndTimeStamp;
michael@0 346
michael@0 347 PRTime mChannelCreationTime;
michael@0 348 TimeStamp mChannelCreationTimestamp;
michael@0 349 TimeStamp mAsyncOpenTime;
michael@0 350 TimeStamp mCacheReadStart;
michael@0 351 TimeStamp mCacheReadEnd;
michael@0 352 // copied from the transaction before we null out mTransaction
michael@0 353 // so that the timing can still be queried from OnStopRequest
michael@0 354 TimingStruct mTransactionTimings;
michael@0 355 };
michael@0 356
michael@0 357 // Share some code while working around C++'s absurd inability to handle casting
michael@0 358 // of member functions between base/derived types.
michael@0 359 // - We want to store member function pointer to call at resume time, but one
michael@0 360 // such function--HandleAsyncAbort--we want to share between the
michael@0 361 // nsHttpChannel/HttpChannelChild. Can't define it in base class, because
michael@0 362 // then we'd have to cast member function ptr between base/derived class
michael@0 363 // types. Sigh...
michael@0 364 template <class T>
michael@0 365 class HttpAsyncAborter
michael@0 366 {
michael@0 367 public:
michael@0 368 HttpAsyncAborter(T *derived) : mThis(derived), mCallOnResume(0) {}
michael@0 369
michael@0 370 // Aborts channel: calls OnStart/Stop with provided status, removes channel
michael@0 371 // from loadGroup.
michael@0 372 nsresult AsyncAbort(nsresult status);
michael@0 373
michael@0 374 // Does most the actual work.
michael@0 375 void HandleAsyncAbort();
michael@0 376
michael@0 377 // AsyncCall calls a member function asynchronously (via an event).
michael@0 378 // retval isn't refcounted and is set only when event was successfully
michael@0 379 // posted, the event is returned for the purpose of cancelling when needed
michael@0 380 nsresult AsyncCall(void (T::*funcPtr)(),
michael@0 381 nsRunnableMethod<T> **retval = nullptr);
michael@0 382 private:
michael@0 383 T *mThis;
michael@0 384
michael@0 385 protected:
michael@0 386 // Function to be called at resume time
michael@0 387 void (T::* mCallOnResume)(void);
michael@0 388 };
michael@0 389
michael@0 390 template <class T>
michael@0 391 nsresult HttpAsyncAborter<T>::AsyncAbort(nsresult status)
michael@0 392 {
michael@0 393 PR_LOG(gHttpLog, 4,
michael@0 394 ("HttpAsyncAborter::AsyncAbort [this=%p status=%x]\n", mThis, status));
michael@0 395
michael@0 396 mThis->mStatus = status;
michael@0 397 mThis->mIsPending = false;
michael@0 398
michael@0 399 // if this fails? Callers ignore our return value anyway....
michael@0 400 return AsyncCall(&T::HandleAsyncAbort);
michael@0 401 }
michael@0 402
michael@0 403 // Each subclass needs to define its own version of this (which just calls this
michael@0 404 // base version), else we wind up casting base/derived member function ptrs
michael@0 405 template <class T>
michael@0 406 inline void HttpAsyncAborter<T>::HandleAsyncAbort()
michael@0 407 {
michael@0 408 NS_PRECONDITION(!mCallOnResume, "How did that happen?");
michael@0 409
michael@0 410 if (mThis->mSuspendCount) {
michael@0 411 PR_LOG(gHttpLog, 4,
michael@0 412 ("Waiting until resume to do async notification [this=%p]\n", mThis));
michael@0 413 mCallOnResume = &T::HandleAsyncAbort;
michael@0 414 return;
michael@0 415 }
michael@0 416
michael@0 417 mThis->DoNotifyListener();
michael@0 418
michael@0 419 // finally remove ourselves from the load group.
michael@0 420 if (mThis->mLoadGroup)
michael@0 421 mThis->mLoadGroup->RemoveRequest(mThis, nullptr, mThis->mStatus);
michael@0 422 }
michael@0 423
michael@0 424 template <class T>
michael@0 425 nsresult HttpAsyncAborter<T>::AsyncCall(void (T::*funcPtr)(),
michael@0 426 nsRunnableMethod<T> **retval)
michael@0 427 {
michael@0 428 nsresult rv;
michael@0 429
michael@0 430 nsRefPtr<nsRunnableMethod<T> > event = NS_NewRunnableMethod(mThis, funcPtr);
michael@0 431 rv = NS_DispatchToCurrentThread(event);
michael@0 432 if (NS_SUCCEEDED(rv) && retval) {
michael@0 433 *retval = event;
michael@0 434 }
michael@0 435
michael@0 436 return rv;
michael@0 437 }
michael@0 438
michael@0 439 } // namespace net
michael@0 440 } // namespace mozilla
michael@0 441
michael@0 442 #endif // mozilla_net_HttpBaseChannel_h

mercurial