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