WebSocket.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*
  2. * Copyright (c) 2021, Dex♪ <dexes.ttp@gmail.com>
  3. * Copyright (c) 2022, the SerenityOS developers.
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #pragma once
  8. #include <AK/Span.h>
  9. #include <LibCore/EventReceiver.h>
  10. #include <LibWebSocket/ConnectionInfo.h>
  11. #include <LibWebSocket/Impl/WebSocketImpl.h>
  12. #include <LibWebSocket/Message.h>
  13. namespace WebSocket {
  14. enum class ReadyState {
  15. Connecting = 0,
  16. Open = 1,
  17. Closing = 2,
  18. Closed = 3,
  19. };
  20. class WebSocket final : public Core::EventReceiver {
  21. C_OBJECT(WebSocket)
  22. public:
  23. static NonnullRefPtr<WebSocket> create(ConnectionInfo, RefPtr<WebSocketImpl> = nullptr);
  24. virtual ~WebSocket() override = default;
  25. URL::URL const& url() const { return m_connection.url(); }
  26. ReadyState ready_state();
  27. ByteString subprotocol_in_use();
  28. // Call this to start the WebSocket connection.
  29. void start();
  30. // This can only be used if the `ready_state` is `ReadyState::Open`
  31. void send(Message const&);
  32. // This can only be used if the `ready_state` is `ReadyState::Open`
  33. void close(u16 code = 1005, ByteString const& reason = {});
  34. Function<void()> on_open;
  35. Function<void(u16 code, ByteString reason, bool was_clean)> on_close;
  36. Function<void(Message message)> on_message;
  37. Function<void(ReadyState)> on_ready_state_change;
  38. Function<void(ByteString)> on_subprotocol;
  39. enum class Error {
  40. CouldNotEstablishConnection,
  41. ConnectionUpgradeFailed,
  42. ServerClosedSocket,
  43. };
  44. Function<void(Error)> on_error;
  45. private:
  46. WebSocket(ConnectionInfo, RefPtr<WebSocketImpl>);
  47. // As defined in section 5.2
  48. enum class OpCode : u8 {
  49. Continuation = 0x0,
  50. Text = 0x1,
  51. Binary = 0x2,
  52. ConnectionClose = 0x8,
  53. Ping = 0x9,
  54. Pong = 0xA,
  55. };
  56. void drain_read();
  57. void send_client_handshake();
  58. void read_server_handshake();
  59. void read_frame();
  60. void send_frame(OpCode, ReadonlyBytes, bool is_final);
  61. void notify_open();
  62. void notify_close(u16 code, ByteString reason, bool was_clean);
  63. void notify_error(Error);
  64. void notify_message(Message);
  65. void fatal_error(Error);
  66. void discard_connection();
  67. enum class InternalState {
  68. NotStarted,
  69. EstablishingProtocolConnection,
  70. SendingClientHandshake,
  71. WaitingForServerHandshake,
  72. Open,
  73. Closing,
  74. Closed,
  75. Errored,
  76. };
  77. InternalState m_state { InternalState::NotStarted };
  78. void set_state(InternalState);
  79. ByteString m_subprotocol_in_use { ByteString::empty() };
  80. ByteString m_websocket_key;
  81. bool m_has_read_server_handshake_first_line { false };
  82. bool m_has_read_server_handshake_upgrade { false };
  83. bool m_has_read_server_handshake_connection { false };
  84. bool m_has_read_server_handshake_accept { false };
  85. u16 m_last_close_code { 1005 };
  86. ByteString m_last_close_message;
  87. ConnectionInfo m_connection;
  88. RefPtr<WebSocketImpl> m_impl;
  89. Vector<u8> m_buffered_data;
  90. ByteBuffer m_fragmented_data_buffer;
  91. WebSocket::OpCode m_initial_fragment_opcode;
  92. };
  93. }