#include "config.h"
#include "FetchLoader.h"
#if ENABLE(FETCH_API)
#include "BlobURL.h"
#include "FetchBody.h"
#include "FetchLoaderClient.h"
#include "FetchRequest.h"
#include "ResourceRequest.h"
#include "ScriptExecutionContext.h"
#include "SecurityOrigin.h"
#include "SharedBuffer.h"
#include "TextResourceDecoder.h"
#include "ThreadableBlobRegistry.h"
#include "ThreadableLoader.h"
namespace WebCore {
void FetchLoader::start(ScriptExecutionContext& context, Blob& blob)
{
auto urlForReading = BlobURL::createPublicURL(context.securityOrigin());
if (urlForReading.isEmpty()) {
m_client.didFail();
return;
}
ThreadableBlobRegistry::registerBlobURL(context.securityOrigin(), urlForReading, blob.url());
ResourceRequest request(urlForReading);
request.setHTTPMethod("GET");
ThreadableLoaderOptions options;
options.setSendLoadCallbacks(SendCallbacks);
options.setSniffContent(DoNotSniffContent);
options.setDataBufferingPolicy(DoNotBufferData);
options.preflightPolicy = ConsiderPreflight;
options.setAllowCredentials(AllowStoredCredentials);
options.crossOriginRequestPolicy = DenyCrossOriginRequests;
options.contentSecurityPolicyEnforcement = ContentSecurityPolicyEnforcement::DoNotEnforce;
m_loader = ThreadableLoader::create(&context, this, request, options);
m_isStarted = m_loader;
}
void FetchLoader::start(ScriptExecutionContext& context, const FetchRequest& request)
{
ThreadableLoaderOptions options;
options.setSendLoadCallbacks(SendCallbacks);
options.setSniffContent(DoNotSniffContent);
options.setDataBufferingPolicy(DoNotBufferData);
options.preflightPolicy = ConsiderPreflight;
options.setAllowCredentials(AllowStoredCredentials);
options.crossOriginRequestPolicy = DenyCrossOriginRequests;
options.contentSecurityPolicyEnforcement = ContentSecurityPolicyEnforcement::DoNotEnforce;
options.redirect = request.fetchOptions().redirect;
m_loader = ThreadableLoader::create(&context, this, request.internalRequest(), options);
m_isStarted = m_loader;
}
FetchLoader::FetchLoader(Type type, FetchLoaderClient& client)
: m_type(type)
, m_client(client)
{
}
void FetchLoader::stop()
{
m_data = nullptr;
if (m_loader)
m_loader->cancel();
}
RefPtr<SharedBuffer> FetchLoader::startStreaming()
{
ASSERT(m_type == Type::ArrayBuffer);
m_type = Type::Stream;
return WTFMove(m_data);
}
void FetchLoader::didReceiveResponse(unsigned long, const ResourceResponse& response)
{
m_client.didReceiveResponse(response);
}
void FetchLoader::didReceiveData(const char* value, int size)
{
if (m_type == Type::Stream) {
m_client.didReceiveData(value, size);
return;
}
if (!m_data) {
m_data = SharedBuffer::create(value, size);
return;
}
m_data->append(value, size);
}
void FetchLoader::didFinishLoading(unsigned long, double)
{
if (m_type == Type::ArrayBuffer)
m_client.didFinishLoadingAsArrayBuffer(m_data ? m_data->createArrayBuffer() : ArrayBuffer::tryCreate(nullptr, 0));
else if (m_type == Type::Text)
m_client.didFinishLoadingAsText(m_data ? TextResourceDecoder::create(ASCIILiteral("text/plain"), "UTF-8")->decodeAndFlush(m_data->data(), m_data->size()): String());
m_data = nullptr;
m_client.didSucceed();
}
void FetchLoader::didFail(const ResourceError&)
{
m_client.didFail();
}
}
#endif // ENABLE(FETCH_API)