WebSocket.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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 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. enum class Error {
  38. CouldNotEstablishConnection,
  39. ConnectionUpgradeFailed,
  40. ServerClosedSocket,
  41. };
  42. Function<void(Error)> on_error;
  43. private:
  44. WebSocket(ConnectionInfo, RefPtr<WebSocketImpl>);
  45. // As defined in section 5.2
  46. enum class OpCode : u8 {
  47. Continuation = 0x0,
  48. Text = 0x1,
  49. Binary = 0x2,
  50. ConnectionClose = 0x8,
  51. Ping = 0x9,
  52. Pong = 0xA,
  53. };
  54. void drain_read();
  55. void send_client_handshake();
  56. void read_server_handshake();
  57. void read_frame();
  58. void send_frame(OpCode, ReadonlyBytes, bool is_final);
  59. void notify_open();
  60. void notify_close(u16 code, ByteString reason, bool was_clean);
  61. void notify_error(Error);
  62. void notify_message(Message);
  63. void fatal_error(Error);
  64. void discard_connection();
  65. enum class InternalState {
  66. NotStarted,
  67. EstablishingProtocolConnection,
  68. SendingClientHandshake,
  69. WaitingForServerHandshake,
  70. Open,
  71. Closing,
  72. Closed,
  73. Errored,
  74. };
  75. InternalState m_state { InternalState::NotStarted };
  76. ByteString m_subprotocol_in_use { ByteString::empty() };
  77. ByteString m_websocket_key;
  78. bool m_has_read_server_handshake_first_line { false };
  79. bool m_has_read_server_handshake_upgrade { false };
  80. bool m_has_read_server_handshake_connection { false };
  81. bool m_has_read_server_handshake_accept { false };
  82. u16 m_last_close_code { 1005 };
  83. ByteString m_last_close_message;
  84. ConnectionInfo m_connection;
  85. RefPtr<WebSocketImpl> m_impl;
  86. Vector<u8> m_buffered_data;
  87. ByteBuffer m_fragmented_data_buffer;
  88. WebSocket::OpCode m_initial_fragment_opcode;
  89. };
  90. }