tor-browser

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

SimpleChannel.h (4989B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 #ifndef SimpleChannel_h
      7 #define SimpleChannel_h
      8 
      9 #include "mozilla/ResultExtensions.h"
     10 #include "mozilla/UniquePtr.h"
     11 #include "nsBaseChannel.h"
     12 #include "nsIChildChannel.h"
     13 #include "nsCOMPtr.h"
     14 
     15 class nsIChannel;
     16 class nsIInputStream;
     17 class nsILoadInfo;
     18 class nsIRequest;
     19 class nsIStreamListener;
     20 class nsIURI;
     21 
     22 //-----------------------------------------------------------------------------
     23 
     24 namespace mozilla {
     25 
     26 using InputStreamOrReason = Result<nsCOMPtr<nsIInputStream>, nsresult>;
     27 using NotNullRequest = NotNull<nsCOMPtr<nsIRequest>>;
     28 using NotNullCancelable = NotNull<nsCOMPtr<nsICancelable>>;
     29 using RequestOrCancelable = Variant<NotNullRequest, NotNullCancelable>;
     30 using RequestOrReason = Result<RequestOrCancelable, nsresult>;
     31 
     32 namespace net {
     33 
     34 class SimpleChannelCallbacks {
     35 public:
     36  virtual InputStreamOrReason OpenContentStream(bool async,
     37                                                nsIChannel* channel) = 0;
     38 
     39  virtual RequestOrReason StartAsyncRead(nsIStreamListener* stream,
     40                                         nsIChannel* channel) = 0;
     41 
     42  virtual ~SimpleChannelCallbacks() = default;
     43 };
     44 
     45 template <typename F1, typename F2, typename T>
     46 class SimpleChannelCallbacksImpl final : public SimpleChannelCallbacks {
     47 public:
     48  SimpleChannelCallbacksImpl(F1&& aStartAsyncRead, F2&& aOpenContentStream,
     49                             T* context)
     50      : mStartAsyncRead(aStartAsyncRead),
     51        mOpenContentStream(aOpenContentStream),
     52        mContext(context) {}
     53 
     54  virtual ~SimpleChannelCallbacksImpl() = default;
     55 
     56  virtual InputStreamOrReason OpenContentStream(bool async,
     57                                                nsIChannel* channel) override {
     58    return mOpenContentStream(async, channel, mContext);
     59  }
     60 
     61  virtual RequestOrReason StartAsyncRead(nsIStreamListener* listener,
     62                                         nsIChannel* channel) override {
     63    return mStartAsyncRead(listener, channel, mContext);
     64  }
     65 
     66 private:
     67  F1 mStartAsyncRead;
     68  F2 mOpenContentStream;
     69  RefPtr<T> mContext;
     70 };
     71 
     72 class SimpleChannel : public nsBaseChannel, public nsIChildChannel {
     73 public:
     74  NS_DECL_ISUPPORTS_INHERITED
     75  NS_DECL_NSICHILDCHANNEL
     76 
     77  explicit SimpleChannel(UniquePtr<SimpleChannelCallbacks>&& aCallbacks);
     78 
     79 protected:
     80  virtual ~SimpleChannel() = default;
     81 
     82  virtual nsresult OpenContentStream(bool async, nsIInputStream** streamOut,
     83                                     nsIChannel** channel) override;
     84 
     85  virtual nsresult BeginAsyncRead(nsIStreamListener* listener,
     86                                  nsIRequest** request,
     87                                  nsICancelable** cancelableRequest) override;
     88 
     89 private:
     90  UniquePtr<SimpleChannelCallbacks> mCallbacks;
     91 };
     92 
     93 already_AddRefed<nsIChannel> NS_NewSimpleChannelInternal(
     94    nsIURI* aURI, nsILoadInfo* aLoadInfo,
     95    UniquePtr<SimpleChannelCallbacks>&& aCallbacks);
     96 
     97 }  // namespace net
     98 }  // namespace mozilla
     99 
    100 /**
    101 * Creates a simple channel which wraps an input stream created by the given
    102 * callbacks. The callbacks are not called until the underlying AsyncOpen or
    103 * Open methods are called, and correspond to the nsBaseChannel::StartAsyncRead
    104 * and nsBaseChannel::OpenContentStream methods of the same names.
    105 *
    106 * The last two arguments of each callback are the created channel instance,
    107 * and the ref-counted context object passed to NS_NewSimpleChannel. A strong
    108 * reference to that object is guaranteed to be kept alive until after a
    109 * callback successfully completes.
    110 */
    111 template <typename T, typename F1, typename F2>
    112 inline already_AddRefed<nsIChannel> NS_NewSimpleChannel(
    113    nsIURI* aURI, nsILoadInfo* aLoadInfo, T* context, F1&& aStartAsyncRead,
    114    F2&& aOpenContentStream) {
    115  using namespace mozilla;
    116 
    117  auto callbacks = MakeUnique<net::SimpleChannelCallbacksImpl<F1, F2, T>>(
    118      std::forward<F1>(aStartAsyncRead), std::forward<F2>(aOpenContentStream),
    119      context);
    120 
    121  return net::NS_NewSimpleChannelInternal(aURI, aLoadInfo,
    122                                          std::move(callbacks));
    123 }
    124 
    125 template <typename T, typename F1>
    126 inline already_AddRefed<nsIChannel> NS_NewSimpleChannel(nsIURI* aURI,
    127                                                        nsILoadInfo* aLoadInfo,
    128                                                        T* context,
    129                                                        F1&& aStartAsyncRead) {
    130  using namespace mozilla;
    131 
    132  auto openContentStream = [](bool async, nsIChannel* channel, T* context) {
    133    return Err(NS_ERROR_NOT_IMPLEMENTED);
    134  };
    135 
    136  return NS_NewSimpleChannel(aURI, aLoadInfo, context,
    137                             std::forward<F1>(aStartAsyncRead),
    138                             std::move(openContentStream));
    139 }
    140 
    141 #endif  // SimpleChannel_h