gecko-dev/dom/fetch/Fetch.h

226 строки
5.9 KiB
C
Исходник Обычный вид История

/* -*- 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/. */
#ifndef mozilla_dom_Fetch_h
#define mozilla_dom_Fetch_h
#include "nsIInputStreamPump.h"
#include "nsIStreamLoader.h"
#include "nsCOMPtr.h"
#include "nsError.h"
#include "nsProxyRelease.h"
#include "nsString.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/RequestBinding.h"
#include "mozilla/dom/workers/bindings/WorkerFeature.h"
class nsIGlobalObject;
namespace mozilla {
namespace dom {
class ArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams;
class InternalRequest;
class OwningArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams;
class RequestOrUSVString;
namespace workers {
class WorkerPrivate;
} // namespace workers
already_AddRefed<Promise>
FetchRequest(nsIGlobalObject* aGlobal, const RequestOrUSVString& aInput,
const RequestInit& aInit, ErrorResult& aRv);
nsresult
UpdateRequestReferrer(nsIGlobalObject* aGlobal, InternalRequest* aRequest);
/*
* 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 OwningArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams& aBodyInit,
nsIInputStream** aStream,
nsCString& aContentType);
/*
* Non-owning version.
*/
nsresult
ExtractByteStreamFromBody(const ArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams& aBodyInit,
nsIInputStream** aStream,
nsCString& aContentType);
template <class Derived> class FetchBodyFeature;
/*
* 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.
*/
template <class Derived>
class FetchBody {
public:
bool
BodyUsed() const { return mBodyUsed; }
already_AddRefed<Promise>
ArrayBuffer(ErrorResult& aRv)
{
return ConsumeBody(CONSUME_ARRAYBUFFER, aRv);
}
already_AddRefed<Promise>
Blob(ErrorResult& aRv)
{
return ConsumeBody(CONSUME_BLOB, aRv);
}
already_AddRefed<Promise>
FormData(ErrorResult& aRv)
{
return ConsumeBody(CONSUME_FORMDATA, aRv);
}
already_AddRefed<Promise>
Json(ErrorResult& aRv)
{
return ConsumeBody(CONSUME_JSON, aRv);
}
already_AddRefed<Promise>
Text(ErrorResult& aRv)
{
return ConsumeBody(CONSUME_TEXT, aRv);
}
// Utility public methods accessed by various runnables.
void
BeginConsumeBodyMainThread();
void
ContinueConsumeBody(nsresult aStatus, uint32_t aLength, uint8_t* aResult);
void
CancelPump();
void
SetBodyUsed()
{
mBodyUsed = true;
}
// Always set whenever the FetchBody is created on the worker thread.
workers::WorkerPrivate* mWorkerPrivate;
// Set when consuming the body is attempted on a worker.
// Unset when consumption is done/aborted.
nsAutoPtr<workers::WorkerFeature> mFeature;
protected:
FetchBody();
virtual ~FetchBody();
void
SetMimeType();
private:
enum ConsumeType
{
CONSUME_ARRAYBUFFER,
CONSUME_BLOB,
CONSUME_FORMDATA,
CONSUME_JSON,
CONSUME_TEXT,
};
Derived*
DerivedClass() const
{
return static_cast<Derived*>(const_cast<FetchBody*>(this));
}
nsresult
BeginConsumeBody();
already_AddRefed<Promise>
ConsumeBody(ConsumeType aType, ErrorResult& aRv);
bool
AddRefObject();
void
ReleaseObject();
bool
RegisterFeature();
void
UnregisterFeature();
bool
IsOnTargetThread()
{
return NS_IsMainThread() == !mWorkerPrivate;
}
void
AssertIsOnTargetThread()
{
MOZ_ASSERT(IsOnTargetThread());
}
// Only ever set once, always on target thread.
bool mBodyUsed;
nsCString mMimeType;
// Only touched on target thread.
ConsumeType mConsumeType;
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<Promise> mConsumePromise;
DebugOnly<bool> mReadDone;
nsMainThreadPtrHandle<nsIInputStreamPump> mConsumeBodyPump;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_Fetch_h