diff options
Diffstat (limited to 'dom/fetch/Fetch.cpp')
-rw-r--r-- | dom/fetch/Fetch.cpp | 154 |
1 files changed, 144 insertions, 10 deletions
diff --git a/dom/fetch/Fetch.cpp b/dom/fetch/Fetch.cpp index 8f67c8f385..dbc940ca56 100644 --- a/dom/fetch/Fetch.cpp +++ b/dom/fetch/Fetch.cpp @@ -843,7 +843,7 @@ ExtractFromURLSearchParams(const URLSearchParams& aParams, } // namespace nsresult -ExtractByteStreamFromBody(const OwningArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams& aBodyInit, +ExtractByteStreamFromBody(const fetch::OwningBodyInit& aBodyInit, nsIInputStream** aStream, nsCString& aContentType, uint64_t& aContentLength) @@ -881,7 +881,7 @@ ExtractByteStreamFromBody(const OwningArrayBufferOrArrayBufferViewOrBlobOrFormDa } nsresult -ExtractByteStreamFromBody(const ArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams& aBodyInit, +ExtractByteStreamFromBody(const fetch::BodyInit& aBodyInit, nsIInputStream** aStream, nsCString& aContentType, uint64_t& aContentLength) @@ -919,6 +919,50 @@ ExtractByteStreamFromBody(const ArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUS return NS_ERROR_FAILURE; } +nsresult +ExtractByteStreamFromBody(const fetch::ResponseBodyInit& aBodyInit, + nsIInputStream** aStream, + nsCString& aContentType, + uint64_t& aContentLength) +{ + MOZ_ASSERT(aStream); + MOZ_ASSERT(!*aStream); + + // ReadableStreams should be handled by + // BodyExtractorReadableStream::GetAsStream. + MOZ_ASSERT(!aBodyInit.IsReadableStream()); + + if (aBodyInit.IsArrayBuffer()) { + const ArrayBuffer& buf = aBodyInit.GetAsArrayBuffer(); + return ExtractFromArrayBuffer(buf, aStream, aContentLength); + } + if (aBodyInit.IsArrayBufferView()) { + const ArrayBufferView& buf = aBodyInit.GetAsArrayBufferView(); + return ExtractFromArrayBufferView(buf, aStream, aContentLength); + } + if (aBodyInit.IsBlob()) { + const Blob& blob = aBodyInit.GetAsBlob(); + return ExtractFromBlob(blob, aStream, aContentType, aContentLength); + } + if (aBodyInit.IsFormData()) { + FormData& form = aBodyInit.GetAsFormData(); + return ExtractFromFormData(form, aStream, aContentType, aContentLength); + } + if (aBodyInit.IsUSVString()) { + nsAutoString str; + str.Assign(aBodyInit.GetAsUSVString()); + return ExtractFromUSVString(str, aStream, aContentType, aContentLength); + } + if (aBodyInit.IsURLSearchParams()) { + URLSearchParams& params = aBodyInit.GetAsURLSearchParams(); + return ExtractFromURLSearchParams(params, aStream, aContentType, aContentLength); + } + + NS_NOTREACHED("Should never reach here"); + return NS_ERROR_FAILURE; +} + + template <class Derived> FetchBody<Derived>::FetchBody() : mWorkerPrivate(nullptr) @@ -962,7 +1006,8 @@ FetchBody<Derived>::BodyUsed() const JS::Rooted<JSObject*> body(cx, mReadableStreamBody); if (JS::ReadableStreamIsDisturbed(body) || - JS::ReadableStreamIsLocked(body)) { + JS::ReadableStreamIsLocked(body) || + !JS::ReadableStreamIsReadable(body)) { return true; } } @@ -995,14 +1040,18 @@ FetchBody<Derived>::ConsumeBody(JSContext* aCx, FetchConsumeType aType, ErrorRes SetBodyUsed(); - nsCOMPtr<nsIGlobalObject> global = DerivedClass()->GetParentObject(); - - // If we already created a ReadableStreamBody we have to close it now. + // If we already created a ReadableStreamBody we have to lock it now because + // it may have been shared with other objects.. if (mReadableStreamBody) { JS::Rooted<JSObject*> body(aCx, mReadableStreamBody); - JS::ReadableStreamClose(aCx, body); + LockStream(aCx, body, aRv); + if (NS_WARN_IF(aRv.Failed())) { + return nullptr; + } } + nsCOMPtr<nsIGlobalObject> global = DerivedClass()->GetParentObject(); + RefPtr<Promise> promise = FetchBodyConsumer<Derived>::Create(global, this, signal, aType, aRv); if (NS_WARN_IF(aRv.Failed())) { @@ -1050,6 +1099,23 @@ FetchBody<Response>::SetMimeType(); template <class Derived> void +FetchBody<Derived>::SetReadableStreamBody(JSObject* aBody) +{ + MOZ_ASSERT(!mReadableStreamBody); + MOZ_ASSERT(aBody); + mReadableStreamBody = aBody; +} + +template +void +FetchBody<Request>::SetReadableStreamBody(JSObject* aBody); + +template +void +FetchBody<Response>::SetReadableStreamBody(JSObject* aBody); + +template <class Derived> +void FetchBody<Derived>::GetBody(JSContext* aCx, JS::MutableHandle<JSObject*> aBodyOut, ErrorResult& aRv) @@ -1075,9 +1141,11 @@ FetchBody<Derived>::GetBody(JSContext* aCx, MOZ_ASSERT(body); // If the body has been already consumed, we close the stream. - if (BodyUsed() && !JS::ReadableStreamClose(aCx, body)) { - aRv.StealExceptionFromJSContext(aCx); - return; + if (BodyUsed()) { + LockStream(aCx, body, aRv); + if (NS_WARN_IF(aRv.Failed())) { + return; + } } mReadableStreamBody = body; @@ -1098,6 +1166,72 @@ FetchBody<Response>::GetBody(JSContext* aCx, JS::MutableHandle<JSObject*> aMessage, ErrorResult& aRv); +template <class Derived> +void +FetchBody<Derived>::LockStream(JSContext* aCx, + JS::HandleObject aStream, + ErrorResult& aRv) +{ + // XXXMC: TODO +} + +template +void +FetchBody<Request>::LockStream(JSContext* aCx, + JS::HandleObject aStream, + ErrorResult& aRv); + +template +void +FetchBody<Response>::LockStream(JSContext* aCx, + JS::HandleObject aStream, + ErrorResult& aRv); + +template <class Derived> +void +FetchBody<Derived>::MaybeTeeReadableStreamBody(JSContext* aCx, + JS::MutableHandle<JSObject*> aBodyOut, + ErrorResult& aRv) +{ + MOZ_DIAGNOSTIC_ASSERT(!BodyUsed()); + + if (!mReadableStreamBody) { + return; + } + + JS::Rooted<JSObject*> stream(aCx, mReadableStreamBody); + + // If this is a ReadableStream with an external source, this has been + // generated by a Fetch. In this case, Fetch will be able to recreate it + // again when GetBody() is called. + if (JS::ReadableStreamGetMode(stream) == JS::ReadableStreamMode::ExternalSource) { + aBodyOut.set(nullptr); + return; + } + + JS::Rooted<JSObject*> branch1(aCx); + JS::Rooted<JSObject*> branch2(aCx); + + if (!JS::ReadableStreamTee(aCx, stream, &branch1, &branch2)) { + aRv.StealExceptionFromJSContext(aCx); + return; + } + + mReadableStreamBody = branch1; + aBodyOut.set(branch2); +} + +template +void +FetchBody<Request>::MaybeTeeReadableStreamBody(JSContext* aCx, + JS::MutableHandle<JSObject*> aMessage, + ErrorResult& aRv); + +template +void +FetchBody<Response>::MaybeTeeReadableStreamBody(JSContext* aCx, + JS::MutableHandle<JSObject*> aMessage, + ErrorResult& aRv); } // namespace dom } // namespace mozilla |