FetchBodyOwner.cpp [plain text]
#include "config.h"
#include "FetchBodyOwner.h"
#if ENABLE(FETCH_API)
#include "ExceptionCode.h"
#include "FetchLoader.h"
#include "FetchResponseSource.h"
#include "JSBlob.h"
#include "ResourceResponse.h"
namespace WebCore {
FetchBodyOwner::FetchBodyOwner(ScriptExecutionContext& context, FetchBody&& body)
: ActiveDOMObject(&context)
, m_body(WTFMove(body))
{
suspendIfNeeded();
}
void FetchBodyOwner::stop()
{
if (m_blobLoader) {
if (m_blobLoader->loader)
m_blobLoader->loader->stop();
}
ASSERT(!m_blobLoader);
}
bool FetchBodyOwner::isDisturbed() const
{
if (m_isDisturbed)
return true;
#if ENABLE(STREAMS_API)
if (m_readableStreamSource && m_readableStreamSource->isReadableStreamLocked())
return true;
#endif
return false;
}
void FetchBodyOwner::arrayBuffer(DeferredWrapper&& promise)
{
if (m_body.isEmpty()) {
fulfillPromiseWithArrayBuffer(promise, nullptr, 0);
return;
}
if (isDisturbed()) {
promise.reject(TypeError);
return;
}
m_isDisturbed = true;
m_body.arrayBuffer(*this, WTFMove(promise));
}
void FetchBodyOwner::blob(DeferredWrapper&& promise)
{
if (m_body.isEmpty()) {
promise.resolve(Blob::create());
return;
}
if (isDisturbed()) {
promise.reject(TypeError);
return;
}
m_isDisturbed = true;
m_body.blob(*this, WTFMove(promise));
}
void FetchBodyOwner::formData(DeferredWrapper&& promise)
{
if (m_body.isEmpty()) {
promise.reject(0);
return;
}
if (isDisturbed()) {
promise.reject(TypeError);
return;
}
m_isDisturbed = true;
m_body.formData(*this, WTFMove(promise));
}
void FetchBodyOwner::json(DeferredWrapper&& promise)
{
if (m_body.isEmpty()) {
promise.reject(SYNTAX_ERR);
return;
}
if (isDisturbed()) {
promise.reject(TypeError);
return;
}
m_isDisturbed = true;
m_body.json(*this, WTFMove(promise));
}
void FetchBodyOwner::text(DeferredWrapper&& promise)
{
if (m_body.isEmpty()) {
promise.resolve(String());
return;
}
if (isDisturbed()) {
promise.reject(TypeError);
return;
}
m_isDisturbed = true;
m_body.text(*this, WTFMove(promise));
}
void FetchBodyOwner::loadBlob(Blob& blob, FetchLoader::Type type)
{
ASSERT(isDisturbed());
ASSERT(!m_blobLoader);
if (!scriptExecutionContext()) {
m_body.loadingFailed();
return;
}
m_blobLoader = { *this };
m_blobLoader->loader = std::make_unique<FetchLoader>(type, *m_blobLoader);
m_blobLoader->loader->start(*scriptExecutionContext(), blob);
if (!m_blobLoader->loader->isStarted()) {
m_body.loadingFailed();
m_blobLoader = Nullopt;
return;
}
setPendingActivity(this);
}
void FetchBodyOwner::finishBlobLoading()
{
ASSERT(m_blobLoader);
m_blobLoader = Nullopt;
unsetPendingActivity(this);
}
void FetchBodyOwner::loadedBlobAsText(String&& text)
{
m_body.loadedAsText(WTFMove(text));
}
void FetchBodyOwner::blobLoadingSucceeded()
{
ASSERT(m_body.type() == FetchBody::Type::Blob);
#if ENABLE(STREAMS_API)
if (m_readableStreamSource) {
m_readableStreamSource->close();
m_readableStreamSource = nullptr;
}
#endif
finishBlobLoading();
}
void FetchBodyOwner::blobLoadingFailed()
{
#if ENABLE(STREAMS_API)
if (m_readableStreamSource) {
if (!m_readableStreamSource->isCancelling())
m_readableStreamSource->error(ASCIILiteral("Blob loading failed"));
m_readableStreamSource = nullptr;
} else
#endif
m_body.loadingFailed();
finishBlobLoading();
}
void FetchBodyOwner::blobChunk(const char* data, size_t size)
{
#if ENABLE(STREAMS_API)
ASSERT(m_readableStreamSource);
m_readableStreamSource->enqueue(ArrayBuffer::tryCreate(data, size));
#else
UNUSED_PARAM(data);
UNUSED_PARAM(size);
#endif
}
FetchBodyOwner::BlobLoader::BlobLoader(FetchBodyOwner& owner)
: owner(owner)
{
}
void FetchBodyOwner::BlobLoader::didReceiveResponse(const ResourceResponse& response)
{
if (response.httpStatusCode() != 200)
didFail();
}
void FetchBodyOwner::BlobLoader::didFail()
{
if (loader->isStarted())
owner.blobLoadingFailed();
}
}
#endif // ENABLE(FETCH_API)