Commit graph

63 commits

Author SHA1 Message Date
Andreas Kling
72720bc229 LibWeb: Preserve JS bytecode in memory cache
Store JavaScript bytecode side data in the WebContent HTTP memory
cache and replay it when serving cached responses. Also update an
already-complete memory-cache entry when asynchronous bytecode cache
generation finishes, so the first source-only response does not keep
shadowing the disk-cache sidecar during same-process navigations.

Keep the HTTP memory-cache backfill keyed with the request headers that
populated the memory-cache entry, so Vary responses still receive their
generated bytecode sidecar.

Add LibHTTP coverage for round-tripping bytecode side data through a
memory-cache entry, attaching it after the response body has already
been cached, and matching Vary headers during updates. Add LibWeb
coverage for preserving the memory-cache request headers when cloning
responses.
2026-06-06 09:15:09 +02:00
Shannon Booth
637fd51595 LibWeb: Unify WebIDL C++ type generation
Represent WebIDL C++ types with a single CppType model that tracks
nullability, optional presence, and contained storage.

GC-like values now use GC::Ref/GC::Ptr directly, while containers choose
"plain", "Root", or "Conservative" container types depending on what
they contain. For example, sequence<Element> becomes a RootVector of
GC::Ref values, while sequence<SomeDictionary> becomes a
ConservativeVector only when the dictionary contains GC-like values.
This moves the generated bindings away from wrapping GC values in
GC::Root by default.

This has broad fallout as the types passed to interfaces for GC
objects changes almost fully across the board.
2026-05-23 18:26:12 +02:00
Andreas Kling
318fb4f2d0 LibWeb: Preserve immutable consumed body bytes
Keep consumed response body bytes in Core::ImmutableBytes instead of
requiring a ByteBuffer. This lets responses that already arrived as
file-backed immutable data keep that representation through body
consumption, while streamed responses can still adopt their
accumulated ByteBuffer without another copy.

Update the body consumers that only inspect bytes to read from
immutable byte views. Font loading still copies at its existing
ownership boundary, where the off-thread preparation path takes a
ByteBuffer.
2026-05-18 01:21:34 +02:00
Andreas Kling
c0b19ff981 RequestServer: Send bytecode cache sidecars as files
Map JavaScript bytecode cache sidecars from the HTTP disk cache instead
of copying them into anonymous shared buffers while handing response
headers to WebContent. Store the mapped data as ImmutableBytes on the
fetch response so script fetching can decode directly from the mapped
sidecar bytes.

Add LibHTTP coverage for retrieving associated cache data as a mappable
file, alongside the existing byte-buffer retrieval API.
2026-05-16 08:13:35 +02:00
Luke Wilde
de35994fc2 LibJS+LibWeb: Use the unified Visitor for Variant-holding members 2026-05-15 08:51:17 +02:00
Andreas Kling
c32b5a3f73 LibWeb+RequestServer: Send cached bytecode with responses
Attach cached JavaScript bytecode sidecars to HTTP response headers so
WebContent can materialize classic and module scripts directly from a
decoded cache blob on cache hits.

Carry the disk cache vary key with the sidecar and reuse it when storing
fresh bytecode, avoiding mismatches against the augmented network
request headers used to create the cache entry.

Keep CORS-filtered module responses intact for status, MIME, and script
creation checks. Read bytecode sidecar data only from the internal
response, and treat decode or materialization failure as a cache miss
that falls back to normal source compilation.
2026-05-06 08:20:06 +02:00
Aliaksandr Kalenik
6830b60e75 LibWeb: Push fetch body chunks directly into the byte stream controller
Previously, each chunk was delivered through a pull promise. Every pull
allocated around seven GC objects (the pull promise, its capability, and
the reaction handlers from react_to_promise) and none of them did
anything useful. The pull algorithm is now a no-op, and
FetchedDataReceiver enqueues bytes into the controller as they arrive.
2026-04-30 14:18:11 +02:00
Sam Atkins
c5f117f1a2 LibWeb/Fetch: Store Body Blob as Ref not Root
To avoid some churn, Body::source() returns the SourceTypeInternal
object, as it's not exposed to JS. The constructor is also adjusted so
that Body::clone() doesn't have to convert to a SourceType and then
immediately back again.
2026-02-17 07:40:03 -05:00
Andreas Kling
37bdcc3488 LibWeb: Support MIME type sniffing for streaming HTTP responses
Previously, when loading a document, we would try to sniff the MIME
type by reading from the response body's source. However, for streaming
HTTP responses, the body source is Empty (the data comes through the
stream instead), so we had no bytes to sniff.

