1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 13:57:35 +00:00

LibWeb: Migrate WebSockets::WebSocket to String

This commit is contained in:
Kenneth Myhra 2023-06-17 09:18:55 +02:00 committed by Andreas Kling
parent c03c0ec900
commit 57626c4f9a
3 changed files with 38 additions and 35 deletions

View file

@ -48,7 +48,7 @@ WebSocketClientSocket::~WebSocketClientSocket() = default;
WebSocketClientManager::WebSocketClientManager() = default;
// https://websockets.spec.whatwg.org/#dom-websocket-websocket
WebIDL::ExceptionOr<JS::NonnullGCPtr<WebSocket>> WebSocket::construct_impl(JS::Realm& realm, DeprecatedString const& url, Optional<Variant<DeprecatedString, Vector<DeprecatedString>>> const& protocols)
WebIDL::ExceptionOr<JS::NonnullGCPtr<WebSocket>> WebSocket::construct_impl(JS::Realm& realm, String const& url, Optional<Variant<String, Vector<String>>> const& protocols)
{
auto& window = verify_cast<HTML::Window>(realm.global_object());
AK::URL url_record(url);
@ -58,13 +58,13 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<WebSocket>> WebSocket::construct_impl(JS::R
return WebIDL::SyntaxError::create(realm, "Invalid protocol");
if (!url_record.fragment().is_empty())
return WebIDL::SyntaxError::create(realm, "Presence of URL fragment is invalid");
Vector<DeprecatedString> protocols_sequence;
Vector<String> protocols_sequence;
if (protocols.has_value()) {
// 5. If `protocols` is a string, set `protocols` to a sequence consisting of just that string
if (protocols.value().has<DeprecatedString>())
protocols_sequence = { protocols.value().get<DeprecatedString>() };
if (protocols.value().has<String>())
protocols_sequence = { protocols.value().get<String>() };
else
protocols_sequence = protocols.value().get<Vector<DeprecatedString>>();
protocols_sequence = protocols.value().get<Vector<String>>();
// 6. If any of the values in `protocols` occur more than once or otherwise fail to match the requirements, throw SyntaxError
auto sorted_protocols = protocols_sequence;
quick_sort(sorted_protocols);
@ -75,7 +75,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<WebSocket>> WebSocket::construct_impl(JS::R
auto protocol = sorted_protocols[i];
if (i < sorted_protocols.size() - 1 && protocol == sorted_protocols[i + 1])
return WebIDL::SyntaxError::create(realm, "Found a duplicate protocol name in the specified list");
for (auto character : protocol) {
for (auto character : protocol.code_points()) {
if (character < '\x21' || character > '\x7E')
return WebIDL::SyntaxError::create(realm, "Found invalid character in subprotocol name");
}
@ -84,13 +84,16 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<WebSocket>> WebSocket::construct_impl(JS::R
return MUST_OR_THROW_OOM(realm.heap().allocate<WebSocket>(realm, window, url_record, protocols_sequence));
}
WebSocket::WebSocket(HTML::Window& window, AK::URL& url, Vector<DeprecatedString> const& protocols)
WebSocket::WebSocket(HTML::Window& window, AK::URL& url, Vector<String> const& protocols)
: EventTarget(window.realm())
, m_window(window)
{
// FIXME: Integrate properly with FETCH as per https://fetch.spec.whatwg.org/#websocket-opening-handshake
auto origin_string = m_window->associated_document().origin().serialize();
m_websocket = WebSocketClientManager::the().connect(url, origin_string, protocols);
Vector<DeprecatedString> protcol_deprecated_strings;
for (auto protocol : protocols)
protcol_deprecated_strings.append(protocol.to_deprecated_string());
m_websocket = WebSocketClientManager::the().connect(url, origin_string, protcol_deprecated_strings);
m_websocket->on_open = [weak_this = make_weak_ptr<WebSocket>()] {
if (!weak_this)
return;
@ -107,7 +110,7 @@ WebSocket::WebSocket(HTML::Window& window, AK::URL& url, Vector<DeprecatedString
if (!weak_this)
return;
auto& websocket = const_cast<WebSocket&>(*weak_this);
websocket.on_close(code, reason, was_clean);
websocket.on_close(code, String::from_deprecated_string(reason).release_value_but_fixme_should_propagate_errors(), was_clean);
};
m_websocket->on_error = [weak_this = make_weak_ptr<WebSocket>()](auto) {
if (!weak_this)
@ -142,25 +145,25 @@ WebSocket::ReadyState WebSocket::ready_state() const
}
// https://websockets.spec.whatwg.org/#dom-websocket-extensions
DeprecatedString WebSocket::extensions() const
String WebSocket::extensions() const
{
if (!m_websocket)
return DeprecatedString::empty();
return String {};
// https://websockets.spec.whatwg.org/#feedback-from-the-protocol
// FIXME: Change the extensions attribute's value to the extensions in use, if it is not the null value.
return DeprecatedString::empty();
return String {};
}
// https://websockets.spec.whatwg.org/#dom-websocket-protocol
DeprecatedString WebSocket::protocol() const
WebIDL::ExceptionOr<String> WebSocket::protocol() const
{
if (!m_websocket)
return DeprecatedString::empty();
return m_websocket->subprotocol_in_use();
return String {};
return TRY_OR_THROW_OOM(vm(), String::from_deprecated_string(m_websocket->subprotocol_in_use()));
}
// https://websockets.spec.whatwg.org/#dom-websocket-close
WebIDL::ExceptionOr<void> WebSocket::close(Optional<u16> code, Optional<DeprecatedString> reason)
WebIDL::ExceptionOr<void> WebSocket::close(Optional<u16> code, Optional<String> reason)
{
// 1. If code is present, but is neither an integer equal to 1000 nor an integer in the range 3000 to 4999, inclusive, throw an "InvalidAccessError" DOMException.
if (code.has_value() && *code != 1000 && (*code < 3000 || *code > 4099))
@ -182,12 +185,12 @@ WebIDL::ExceptionOr<void> WebSocket::close(Optional<u16> code, Optional<Deprecat
// -> Otherwise
// NOTE: All of these are handled by the WebSocket Protocol when calling close()
// FIXME: LibProtocol does not yet support sending empty Close messages, so we use default values for now
m_websocket->close(code.value_or(1000), reason.value_or(DeprecatedString::empty()));
m_websocket->close(code.value_or(1000), reason.value_or(String {}).to_deprecated_string());
return {};
}
// https://websockets.spec.whatwg.org/#dom-websocket-send
WebIDL::ExceptionOr<void> WebSocket::send(Variant<JS::Handle<JS::Object>, JS::Handle<FileAPI::Blob>, DeprecatedString> const& data)
WebIDL::ExceptionOr<void> WebSocket::send(Variant<JS::Handle<JS::Object>, JS::Handle<FileAPI::Blob>, String> const& data)
{
auto state = ready_state();
if (state == WebSocket::ReadyState::Connecting)
@ -195,7 +198,7 @@ WebIDL::ExceptionOr<void> WebSocket::send(Variant<JS::Handle<JS::Object>, JS::Ha
if (state == WebSocket::ReadyState::Open) {
TRY_OR_THROW_OOM(vm(),
data.visit(
[this](DeprecatedString const& string) -> ErrorOr<void> {
[this](String const& string) -> ErrorOr<void> {
m_websocket->send(string);
return {};
},
@ -233,14 +236,14 @@ void WebSocket::on_error()
}
// https://websockets.spec.whatwg.org/#feedback-from-the-protocol
void WebSocket::on_close(u16 code, DeprecatedString reason, bool was_clean)
void WebSocket::on_close(u16 code, String reason, bool was_clean)
{
// 1. Change the readyState attribute's value to CLOSED. This is handled by the Protocol's WebSocket
// 2. If [needed], fire an event named error at the WebSocket object. This is handled by the Protocol's WebSocket
HTML::CloseEventInit event_init {};
event_init.was_clean = was_clean;
event_init.code = code;
event_init.reason = String::from_deprecated_string(reason).release_value_but_fixme_should_propagate_errors();
event_init.reason = reason;
dispatch_event(HTML::CloseEvent::create(realm(), HTML::EventNames::close, event_init).release_value_but_fixme_should_propagate_errors());
}
@ -253,7 +256,7 @@ void WebSocket::on_message(ByteBuffer message, bool is_text)
auto text_message = DeprecatedString(ReadonlyBytes(message));
HTML::MessageEventInit event_init;
event_init.data = JS::PrimitiveString::create(vm(), text_message);
event_init.origin = String::from_deprecated_string(url()).release_value_but_fixme_should_propagate_errors();
event_init.origin = url().release_value_but_fixme_should_propagate_errors();
dispatch_event(HTML::MessageEvent::create(realm(), HTML::EventNames::message, event_init).release_value_but_fixme_should_propagate_errors());
return;
}
@ -265,7 +268,7 @@ void WebSocket::on_message(ByteBuffer message, bool is_text)
// type indicates that the data is Binary and binaryType is "arraybuffer"
HTML::MessageEventInit event_init;
event_init.data = JS::ArrayBuffer::create(realm(), message);
event_init.origin = String::from_deprecated_string(url()).release_value_but_fixme_should_propagate_errors();
event_init.origin = url().release_value_but_fixme_should_propagate_errors();
dispatch_event(HTML::MessageEvent::create(realm(), HTML::EventNames::message, event_init).release_value_but_fixme_should_propagate_errors());
return;
}