mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-05-21 02:22:51 +00:00
Supporting unbuffered fetches is actually part of the fetch spec in its HTTP-network-fetch algorithm. We had previously implemented this method in a very ad-hoc manner as a simple wrapper around ResourceLoader. This is still the case, but we now implement a good amount of these steps according to spec, using ResourceLoader's unbuffered API. The response data is forwarded through to the fetch response using streams. This will eventually let us remove the use of ResourceLoader's buffered API, as all responses should just be streamed this way. The streams spec then supplies ways to wait for completion, thus allowing fully buffered responses. However, we have more work to do to make the other parts of our fetch implementation (namely, Body::fully_read) use streams before we can do this.
47 lines
1.7 KiB
C++
47 lines
1.7 KiB
C++
/*
|
|
* Copyright (c) 2022, Linus Groh <linusg@serenityos.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <LibJS/Forward.h>
|
|
#include <LibJS/Heap/Cell.h>
|
|
#include <LibJS/Heap/GCPtr.h>
|
|
#include <LibJS/SafeFunction.h>
|
|
#include <LibWeb/Fetch/Infrastructure/HTTP/Responses.h>
|
|
|
|
namespace Web::Fetch::Fetching {
|
|
|
|
// Non-standard wrapper around a possibly pending Infrastructure::Response.
|
|
// This is needed to fit the asynchronous nature of ResourceLoader into the synchronous expectations
|
|
// of the Fetch spec - we run 'in parallel' as a deferred_invoke(), which is still on the main thread;
|
|
// therefore we use callbacks to run portions of the spec that require waiting for an HTTP load.
|
|
class PendingResponse : public JS::Cell {
|
|
JS_CELL(PendingResponse, JS::Cell);
|
|
JS_DECLARE_ALLOCATOR(PendingResponse);
|
|
|
|
public:
|
|
using Callback = Function<void(JS::NonnullGCPtr<Infrastructure::Response>)>;
|
|
|
|
[[nodiscard]] static JS::NonnullGCPtr<PendingResponse> create(JS::VM&, JS::NonnullGCPtr<Infrastructure::Request>);
|
|
[[nodiscard]] static JS::NonnullGCPtr<PendingResponse> create(JS::VM&, JS::NonnullGCPtr<Infrastructure::Request>, JS::NonnullGCPtr<Infrastructure::Response>);
|
|
|
|
void when_loaded(Callback);
|
|
void resolve(JS::NonnullGCPtr<Infrastructure::Response>);
|
|
bool is_resolved() const { return m_response != nullptr; }
|
|
|
|
private:
|
|
PendingResponse(JS::NonnullGCPtr<Infrastructure::Request>, JS::GCPtr<Infrastructure::Response> = {});
|
|
|
|
virtual void visit_edges(JS::Cell::Visitor&) override;
|
|
|
|
void run_callback();
|
|
|
|
JS::GCPtr<JS::HeapFunction<void(JS::NonnullGCPtr<Infrastructure::Response>)>> m_callback;
|
|
JS::NonnullGCPtr<Infrastructure::Request> m_request;
|
|
JS::GCPtr<Infrastructure::Response> m_response;
|
|
};
|
|
|
|
}
|