WebServiceWorkerFetchTaskClient.cpp [plain text]
#include "config.h"
#include "WebServiceWorkerFetchTaskClient.h"
#if ENABLE(SERVICE_WORKER)
#include "DataReference.h"
#include "FormDataReference.h"
#include "StorageProcessMessages.h"
#include "WebCoreArgumentCoders.h"
#include "WebErrors.h"
#include <WebCore/ResourceError.h>
#include <WebCore/ResourceResponse.h>
#include <WebCore/SWContextManager.h>
#include <wtf/RunLoop.h>
using namespace WebCore;
namespace WebKit {
WebServiceWorkerFetchTaskClient::~WebServiceWorkerFetchTaskClient()
{
if (m_connection)
RunLoop::main().dispatch([connection = WTFMove(m_connection)] { });
}
WebServiceWorkerFetchTaskClient::WebServiceWorkerFetchTaskClient(Ref<IPC::Connection>&& connection, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, WebCore::SWServerConnectionIdentifier serverConnectionIdentifier, FetchIdentifier fetchIdentifier)
: m_connection(WTFMove(connection))
, m_serverConnectionIdentifier(serverConnectionIdentifier)
, m_serviceWorkerIdentifier(serviceWorkerIdentifier)
, m_fetchIdentifier(fetchIdentifier)
{
}
void WebServiceWorkerFetchTaskClient::didReceiveResponse(const ResourceResponse& response)
{
if (!m_connection)
return;
m_connection->send(Messages::StorageProcess::DidReceiveFetchResponse { m_serverConnectionIdentifier, m_fetchIdentifier, response }, 0);
}
void WebServiceWorkerFetchTaskClient::didReceiveData(Ref<SharedBuffer>&& buffer)
{
if (!m_connection)
return;
IPC::SharedBufferDataReference dataReference { buffer.ptr() };
m_connection->send(Messages::StorageProcess::DidReceiveFetchData { m_serverConnectionIdentifier, m_fetchIdentifier, dataReference, static_cast<int64_t>(buffer->size()) }, 0);
}
void WebServiceWorkerFetchTaskClient::didReceiveFormDataAndFinish(Ref<FormData>&& formData)
{
if (!m_connection)
return;
URL blobURL = formData->asBlobURL();
if (blobURL.isNull()) {
m_connection->send(Messages::StorageProcess::DidReceiveFetchFormData { m_serverConnectionIdentifier, m_fetchIdentifier, IPC::FormDataReference { WTFMove(formData) } }, 0);
return;
}
callOnMainThread([this, protectedThis = makeRef(*this), blobURL = blobURL.isolatedCopy()] () {
auto* serviceWorkerThreadProxy = SWContextManager::singleton().serviceWorkerThreadProxy(m_serviceWorkerIdentifier);
if (!serviceWorkerThreadProxy) {
didFail(internalError(blobURL));
return;
}
m_blobLoader.emplace(*this);
auto loader = serviceWorkerThreadProxy->createBlobLoader(*m_blobLoader, blobURL);
if (!loader) {
m_blobLoader = std::nullopt;
didFail(internalError(blobURL));
return;
}
m_blobLoader->loader = WTFMove(loader);
});
}
void WebServiceWorkerFetchTaskClient::didReceiveBlobChunk(const char* data, size_t size)
{
if (!m_connection)
return;
IPC::DataReference dataReference { reinterpret_cast<const uint8_t*>(data), size };
m_connection->send(Messages::StorageProcess::DidReceiveFetchData { m_serverConnectionIdentifier, m_fetchIdentifier, dataReference, static_cast<int64_t>(size) }, 0);
}
void WebServiceWorkerFetchTaskClient::didFinishBlobLoading()
{
didFinish();
std::exchange(m_blobLoader, std::nullopt);
}
void WebServiceWorkerFetchTaskClient::didFail(const ResourceError& error)
{
if (!m_connection)
return;
m_connection->send(Messages::StorageProcess::DidFailFetch { m_serverConnectionIdentifier, m_fetchIdentifier, error }, 0);
cleanup();
}
void WebServiceWorkerFetchTaskClient::didFinish()
{
if (!m_connection)
return;
m_connection->send(Messages::StorageProcess::DidFinishFetch { m_serverConnectionIdentifier, m_fetchIdentifier }, 0);
cleanup();
}
void WebServiceWorkerFetchTaskClient::didNotHandle()
{
if (!m_connection)
return;
m_connection->send(Messages::StorageProcess::DidNotHandleFetch { m_serverConnectionIdentifier, m_fetchIdentifier }, 0);
cleanup();
}
void WebServiceWorkerFetchTaskClient::cancel()
{
m_connection = nullptr;
}
void WebServiceWorkerFetchTaskClient::cleanup()
{
m_connection = nullptr;
if (!isMainThread()) {
callOnMainThread([protectedThis = makeRef(*this)] () {
protectedThis->cleanup();
});
return;
}
if (auto* serviceWorkerThreadProxy = SWContextManager::singleton().serviceWorkerThreadProxy(m_serviceWorkerIdentifier))
serviceWorkerThreadProxy->removeFetch(m_serverConnectionIdentifier, m_fetchIdentifier);
}
}
#endif // ENABLE(SERVICE_WORKER)