
This change unfortunately cannot be atomically made without a single commit changing everything. Most of the important changes are in LibIPC/Connection.cpp, LibIPC/ServerConnection.cpp and LibCore/LocalServer.cpp. The notable changes are: - IPCCompiler now generates the decode and decode_message functions such that they take a Core::Stream::LocalSocket instead of the socket fd. - IPC::Decoder now uses the receive_fd method of LocalSocket instead of doing system calls directly on the fd. - IPC::ConnectionBase and related classes now use the Stream API functions. - IPC::ServerConnection no longer constructs the socket itself; instead, a convenience macro, IPC_CLIENT_CONNECTION, is used in place of C_OBJECT and will generate a static try_create factory function for the ServerConnection subclass. The subclass is now responsible for passing the socket constructed in this function to its ServerConnection base; the socket is passed as the first argument to the constructor (as a NonnullOwnPtr<Core::Stream::LocalServer>) before any other arguments. - The functionality regarding taking over sockets from SystemServer has been moved to LibIPC/SystemServerTakeover.cpp. The Core::LocalSocket implementation of this functionality hasn't been deleted due to my intention of removing this class in the near future and to reduce noise on this (already quite noisy) PR.
112 lines
3 KiB
C++
112 lines
3 KiB
C++
/*
|
|
* Copyright (c) 2021, Dex♪ <dexes.ttp@gmail.com>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <AK/ByteBuffer.h>
|
|
#include <AK/RefCounted.h>
|
|
#include <AK/URL.h>
|
|
#include <AK/Weakable.h>
|
|
#include <LibCore/Object.h>
|
|
#include <LibWeb/Bindings/WindowObject.h>
|
|
#include <LibWeb/Bindings/Wrappable.h>
|
|
#include <LibWeb/DOM/EventTarget.h>
|
|
#include <LibWeb/DOM/ExceptionOr.h>
|
|
#include <LibWeb/Forward.h>
|
|
|
|
#define ENUMERATE_WEBSOCKET_EVENT_HANDLERS(E) \
|
|
E(onerror, HTML::EventNames::error) \
|
|
E(onclose, HTML::EventNames::close) \
|
|
E(onopen, HTML::EventNames::open) \
|
|
E(onmessage, HTML::EventNames::message)
|
|
|
|
namespace Protocol {
|
|
class WebSocketClient;
|
|
class WebSocket;
|
|
}
|
|
|
|
namespace Web::HTML {
|
|
|
|
class WebSocketClientManager : public Core::Object {
|
|
C_OBJECT_ABSTRACT(WebSocketClientManager)
|
|
public:
|
|
static WebSocketClientManager& the();
|
|
|
|
RefPtr<Protocol::WebSocket> connect(const AK::URL&);
|
|
|
|
private:
|
|
static ErrorOr<NonnullRefPtr<WebSocketClientManager>> try_create();
|
|
WebSocketClientManager(NonnullRefPtr<Protocol::WebSocketClient>);
|
|
|
|
RefPtr<Protocol::WebSocketClient> m_websocket_client;
|
|
};
|
|
|
|
class WebSocket final
|
|
: public RefCounted<WebSocket>
|
|
, public Weakable<WebSocket>
|
|
, public DOM::EventTarget
|
|
, public Bindings::Wrappable {
|
|
public:
|
|
enum class ReadyState : u16 {
|
|
Connecting = 0,
|
|
Open = 1,
|
|
Closing = 2,
|
|
Closed = 3,
|
|
};
|
|
|
|
using WrapperType = Bindings::WebSocketWrapper;
|
|
|
|
static NonnullRefPtr<WebSocket> create(DOM::Window& window, AK::URL& url)
|
|
{
|
|
return adopt_ref(*new WebSocket(window, url));
|
|
}
|
|
|
|
static DOM::ExceptionOr<NonnullRefPtr<WebSocket>> create_with_global_object(Bindings::WindowObject& window, const String& url);
|
|
|
|
virtual ~WebSocket() override;
|
|
|
|
using RefCounted::ref;
|
|
using RefCounted::unref;
|
|
|
|
String url() const { return m_url.to_string(); }
|
|
|
|
#undef __ENUMERATE
|
|
#define __ENUMERATE(attribute_name, event_name) \
|
|
void set_##attribute_name(HTML::EventHandler); \
|
|
HTML::EventHandler attribute_name();
|
|
ENUMERATE_WEBSOCKET_EVENT_HANDLERS(__ENUMERATE)
|
|
#undef __ENUMERATE
|
|
|
|
ReadyState ready_state() const;
|
|
String extensions() const;
|
|
String protocol() const;
|
|
|
|
const String& binary_type() { return m_binary_type; };
|
|
void set_binary_type(const String& type) { m_binary_type = type; };
|
|
|
|
DOM::ExceptionOr<void> close(u16 code, const String& reason);
|
|
DOM::ExceptionOr<void> send(const String& data);
|
|
|
|
private:
|
|
virtual void ref_event_target() override { ref(); }
|
|
virtual void unref_event_target() override { unref(); }
|
|
virtual JS::Object* create_wrapper(JS::GlobalObject&) override;
|
|
|
|
void on_open();
|
|
void on_message(ByteBuffer message, bool is_text);
|
|
void on_error();
|
|
void on_close(u16 code, String reason, bool was_clean);
|
|
|
|
explicit WebSocket(DOM::Window&, AK::URL&);
|
|
|
|
NonnullRefPtr<DOM::Window> m_window;
|
|
|
|
AK::URL m_url;
|
|
String m_binary_type { "blob" };
|
|
RefPtr<Protocol::WebSocket> m_websocket;
|
|
};
|
|
|
|
}
|