#pragma once
#if ENABLE(FETCH_API)
#include "FetchBodyOwner.h"
#include "ResourceResponse.h"
#include <runtime/TypedArrays.h>
namespace JSC {
class ExecState;
class JSValue;
};
namespace WebCore {
class FetchRequest;
class ReadableStreamSource;
class FetchResponse final : public FetchBodyOwner {
public:
using Type = ResourceResponse::Type;
static Ref<FetchResponse> create(ScriptExecutionContext& context) { return adoptRef(*new FetchResponse(context, std::nullopt, FetchHeaders::create(FetchHeaders::Guard::Response), ResourceResponse())); }
static Ref<FetchResponse> error(ScriptExecutionContext&);
static ExceptionOr<Ref<FetchResponse>> redirect(ScriptExecutionContext&, const String& url, int status);
using FetchPromise = DOMPromiseDeferred<IDLInterface<FetchResponse>>;
static void fetch(ScriptExecutionContext&, FetchRequest&, FetchPromise&&);
void consume(unsigned, Ref<DeferredPromise>&&);
#if ENABLE(STREAMS_API)
void startConsumingStream(unsigned);
void consumeChunk(Ref<JSC::Uint8Array>&&);
void finishConsumingStream(Ref<DeferredPromise>&&);
#endif
ExceptionOr<void> setStatus(int status, const String& statusText);
void initializeWith(FetchBody::BindingDataType&&);
void setBodyAsReadableStream();
Type type() const { return m_response.type(); }
const String& url() const;
bool redirected() const { return m_response.isRedirected(); }
int status() const { return m_response.httpStatusCode(); }
bool ok() const { return m_response.isSuccessful(); }
const String& statusText() const { return m_response.httpStatusText(); }
FetchHeaders& headers() { return m_headers; }
Ref<FetchResponse> cloneForJS();
#if ENABLE(STREAMS_API)
ReadableStreamSource* createReadableStreamSource();
void consumeBodyAsStream();
void feedStream();
void cancel();
#endif
bool isLoading() const { return !!m_bodyLoader; }
private:
FetchResponse(ScriptExecutionContext&, std::optional<FetchBody>&&, Ref<FetchHeaders>&&, ResourceResponse&&);
static void startFetching(ScriptExecutionContext&, const FetchRequest&, FetchPromise&&);
void stop() final;
const char* activeDOMObjectName() const final;
bool canSuspendForDocumentSuspension() const final;
#if ENABLE(STREAMS_API)
void closeStream();
#endif
class BodyLoader final : public FetchLoaderClient {
public:
BodyLoader(FetchResponse&, FetchPromise&&);
~BodyLoader();
bool start(ScriptExecutionContext&, const FetchRequest&);
void stop();
#if ENABLE(STREAMS_API)
RefPtr<SharedBuffer> startStreaming();
#endif
private:
void didSucceed() final;
void didFail() final;
void didReceiveResponse(const ResourceResponse&) final;
void didReceiveData(const char*, size_t) final;
FetchResponse& m_response;
std::optional<FetchPromise> m_promise;
std::unique_ptr<FetchLoader> m_loader;
};
ResourceResponse m_response;
std::optional<BodyLoader> m_bodyLoader;
mutable String m_responseURL;
FetchBodyConsumer m_consumer { FetchBodyConsumer::Type::ArrayBuffer };
};
}
#endif // ENABLE(FETCH_API)