/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
namespace ipc { class PrincipalInfo;
} // namespace ipc
namespace dom {
class BlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString; class
BlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrReadableStreamOrUSVString; class BlobImpl; class InternalRequest; class
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString;
class ReadableStreamDefaultReader; class RequestOrUTF8String; class WorkerPrivate;
namespace fetch { using BodyInit =
BlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString; using ResponseBodyInit =
BlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrReadableStreamOrUSVString; using OwningBodyInit =
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString;
}; // namespace fetch
/* * Creates an nsIInputStream based on the fetch specifications 'extract a byte * stream algorithm' - http://fetch.spec.whatwg.org/#concept-bodyinit-extract. * Stores content type in out param aContentType.
*/
nsresult ExtractByteStreamFromBody(const fetch::OwningBodyInit& aBodyInit,
nsIInputStream** aStream,
nsCString& aContentType,
uint64_t& aContentLength);
/* * Non-owning version. This method should go away when BodyInit will contain * ReadableStream.
*/
nsresult ExtractByteStreamFromBody(const fetch::ResponseBodyInit& aBodyInit,
nsIInputStream** aStream,
nsCString& aContentType,
uint64_t& aContentLength);
/* * FetchBody's body consumption uses nsIInputStreamPump to read from the * underlying stream to a block of memory, which is then adopted by * ContinueConsumeBody() and converted to the right type based on the JS * function called. * * Use of the nsIInputStreamPump complicates things on the worker thread. * The solution used here is similar to WebSockets. * The difference is that we are only interested in completion and not data * events, and nsIInputStreamPump can only deliver completion on the main * thread. * * Before starting the pump on the main thread, we addref the FetchBody to keep * it alive. Then we add a feature, to track the status of the worker. * * ContinueConsumeBody() is the function that cleans things up in both success * and error conditions and so all callers call it with the appropriate status. * * Once the read is initiated on the main thread there are two possibilities. * * 1) Pump finishes before worker has finished Running. * In this case we adopt the data and dispatch a runnable to the worker, * which derefs FetchBody and removes the feature and resolves the Promise. * * 2) Pump still working while worker has stopped Running. * The feature is Notify()ed and ContinueConsumeBody() is called with * NS_BINDING_ABORTED. We first Cancel() the pump using a sync runnable to * ensure that mFetchBody remains alive (since mConsumeBodyPump is strongly * held by it) until pump->Cancel() is called. OnStreamComplete() will not * do anything if the error code is NS_BINDING_ABORTED, so we don't have to * worry about keeping anything alive. * * The pump is always released on the main thread.
*/
class FetchBodyBase : public nsISupports { public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(FetchBodyBase)
protected: virtual ~FetchBodyBase() = default;
RefPtr<ReadableStream> mReadableStreamBody;
};
template <class Derived> class FetchBody : public FetchBodyBase, public AbortFollower { public: using FetchBodyBase::QueryInterface;
// If the body contains a ReadableStream body object, this method produces a // tee() of it. // // This is marked as a script boundary minimize changes required for // annotation while we work out how to correctly annotate this code. // Tracked in Bug 1750650.
MOZ_CAN_RUN_SCRIPT_BOUNDARY void MaybeTeeReadableStreamBody(JSContext* aCx, ReadableStream** aBodyOut,
FetchStreamReader** aStreamReader,
nsIInputStream** aInputStream,
ErrorResult& aRv);
// Utility public methods accessed by various runnables.
// This method _must_ be called in order to set the body as used. If the body // is a ReadableStream, this method will start reading the stream. // More in details, this method does: // 1) It uses an internal flag to track if the body is used. This is tracked // separately from the ReadableStream disturbed state due to purely native // streams. // 2) If there is a ReadableStream reflector for the native stream it is // Locked. // 3) If there is a JS ReadableStream then we begin pumping it into the native // body stream. This effectively locks and disturbs the stream. // // Note that JSContext is used only if there is a ReadableStream (this can // happen because the body is a ReadableStream or because attribute body has // already been used by content). If something goes wrong using // ReadableStream, errors will be reported via ErrorResult and not as JS // exceptions in JSContext. This is done in order to have a centralized error // reporting way. // // Exceptions generated when reading from the ReadableStream are directly sent // to the Console. void SetBodyUsed(JSContext* aCx, ErrorResult& aRv);
// Only ever set once, always on target thread. bool mBodyUsed;
// The main-thread event target for runnable dispatching.
nsCOMPtr<nsISerialEventTarget> mMainThreadEventTarget;
};
class EmptyBody final : public FetchBody<EmptyBody> {
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(EmptyBody,
FetchBody<EmptyBody>)
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.