tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsStreamListenerWrapper.h (2103B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #ifndef nsStreamListenerWrapper_h__
      6 #define nsStreamListenerWrapper_h__
      7 
      8 #include "nsCOMPtr.h"
      9 #include "nsIRequest.h"
     10 #include "nsIStreamListener.h"
     11 #include "nsIThreadRetargetableStreamListener.h"
     12 #include "nsIMultiPartChannel.h"
     13 
     14 namespace mozilla {
     15 namespace net {
     16 
     17 // Wrapper class to make replacement of nsHttpChannel's listener
     18 // from JavaScript possible. It is workaround for bug 433711 and 682305.
     19 class nsStreamListenerWrapper final
     20    : public nsIMultiPartChannelListener,
     21      public nsIThreadRetargetableStreamListener {
     22 public:
     23  explicit nsStreamListenerWrapper(nsIStreamListener* listener)
     24      : mListener(listener) {
     25    MOZ_ASSERT(mListener, "no stream listener specified");
     26  }
     27 
     28  NS_DECL_THREADSAFE_ISUPPORTS
     29  NS_FORWARD_SAFE_NSISTREAMLISTENER(mListener)
     30  NS_DECL_NSIMULTIPARTCHANNELLISTENER
     31  NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
     32 
     33  //  Don't use NS_FORWARD_NSIREQUESTOBSERVER(mListener->) here, because we need
     34  //  to release mListener in OnStopRequest, and IDL-generated function doesn't.
     35  NS_IMETHOD OnStartRequest(nsIRequest* aRequest) override {
     36    // OnStartRequest can come after OnStopRequest in certain cases (multipart
     37    // listeners)
     38    nsCOMPtr<nsIMultiPartChannel> multiPartChannel =
     39        do_QueryInterface(aRequest);
     40    if (multiPartChannel) {
     41      mIsMulti = true;
     42    }
     43    return mListener->OnStartRequest(aRequest);
     44  }
     45  NS_IMETHOD OnStopRequest(nsIRequest* aRequest,
     46                           nsresult aStatusCode) override {
     47    nsresult rv = mListener->OnStopRequest(aRequest, aStatusCode);
     48    if (!mIsMulti) {
     49      // Multipart channels can call OnStartRequest again
     50      mListener = nullptr;
     51    }
     52    return rv;
     53  }
     54 
     55 private:
     56  bool mIsMulti{false};
     57  ~nsStreamListenerWrapper() = default;
     58  nsCOMPtr<nsIStreamListener> mListener;
     59 };
     60 
     61 }  // namespace net
     62 }  // namespace mozilla
     63 
     64 #endif  // nsStreamListenerWrapper_h__