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
Notes: sideshowbarker 2024-07-17 01:53:23 +09:00
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;
}

View File

@ -37,11 +37,11 @@ public:
Closed = 3,
};
static WebIDL::ExceptionOr<JS::NonnullGCPtr<WebSocket>> construct_impl(JS::Realm&, DeprecatedString const& url, Optional<Variant<DeprecatedString, Vector<DeprecatedString>>> const& protocols);
static WebIDL::ExceptionOr<JS::NonnullGCPtr<WebSocket>> construct_impl(JS::Realm&, String const& url, Optional<Variant<String, Vector<String>>> const& protocols);
virtual ~WebSocket() override;
DeprecatedString url() const { return m_url.to_deprecated_string(); }
WebIDL::ExceptionOr<String> url() const { return TRY_OR_THROW_OOM(vm(), m_url.to_string()); }
#undef __ENUMERATE
#define __ENUMERATE(attribute_name, event_name) \
@ -51,22 +51,22 @@ public:
#undef __ENUMERATE
ReadyState ready_state() const;
DeprecatedString extensions() const;
DeprecatedString protocol() const;
String extensions() const;
WebIDL::ExceptionOr<String> protocol() const;
DeprecatedString const& binary_type() { return m_binary_type; };
void set_binary_type(DeprecatedString const& type) { m_binary_type = type; };
String const& binary_type() { return m_binary_type; };
void set_binary_type(String const& type) { m_binary_type = type; };
WebIDL::ExceptionOr<void> close(Optional<u16> code, Optional<DeprecatedString> reason);
WebIDL::ExceptionOr<void> send(Variant<JS::Handle<JS::Object>, JS::Handle<FileAPI::Blob>, DeprecatedString> const& data);
WebIDL::ExceptionOr<void> close(Optional<u16> code, Optional<String> reason);
WebIDL::ExceptionOr<void> send(Variant<JS::Handle<JS::Object>, JS::Handle<FileAPI::Blob>, String> const& data);
private:
void on_open();
void on_message(ByteBuffer message, bool is_text);
void on_error();
void on_close(u16 code, DeprecatedString reason, bool was_clean);
void on_close(u16 code, String reason, bool was_clean);
WebSocket(HTML::Window&, AK::URL&, Vector<DeprecatedString> const& protocols);
WebSocket(HTML::Window&, AK::URL&, Vector<String> const& protocols);
virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override;
virtual void visit_edges(Cell::Visitor&) override;
@ -74,7 +74,7 @@ private:
JS::NonnullGCPtr<HTML::Window> m_window;
AK::URL m_url;
DeprecatedString m_binary_type { "blob" };
String m_binary_type { "blob"_string.release_value_but_fixme_should_propagate_errors() };
RefPtr<WebSocketClientSocket> m_websocket;
};

View File

@ -2,7 +2,7 @@
#import <DOM/EventHandler.idl>
// https://websockets.spec.whatwg.org/#websocket
[Exposed=(Window,Worker)]
[Exposed=(Window,Worker), UseNewAKString]
interface WebSocket : EventTarget {
constructor(USVString url, optional (DOMString or sequence<DOMString>) protocols);