• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef ARKCOMPILER_TOOLCHAIN_WEBSOCKET_WEBSOCKET_BASE_H
17 #define ARKCOMPILER_TOOLCHAIN_WEBSOCKET_WEBSOCKET_BASE_H
18 
19 #include "websocket/frame_builder.h"
20 #include "websocket/web_socket_frame.h"
21 
22 #include <atomic>
23 #include <functional>
24 #include <type_traits>
25 
26 namespace OHOS::ArkCompiler::Toolchain {
27 enum CloseStatusCode : uint16_t {
28     NO_STATUS_CODE = 0,
29     NORMAL = 1000,
30     SERVER_GO_AWAY = 1001,
31     PROTOCOL_ERROR = 1002,
32     UNACCEPTABLE_DATA = 1003,
33     INCONSISTENT_DATA = 1007,
34     POLICY_VIOLATION = 1008,
35     MESSAGE_TOO_BIG = 1009,
36     UNEXPECTED_ERROR = 1011,
37 };
38 
ToString(CloseStatusCode status)39 inline std::string ToString(CloseStatusCode status)
40 {
41     if (status == CloseStatusCode::NO_STATUS_CODE) {
42         return "";
43     }
44     std::string result;
45     PushNumberPerByte(result, EnumToNumber(status));
46     return result;
47 }
48 
49 class WebSocketBase {
50 public:
51     using CloseConnectionCallback = std::function<void()>;
52     using FailConnectionCallback = std::function<void()>;
53 
54 public:
55     static bool IsDecodeDisconnectMsg(const std::string& message);
56 
57     WebSocketBase() = default;
58     virtual ~WebSocketBase() noexcept = default;
59 
60     // Receive and decode a message.
61     // In case of control frames this method handles it accordingly and returns an empty string,
62     // otherwise returns the decoded received message.
63     std::string Decode();
64     // Send message on current connection.
65     // Returns success status.
66     bool SendReply(const std::string& message, FrameType frameType = FrameType::TEXT, bool isLast = true) const;
67 
68     bool IsConnected();
69 
70     void SetCloseConnectionCallback(CloseConnectionCallback cb);
71     void SetFailConnectionCallback(FailConnectionCallback cb);
72 
73     // Close current websocket endpoint and connections (if any).
74     virtual void Close() = 0;
75 
76 protected:
77     enum class SocketState : uint8_t {
78         UNINITED,
79         INITED,
80         CONNECTED,
81     };
82 
83     enum class ConnectionCloseReason: uint8_t {
84         FAIL,
85         CLOSE,
86     };
87 
88 protected:
89     static bool SetWebSocketTimeOut(int32_t fd, uint32_t timeoutLimit);
90 
91     bool ReadPayload(WebSocketFrame& wsFrame);
92     void SendPongFrame(std::string payload);
93     void SendCloseFrame(CloseStatusCode status);
94     // Sending close frame and close connection.
95     void CloseConnection(CloseStatusCode status, SocketState newSocketState);
96     // Close connection socket.
97     void CloseConnectionSocket(ConnectionCloseReason status, SocketState newSocketState);
98 
99     virtual bool HandleDataFrame(WebSocketFrame& wsFrame);
100     virtual bool HandleControlFrame(WebSocketFrame& wsFrame);
101 
102     virtual bool ValidateIncomingFrame(const WebSocketFrame& wsFrame) = 0;
103     virtual std::string CreateFrame(bool isLast, FrameType frameType) const = 0;
104     virtual std::string CreateFrame(bool isLast, FrameType frameType, const std::string& payload) const = 0;
105     virtual std::string CreateFrame(bool isLast, FrameType frameType, std::string&& payload) const = 0;
106     virtual bool DecodeMessage(WebSocketFrame& wsFrame) const = 0;
107 
108 protected:
109     std::atomic<SocketState> socketState_ {SocketState::UNINITED};
110 
111     int connectionFd_ {-1};
112 
113     // Callbacks used during different stages of connection lifecycle.
114     CloseConnectionCallback closeCb_;
115     FailConnectionCallback failCb_;
116 
117     static constexpr char WEB_SOCKET_GUID[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
118     static constexpr size_t HTTP_HANDSHAKE_MAX_LEN = 1024;
119     static constexpr int SOCKET_SUCCESS = 0;
120     static constexpr std::string_view DECODE_DISCONNECT_MSG = "disconnect";
121 };
122 } // namespace OHOS::ArkCompiler::Toolchain
123 
124 #endif // ARKCOMPILER_TOOLCHAIN_WEBSOCKET_WEBSOCKET_BASE_H
125