mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-27 20:58:16 +00:00
Everywhere: Hoist the Libraries folder to the top-level
This commit is contained in:
parent
950e819ee7
commit
93712b24bf
Notes:
github-actions[bot]
2024-11-10 11:51:52 +00:00
Author: https://github.com/trflynn89
Commit: 93712b24bf
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2256
Reviewed-by: https://github.com/sideshowbarker
4547 changed files with 104 additions and 113 deletions
85
Libraries/LibWeb/Fetch/Fetching/Checks.cpp
Normal file
85
Libraries/LibWeb/Fetch/Fetching/Checks.cpp
Normal file
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright (c) 2022-2023, Linus Groh <linusg@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/DOMURL/DOMURL.h>
|
||||
#include <LibWeb/Fetch/Fetching/Checks.h>
|
||||
#include <LibWeb/Fetch/Infrastructure/HTTP/Requests.h>
|
||||
#include <LibWeb/Fetch/Infrastructure/HTTP/Responses.h>
|
||||
|
||||
namespace Web::Fetch::Fetching {
|
||||
|
||||
// https://fetch.spec.whatwg.org/#concept-cors-check
|
||||
bool cors_check(Infrastructure::Request const& request, Infrastructure::Response const& response)
|
||||
{
|
||||
// 1. Let origin be the result of getting `Access-Control-Allow-Origin` from response’s header list.
|
||||
auto origin = response.header_list()->get("Access-Control-Allow-Origin"sv.bytes());
|
||||
|
||||
// 2. If origin is null, then return failure.
|
||||
// NOTE: Null is not `null`.
|
||||
if (!origin.has_value())
|
||||
return false;
|
||||
|
||||
// 3. If request’s credentials mode is not "include" and origin is `*`, then return success.
|
||||
if (request.credentials_mode() != Infrastructure::Request::CredentialsMode::Include && origin->span() == "*"sv.bytes())
|
||||
return true;
|
||||
|
||||
// 4. If the result of byte-serializing a request origin with request is not origin, then return failure.
|
||||
if (request.byte_serialize_origin() != *origin)
|
||||
return false;
|
||||
|
||||
// 5. If request’s credentials mode is not "include", then return success.
|
||||
if (request.credentials_mode() != Infrastructure::Request::CredentialsMode::Include)
|
||||
return true;
|
||||
|
||||
// 6. Let credentials be the result of getting `Access-Control-Allow-Credentials` from response’s header list.
|
||||
auto credentials = response.header_list()->get("Access-Control-Allow-Credentials"sv.bytes());
|
||||
|
||||
// 7. If credentials is `true`, then return success.
|
||||
if (credentials.has_value() && credentials->span() == "true"sv.bytes())
|
||||
return true;
|
||||
|
||||
// 8. Return failure.
|
||||
return false;
|
||||
}
|
||||
|
||||
// https://fetch.spec.whatwg.org/#concept-tao-check
|
||||
bool tao_check(Infrastructure::Request const& request, Infrastructure::Response const& response)
|
||||
{
|
||||
// 1. If request’s timing allow failed flag is set, then return failure.
|
||||
if (request.timing_allow_failed())
|
||||
return false;
|
||||
|
||||
// 2. Let values be the result of getting, decoding, and splitting `Timing-Allow-Origin` from response’s header list.
|
||||
auto values = response.header_list()->get_decode_and_split("Timing-Allow-Origin"sv.bytes());
|
||||
|
||||
// 3. If values contains "*", then return success.
|
||||
if (values.has_value() && values->contains_slow("*"sv))
|
||||
return true;
|
||||
|
||||
// 4. If values contains the result of serializing a request origin with request, then return success.
|
||||
if (values.has_value() && values->contains_slow(request.serialize_origin()))
|
||||
return true;
|
||||
|
||||
// 5. If request’s mode is "navigate" and request’s current URL’s origin is not same origin with request’s origin, then return failure.
|
||||
// NOTE: This is necessary for navigations of a nested browsing context. There, request’s origin would be the
|
||||
// container document’s origin and the TAO check would return failure. Since navigation timing never
|
||||
// validates the results of the TAO check, the nested document would still have access to the full timing
|
||||
// information, but the container document would not.
|
||||
if (request.mode() == Infrastructure::Request::Mode::Navigate
|
||||
&& request.origin().has<URL::Origin>()
|
||||
&& !request.current_url().origin().is_same_origin(request.origin().get<URL::Origin>())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 6. If request’s response tainting is "basic", then return success.
|
||||
if (request.response_tainting() == Infrastructure::Request::ResponseTainting::Basic)
|
||||
return true;
|
||||
|
||||
// 7. Return failure.
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
17
Libraries/LibWeb/Fetch/Fetching/Checks.h
Normal file
17
Libraries/LibWeb/Fetch/Fetching/Checks.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Linus Groh <linusg@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Forward.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
|
||||
namespace Web::Fetch::Fetching {
|
||||
|
||||
[[nodiscard]] bool cors_check(Infrastructure::Request const&, Infrastructure::Response const&);
|
||||
[[nodiscard]] bool tao_check(Infrastructure::Request const&, Infrastructure::Response const&);
|
||||
|
||||
}
|
89
Libraries/LibWeb/Fetch/Fetching/FetchedDataReceiver.cpp
Normal file
89
Libraries/LibWeb/Fetch/Fetching/FetchedDataReceiver.cpp
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Tim Flynn <trflynn89@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibJS/Heap/HeapFunction.h>
|
||||
#include <LibWeb/Bindings/ExceptionOrUtils.h>
|
||||
#include <LibWeb/Fetch/Fetching/FetchedDataReceiver.h>
|
||||
#include <LibWeb/Fetch/Infrastructure/FetchParams.h>
|
||||
#include <LibWeb/Fetch/Infrastructure/Task.h>
|
||||
#include <LibWeb/HTML/Scripting/ExceptionReporter.h>
|
||||
#include <LibWeb/HTML/Scripting/TemporaryExecutionContext.h>
|
||||
#include <LibWeb/Streams/AbstractOperations.h>
|
||||
#include <LibWeb/WebIDL/Promise.h>
|
||||
|
||||
namespace Web::Fetch::Fetching {
|
||||
|
||||
JS_DEFINE_ALLOCATOR(FetchedDataReceiver);
|
||||
|
||||
FetchedDataReceiver::FetchedDataReceiver(JS::NonnullGCPtr<Infrastructure::FetchParams const> fetch_params, JS::NonnullGCPtr<Streams::ReadableStream> stream)
|
||||
: m_fetch_params(fetch_params)
|
||||
, m_stream(stream)
|
||||
{
|
||||
}
|
||||
|
||||
FetchedDataReceiver::~FetchedDataReceiver() = default;
|
||||
|
||||
void FetchedDataReceiver::visit_edges(Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
visitor.visit(m_fetch_params);
|
||||
visitor.visit(m_stream);
|
||||
visitor.visit(m_pending_promise);
|
||||
}
|
||||
|
||||
void FetchedDataReceiver::set_pending_promise(JS::NonnullGCPtr<WebIDL::Promise> promise)
|
||||
{
|
||||
auto had_pending_promise = m_pending_promise != nullptr;
|
||||
m_pending_promise = promise;
|
||||
|
||||
if (!had_pending_promise && !m_buffer.is_empty()) {
|
||||
on_data_received(m_buffer);
|
||||
m_buffer.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// This implements the parallel steps of the pullAlgorithm in HTTP-network-fetch.
|
||||
// https://fetch.spec.whatwg.org/#ref-for-in-parallel④
|
||||
void FetchedDataReceiver::on_data_received(ReadonlyBytes bytes)
|
||||
{
|
||||
// FIXME: 1. If the size of buffer is smaller than a lower limit chosen by the user agent and the ongoing fetch
|
||||
// is suspended, resume the fetch.
|
||||
// FIXME: 2. Wait until buffer is not empty.
|
||||
|
||||
// If the remote end sends data immediately after we receive headers, we will often get that data here before the
|
||||
// stream tasks have all been queued internally. Just hold onto that data.
|
||||
if (!m_pending_promise) {
|
||||
m_buffer.append(bytes);
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. Queue a fetch task to run the following steps, with fetchParams’s task destination.
|
||||
Infrastructure::queue_fetch_task(
|
||||
m_fetch_params->controller(),
|
||||
m_fetch_params->task_destination().get<JS::NonnullGCPtr<JS::Object>>(),
|
||||
JS::create_heap_function(heap(), [this, bytes = MUST(ByteBuffer::copy(bytes))]() mutable {
|
||||
HTML::TemporaryExecutionContext execution_context { m_stream->realm(), HTML::TemporaryExecutionContext::CallbacksEnabled::Yes };
|
||||
|
||||
// 1. Pull from bytes buffer into stream.
|
||||
if (auto result = Streams::readable_stream_pull_from_bytes(m_stream, move(bytes)); result.is_error()) {
|
||||
auto throw_completion = Bindings::dom_exception_to_throw_completion(m_stream->vm(), result.release_error());
|
||||
|
||||
dbgln("FetchedDataReceiver: Stream error pulling bytes");
|
||||
HTML::report_exception(throw_completion, m_stream->realm());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. If stream is errored, then terminate fetchParams’s controller.
|
||||
if (m_stream->is_errored())
|
||||
m_fetch_params->controller()->terminate();
|
||||
|
||||
// 3. Resolve promise with undefined.
|
||||
WebIDL::resolve_promise(m_stream->realm(), *m_pending_promise, JS::js_undefined());
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
37
Libraries/LibWeb/Fetch/Fetching/FetchedDataReceiver.h
Normal file
37
Libraries/LibWeb/Fetch/Fetching/FetchedDataReceiver.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Tim Flynn <trflynn89@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/ByteBuffer.h>
|
||||
#include <LibJS/Heap/Cell.h>
|
||||
#include <LibJS/Heap/CellAllocator.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
|
||||
namespace Web::Fetch::Fetching {
|
||||
|
||||
class FetchedDataReceiver final : public JS::Cell {
|
||||
JS_CELL(FetchedDataReceiver, JS::Cell);
|
||||
JS_DECLARE_ALLOCATOR(FetchedDataReceiver);
|
||||
|
||||
public:
|
||||
virtual ~FetchedDataReceiver() override;
|
||||
|
||||
void set_pending_promise(JS::NonnullGCPtr<WebIDL::Promise>);
|
||||
void on_data_received(ReadonlyBytes);
|
||||
|
||||
private:
|
||||
FetchedDataReceiver(JS::NonnullGCPtr<Infrastructure::FetchParams const>, JS::NonnullGCPtr<Streams::ReadableStream>);
|
||||
|
||||
virtual void visit_edges(Visitor& visitor) override;
|
||||
|
||||
JS::NonnullGCPtr<Infrastructure::FetchParams const> m_fetch_params;
|
||||
JS::NonnullGCPtr<Streams::ReadableStream> m_stream;
|
||||
JS::GCPtr<WebIDL::Promise> m_pending_promise;
|
||||
ByteBuffer m_buffer;
|
||||
};
|
||||
|
||||
}
|
2710
Libraries/LibWeb/Fetch/Fetching/Fetching.cpp
Normal file
2710
Libraries/LibWeb/Fetch/Fetching/Fetching.cpp
Normal file
File diff suppressed because it is too large
Load diff
55
Libraries/LibWeb/Fetch/Fetching/Fetching.h
Normal file
55
Libraries/LibWeb/Fetch/Fetching/Fetching.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Linus Groh <linusg@serenityos.org>
|
||||
* Copyright (c) 2024, Jamie Mansfield <jmansfield@cadixdev.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Forward.h>
|
||||
#include <LibJS/Forward.h>
|
||||
#include <LibJS/Heap/GCPtr.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
|
||||
namespace Web::Fetch::Fetching {
|
||||
|
||||
// https://fetch.spec.whatwg.org/#document-accept-header-value
|
||||
// The document `Accept` header value is `text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8`.
|
||||
constexpr auto document_accept_header_value = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"sv;
|
||||
|
||||
// https://fetch.spec.whatwg.org/#http-network-or-cache-fetch
|
||||
// If the sum of contentLength and inflightKeepaliveBytes is greater than 64 kibibytes, then return a network error.
|
||||
constexpr auto keepalive_maximum_size = 64 * KiB;
|
||||
|
||||
#define ENUMERATE_BOOL_PARAMS \
|
||||
__ENUMERATE_BOOL_PARAM(IncludeCredentials) \
|
||||
__ENUMERATE_BOOL_PARAM(IsAuthenticationFetch) \
|
||||
__ENUMERATE_BOOL_PARAM(IsNewConnectionFetch) \
|
||||
__ENUMERATE_BOOL_PARAM(MakeCORSPreflight) \
|
||||
__ENUMERATE_BOOL_PARAM(Recursive) \
|
||||
__ENUMERATE_BOOL_PARAM(UseParallelQueue)
|
||||
|
||||
#define __ENUMERATE_BOOL_PARAM(Name) \
|
||||
enum class Name { \
|
||||
Yes, \
|
||||
No, \
|
||||
};
|
||||
ENUMERATE_BOOL_PARAMS
|
||||
#undef __ENUMERATE_BOOL_PARAM
|
||||
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<Infrastructure::FetchController>> fetch(JS::Realm&, Infrastructure::Request&, Infrastructure::FetchAlgorithms const&, UseParallelQueue use_parallel_queue = UseParallelQueue::No);
|
||||
WebIDL::ExceptionOr<JS::GCPtr<PendingResponse>> main_fetch(JS::Realm&, Infrastructure::FetchParams const&, Recursive recursive = Recursive::No);
|
||||
void fetch_response_handover(JS::Realm&, Infrastructure::FetchParams const&, Infrastructure::Response&);
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> scheme_fetch(JS::Realm&, Infrastructure::FetchParams const&);
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> http_fetch(JS::Realm&, Infrastructure::FetchParams const&, MakeCORSPreflight make_cors_preflight = MakeCORSPreflight::No);
|
||||
WebIDL::ExceptionOr<JS::GCPtr<PendingResponse>> http_redirect_fetch(JS::Realm&, Infrastructure::FetchParams const&, Infrastructure::Response&);
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> http_network_or_cache_fetch(JS::Realm&, Infrastructure::FetchParams const&, IsAuthenticationFetch is_authentication_fetch = IsAuthenticationFetch::No, IsNewConnectionFetch is_new_connection_fetch = IsNewConnectionFetch::No);
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> nonstandard_resource_loader_file_or_http_network_fetch(JS::Realm&, Infrastructure::FetchParams const&, IncludeCredentials include_credentials = IncludeCredentials::No, IsNewConnectionFetch is_new_connection_fetch = IsNewConnectionFetch::No);
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> cors_preflight_fetch(JS::Realm&, Infrastructure::Request&);
|
||||
void set_sec_fetch_dest_header(Infrastructure::Request&);
|
||||
void set_sec_fetch_mode_header(Infrastructure::Request&);
|
||||
void set_sec_fetch_site_header(Infrastructure::Request&);
|
||||
void set_sec_fetch_user_header(Infrastructure::Request&);
|
||||
void append_fetch_metadata_headers_for_request(Infrastructure::Request&);
|
||||
}
|
70
Libraries/LibWeb/Fetch/Fetching/PendingResponse.cpp
Normal file
70
Libraries/LibWeb/Fetch/Fetching/PendingResponse.cpp
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Linus Groh <linusg@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibJS/Heap/Heap.h>
|
||||
#include <LibJS/Runtime/VM.h>
|
||||
#include <LibWeb/Fetch/Fetching/PendingResponse.h>
|
||||
#include <LibWeb/Fetch/Infrastructure/HTTP/Requests.h>
|
||||
#include <LibWeb/Platform/EventLoopPlugin.h>
|
||||
|
||||
namespace Web::Fetch::Fetching {
|
||||
|
||||
JS_DEFINE_ALLOCATOR(PendingResponse);
|
||||
|
||||
JS::NonnullGCPtr<PendingResponse> PendingResponse::create(JS::VM& vm, JS::NonnullGCPtr<Infrastructure::Request> request)
|
||||
{
|
||||
return vm.heap().allocate_without_realm<PendingResponse>(request);
|
||||
}
|
||||
|
||||
JS::NonnullGCPtr<PendingResponse> PendingResponse::create(JS::VM& vm, JS::NonnullGCPtr<Infrastructure::Request> request, JS::NonnullGCPtr<Infrastructure::Response> response)
|
||||
{
|
||||
return vm.heap().allocate_without_realm<PendingResponse>(request, response);
|
||||
}
|
||||
|
||||
PendingResponse::PendingResponse(JS::NonnullGCPtr<Infrastructure::Request> request, JS::GCPtr<Infrastructure::Response> response)
|
||||
: m_request(request)
|
||||
, m_response(response)
|
||||
{
|
||||
m_request->add_pending_response({}, *this);
|
||||
}
|
||||
|
||||
void PendingResponse::visit_edges(JS::Cell::Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
visitor.visit(m_callback);
|
||||
visitor.visit(m_request);
|
||||
visitor.visit(m_response);
|
||||
}
|
||||
|
||||
void PendingResponse::when_loaded(Callback callback)
|
||||
{
|
||||
VERIFY(!m_callback);
|
||||
m_callback = JS::create_heap_function(heap(), move(callback));
|
||||
if (m_response)
|
||||
run_callback();
|
||||
}
|
||||
|
||||
void PendingResponse::resolve(JS::NonnullGCPtr<Infrastructure::Response> response)
|
||||
{
|
||||
VERIFY(!m_response);
|
||||
m_response = response;
|
||||
if (m_callback)
|
||||
run_callback();
|
||||
}
|
||||
|
||||
void PendingResponse::run_callback()
|
||||
{
|
||||
VERIFY(m_callback);
|
||||
VERIFY(m_response);
|
||||
Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(heap(), [this] {
|
||||
VERIFY(m_callback);
|
||||
VERIFY(m_response);
|
||||
m_callback->function()(*m_response);
|
||||
m_request->remove_pending_response({}, *this);
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
46
Libraries/LibWeb/Fetch/Fetching/PendingResponse.h
Normal file
46
Libraries/LibWeb/Fetch/Fetching/PendingResponse.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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 <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;
|
||||
};
|
||||
|
||||
}
|
22
Libraries/LibWeb/Fetch/Fetching/RefCountedFlag.cpp
Normal file
22
Libraries/LibWeb/Fetch/Fetching/RefCountedFlag.cpp
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Linus Groh <linusg@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/NonnullRefPtr.h>
|
||||
#include <LibWeb/Fetch/Fetching/RefCountedFlag.h>
|
||||
|
||||
namespace Web::Fetch::Fetching {
|
||||
|
||||
NonnullRefPtr<RefCountedFlag> RefCountedFlag::create(bool value)
|
||||
{
|
||||
return adopt_ref(*new RefCountedFlag(value));
|
||||
}
|
||||
|
||||
RefCountedFlag::RefCountedFlag(bool value)
|
||||
: m_value(value)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
28
Libraries/LibWeb/Fetch/Fetching/RefCountedFlag.h
Normal file
28
Libraries/LibWeb/Fetch/Fetching/RefCountedFlag.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Linus Groh <linusg@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/RefCounted.h>
|
||||
|
||||
namespace Web::Fetch::Fetching {
|
||||
|
||||
/// A ref-counted boolean flag.
|
||||
/// This is used to share flags between multiple callback closures.
|
||||
class RefCountedFlag : public RefCounted<RefCountedFlag> {
|
||||
public:
|
||||
static NonnullRefPtr<RefCountedFlag> create(bool);
|
||||
|
||||
[[nodiscard]] bool value() const { return m_value; }
|
||||
void set_value(bool value) { m_value = value; }
|
||||
|
||||
private:
|
||||
explicit RefCountedFlag(bool);
|
||||
|
||||
bool m_value { false };
|
||||
};
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue