LibHTTP+LibWebView+RequestServer: Allow users to set disk cache limits

This adds a settings box to about:settings to allow users to limit the
disk cache size. This will override the default 5 GiB limit. We do not
automatically delete cache data if the new limit is suddenly less than
the used disk space; this will happen on the next request. This allows
multiple changes to the settings in a row without thrashing the cache.

In the future, we can add more toggles, such as disabling the disk
cache altogether.
This commit is contained in:
Timothy Flynn 2026-02-05 12:25:14 -05:00 committed by Tim Flynn
parent c5d666ea7b
commit 7d60d0bfb7
21 changed files with 299 additions and 46 deletions

View file

@ -145,6 +145,7 @@
font-size: 14px;
}
input[type="number"],
input[type="text"],
input[type="url"],
select {
@ -154,11 +155,13 @@
border: 1px solid var(--border-color);
}
input[type="number"].success,
input[type="text"].success,
input[type="url"].success {
border: 1px solid green;
}
input[type="number"].error,
input[type="text"].error,
input[type="url"].error {
border: 1px solid red;
@ -390,7 +393,7 @@
<div class="card-body">
<div class="card-group inline-container">
<span>Browsing Data</span>
<button id="clear-browsing-data" class="secondary-button">Clear...</button>
<button id="browsing-data-settings" class="secondary-button">Settings...</button>
</div>
<hr />
@ -518,17 +521,34 @@
</div>
</dialog>
<dialog id="clear-browsing-data-dialog">
<dialog id="browsing-data-settings-dialog">
<div class="dialog-header">
<h3 id="clear-browsing-data-title" class="dialog-title">Clear Browsing Data</h3>
<button id="clear-browsing-data-close" class="close-button dialog-button">&times;</button>
<h3 class="dialog-title">Browsing Data Settings</h3>
<button id="browsing-data-settings-close" class="close-button dialog-button">&times;</button>
</div>
<div class="dialog-body">
<p id="clear-browsing-data-total-size" class="description"></p>
<p id="browsing-data-total-size" class="description"></p>
<hr />
<div class="input-field-container">
<p>From:</p>
<label for="browsing-data-settings-max-disk-cache-size">
Maximum&nbsp;disk&nbsp;cache&nbsp;size:
</label>
<input id="browsing-data-settings-max-disk-cache-size" type="number" min="1" />
<select id="browsing-data-settings-max-disk-cache-unit">
<option value="MiB">MiB</option>
<option value="GiB">GiB</option>
</select>
</div>
<p class="description" style="margin-top: 10px">
Limit the amount of space used for the HTTP disk cache. This may be further limited by the browser,
depending on the amount of disk space available.
</p>
<hr />
<div class="input-field-container">
<p>Remove&nbsp;browsing&nbsp;data&nbsp;from:</p>
<select id="clear-browsing-data-time-range">
<option value="lastHour">Last hour</option>
<option value="last4Hours">Last 4 hours</option>
@ -536,7 +556,6 @@
<option value="all" selected>All time</option>
</select>
</div>
<div class="input-field-container">
<input id="clear-browsing-data-cached-files" type="checkbox" value="" checked />
<label for="clear-browsing-data-cached-files">
@ -551,9 +570,9 @@
<p class="description">Remove items that may sign you out of most sites</p>
</label>
</div>
</div>
<div class="dialog-footer">
<button id="clear-browsing-data-remove-data" class="secondary-button">Remove Data</button>
<div class="button-container">
<button id="clear-browsing-data-remove-data" class="secondary-button">Remove Data</button>
</div>
</div>
</dialog>

View file

@ -1,4 +1,5 @@
import { getByteFormatter } from "../../utils.js";
const byteFormatter = getByteFormatter(unit => {
return {
unitDisplay: unit === "byte" ? "long" : "short",
@ -6,20 +7,52 @@ const byteFormatter = getByteFormatter(unit => {
};
});
const clearBrowsingData = document.querySelector("#clear-browsing-data");
const browsingDataSettings = document.querySelector("#browsing-data-settings");
const browsingDataSettingsClose = document.querySelector("#browsing-data-settings-close");
const browsingDataSettingsDialog = document.querySelector("#browsing-data-settings-dialog");
const browsingDataSettingsMaxDiskCacheSize = document.querySelector("#browsing-data-settings-max-disk-cache-size");
const browsingDataSettingsMaxDiskCacheUnit = document.querySelector("#browsing-data-settings-max-disk-cache-unit");
const browsingDataTotalSize = document.querySelector("#browsing-data-total-size");
const clearBrowsingDataCachedFiles = document.querySelector("#clear-browsing-data-cached-files");
const clearBrowsingDataCachedFilesSize = document.querySelector("#clear-browsing-data-cached-files-size");
const clearBrowsingDataClose = document.querySelector("#clear-browsing-data-close");
const clearBrowsingDataDialog = document.querySelector("#clear-browsing-data-dialog");
const clearBrowsingDataRemoveData = document.querySelector("#clear-browsing-data-remove-data");
const clearBrowsingDataSiteData = document.querySelector("#clear-browsing-data-site-data");
const clearBrowsingDataSiteDataSize = document.querySelector("#clear-browsing-data-site-data-size");
const clearBrowsingDataTimeRange = document.querySelector("#clear-browsing-data-time-range");
const clearBrowsingDataTotalSize = document.querySelector("#clear-browsing-data-total-size");
const globalPrivacyControlToggle = document.querySelector("#global-privacy-control-toggle");
const MiB = 1024 * 1024;
const GiB = MiB * 1024;
let BROWSING_DATA = {};
function loadSettings(settings) {
BROWSING_DATA = settings.browsingData || {};
globalPrivacyControlToggle.checked = settings.globalPrivacyControl;
if (browsingDataSettingsDialog.open) {
showBrowsingDataSettings();
}
}
function updateBrowsingDataSizes(sizes) {
const totalSize = sizes.totalCacheSize + sizes.totalSiteDataSize;
browsingDataTotalSize.innerText = `Your browsing data is currently using ${byteFormatter.formatBytes(totalSize)} of disk space`;
clearBrowsingDataCachedFilesSize.innerText = ` (remove ${byteFormatter.formatBytes(sizes.cacheSizeSinceRequestedTime)})`;
clearBrowsingDataSiteDataSize.innerText = ` (remove ${byteFormatter.formatBytes(sizes.siteDataSizeSinceRequestedTime)})`;
}
function formatDiskCacheSize(bytes) {
if (bytes >= GiB && bytes % GiB == 0) {
return { value: bytes / GiB, unit: "GiB" };
}
return { value: bytes / MiB, unit: "MiB" };
}
function computeTimeRange() {
@ -48,28 +81,64 @@ function estimateBrowsingDataSizes() {
});
}
function updateBrowsingDataSizes(sizes) {
const totalSize = sizes.totalCacheSize + sizes.totalSiteDataSize;
function saveBrowsingDataSettings() {
browsingDataSettingsMaxDiskCacheSize.classList.remove("success");
browsingDataSettingsMaxDiskCacheSize.classList.remove("error");
clearBrowsingDataTotalSize.innerText = `Your browsing data is currently using ${byteFormatter.formatBytes(totalSize)} of disk space`;
if (
browsingDataSettingsMaxDiskCacheSize.value.length === 0 ||
!browsingDataSettingsMaxDiskCacheSize.checkValidity()
) {
browsingDataSettingsMaxDiskCacheSize.classList.add("error");
return;
}
clearBrowsingDataCachedFilesSize.innerText = ` (remove ${byteFormatter.formatBytes(sizes.cacheSizeSinceRequestedTime)})`;
clearBrowsingDataSiteDataSize.innerText = ` (remove ${byteFormatter.formatBytes(sizes.siteDataSizeSinceRequestedTime)})`;
BROWSING_DATA.diskCache = {};
BROWSING_DATA.diskCache.maxSize =
browsingDataSettingsMaxDiskCacheUnit.value === "MiB"
? browsingDataSettingsMaxDiskCacheSize.value * MiB
: browsingDataSettingsMaxDiskCacheSize.value * GiB;
ladybird.sendMessage("setBrowsingDataSettings", BROWSING_DATA);
browsingDataSettingsMaxDiskCacheSize.classList.add("success");
setTimeout(() => {
browsingDataSettingsMaxDiskCacheSize.classList.remove("success");
}, 1000);
}
clearBrowsingData.addEventListener("click", () => {
function showBrowsingDataSettings() {
const maxDiskCacheSize = BROWSING_DATA.diskCache?.maxSize || 5 * GiB;
const { value, unit } = formatDiskCacheSize(maxDiskCacheSize);
browsingDataSettingsMaxDiskCacheSize.value = value;
browsingDataSettingsMaxDiskCacheUnit.value = unit;
if (!browsingDataSettingsDialog.open) {
browsingDataSettingsDialog.showModal();
}
}
browsingDataSettings.addEventListener("click", () => {
estimateBrowsingDataSizes();
clearBrowsingDataDialog.showModal();
showBrowsingDataSettings();
});
browsingDataSettingsClose.addEventListener("click", () => {
browsingDataSettingsDialog.close();
});
browsingDataSettingsMaxDiskCacheSize.addEventListener("change", () => {
saveBrowsingDataSettings();
});
browsingDataSettingsMaxDiskCacheUnit.addEventListener("change", () => {
saveBrowsingDataSettings();
});
clearBrowsingDataTimeRange.addEventListener("change", () => {
estimateBrowsingDataSizes();
});
clearBrowsingDataClose.addEventListener("click", () => {
clearBrowsingDataDialog.close();
});
function setRemoveDataEnabledState() {
clearBrowsingDataRemoveData.disabled = !clearBrowsingDataCachedFiles.checked && !clearBrowsingDataSiteData.checked;
}
@ -86,7 +155,7 @@ clearBrowsingDataRemoveData.addEventListener("click", () => {
siteData: clearBrowsingDataSiteData.checked,
});
clearBrowsingDataDialog.close();
browsingDataSettingsDialog.close();
});
globalPrivacyControlToggle.addEventListener("change", () => {

View file

@ -130,6 +130,7 @@ button.secondary-button:active {
background-color: var(--secondary-button-active);
}
input[type="number"],
input[type="search"],
input[type="text"],
input[type="url"],
@ -142,6 +143,7 @@ select {
padding: 10px 12px;
}
input[type="number"]:focus,
input[type="search"]:focus,
input[type="text"]:focus,
input[type="url"]:focus,

View file

@ -2,6 +2,7 @@ set(SOURCES
Cache/CacheEntry.cpp
Cache/CacheIndex.cpp
Cache/DiskCache.cpp
Cache/DiskCacheSettings.cpp
Cache/MemoryCache.cpp
Cache/Utilities.cpp
Cookie/Cookie.cpp

View file

@ -311,4 +311,13 @@ Requests::CacheSizes CacheIndex::estimate_cache_size_accessed_since(UnixDateTime
return sizes;
}
void CacheIndex::set_maximum_disk_cache_size(u64 maximum_disk_cache_size)
{
if (maximum_disk_cache_size == m_limits.maximum_disk_cache_size)
return;
m_limits.maximum_disk_cache_size = compute_maximum_disk_cache_size(m_limits.free_disk_space, maximum_disk_cache_size);
m_limits.maximum_disk_cache_entry_size = compute_maximum_disk_cache_entry_size(m_limits.maximum_disk_cache_size);
}
}

View file

@ -48,6 +48,8 @@ public:
Requests::CacheSizes estimate_cache_size_accessed_since(UnixDateTime since);
void set_maximum_disk_cache_size(u64 maximum_disk_cache_size);
private:
struct Statements {
Database::StatementID insert_entry { 0 };

View file

@ -237,6 +237,11 @@ void DiskCache::remove_entries_exceeding_cache_limit()
});
}
void DiskCache::set_maximum_disk_cache_size(u64 maximum_disk_cache_size)
{
m_index.set_maximum_disk_cache_size(maximum_disk_cache_size);
}
Requests::CacheSizes DiskCache::estimate_cache_size_accessed_since(UnixDateTime since)
{
return m_index.estimate_cache_size_accessed_since(since);

View file

@ -53,6 +53,7 @@ public:
Variant<Optional<CacheEntryReader&>, CacheHasOpenEntry> open_entry(CacheRequest&, URL::URL const&, StringView method, HeaderList const& request_headers, CacheMode, OpenMode);
void remove_entries_exceeding_cache_limit();
void set_maximum_disk_cache_size(u64 maximum_disk_cache_size);
Requests::CacheSizes estimate_cache_size_accessed_since(UnixDateTime since);
void remove_entries_accessed_since(UnixDateTime since);

View file

@ -0,0 +1,29 @@
/*
* Copyright (c) 2026, Tim Flynn <trflynn89@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibHTTP/Cache/DiskCacheSettings.h>
#include <LibIPC/Decoder.h>
#include <LibIPC/Encoder.h>
namespace IPC {
template<>
ErrorOr<void> encode(Encoder& encoder, HTTP::DiskCacheSettings const& sizes)
{
TRY(encoder.encode(sizes.maximum_size));
return {};
}
template<>
ErrorOr<HTTP::DiskCacheSettings> decode(Decoder& decoder)
{
auto maximum_size = TRY(decoder.decode<u64>());
return HTTP::DiskCacheSettings { maximum_size };
}
}

View file

@ -0,0 +1,30 @@
/*
* Copyright (c) 2026, Tim Flynn <trflynn89@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Types.h>
#include <LibHTTP/Cache/Utilities.h>
#include <LibHTTP/Forward.h>
#include <LibIPC/Forward.h>
namespace HTTP {
struct DiskCacheSettings {
u64 maximum_size { DEFAULT_MAXIMUM_DISK_CACHE_SIZE };
};
}
namespace IPC {
template<>
ErrorOr<void> encode(Encoder&, HTTP::DiskCacheSettings const&);
template<>
ErrorOr<HTTP::DiskCacheSettings> decode(Decoder&);
}

View file

@ -24,19 +24,21 @@ static Optional<UnixDateTime> parse_http_date(Optional<ByteString const&> date)
return {};
}
u64 compute_maximum_disk_cache_size(u64 free_bytes)
u64 compute_maximum_disk_cache_size(u64 free_bytes, u64 limit_maximum_disk_cache_size)
{
static constexpr u64 MAXIMUM_DISK_CACHE_SIZE = 5 * GiB;
auto cache_size = [&]() {
if (free_bytes <= 100 * MiB)
return free_bytes * 8 / 10; // Up to 80 MiB
if (free_bytes <= 800 * MiB)
return free_bytes * 6 / 10; // Up to 480 MiB
if (free_bytes <= 2 * GiB)
return free_bytes * 4 / 10; // Up to 820 MiB
if (free_bytes <= 10 * GiB)
return free_bytes * 2 / 10; // Up to 2 GiB
return limit_maximum_disk_cache_size;
}();
if (free_bytes <= 100 * MiB)
return free_bytes * 8 / 10; // Up to 80 MiB
if (free_bytes <= 800 * MiB)
return free_bytes * 6 / 10; // Up to 480 MiB
if (free_bytes <= 2 * GiB)
return free_bytes * 4 / 10; // Up to 820 MiB
if (free_bytes <= 10 * GiB)
return free_bytes * 2 / 10; // Up to 2 GiB
return MAXIMUM_DISK_CACHE_SIZE;
return min(cache_size, limit_maximum_disk_cache_size);
}
u64 compute_maximum_disk_cache_entry_size(u64 maximum_disk_cache_size)

View file

@ -21,7 +21,9 @@ constexpr inline auto TEST_CACHE_STATUS_HEADER = "X-Ladybird-Disk-Cache-Status"s
constexpr inline auto TEST_CACHE_REVALIDATION_STATUS_HEADER = "X-Ladybird-Revalidation-Status"sv;
constexpr inline auto TEST_CACHE_REQUEST_TIME_OFFSET = "X-Ladybird-Request-Time-Offset"sv;
u64 compute_maximum_disk_cache_size(u64 free_bytes);
constexpr inline u64 DEFAULT_MAXIMUM_DISK_CACHE_SIZE = 5 * GiB;
u64 compute_maximum_disk_cache_size(u64 free_bytes, u64 limit_maximum_disk_cache_size = DEFAULT_MAXIMUM_DISK_CACHE_SIZE);
u64 compute_maximum_disk_cache_entry_size(u64 maximum_disk_cache_size);
String serialize_url_for_cache_storage(URL::URL const&);

View file

@ -35,6 +35,12 @@ namespace WebView {
Application* Application::s_the = nullptr;
struct ApplicationSettingsObserver : public SettingsObserver {
virtual void browsing_data_settings_changed() override
{
auto const& browsing_data_settings = Application::settings().browsing_data_settings();
Application::request_server_client().async_set_disk_cache_settings(browsing_data_settings.disk_cache_settings);
}
virtual void dns_settings_changed() override
{
Application::settings().dns_settings().visit(

View file

@ -247,13 +247,16 @@ ErrorOr<NonnullRefPtr<Requests::RequestClient>> launch_request_server_process()
auto client = TRY(launch_server_process<Requests::RequestClient>("RequestServer"sv, move(arguments)));
WebView::Application::settings().dns_settings().visit(
[](WebView::SystemDNS) {},
[&](WebView::DNSOverTLS const& dns_over_tls) {
auto const& browsing_data_settings = Application::settings().browsing_data_settings();
client->async_set_disk_cache_settings(browsing_data_settings.disk_cache_settings);
Application::settings().dns_settings().visit(
[](SystemDNS) {},
[&](DNSOverTLS const& dns_over_tls) {
dbgln("Setting DNS server to {}:{} with TLS ({} local dnssec)", dns_over_tls.server_address, dns_over_tls.port, dns_over_tls.validate_dnssec_locally ? "with" : "without");
client->async_set_dns_server(dns_over_tls.server_address, dns_over_tls.port, true, dns_over_tls.validate_dnssec_locally);
},
[&](WebView::DNSOverUDP const& dns_over_udp) {
[&](DNSOverUDP const& dns_over_udp) {
dbgln("Setting DNS server to {}:{} ({} local dnssec)", dns_over_udp.server_address, dns_over_udp.port, dns_over_udp.validate_dnssec_locally ? "with" : "without");
client->async_set_dns_server(dns_over_udp.server_address, dns_over_udp.port, false, dns_over_udp.validate_dnssec_locally);
});

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2025, Tim Flynn <trflynn89@ladybird.org>
* Copyright (c) 2025-2026, Tim Flynn <trflynn89@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -42,6 +42,10 @@ static constexpr auto site_setting_site_filters_key = "siteFilters"sv;
static constexpr auto autoplay_key = "autoplay"sv;
static constexpr auto browsing_data_key = "browsingData"sv;
static constexpr auto disk_cache_key = "diskCache"sv;
static constexpr auto disk_cache_maximum_size_key = "maxSize"sv;
static constexpr auto global_privacy_control_key = "globalPrivacyControl"sv;
static constexpr auto dns_settings_key = "dnsSettings"sv;
@ -141,6 +145,9 @@ Settings Settings::create(Badge<Application>)
load_site_setting(settings.m_autoplay, autoplay_key);
if (auto browsing_data_settings = settings_json.value().get(browsing_data_key); browsing_data_settings.has_value())
settings.m_browsing_data_settings = parse_browsing_data_settings(*browsing_data_settings);
if (auto global_privacy_control = settings_json.value().get_bool(global_privacy_control_key); global_privacy_control.has_value())
settings.m_global_privacy_control = *global_privacy_control ? GlobalPrivacyControl::Yes : GlobalPrivacyControl::No;
@ -215,6 +222,13 @@ JsonValue Settings::serialize_json() const
save_site_setting(m_autoplay, autoplay_key);
JsonObject disk_cache_settings;
disk_cache_settings.set(disk_cache_maximum_size_key, m_browsing_data_settings.disk_cache_settings.maximum_size);
JsonObject browsing_data;
browsing_data.set(disk_cache_key, move(disk_cache_settings));
settings.set(browsing_data_key, move(browsing_data));
settings.set(global_privacy_control_key, m_global_privacy_control == GlobalPrivacyControl::Yes);
// dnsSettings :: { mode: "system" } | { mode: "custom", server: string, port: u16, type: "udp" | "tls", forciblyEnabled: bool, dnssec: bool }
@ -253,6 +267,7 @@ void Settings::restore_defaults()
m_custom_search_engines.clear();
m_autocomplete_engine.clear();
m_autoplay = SiteSetting {};
m_browsing_data_settings = {};
m_global_privacy_control = GlobalPrivacyControl::No;
m_dns_settings = SystemDNS {};
@ -265,6 +280,7 @@ void Settings::restore_defaults()
observer.search_engine_changed();
observer.autocomplete_engine_changed();
observer.autoplay_settings_changed();
observer.browsing_data_settings_changed();
observer.global_privacy_control_changed();
observer.dns_settings_changed();
}
@ -438,6 +454,30 @@ void Settings::remove_all_autoplay_site_filters()
observer.autoplay_settings_changed();
}
BrowsingDataSettings Settings::parse_browsing_data_settings(JsonValue const& settings)
{
if (!settings.is_object())
return {};
BrowsingDataSettings browsing_data_settings;
if (auto disk_cache_settings = settings.as_object().get_object(disk_cache_key); disk_cache_settings.has_value()) {
if (auto maximum_size = disk_cache_settings->get_integer<u64>(disk_cache_maximum_size_key); maximum_size.has_value())
browsing_data_settings.disk_cache_settings.maximum_size = *maximum_size;
}
return browsing_data_settings;
}
void Settings::set_browsing_data_settings(BrowsingDataSettings browsing_data_settings)
{
m_browsing_data_settings = browsing_data_settings;
persist_settings();
for (auto& observer : m_observers)
observer.browsing_data_settings_changed();
}
void Settings::set_global_privacy_control(GlobalPrivacyControl global_privacy_control)
{
m_global_privacy_control = global_privacy_control;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2025, Tim Flynn <trflynn89@ladybird.org>
* Copyright (c) 2025-2026, Tim Flynn <trflynn89@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -10,6 +10,7 @@
#include <AK/HashTable.h>
#include <AK/JsonValue.h>
#include <AK/Optional.h>
#include <LibHTTP/Cache/DiskCacheSettings.h>
#include <LibURL/URL.h>
#include <LibWebView/Autocomplete.h>
#include <LibWebView/Forward.h>
@ -25,6 +26,10 @@ struct WEBVIEW_API SiteSetting {
OrderedHashTable<String> site_filters;
};
struct BrowsingDataSettings {
HTTP::DiskCacheSettings disk_cache_settings;
};
enum class GlobalPrivacyControl {
No,
Yes,
@ -41,6 +46,7 @@ public:
virtual void search_engine_changed() { }
virtual void autocomplete_engine_changed() { }
virtual void autoplay_settings_changed() { }
virtual void browsing_data_settings_changed() { }
virtual void global_privacy_control_changed() { }
virtual void dns_settings_changed() { }
};
@ -79,6 +85,10 @@ public:
void remove_autoplay_site_filter(String const&);
void remove_all_autoplay_site_filters();
static BrowsingDataSettings parse_browsing_data_settings(JsonValue const&);
BrowsingDataSettings const& browsing_data_settings() const { return m_browsing_data_settings; }
void set_browsing_data_settings(BrowsingDataSettings);
GlobalPrivacyControl global_privacy_control() const { return m_global_privacy_control; }
void set_global_privacy_control(GlobalPrivacyControl);
@ -105,6 +115,7 @@ private:
Vector<SearchEngine> m_custom_search_engines;
Optional<AutocompleteEngine> m_autocomplete_engine;
SiteSetting m_autoplay;
BrowsingDataSettings m_browsing_data_settings;
GlobalPrivacyControl m_global_privacy_control { GlobalPrivacyControl::No };
DNSSettings m_dns_settings { SystemDNS() };
bool m_dns_override_by_command_line { false };

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2025, Tim Flynn <trflynn89@ladybird.org>
* Copyright (c) 2025-2026, Tim Flynn <trflynn89@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -66,6 +66,9 @@ void SettingsUI::register_interfaces()
register_interface("estimateBrowsingDataSizes"sv, [this](auto const& data) {
estimate_browsing_data_sizes(data);
});
register_interface("setBrowsingDataSettings"sv, [this](auto const& data) {
set_browsing_data_settings(data);
});
register_interface("clearBrowsingData"sv, [this](auto const& data) {
clear_browsing_data(data);
});
@ -311,6 +314,12 @@ void SettingsUI::estimate_browsing_data_sizes(JsonValue const& options)
});
}
void SettingsUI::set_browsing_data_settings(JsonValue const& settings)
{
Application::settings().set_browsing_data_settings(Settings::parse_browsing_data_settings(settings));
load_current_settings();
}
void SettingsUI::clear_browsing_data(JsonValue const& options)
{
if (!options.is_object())

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2025, Tim Flynn <trflynn89@ladybird.org>
* Copyright (c) 2025-2026, Tim Flynn <trflynn89@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -37,6 +37,7 @@ private:
void remove_all_site_setting_filters(JsonValue const&);
void estimate_browsing_data_sizes(JsonValue const&);
void set_browsing_data_settings(JsonValue const&);
void clear_browsing_data(JsonValue const&);
void set_global_privacy_control(JsonValue const&);

View file

@ -165,6 +165,12 @@ ErrorOr<IPC::File> ConnectionFromClient::create_client_socket()
return IPC::File::adopt_fd(socket_fds[1]);
}
void ConnectionFromClient::set_disk_cache_settings(HTTP::DiskCacheSettings disk_cache_settings)
{
if (g_disk_cache.has_value())
g_disk_cache->set_maximum_disk_cache_size(disk_cache_settings.maximum_size);
}
Messages::RequestServer::IsSupportedProtocolResponse ConnectionFromClient::is_supported_protocol(ByteString protocol)
{
return protocol == "http"sv || protocol == "https"sv;

View file

@ -9,6 +9,7 @@
#include <AK/Badge.h>
#include <AK/HashMap.h>
#include <LibHTTP/Cache/CacheMode.h>
#include <LibHTTP/Cache/DiskCacheSettings.h>
#include <LibIPC/ConnectionFromClient.h>
#include <LibWebSocket/WebSocket.h>
#include <RequestServer/Forward.h>
@ -41,6 +42,8 @@ private:
virtual Messages::RequestServer::ConnectNewClientResponse connect_new_client() override;
virtual Messages::RequestServer::ConnectNewClientsResponse connect_new_clients(size_t count) override;
virtual void set_disk_cache_settings(HTTP::DiskCacheSettings) override;
virtual Messages::RequestServer::IsSupportedProtocolResponse is_supported_protocol(ByteString) override;
virtual void set_dns_server(ByteString host_or_address, u16 port, bool use_tls, bool validate_dnssec_locally) override;
virtual void set_use_system_dns() override;

View file

@ -1,5 +1,6 @@
#include <LibCore/Proxy.h>
#include <LibHTTP/Cache/CacheMode.h>
#include <LibHTTP/Cache/DiskCacheSettings.h>
#include <LibHTTP/Cookie/IncludeCredentials.h>
#include <LibHTTP/Header.h>
#include <LibURL/URL.h>
@ -11,6 +12,8 @@ endpoint RequestServer
connect_new_client() => (IPC::File client_socket)
connect_new_clients(size_t count) => (Vector<IPC::File> sockets)
set_disk_cache_settings(HTTP::DiskCacheSettings disk_cache_settings) =|
// use_tls: enable DNS over TLS
set_dns_server(ByteString host_or_address, u16 port, bool use_tls, bool validate_dnssec_locally) =|
set_use_system_dns() =|