This caused pages like hypr.land (which sends no Content-Type header)
to be misidentified as plain text instead of HTML, since the MIME
sniffing algorithm would receive zero bytes and fall back to the
default type.

The fix captures the first bytes of the response body during fetch,
storing them on the Body object. These bytes are the "resource header"
defined by the MIME Sniffing spec - up to 1445 bytes, which is enough
to identify any MIME type the spec can detect.

Since bytes may arrive asynchronously during streaming, we use a
callback mechanism: if bytes aren't ready yet when load_document()
needs them, it registers a callback that fires once enough bytes have
been captured (or the stream ends).

The flow is:
1. FetchedDataReceiver receives network bytes, buffers them
2. When Body is created, buffered bytes are flushed to Body's sniff
   buffer, and subsequent bytes are appended as they arrive
3. Before calling load_document(), Navigable waits for sniff bytes
4. load_document() passes the bytes to MimeSniff::Resource::sniff()
2026-01-24 15:21:26 +01:00
Timothy Flynn
6b91199253 LibHTTP+LibWeb: Move Infrastructure::Request::CacheMode to LibHTTP
We will need to send this enum over IPC to RequestServer to affect the
disk cache's behavior.
2026-01-22 07:05:06 -05:00
Timothy Flynn
1a5cd6b05f LibWeb: Do not perform any cache revalidation from WebContent
We currently will perform some revalidation from both WebContent and
RequestServer. For simplicity's sake, now that the memory cache only
holds fresh responses, let's remove revalidation handling from the
WebContent process. If a memory-cached response is stale, it's fine
to just forward that request to RequestServer. It will then either
be served by disk cache, or revalidated at that point.
2026-01-19 08:02:14 -05:00
Timothy Flynn
2ac219405f LibHTTP+LibWeb: Purge non-fresh entries from the memory cache
Once a cache entry is not fresh, we now remove it from the memory cache.
We will avoid handling revalidation from within WebContent. Instead, we
will just forward the request to RequestServer, where the disk cache
will handle revalidation for itself if needed.
2026-01-19 08:02:14 -05:00
Timothy Flynn
46b3218241 LibHTTP+LibWeb: Use LibHTTP to calculate stale-while-revalidate values
No need to duplicate this in LibWeb.

In doing so, this also fixes an apparent bug for SWR handling in LibWeb.
We were previously deciding if we were in the SWR lifetime with:

    stale_while_revalidate > current_age

However, the SWR lifetime is meant to be an additional time on top of
the freshness lifetime:

    freshness_lifetime + stale_while_revalidate > current_age
2025-12-14 11:33:02 -05:00
Timothy Flynn
854981714f LibWeb: Remove errant "non-standard" comment
The method this comment was attached to was removed in commit
a5df972055.
2025-12-14 11:33:02 -05:00
Timothy Flynn
2453f0bc04 LibHTTP+LibWeb: Use LibHTTP's cache implementation in LibWeb
There are a couple of remaining RFC 9111 methods in LibWeb's Fetch, but
these are currently directly tied to the way we store GC-allocated HTTP
response objects. So de-coupling that is left as a future exercise.
2025-11-29 08:35:02 -05:00
Timothy Flynn
9375660b64 LibHTTP+LibWeb+RequestServer: Move Fetch's HTTP header infra to LibHTTP
The end goal here is for LibHTTP to be the home of our RFC 9111 (HTTP
caching) implementation. We currently have one implementation in LibWeb
for our in-memory cache and another in RequestServer for our disk cache.

The implementations both largely revolve around interacting with HTTP
headers. But in LibWeb, we are using Fetch's header infra, and in RS we
are using are home-grown header infra from LibHTTP.

So to give these a common denominator, this patch replaces the LibHTTP
implementation with Fetch's infra. Our existing LibHTTP implementation
was not particularly compliant with any spec, so this at least gives us
a standards-based common implementation.

This migration also required moving a handful of other Fetch AOs over
to LibHTTP. (It turns out these AOs were all from the Fetch/Infra/HTTP
folder, so perhaps it makes sense for LibHTTP to be the implementation
of that entire set of facilities.)
2025-11-27 14:57:29 +01:00
Timothy Flynn
3dce6766a3 LibWeb: Extract some CORS and MIME Fetch helpers to their own files
An upcoming commit will migrate the contents of Headers.h/cpp to LibHTTP
for use outside of LibWeb. These CORS and MIME helpers depend on other
LibWeb facilities, however, so they cannot be moved.
2025-11-27 14:57:29 +01:00
Timothy Flynn
0fd80a8f99 LibTextCodec+LibWeb: Move isomorphic coders to LibTextCodec
This will be used outside of LibWeb.
2025-11-27 14:57:29 +01:00
Timothy Flynn
cbfae97101 LibWeb: Include empty header values when joining duplicated headers
Fixes a regression from commit:
f675cfe90f

