LibWeb: Make CSS font loader tolerate WPT web server shenanigans

The web server for WPT has a tendency to just disconnect after sending
us a resource. This makes curl think an error occurred, but it's
actually still recoverable and we have the data.

So instead of just bailing, do what we already do for other kinds of
resources and try to parse the data we got. If it works out, great!

It would be nice to solve this in the networking layer instead, but
I'll leave that as an exercise for our future selves.
This commit is contained in:
Andreas Kling 2024-09-21 18:35:31 +02:00 committed by Andreas Kling
parent 2303142386
commit 32299e74cb
Notes: github-actions[bot] 2024-09-21 17:21:21 +00:00
5 changed files with 32 additions and 16 deletions

View file

@ -119,6 +119,26 @@ FontLoader::~FontLoader() = default;
void FontLoader::resource_did_load()
{
resource_did_load_or_fail();
if (m_on_load)
m_on_load(*this);
}
void FontLoader::resource_did_fail()
{
resource_did_load_or_fail();
if (m_on_fail) {
m_on_fail();
}
}
void FontLoader::resource_did_load_or_fail()
{
// NOTE: Even if the resource "failed" to load, we still want to try to parse it as a font.
// This is necessary for https://wpt.live/ to work correctly, as it just drops the connection
// after sending a resource, which looks like an error, but is actually recoverable.
// FIXME: It would be nice to solve this in the network layer instead.
// It would also be nice to move font loading to using fetch primitives.
auto result = try_load_font();
if (result.is_error()) {
dbgln("Failed to parse font: {}", result.error());
@ -127,15 +147,6 @@ void FontLoader::resource_did_load()
}
m_vector_font = result.release_value();
m_style_computer.did_load_font(m_family_name);
if (m_on_load)
m_on_load(*this);
}
void FontLoader::resource_did_fail()
{
if (m_on_fail) {
m_on_fail();
}
}
RefPtr<Gfx::Font> FontLoader::font_with_point_size(float point_size)

View file

@ -251,13 +251,16 @@ public:
Vector<Gfx::UnicodeRange> const& unicode_ranges() const { return m_unicode_ranges; }
RefPtr<Gfx::Typeface> vector_font() const { return m_vector_font; }
virtual void resource_did_load() override;
virtual void resource_did_fail() override;
RefPtr<Gfx::Font> font_with_point_size(float point_size);
void start_loading_next_url();
private:
// ^ResourceClient
virtual void resource_did_load() override;
virtual void resource_did_fail() override;
void resource_did_load_or_fail();
ErrorOr<NonnullRefPtr<Gfx::Typeface>> try_load_font();
StyleComputer& m_style_computer;

View file

@ -120,9 +120,11 @@ void Resource::did_load(Badge<ResourceLoader>, ReadonlyBytes data, HTTP::HeaderM
});
}
void Resource::did_fail(Badge<ResourceLoader>, ByteString const& error, Optional<u32> status_code)
void Resource::did_fail(Badge<ResourceLoader>, ByteString const& error, ReadonlyBytes data, HTTP::HeaderMap const& headers, Optional<u32> status_code)
{
m_error = error;
m_encoded_data = ByteBuffer::copy(data).release_value_but_fixme_should_propagate_errors();
m_response_headers = headers;
m_status_code = move(status_code);
m_state = State::Failed;

View file

@ -68,7 +68,7 @@ public:
void for_each_client(Function<void(ResourceClient&)>);
void did_load(Badge<ResourceLoader>, ReadonlyBytes data, HTTP::HeaderMap const&, Optional<u32> status_code);
void did_fail(Badge<ResourceLoader>, ByteString const& error, Optional<u32> status_code);
void did_fail(Badge<ResourceLoader>, ByteString const& error, ReadonlyBytes data, HTTP::HeaderMap const&, Optional<u32> status_code);
protected:
explicit Resource(Type, LoadRequest const&);

View file

@ -121,8 +121,8 @@ RefPtr<Resource> ResourceLoader::load_resource(Resource::Type type, LoadRequest&
[=](auto data, auto& headers, auto status_code) {
const_cast<Resource&>(*resource).did_load({}, data, headers, status_code);
},
[=](auto& error, auto status_code, auto, auto) {
const_cast<Resource&>(*resource).did_fail({}, error, status_code);
[=](auto& error, auto status_code, auto data, auto& headers) {
const_cast<Resource&>(*resource).did_fail({}, error, data, headers, status_code);
});
return resource;