diff --git a/Userland/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp b/Userland/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp index 802ca33362..9873b770c9 100644 --- a/Userland/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp +++ b/Userland/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp @@ -832,6 +832,10 @@ WebIDL::ExceptionOr> scheme_fetch(JS::Realm& r // Return the result of running HTTP fetch given fetchParams. return http_fetch(realm, fetch_params); } + // AD-HOC: "resource" + else if (request->current_url().scheme() == "resource"sv) { + return TRY(nonstandard_resource_loader_file_or_http_network_fetch(realm, fetch_params)); + } // 4. Return a network error. auto message = request->current_url().scheme() == "about"sv diff --git a/Userland/Libraries/LibWeb/Fetch/Infrastructure/URL.h b/Userland/Libraries/LibWeb/Fetch/Infrastructure/URL.h index c93554033f..ad1048007c 100644 --- a/Userland/Libraries/LibWeb/Fetch/Infrastructure/URL.h +++ b/Userland/Libraries/LibWeb/Fetch/Infrastructure/URL.h @@ -27,7 +27,10 @@ inline constexpr Array HTTP_SCHEMES = { // https://fetch.spec.whatwg.org/#fetch-scheme // A fetch scheme is "about", "blob", "data", "file", or an HTTP(S) scheme. inline constexpr Array FETCH_SCHEMES = { - "about"sv, "blob"sv, "data"sv, "file"sv, "http"sv, "https"sv + "about"sv, "blob"sv, "data"sv, "file"sv, "http"sv, "https"sv, + + // AD-HOC: Internal fetch schemes: + "resource"sv }; [[nodiscard]] bool is_local_url(AK::URL const&); diff --git a/Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp b/Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp index 6bdbeb4da9..3075152392 100644 --- a/Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp +++ b/Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -158,6 +159,18 @@ static void store_response_cookies(Page& page, AK::URL const& url, ByteString co static size_t resource_id = 0; +static HashMap response_headers_for_file(StringView path) +{ + // For file:// and resource:// URLs, we have to guess the MIME type, since there's no HTTP header to tell us what + // it is. We insert a fake Content-Type header here, so that clients can use it to learn the MIME type. + auto mime_type = Core::guess_mime_type_based_on_filename(path); + + HashMap response_headers; + response_headers.set("Content-Type"sv, mime_type); + + return response_headers; +} + void ResourceLoader::load(LoadRequest& request, SuccessCallback success_callback, ErrorCallback error_callback, Optional timeout, TimeoutCallback timeout_callback) { auto& url = request.url(); @@ -230,6 +243,22 @@ void ResourceLoader::load(LoadRequest& request, SuccessCallback success_callback return; } + if (url.scheme() == "resource") { + auto resource = Core::Resource::load_from_uri(url.serialize()); + if (resource.is_error()) { + log_failure(request, resource.error()); + return; + } + + auto data = resource.value()->data(); + auto response_headers = response_headers_for_file(url.serialize_path()); + + log_success(request); + success_callback(data, response_headers, {}); + + return; + } + if (url.scheme() == "file") { if (request.page()) m_page = request.page(); @@ -290,15 +319,11 @@ void ResourceLoader::load(LoadRequest& request, SuccessCallback success_callback error_callback(ByteString::formatted("{}", maybe_data.error()), 500u, {}, {}); return; } + auto data = maybe_data.release_value(); + auto response_headers = response_headers_for_file(request.url().serialize_path()); + log_success(request); - - // NOTE: For file:// URLs, we have to guess the MIME type, since there's no HTTP header to tell us what this is. - // We insert a fake Content-Type header here, so that clients can use it to learn the MIME type. - HashMap response_headers; - auto mime_type = Core::guess_mime_type_based_on_filename(request.url().serialize_path()); - response_headers.set("Content-Type"sv, mime_type); - success_callback(data, response_headers, {}); });