tor-browser

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

FetchStreamReader.h (4330B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef mozilla_dom_FetchStreamReader_h
      8 #define mozilla_dom_FetchStreamReader_h
      9 
     10 #include "js/RootingAPI.h"
     11 #include "js/TypeDecls.h"
     12 #include "mozilla/Attributes.h"
     13 #include "mozilla/WeakPtr.h"
     14 #include "mozilla/dom/FetchBinding.h"
     15 #include "mozilla/dom/PromiseNativeHandler.h"
     16 #include "nsIAsyncOutputStream.h"
     17 #include "nsIGlobalObject.h"
     18 
     19 namespace mozilla::dom {
     20 
     21 class ReadableStream;
     22 class ReadableStreamDefaultReader;
     23 class StrongWorkerRef;
     24 
     25 class FetchStreamReader;
     26 
     27 class OutputStreamHolder final : public nsIOutputStreamCallback {
     28 public:
     29  NS_DECL_ISUPPORTS
     30  NS_DECL_NSIOUTPUTSTREAMCALLBACK
     31 
     32  OutputStreamHolder(FetchStreamReader* aReader, nsIAsyncOutputStream* aOutput);
     33 
     34  nsresult Init(JSContext* aCx);
     35 
     36  void Shutdown();
     37 
     38  // These just proxy the calls to the nsIAsyncOutputStream
     39  nsresult AsyncWait(uint32_t aFlags, uint32_t aRequestedCount,
     40                     nsIEventTarget* aEventTarget);
     41  nsresult Write(char* aBuffer, uint32_t aLength, uint32_t* aWritten) {
     42    return mOutput->Write(aBuffer, aLength, aWritten);
     43  }
     44  nsresult CloseWithStatus(nsresult aStatus) {
     45    return mOutput->CloseWithStatus(aStatus);
     46  }
     47  nsresult StreamStatus() { return mOutput->StreamStatus(); }
     48 
     49  nsIAsyncOutputStream* GetOutputStream() { return mOutput; }
     50 
     51 private:
     52  ~OutputStreamHolder();
     53 
     54  RefPtr<FetchStreamReader> mAsyncWaitReader;
     55  // WeakPtr to avoid cycles
     56  WeakPtr<FetchStreamReader> mReader;
     57  // To ensure the worker sticks around
     58  RefPtr<StrongWorkerRef> mAsyncWaitWorkerRef;
     59  RefPtr<StrongWorkerRef> mWorkerRef;
     60  nsCOMPtr<nsIAsyncOutputStream> mOutput;
     61 };
     62 
     63 class FetchStreamReader final : public nsISupports, public SupportsWeakPtr {
     64 public:
     65  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
     66  NS_DECL_CYCLE_COLLECTION_CLASS(FetchStreamReader)
     67 
     68  // This creates a nsIInputStream able to retrieve data from the ReadableStream
     69  // object. The reading starts when StartConsuming() is called.
     70  static nsresult Create(JSContext* aCx, nsIGlobalObject* aGlobal,
     71                         FetchStreamReader** aStreamReader,
     72                         nsIInputStream** aInputStream);
     73 
     74  bool OnOutputStreamReady();
     75 
     76  MOZ_CAN_RUN_SCRIPT
     77  void ChunkSteps(JSContext* aCx, JS::Handle<JS::Value> aChunk,
     78                  ErrorResult& aRv);
     79  MOZ_CAN_RUN_SCRIPT
     80  void CloseSteps(JSContext* aCx, ErrorResult& aRv);
     81  MOZ_CAN_RUN_SCRIPT
     82  void ErrorSteps(JSContext* aCx, JS::Handle<JS::Value> aError,
     83                  ErrorResult& aRv);
     84 
     85  // Idempotently close the output stream and null out all state. If aCx is
     86  // provided, the reader will also be canceled.  aStatus must be a DOM error
     87  // as understood by DOMException because it will be provided as the
     88  // cancellation reason.
     89  //
     90  // This is a script boundary minimize annotation changes required while
     91  // we figure out how to handle some more tricky annotation cases (for
     92  // example, the destructor of this class. Tracking under Bug 1750656)
     93  MOZ_CAN_RUN_SCRIPT_BOUNDARY
     94  void CloseAndRelease(JSContext* aCx, nsresult aStatus);
     95 
     96  void StartConsuming(JSContext* aCx, ReadableStream* aStream,
     97                      ErrorResult& aRv);
     98 
     99 private:
    100  explicit FetchStreamReader(nsIGlobalObject* aGlobal);
    101  ~FetchStreamReader();
    102 
    103  nsresult WriteBuffer();
    104 
    105  // Attempt to copy data from mBuffer into mPipeOut. Returns `true` if data was
    106  // written, and AsyncWait callbacks or FetchReadRequest calls have been set up
    107  // to write more data in the future, and `false` otherwise.
    108  MOZ_CAN_RUN_SCRIPT
    109  bool Process(JSContext* aCx);
    110 
    111  void ReportErrorToConsole(JSContext* aCx, JS::Handle<JS::Value> aValue);
    112 
    113  nsCOMPtr<nsIGlobalObject> mGlobal;
    114  nsCOMPtr<nsIEventTarget> mOwningEventTarget;
    115 
    116  RefPtr<OutputStreamHolder> mOutput;
    117 
    118  RefPtr<ReadableStreamDefaultReader> mReader;
    119 
    120  nsTArray<uint8_t> mBuffer;
    121  uint32_t mBufferRemaining = 0;
    122  uint32_t mBufferOffset = 0;
    123 
    124  bool mHasOutstandingReadRequest = false;
    125  bool mStreamClosed = false;
    126 };
    127 
    128 }  // namespace mozilla::dom
    129 
    130 #endif  // mozilla_dom_FetchStreamReader_h