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_BodyConsumer_h 8 #define mozilla_dom_BodyConsumer_h 9 10 #include "mozilla/dom/AbortSignal.h" 11 #include "mozilla/dom/MutableBlobStorage.h" 12 #include "nsIInputStreamPump.h" 13 #include "nsNetUtil.h" 14 #include "nsIObserver.h" 15 #include "nsWeakReference.h" 16 17 class nsIThread; 18 19 namespace mozilla { 20 namespace dom { 21 22 class Promise; 23 class ThreadSafeWorkerRef; 24 25 // In order to keep alive the object all the time, we use a ThreadSafeWorkerRef, 26 // if created on workers. 27 class BodyConsumer final : public nsIObserver, 28 public nsSupportsWeakReference, 29 public AbortFollower { 30 public: 31 NS_DECL_THREADSAFE_ISUPPORTS 32 NS_DECL_NSIOBSERVER 33 34 enum ConsumeType { 35 CONSUME_ARRAYBUFFER, 36 CONSUME_BLOB, 37 CONSUME_FORMDATA, 38 CONSUME_JSON, 39 CONSUME_TEXT, 40 }; 41 42 /** 43 * Returns a promise which will be resolved when the body is completely 44 * consumed and converted to the wanted type (See ConsumeType). 45 * 46 * @param aGlobal the global to construct the Promise. 47 * @param aMainThreadEventTarget the main-thread event target. The reading 48 * needs to start on the main-thread because of nsIInputStreamPump. 49 * @param aBodyStream the stream to read. 50 * @param aSignalImpl an AbortSignal object. Optional. 51 * @param aType the consume type. 52 * @param aBodyBlobURISpec this is used only if the consume type is 53 * CONSUME_BLOB. Optional. 54 * @param aBodyLocalPath local path in case the blob is created from a local 55 * file. Used only by CONSUME_BLOB. Optional. 56 * @param aBodyMimeType the mime-type for blob. Used only by CONSUME_BLOB. 57 * Optional. 58 * @param aBlobStorageType Blobs can be saved in temporary file. This is the 59 * type of blob storage to use. Used only by CONSUME_BLOB. 60 * @param aRv An ErrorResult. 61 */ 62 static already_AddRefed<Promise> Create( 63 nsIGlobalObject* aGlobal, nsIEventTarget* aMainThreadEventTarget, 64 nsIInputStream* aBodyStream, AbortSignalImpl* aSignalImpl, 65 ConsumeType aType, const nsACString& aBodyBlobURISpec, 66 const nsAString& aBodyLocalPath, const nsACString& aBodyMimeType, 67 MutableBlobStorage::MutableBlobStorageType aBlobStorageType, 68 ErrorResult& aRv); 69 70 void ReleaseObject(); 71 72 void BeginConsumeBodyMainThread(ThreadSafeWorkerRef* aWorkerRef); 73 74 void OnBlobResult(BlobImpl* aBlobImpl, 75 ThreadSafeWorkerRef* aWorkerRef = nullptr); 76 77 void ContinueConsumeBody(nsresult aStatus, uint32_t aLength, uint8_t* aResult, 78 bool aShuttingDown = false); 79 80 void ContinueConsumeBlobBody(BlobImpl* aBlobImpl, bool aShuttingDown = false); 81 82 void DispatchContinueConsumeBlobBody(BlobImpl* aBlobImpl, 83 ThreadSafeWorkerRef* aWorkerRef); 84 85 void ShutDownMainThreadConsuming(); 86 NullifyConsumeBodyPump()87 void NullifyConsumeBodyPump() { 88 mShuttingDown = true; 89 mConsumeBodyPump = nullptr; 90 } 91 92 // AbortFollower 93 void Abort() override; 94 95 private: 96 BodyConsumer(nsIEventTarget* aMainThreadEventTarget, 97 nsIGlobalObject* aGlobalObject, nsIInputStream* aBodyStream, 98 Promise* aPromise, ConsumeType aType, 99 const nsACString& aBodyBlobURISpec, 100 const nsAString& aBodyLocalPath, const nsACString& aBodyMimeType, 101 MutableBlobStorage::MutableBlobStorageType aBlobStorageType); 102 103 ~BodyConsumer(); 104 105 nsresult GetBodyLocalFile(nsIFile** aFile) const; 106 107 void AssertIsOnTargetThread() const; 108 109 nsCOMPtr<nsIThread> mTargetThread; 110 nsCOMPtr<nsIEventTarget> mMainThreadEventTarget; 111 112 // This is nullified when the consuming of the body starts. 113 nsCOMPtr<nsIInputStream> mBodyStream; 114 115 MutableBlobStorage::MutableBlobStorageType mBlobStorageType; 116 nsCString mBodyMimeType; 117 118 nsCString mBodyBlobURISpec; 119 nsString mBodyLocalPath; 120 121 nsCOMPtr<nsIGlobalObject> mGlobal; 122 123 // Touched on the main-thread only. 124 nsCOMPtr<nsIInputStreamPump> mConsumeBodyPump; 125 126 // Only ever set once, always on target thread. 127 ConsumeType mConsumeType; 128 RefPtr<Promise> mConsumePromise; 129 130 // touched only on the target thread. 131 bool mBodyConsumed; 132 133 // touched only on the main-thread. 134 bool mShuttingDown; 135 }; 136 137 } // namespace dom 138 } // namespace mozilla 139 140 #endif // mozilla_dom_BodyConsumer_h 141