It is not sufficient to only check if the builder is empty, as we will
then drop empty header values (when the first found value is empty).

This is tested in WPT by /cors/origin.htm, but that requires an HTTP
server.
2025-11-26 21:22:35 -05:00
Timothy Flynn
f675cfe90f LibWeb: Store HTTP methods and headers as ByteString
The spec declares these as a byte sequence, which we then implemented as
a ByteBuffer. This has become pretty awkward to deal with, as evidenced
by the plethora of `MUST(ByteBuffer::copy(...))` and `.bytes()` calls
everywhere inside Fetch. We would then treat the bytes as a string
anyways by wrapping them in StringView everywhere.

We now store these as a ByteString. This is more comfortable to deal
with, and we no longer need to continually copy underlying storage (as
ByteString is ref-counted).

This work is largely preparatory for an upcoming HTTP header refactor.
2025-11-26 09:15:06 -05:00
Timothy Flynn
ed27eea091 LibWeb: Do not copy the result of HeaderList::extract_header_list_values
There's no need to copy the Vector out of this result every time we call
it. We can move it out or access it directly.
2025-11-26 09:15:06 -05:00
Timothy Flynn
44fbf6451e LibWeb: Simplify Fetch's build-content-range implementation
* Don't pass u64 by reference
* Don't double-format the range numbers
2025-11-26 09:15:06 -05:00
Timothy Flynn
d70224ad2e LibWeb: Organize Fetch Headers.h/Headers.cpp a bit
Generally just define things in the order they are declared (will make a
change to use ByteString in this file a bit easier to follow). Also make
a couple of free functions be class methods on Header / HeaderList.
2025-11-26 09:15:06 -05:00
Aliaksandr Kalenik
69cede4a0f AK+LibWeb: Make StringBase::bytes() lvalue-only
Disallow calling `StringBase::bytes()` on temporaries to avoid returning
`ReadonlyBytes` that outlive the underlying string.

With this change, we catch a real UAF:
`load_result.data = maybe_response.release_value().bytes();`
All other updated call sites were already safe, they just needed to use
an intermediate named variable to satisfy the new lvalue-only
requirement.
2025-11-25 13:02:20 -05:00
Aliaksandr Kalenik
0eb28a1a54 LibWeb: Delete unused BufferPolicy from fetch Request
This is no longer needed since all requests are unbuffered.
2025-11-20 06:29:13 -05:00
Psychpsyo
100f37995f Everywhere: Clean up AD-HOC and FIXME comments without colons 2025-11-13 15:56:04 +01:00
Timothy Flynn
6057719f63 LibWeb: Use fetch to retrieve all HTMLLinkElement resources
HTMLLinkElement is the final user of Resource/ResourceClient (used for
preloads and icons). This ports these link types to use fetch according
to the spec.

Preloads were particularly goofy because they would be stored in the
ResourceLoader's ad-hoc cache. But this cache was never consulted for
organic loads, thus were never used. There is more work to be done to
use these preloads within fetch, but for now they at least are stored
in fetch's HTTP cache for re-use.
2025-11-05 18:27:36 +01:00
Luke Wilde
4772e1b0c9 LibWeb/Fetch: Add missing spec step for checking for tuple origin
Fixes https://github.com/LadybirdBrowser/ladybird/issues/6188
2025-09-15 09:58:33 +02:00
Ali Mohammad Pur
4462348916 Everywhere: Slap some [[clang::lifetimebound]] where appropriate
This first pass only applies to the following two cases:
- Public functions returning a view type into an object they own
- Public ctors storing a view type

This catches a grand total of one (1) issue, which is fixed in
the previous commit.
2025-09-01 11:11:38 +02:00
ayeteadoe
3df8e00d91 LibWeb: Enable EXPLICIT_SYMBOL_EXPORT 2025-08-23 16:04:36 -06:00
Kenneth Myhra
1228063a85 LibWeb: Enforce Integrity Policy on Fetch requests 2025-08-14 13:37:38 +01:00
Kenneth Myhra
0dc2fb3781 LibWeb: Update Fetch's compute the redirect-taint concept 2025-08-12 07:08:33 -04:00
Kenneth Myhra
e9246c15d9 LibWeb: Pass top-level navigation initiator origin to Fetch's Request 2025-08-12 07:08:33 -04:00
Kenneth Myhra
70cafc558e LibWeb: Replace request's "window" with "traversable for user prompts"
User prompts are not tied to specific Windows or the client's Window.
They are tied to a traversable navigable (browser tab).
2025-08-08 11:12:53 +01:00
Andreas Kling
66a19b8550 LibWeb: Make ESO "fetch group" weakly reference the fetch records
Otherwise we end up holding on to every fetch record indefinitely.

