LibWeb: Implement an ephemeral Blob URL store

The Blob URL store is intended to be a singleton across all WebContent
instances. But for now, this implements a per-WebContent store, which
only lives as long as the WebContent process itself.
This commit is contained in:
Timothy Flynn 2023-08-01 18:29:54 -04:00 committed by Linus Groh
parent 2ce416a676
commit b3f82f724d
Notes: sideshowbarker 2024-07-16 22:26:05 +09:00
3 changed files with 124 additions and 0 deletions

View File

@ -206,6 +206,7 @@ set(SOURCES
Fetch/Request.cpp
Fetch/Response.cpp
FileAPI/Blob.cpp
FileAPI/BlobURLStore.cpp
FileAPI/File.cpp
FileAPI/FileList.cpp
FontCache.cpp

View File

@ -0,0 +1,92 @@
/*
* Copyright (c) 2023, Tim Flynn <trflynn89@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/StringBuilder.h>
#include <AK/URL.h>
#include <LibWeb/Crypto/Crypto.h>
#include <LibWeb/FileAPI/Blob.h>
#include <LibWeb/FileAPI/BlobURLStore.h>
#include <LibWeb/HTML/Origin.h>
#include <LibWeb/HTML/Scripting/Environments.h>
namespace Web::FileAPI {
BlobURLStore& blob_url_store()
{
static HashMap<String, BlobURLEntry> store;
return store;
}
// https://w3c.github.io/FileAPI/#unicodeBlobURL
ErrorOr<String> generate_new_blob_url()
{
// 1. Let result be the empty string.
StringBuilder result;
// 2. Append the string "blob:" to result.
TRY(result.try_append("blob:"sv));
// 3. Let settings be the current settings object
auto& settings = HTML::current_settings_object();
// 4. Let origin be settingss origin.
auto origin = settings.origin();
// 5. Let serialized be the ASCII serialization of origin.
auto serialized = origin.serialize();
// 6. If serialized is "null", set it to an implementation-defined value.
if (serialized == "null"sv)
serialized = "ladybird"sv;
// 7. Append serialized to result.
TRY(result.try_append(serialized));
// 8. Append U+0024 SOLIDUS (/) to result.
TRY(result.try_append('/'));
// 9. Generate a UUID [RFC4122] as a string and append it to result.
auto uuid = TRY(Crypto::generate_random_uuid());
TRY(result.try_append(uuid));
// 10. Return result.
return result.to_string();
}
// https://w3c.github.io/FileAPI/#add-an-entry
ErrorOr<String> add_entry_to_blob_url_store(JS::NonnullGCPtr<Blob> object)
{
// 1. Let store be the user agents blob URL store.
auto& store = blob_url_store();
// 2. Let url be the result of generating a new blob URL.
auto url = TRY(generate_new_blob_url());
// 3. Let entry be a new blob URL entry consisting of object and the current settings object.
BlobURLEntry entry { object, HTML::current_settings_object() };
// 4. Set store[url] to entry.
TRY(store.try_set(url, move(entry)));
// 5. Return url.
return url;
}
// https://w3c.github.io/FileAPI/#removeTheEntry
ErrorOr<void> remove_entry_from_blob_url_store(StringView url)
{
// 1. Let store be the user agents blob URL store;
auto& store = blob_url_store();
// 2. Let url string be the result of serializing url.
auto url_string = TRY(AK::URL { url }.to_string());
// 3. Remove store[url string].
store.remove(url_string);
return {};
}
}

View File

@ -0,0 +1,31 @@
/*
* Copyright (c) 2023, Tim Flynn <trflynn89@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/HashMap.h>
#include <AK/String.h>
#include <LibJS/Heap/GCPtr.h>
#include <LibJS/Heap/Handle.h>
#include <LibWeb/Forward.h>
namespace Web::FileAPI {
// https://w3c.github.io/FileAPI/#blob-url-entry
struct BlobURLEntry {
JS::Handle<Blob> object; // FIXME: This could also be a MediaSource after we implement MSE.
JS::Handle<HTML::EnvironmentSettingsObject> environment;
};
// https://w3c.github.io/FileAPI/#BlobURLStore
using BlobURLStore = HashMap<String, BlobURLEntry>;
BlobURLStore& blob_url_store();
ErrorOr<String> generate_new_blob_url();
ErrorOr<String> add_entry_to_blob_url_store(JS::NonnullGCPtr<Blob> object);
ErrorOr<void> remove_entry_from_blob_url_store(StringView url);
}