1 /*
2 * Copyright (c) 2025 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 #include "net_websocket_connect_context.h"
17
18 #include "net_websocket_utils.h"
19
20 namespace OHOS::NetStack::NetWebSocket {
WebSocketConnectContext(CJWebsocketProxy * websocketProxy)21 WebSocketConnectContext::WebSocketConnectContext(CJWebsocketProxy* websocketProxy)
22 : WebSocketBaseContext(websocketProxy)
23 {
24 }
25
26 WebSocketConnectContext::~WebSocketConnectContext() = default;
27
AddSlashBeforeQuery(std::string & url)28 static void AddSlashBeforeQuery(std::string &url)
29 {
30 if (url.empty()) {
31 return;
32 }
33 std::string delimiter = "://";
34 size_t posStart = url.find(delimiter);
35 if (posStart != std::string::npos) {
36 posStart += delimiter.length();
37 } else {
38 posStart = 0;
39 }
40 size_t notSlash = url.find_first_not_of('/', posStart);
41 if (notSlash != std::string::npos) {
42 posStart = notSlash;
43 }
44 auto queryPos = url.find('?', posStart);
45 if (url.find('/', posStart) > queryPos) {
46 url.insert(queryPos, 1, '/');
47 }
48 }
49
ParseParams(std::string url,CWebSocketRequestOptions * opt)50 void WebSocketConnectContext::ParseParams(std::string url, CWebSocketRequestOptions *opt)
51 {
52 this->url = url;
53 AddSlashBeforeQuery(url);
54 if (opt != nullptr) {
55 ParseHeader(opt->header);
56 if (opt->caPath != nullptr) {
57 caPath_ = std::string{opt->caPath};
58 }
59 if (opt->clientCert != nullptr) {
60 std::string certPath{opt->clientCert->certPath};
61 SecureChar keySecure;
62 if (opt->clientCert->keyPath != nullptr) {
63 keySecure = SecureChar(opt->clientCert->keyPath);
64 } else {
65 keySecure = SecureChar("");
66 }
67 SecureChar keyPasswd;
68 if (opt->clientCert->keyPassword != nullptr) {
69 keyPasswd = SecureChar(opt->clientCert->keyPassword);
70 } else {
71 keyPasswd = SecureChar("");
72 }
73 SetClientCert(certPath, keySecure, keyPasswd);
74 }
75 if (opt->protocol != nullptr) {
76 SetProtocol(std::string{opt->protocol});
77 }
78 ParseProxy(opt->httpProxy, opt->usingSystemProxy);
79 }
80 SetParseOK(true);
81 }
82
SetClientCert(std::string & cert,SecureChar & key,SecureChar & keyPassword)83 void WebSocketConnectContext::SetClientCert(std::string &cert, SecureChar &key, SecureChar &keyPassword)
84 {
85 clientCert_ = cert;
86 clientKey_ = key;
87 keyPassword_ = keyPassword;
88 }
89
GetClientCert(std::string & cert,SecureChar & key,SecureChar & keyPassword)90 void WebSocketConnectContext::GetClientCert(std::string &cert, SecureChar &key, SecureChar &keyPassword)
91 {
92 cert = clientCert_;
93 key = clientKey_;
94 keyPassword = keyPassword_;
95 }
96
SetProtocol(std::string protocol)97 void WebSocketConnectContext::SetProtocol(std::string protocol)
98 {
99 websocketProtocol_ = std::move(protocol);
100 }
101
GetProtocol() const102 std::string WebSocketConnectContext::GetProtocol() const
103 {
104 return websocketProtocol_;
105 }
106
SetWebsocketProxyType(WebsocketProxyType type)107 void WebSocketConnectContext::SetWebsocketProxyType(WebsocketProxyType type)
108 {
109 usingWebsocketProxyType_ = type;
110 }
111
GetUsingWebsocketProxyType() const112 WebsocketProxyType WebSocketConnectContext::GetUsingWebsocketProxyType() const
113 {
114 return usingWebsocketProxyType_;
115 }
116
SetSpecifiedWebsocketProxy(const std::string & host,int32_t port,const std::string & exclusionList)117 void WebSocketConnectContext::SetSpecifiedWebsocketProxy(const std::string &host,
118 int32_t port, const std::string &exclusionList)
119 {
120 websocketProxyHost_ = host;
121 websocketProxyPort_ = port;
122 websocketProxyExclusions_ = exclusionList;
123 }
124
GetSpecifiedWebsocketProxy(std::string & host,uint32_t & port,std::string & exclusionList) const125 void WebSocketConnectContext::GetSpecifiedWebsocketProxy(std::string &host, uint32_t &port,
126 std::string &exclusionList) const
127 {
128 host = websocketProxyHost_;
129 port = websocketProxyPort_;
130 exclusionList = websocketProxyExclusions_;
131 }
132
GetErrorCode() const133 int32_t WebSocketConnectContext::GetErrorCode() const
134 {
135 if (WebSocketBaseContext::IsPermissionDenied()) {
136 return WEBSOCKET_PERMISSION_DENIED_CODE;
137 }
138 auto err = WebSocketBaseContext::GetErrorCode();
139 if (WEBSOCKET_ERR_MAP.find(err) != WEBSOCKET_ERR_MAP.end()) {
140 return err;
141 }
142 return WEBSOCKET_UNKNOWN_OTHER_ERROR;
143 }
144
GetErrorMessage() const145 std::string WebSocketConnectContext::GetErrorMessage() const
146 {
147 auto err = WebSocketBaseContext::GetErrorCode();
148 auto it = WEBSOCKET_ERR_MAP.find(err);
149 if (it != WEBSOCKET_ERR_MAP.end()) {
150 return it->second;
151 }
152 it = WEBSOCKET_ERR_MAP.find(WEBSOCKET_UNKNOWN_OTHER_ERROR);
153 if (it != WEBSOCKET_ERR_MAP.end()) {
154 return it->second;
155 }
156 return {};
157 }
158
ParseHeader(CArrString header)159 void WebSocketConnectContext::ParseHeader(CArrString header)
160 {
161 if (header.head == nullptr || header.size == 0) {
162 return;
163 }
164 for (int i = 0; i < header.size; i += MAP_TUPLE_SIZE) {
165 std::string key{header.head[i]};
166 std::string value{header.head[i + 1]};
167 this->header[key] = value;
168 }
169 }
170
ParseProxy(CHttpProxy * proxy,bool useDefault)171 void WebSocketConnectContext::ParseProxy(CHttpProxy* proxy, bool useDefault)
172 {
173 if (proxy != nullptr) {
174 SetWebsocketProxyType(WebsocketProxyType::USE_SPECIFIED);
175 std::string host{proxy->host};
176 std::string exclusionList;
177 for (int i = 0; i < proxy->exclusionListSize; i++) {
178 if (i != 0) {
179 exclusionList = exclusionList + WEBSOCKET_PROXY_EXCLUSIONS_SEPARATOR;
180 }
181 exclusionList += std::string{proxy->exclusionList[i]};
182 }
183 SetSpecifiedWebsocketProxy(host, proxy->port, exclusionList);
184 } else {
185 SetWebsocketProxyType(useDefault ? WebsocketProxyType::USE_SYSTEM : WebsocketProxyType::NOT_USE);
186 }
187 }
188 }
189