Found by analyzing GC heap graphs on Discord.
2025-07-29 20:00:17 -04:00
Andreas Kling
03256a2543 LibWeb: Add "parallel queue" and allow it as fetch task destination
Note that it's not actually executing tasks in parallel, it's still
throwing them on the HTML event loop task queue, each with its own
unique task source.

This makes our fetch implementation a lot more robust when HTTP caching
is enabled, and you can now click links on https://terminal.shop/
without hitting TODO assertions in fetch.
2025-07-17 00:13:39 +02:00
Timothy Flynn
7280ed6312 Meta: Enforce newlines around namespaces
This has come up several times during code review, so let's just enforce
it using a new clang-format 20 option.
2025-05-14 02:01:59 -06:00
Timothy Flynn
0cd5e99066 LibWeb: Use the correct target realm to tee a stream
We currently store Web::Fetch::Infrastructure::Response objects in the
HTTP cache. They are associated with their original realm, but when we
use a cached response, we clone it into the target realm. For example,
two <iframe> objects loading the same HTML will be in different realms.

When we clone the response, we must use the target realm throughout the
entire cloning process. We neglected to do this for the cloned response
body stream, which is cloned via teeing. The result was the the stream
for the "cloned" response was created in the original realm, causing
issues down the line when reading from that stream tried to handle read
promises on behalf of the original realm. There are protections in place
to prevent this from happening, and the cached response read would never
complete.
2025-04-30 09:30:15 -04:00
Timothy Flynn
a9ddd427cb LibWeb: Move ReadableStream AOs into their own file
The main streams AO file has gotten very large, and is a bit difficult
to navigate. In an effort to improve DX, this migrates ReadableStream
AOs to their own file. And the helper classes used for the tee and pipe-
to operations are also in their own files.
2025-04-18 06:55:40 -04:00
Andreas Kling
de424d6879 LibJS: Make Completion.[[Value]] non-optional
Instead, just use js_undefined() whenever the [[Value]] field is unused.
This avoids a whole bunch of presence checks.
2025-04-05 11:20:26 +02:00
Shannon Booth
a5df972055 LibWeb: Do not store network errors as a StringView
This is very clearly a very dangerous API to have, and was causing
a crash on Linux as a result of a stack use-after-free when visiting
https://www.index.hr/.

Fixes #3901
2025-04-02 11:43:53 +02:00
Luke Wilde
6f771f45e2 LibWeb: Enforce Content Security Policy on Fetch requests 2025-03-19 00:55:14 +01:00
Luke Wilde
6d1f78198d LibWeb: Implement Resource Timing 2025-03-06 09:00:53 -07:00
Luke Wilde
cae0ab2139 LibWeb: Make PolicyContainer GC allocated
This is required to store Content Security Policies, as their
Directives are implemented as subclasses with overridden virtual
functions. Thus, they cannot be stored as generic Directive classes, as
it'll lose the ability to call overridden functions when they are
copied.
2025-02-21 12:43:48 +00:00
Tim Ledbetter
a8904451ff LibWeb: Set navigation start time when creating a new Document
This currently uses a non spec-compliant property on the Response
object, which represents the time that the Response was created.

Setting this value allows `Performance.timeOrigin` to return a
reasonable value.
2025-01-27 14:53:33 +01:00
Tim Ledbetter
ddea1c6248 LibWeb: Store response creation time as MonotonicTime
This non-standard value is used for calculating durations relative to
when the response was created. MonotonicTime is more suitable for this
use case.
2025-01-27 14:53:33 +01:00
Shannon Booth
fd27eef0d1 LibWeb: Return OptionalNone from DOMURL::parse on failure
This ports one more function away from needing to use the awkward
valid state of the URL class.
2025-01-22 12:33:55 +00:00
Shannon Booth
9ce0c5914b LibWeb: Add a 'get a reader' helper method on ReadableStream 2024-12-25 12:00:54 +01:00
Sam Atkins
a4db7e9e23 LibWeb: Add method for "is CORS-same-origin" 2024-12-22 12:30:09 +01:00
Feng Yu
e0c0668f3d LibWeb: Avoid re-encoding response headers
isomorphic encoding a value that has already been encoded will
result in garbage data. `response_headers` is already encoded in
ISO-8859-1/latin1, we cannot use `from_string_pair`, as it triggers
ISO-8859-1/latin1 encoding.

Follow-up of https://github.com/LadybirdBrowser/ladybird/pull/1893
2024-12-17 13:44:10 +01:00