Skip to content

Commit 0ddf5e2

Browse files
refactor: readability changes to sslclient and wsclient (#1210)
2 parents ced36fd + bf67165 commit 0ddf5e2

File tree

4 files changed

+202
-195
lines changed

4 files changed

+202
-195
lines changed

include/dpp/sslclient.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -239,10 +239,10 @@ class DPP_EXPORT ssl_client
239239

240240
/**
241241
* @brief Write to the output buffer.
242-
* @param data Data to be written to the buffer
242+
* @param data Data to be written to the buffer.
243243
* @note The data may not be written immediately and may be written at a later time to the socket.
244244
*/
245-
virtual void write(const std::string &data);
245+
virtual void write(const std::string_view data);
246246

247247
/**
248248
* @brief Close socket connection

include/dpp/wsclient.h

+21-24
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@
2323
#include <dpp/export.h>
2424
#include <string>
2525
#include <map>
26-
#include <vector>
27-
#include <variant>
2826
#include <dpp/sslclient.h>
2927

3028
namespace dpp {
@@ -37,7 +35,7 @@ enum websocket_protocol_t : uint8_t {
3735
* @brief JSON data, text, UTF-8 character set
3836
*/
3937
ws_json = 0,
40-
38+
4139
/**
4240
* @brief Erlang Term Format (ETF) binary protocol
4341
*/
@@ -68,32 +66,32 @@ enum ws_opcode : uint8_t {
6866
/**
6967
* @brief Continuation.
7068
*/
71-
OP_CONTINUATION = 0x00,
69+
OP_CONTINUATION = 0x00,
7270

7371
/**
7472
* @brief Text frame.
7573
*/
76-
OP_TEXT = 0x01,
74+
OP_TEXT = 0x01,
7775

7876
/**
7977
* @brief Binary frame.
8078
*/
81-
OP_BINARY = 0x02,
79+
OP_BINARY = 0x02,
8280

8381
/**
8482
* @brief Close notification with close code.
8583
*/
86-
OP_CLOSE = 0x08,
84+
OP_CLOSE = 0x08,
8785

8886
/**
8987
* @brief Low level ping.
9088
*/
91-
OP_PING = 0x09,
89+
OP_PING = 0x09,
9290

9391
/**
9492
* @brief Low level pong.
9593
*/
96-
OP_PONG = 0x0a
94+
OP_PONG = 0x0a
9795
};
9896

9997
/**
@@ -130,7 +128,7 @@ class DPP_EXPORT websocket_client : public ssl_client {
130128
* @param buffer The buffer to operate on. Will modify the string removing completed items from the head of the queue
131129
* @return true if a complete header has been received
132130
*/
133-
bool parseheader(std::string &buffer);
131+
bool parseheader(std::string& buffer);
134132

135133
/**
136134
* @brief Unpack a frame and pass completed frames up the stack.
@@ -139,7 +137,7 @@ class DPP_EXPORT websocket_client : public ssl_client {
139137
* @param first True if is the first element (reserved for future use)
140138
* @return true if a complete frame has been received
141139
*/
142-
bool unpack(std::string &buffer, uint32_t offset, bool first = true);
140+
bool unpack(std::string& buffer, uint32_t offset, bool first = true);
143141

144142
/**
145143
* @brief Fill a header for outbound messages
@@ -151,11 +149,10 @@ class DPP_EXPORT websocket_client : public ssl_client {
151149
size_t fill_header(unsigned char* outbuf, size_t sendlength, ws_opcode opcode);
152150

153151
/**
154-
* @brief Handle ping and pong requests.
155-
* @param ping True if this is a ping, false if it is a pong
156-
* @param payload The ping payload, to be returned as-is for a ping
152+
* @brief Handle ping requests.
153+
* @param payload The ping payload, to be returned as-is for a pong
157154
*/
158-
void handle_ping_pong(bool ping, const std::string &payload);
155+
void handle_ping(const std::string& payload);
159156

160157
protected:
161158

@@ -168,7 +165,7 @@ class DPP_EXPORT websocket_client : public ssl_client {
168165
* @brief Get websocket state
169166
* @return websocket state
170167
*/
171-
ws_state get_state();
168+
[[nodiscard]] ws_state get_state() const;
172169

173170
public:
174171

@@ -181,41 +178,41 @@ class DPP_EXPORT websocket_client : public ssl_client {
181178
* @note Voice websockets only support OP_TEXT, and other websockets must be
182179
* OP_BINARY if you are going to send ETF.
183180
*/
184-
websocket_client(const std::string &hostname, const std::string &port = "443", const std::string &urlpath = "", ws_opcode opcode = OP_BINARY);
181+
websocket_client(const std::string& hostname, const std::string& port = "443", const std::string& urlpath = "", ws_opcode opcode = OP_BINARY);
185182

186183
/**
187184
* @brief Destroy the websocket client object
188185
*/
189-
virtual ~websocket_client() = default;
186+
virtual ~websocket_client() = default;
190187

191188
/**
192189
* @brief Write to websocket. Encapsulates data in frames if the status is CONNECTED.
193190
* @param data The data to send.
194191
*/
195-
virtual void write(const std::string &data);
192+
virtual void write(const std::string_view data);
196193

197194
/**
198195
* @brief Processes incoming frames from the SSL socket input buffer.
199196
* @param buffer The buffer contents. Can modify this value removing the head elements when processed.
200197
*/
201-
virtual bool handle_buffer(std::string &buffer);
198+
virtual bool handle_buffer(std::string& buffer);
202199

203200
/**
204201
* @brief Close websocket
205202
*/
206-
virtual void close();
203+
virtual void close();
207204

208205
/**
209206
* @brief Receives raw frame content only without headers
210-
*
207+
*
211208
* @param buffer The buffer contents
212209
* @return True if the frame was successfully handled. False if no valid frame is in the buffer.
213210
*/
214-
virtual bool handle_frame(const std::string &buffer);
211+
virtual bool handle_frame(const std::string& buffer);
215212

216213
/**
217214
* @brief Called upon error frame.
218-
*
215+
*
219216
* @param errorcode The error code from the websocket server
220217
*/
221218
virtual void error(uint32_t errorcode);

src/dpp/sslclient.cpp

+48-45
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
#include <dpp/dns.h>
7474

7575
/* Maximum allowed time in milliseconds for socket read/write timeouts and connect() */
76-
#define SOCKET_OP_TIMEOUT 5000
76+
constexpr uint16_t SOCKET_OP_TIMEOUT{5000};
7777

7878
namespace dpp {
7979

@@ -123,10 +123,10 @@ thread_local std::unordered_map<std::string, keepalive_cache_t> keepalives;
123123
* SSL_read in non-blocking mode will only read 16k at a time. There's no point in a bigger buffer as
124124
* it'd go unused.
125125
*/
126-
#define DPP_BUFSIZE 16 * 1024
126+
constexpr uint16_t DPP_BUFSIZE{16 * 1024};
127127

128128
/* Represents a failed socket system call, e.g. connect() failure */
129-
const int ERROR_STATUS = -1;
129+
constexpr int ERROR_STATUS{-1};
130130

131131
bool close_socket(dpp::socket sfd)
132132
{
@@ -176,8 +176,8 @@ bool set_nonblocking(dpp::socket sockfd, bool non_blocking)
176176
*/
177177
int connect_with_timeout(dpp::socket sockfd, const struct sockaddr *addr, socklen_t addrlen, unsigned int timeout_ms) {
178178
#ifdef __APPLE__
179-
/* Unreliable on OSX right now */
180-
return (::connect(sockfd, addr, addrlen));
179+
/* Unreliable on OSX right now */
180+
return (::connect(sockfd, addr, addrlen));
181181
#else
182182
if (!set_nonblocking(sockfd, true)) {
183183
throw dpp::connection_exception(err_nonblocking_failure, "Can't switch socket to non-blocking mode!");
@@ -197,25 +197,26 @@ int connect_with_timeout(dpp::socket sockfd, const struct sockaddr *addr, sockle
197197
#endif
198198
if (rc == -1 && err != EWOULDBLOCK && err != EINPROGRESS) {
199199
throw connection_exception(err_connect_failure, strerror(errno));
200-
} else {
201-
/* Set a deadline timestamp 'timeout' ms from now */
202-
double deadline = utility::time_f() + (timeout_ms / 1000.0);
203-
do {
204-
rc = -1;
205-
if (utility::time_f() >= deadline) {
206-
throw connection_exception(err_connection_timed_out, "Connection timed out");
207-
}
208-
pollfd pfd = {};
209-
pfd.fd = sockfd;
210-
pfd.events = POLLOUT;
211-
int r = ::poll(&pfd, 1, 10);
212-
if (r > 0 && pfd.revents & POLLOUT) {
213-
rc = 0;
214-
} else if (r != 0 || pfd.revents & POLLERR) {
215-
throw connection_exception(err_connection_timed_out, strerror(errno));
216-
}
217-
} while (rc == -1);
218200
}
201+
202+
/* Set a deadline timestamp 'timeout' ms from now */
203+
double deadline = utility::time_f() + (timeout_ms / 1000.0);
204+
205+
do {
206+
if (utility::time_f() >= deadline) {
207+
throw connection_exception(err_connection_timed_out, "Connection timed out");
208+
}
209+
pollfd pfd = {};
210+
pfd.fd = sockfd;
211+
pfd.events = POLLOUT;
212+
const int r = ::poll(&pfd, 1, 10);
213+
if (r > 0 && pfd.revents & POLLOUT) {
214+
rc = 0;
215+
} else if (r != 0 || pfd.revents & POLLERR) {
216+
throw connection_exception(err_connection_timed_out, strerror(errno));
217+
}
218+
} while (rc == -1);
219+
219220
if (!set_nonblocking(sockfd, false)) {
220221
throw connection_exception(err_nonblocking_failure, "Can't switch socket to blocking mode!");
221222
}
@@ -226,7 +227,7 @@ int connect_with_timeout(dpp::socket sockfd, const struct sockaddr *addr, sockle
226227
#ifndef _WIN32
227228
void set_signal_handler(int signal)
228229
{
229-
struct sigaction sa;
230+
struct sigaction sa{};
230231
sigaction(signal, nullptr, &sa);
231232
if (sa.sa_flags == 0 && sa.sa_handler == nullptr) {
232233
sa = {};
@@ -378,7 +379,7 @@ void ssl_client::connect()
378379
}
379380
}
380381

381-
void ssl_client::write(const std::string &data)
382+
void ssl_client::write(const std::string_view data)
382383
{
383384
/* If we are in nonblocking mode, append to the buffer,
384385
* otherwise just use SSL_write directly. The only time we
@@ -388,16 +389,17 @@ void ssl_client::write(const std::string &data)
388389
*/
389390
if (nonblocking) {
390391
obuffer += data;
392+
return;
393+
}
394+
395+
const int data_length = static_cast<int>(data.length());
396+
if (plaintext) {
397+
if (sfd == INVALID_SOCKET || ::send(sfd, data.data(), data_length, 0) != data_length) {
398+
throw dpp::connection_exception(err_write, "write() failed");
399+
}
391400
} else {
392-
const int data_length = (int)data.length();
393-
if (plaintext) {
394-
if (sfd == INVALID_SOCKET || ::send(sfd, data.data(), data_length, 0) != data_length) {
395-
throw dpp::connection_exception(err_write, "write() failed");
396-
}
397-
} else {
398-
if (SSL_write(ssl->ssl, data.data(), data_length) != data_length) {
399-
throw dpp::connection_exception(err_ssl_write, "SSL_write() failed");
400-
}
401+
if (SSL_write(ssl->ssl, data.data(), data_length) != data_length) {
402+
throw dpp::connection_exception(err_ssl_write, "SSL_write() failed");
401403
}
402404
}
403405
}
@@ -502,16 +504,17 @@ void ssl_client::read_loop()
502504
read_blocked_on_write = false;
503505
read_blocked = false;
504506
r = (int) ::recv(sfd, server_to_client_buffer, DPP_BUFSIZE, 0);
507+
505508
if (r <= 0) {
506509
/* error or EOF */
507510
return;
508-
} else {
509-
buffer.append(server_to_client_buffer, r);
510-
if (!this->handle_buffer(buffer)) {
511-
return;
512-
}
513-
bytes_in += r;
514511
}
512+
513+
buffer.append(server_to_client_buffer, r);
514+
if (!this->handle_buffer(buffer)) {
515+
return;
516+
}
517+
bytes_in += r;
515518
} else {
516519
do {
517520
read_blocked_on_write = false;
@@ -577,14 +580,14 @@ void ssl_client::read_loop()
577580
if (r < 0) {
578581
/* Write error */
579582
return;
580-
} else {
581-
client_to_server_length -= r;
582-
client_to_server_offset += r;
583-
bytes_out += r;
584583
}
584+
585+
client_to_server_length -= r;
586+
client_to_server_offset += r;
587+
bytes_out += r;
585588
} else {
586589
r = SSL_write(ssl->ssl, client_to_server_buffer + client_to_server_offset, (int)client_to_server_length);
587-
590+
588591
switch(SSL_get_error(ssl->ssl,r)) {
589592
/* We wrote something */
590593
case SSL_ERROR_NONE:

0 commit comments

Comments
 (0)