LibWeb: Don't drop messages received before MessagePort is enabled
Some checks are pending
CI / macOS, arm64, Sanitizer_CI, Clang (push) Waiting to run
CI / Linux, x86_64, Fuzzers_CI, Clang (push) Waiting to run
CI / Linux, x86_64, Sanitizer_CI, GNU (push) Waiting to run
CI / Linux, x86_64, Sanitizer_CI, Clang (push) Waiting to run
Package the js repl as a binary artifact / macOS, arm64 (push) Waiting to run
Package the js repl as a binary artifact / Linux, x86_64 (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run

This change implements following behavior defined in the spec:
https://html.spec.whatwg.org/multipage/web-messaging.html#examples-5
> The start() method, whether called explicitly or implicitly (by
setting onmessage), starts the flow of messages: messages posted on
message ports are initially paused, so that they don't get dropped on
the floor before the script has had a chance to set up its handlers.

Now we don't read bytes from the underlying transport socket until the
message port transitions to the enabled state. This required the
following places to explicitly enable the message port, because now,
when it actually matters, we must do so, or otherwise sent messages will
get stuck:
- `onmessage` attribute setter in DedicatedWorkerGlobalScope, because
  it implicitly sets the onmessage handler for the worker's underlying
  port.
- Stream API operations where the message port enabling steps were
  previously marked as FIXMEs.
This commit is contained in:
Aliaksandr Kalenik 2025-06-07 23:57:17 +02:00 committed by Alexander Kalenik
commit 346c083d58
Notes: github-actions[bot] 2025-06-08 16:27:20 +00:00
7 changed files with 64 additions and 29 deletions

View file

@ -66,17 +66,31 @@ WebIDL::ExceptionOr<void> DedicatedWorkerGlobalScope::post_message(JS::Value mes
return m_internal_port->post_message(message, transfer);
}
#undef __ENUMERATE
#define __ENUMERATE(attribute_name, event_name) \
void DedicatedWorkerGlobalScope::set_##attribute_name(WebIDL::CallbackType* value) \
{ \
set_event_handler_attribute(event_name, move(value)); \
} \
WebIDL::CallbackType* DedicatedWorkerGlobalScope::attribute_name() \
{ \
return event_handler_attribute(event_name); \
}
ENUMERATE_DEDICATED_WORKER_GLOBAL_SCOPE_EVENT_HANDLERS(__ENUMERATE)
#undef __ENUMERATE
WebIDL::CallbackType* DedicatedWorkerGlobalScope::onmessage()
{
return event_handler_attribute(EventNames::message);
}
void DedicatedWorkerGlobalScope::set_onmessage(WebIDL::CallbackType* callback)
{
set_event_handler_attribute(EventNames::message, callback);
// NOTE: This onmessage attribute setter implicitly sets worker's underlying MessagePort's onmessage attribute, so this
// spec behavior also applies here:
// https://html.spec.whatwg.org/multipage/web-messaging.html#message-ports:handler-messageeventtarget-onmessage
// The first time a MessagePort object's onmessage IDL attribute is set, the port's port message queue must be enabled,
// as if the start() method had been called.
m_internal_port->start();
}
void DedicatedWorkerGlobalScope::set_onmessageerror(WebIDL::CallbackType* callback)
{
set_event_handler_attribute(EventNames::messageerror, callback);
}
WebIDL::CallbackType* DedicatedWorkerGlobalScope::onmessageerror()
{
return event_handler_attribute(EventNames::messageerror);
}
}