Skip to content

Commit c899d3f

Browse files
committed
rename WSErrorCode::timeout to timeout_error, WSErrorCode::uncategorized to uncategorized_error + refactor OpenSslSocket and ignore SIGPIPE by default + make enum members lowercase in AddrType
1 parent 7a890e0 commit c899d3f

29 files changed

+455
-371
lines changed

CONTRIBUTING.md

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,6 @@ Pull requests and issues are welcome.
88
- auto fragmentation write
99
- timeout for DnsResolver
1010

11-
- SSL_shutdown sig pipe
12-
13-
- https://stackoverflow.com/questions/108183/how-to-prevent-sigpipes-or-handle-them-properly
14-
- BIO_free_all(this->web); // TODO throws sometimes, e.g. websocketclient init error
15-
16-
NOTE: When using SSL, it seems impossible to avoid SIGPIPE in all cases, since on some operating systems, SIGPIPE can only be suppressed on a per-message basis, but there is no way to make the OpenSSL library do so for its internal communications. If your program needs to avoid being terminated on SIGPIPE, the only fully general way might be to set up a signal handler for SIGPIPE to handle or ignore it yourself.
17-
18-
OpenSslSocket.hpp: Use custom BIO to allow setting MSG_NOSIGNAL
19-
2011
## Useful resources
2112

2213
- https://jamespascoe.github.io/accu2023/#/9/2/3
@@ -28,21 +19,23 @@ Pull requests and issues are welcome.
2819
Lists all connections:
2920

3021
```bash
31-
sudo ss -tp | grep main_demo
22+
sudo ss -tp | grep "pid=$(pidof ex_reconnect_builtin)"
3223
```
3324

3425
Closes WebSocket connection at port 443 of process:
3526

3627
```bash
37-
sudo ss -tp | grep "pid=$(pidof bybit_orderbook)" | grep -oP '\s\K[^ ]+(?=:https)'443
28+
sudo ss -tp | grep "pid=$(pidof ex_reconnect_builtin)" | grep -oP '\s\K[^ ]+(?=:https)'
29+
30+
sudo ss -K dst $(sudo ss -tp | grep "pid=$(pidof ex_reconnect_builtin)" | grep -oP '\s\K[^ ]+(?=:https)') dport = 443
3831

39-
sudo ss -K dst $(sudo ss -tp | grep "pid=$(pidof bybit_orderbook)" | grep -oP '\s\K[^ ]+(?=:https)') dport = 443
32+
sudo ss -K dst $(sudo ss -tp | grep "pid=$(pidof ex_hello_ws_builtin)" | grep -oP '\s\K[^ ]+(?=:http)') dport = 8080
4033

4134
sudo ss -K dst '127.0.0.1' dport = 443
4235

4336
sudo ss -K dst 66.241.124.119:443
4437

45-
pidof bybit_orderbook
38+
pidof ex_echo_builtin
4639
```
4740

4841
## Compiler varia

examples/asio/ex_reconnect_asio.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ awaitable<expected<void, WSError>> run()
119119
}
120120
else if (auto err = std::get_if<WSError>(&var))
121121
{
122-
if (err->code == WSErrorCode::timeout)
122+
if (err->code == WSErrorCode::timeout_error)
123123
{
124124
std::cout << "read_message timed out\n";
125125
break;

examples/builtin/ex_custom_logger_builtin.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ expected<void, WSError> run()
5353

5454
// resolve hostname
5555
DnsResolver dns(&logger);
56-
WS_TRY(dns_res, dns.resolve(url->host(), url->port_str(), AddrType::IPv4));
56+
WS_TRY(dns_res, dns.resolve(url->host(), url->port_str(), AddrType::ipv4));
5757
AddressInfo& addr = (*dns_res)[0];
5858

5959
// create TCP socket

examples/builtin/ex_echo_builtin.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ expected<void, WSError> run()
2121

2222
// resolve hostname
2323
DnsResolver dns(&logger);
24-
WS_TRY(dns_res, dns.resolve(url->host(), url->port_str(), AddrType::IPv4));
24+
WS_TRY(dns_res, dns.resolve(url->host(), url->port_str(), AddrType::ipv4));
2525
AddressInfo& addr = (*dns_res)[0];
2626

2727
// create TCP socket

examples/builtin/ex_hello_ws_builtin.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ expected<void, WSError> run()
2727

2828
// resolve hostname
2929
DnsResolver dns(&logger);
30-
WS_TRY(dns_res, dns.resolve(url->host(), url->port_str(), AddrType::IPv4));
30+
WS_TRY(dns_res, dns.resolve(url->host(), url->port_str(), AddrType::ipv4));
3131
AddressInfo& addr = (*dns_res)[0];
3232

3333
// create TCP socket

examples/builtin/ex_hello_wss_builtin.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ expected<void, WSError> run()
2626

2727
// resolve hostname
2828
DnsResolver dns(&logger);
29-
WS_TRY(dns_res, dns.resolve(url->host(), url->port_str(), AddrType::IPv4));
29+
WS_TRY(dns_res, dns.resolve(url->host(), url->port_str(), AddrType::ipv4));
3030
AddressInfo& addr = (*dns_res)[0];
3131

3232
// create TCP socket

examples/builtin/ex_reconnect_builtin.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ expected<void, WSError> run()
105105
}
106106
else if (auto err = std::get_if<WSError>(&var))
107107
{
108-
if (err->code == WSErrorCode::timeout)
108+
if (err->code == WSErrorCode::timeout_error)
109109
{
110110
std::cout << "read_message timed out\n";
111111
break;

examples/builtin/ex_wait_message_wss_builtin.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,13 @@ expected<void, WSError> run()
7474

7575
while (true)
7676
{
77-
// wait for message for 3 sec
77+
// wait for message for 2 sec
7878
bool readable = false;
7979
do
8080
{
81-
WS_TRY(read_res, client.wait_message(3s));
81+
WS_TRY(read_res, client.wait_message(2s));
8282
if (!(readable = read_res.value()))
83-
logger.log<LogLevel::W>("No message received within 3 sec, continue waiting...");
83+
logger.log<LogLevel::W>("No message received within 2 sec, continue waiting...");
8484
} while (!readable);
8585

8686
// read message (only 1 sec timeout since we know socket is readable)

include/ws_client/Frame.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

33
#include <string>
4+
#include <string_view>
45
#include <cstdint>
56
#include <span>
67
#include <limits>
@@ -73,7 +74,7 @@ static bool is_reserved(opcode v) noexcept
7374
(v >= opcode::control_rsvb && v <= opcode::control_rsvf);
7475
}
7576

76-
static constexpr string to_string(opcode v)
77+
static constexpr string_view to_string(opcode v)
7778
{
7879
switch (v)
7980
{
@@ -110,7 +111,7 @@ static constexpr string to_string(opcode v)
110111
case opcode::control_rsvf:
111112
return "control_rsvf";
112113
default:
113-
return "Unknown (" + std::to_string(static_cast<uint8_t>(v)) + ")";
114+
return "unknown";
114115
}
115116
}
116117

include/ws_client/Message.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ enum class MessageType : uint8_t
2121
binary = static_cast<uint8_t>(opcode::binary)
2222
};
2323

24-
static constexpr string to_string(MessageType v)
24+
static constexpr string_view to_string(MessageType v)
2525
{
2626
switch (v)
2727
{
@@ -30,7 +30,7 @@ static constexpr string to_string(MessageType v)
3030
case MessageType::binary:
3131
return "binary";
3232
default:
33-
return "UNKNOWN (" + std::to_string(static_cast<uint8_t>(v)) + ")";
33+
return "unknown";
3434
}
3535
}
3636

include/ws_client/WebSocketClient.hpp

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ class WebSocketClient
280280
{
281281
return WSError(
282282
WSErrorCode::protocol_error,
283-
"Reserved opcode received: " + to_string(frame.header.op_code()),
283+
"Reserved opcode received: " + std::string(to_string(frame.header.op_code())),
284284
close_code::protocol_error
285285
);
286286
}
@@ -311,7 +311,9 @@ class WebSocketClient
311311
" bytes is too large, only " +
312312
std::to_string(buffer.max_size() - buffer.size()) +
313313
" bytes available.";
314-
return WSError(WSErrorCode::buffer_error, msg, close_code::message_too_big);
314+
return WSError(
315+
WSErrorCode::buffer_error, std::move(msg), close_code::message_too_big
316+
);
315317
}
316318

317319
// check if this is the first frame
@@ -354,8 +356,8 @@ class WebSocketClient
354356
{
355357
return WSError(
356358
WSErrorCode::protocol_error,
357-
"Expected continuation frame, but received " +
358-
to_string(frame.header.op_code()),
359+
std::move(string("Expected continuation frame, but received ")
360+
.append(to_string(frame.header.op_code()))),
359361
close_code::protocol_error
360362
);
361363
}
@@ -376,8 +378,8 @@ class WebSocketClient
376378
{
377379
return WSError(
378380
WSErrorCode::protocol_error,
379-
"Unexpected opcode in websocket frame received: " +
380-
to_string(read_state_.op_code),
381+
std::move(string("Unexpected opcode in websocket frame received: ")
382+
.append(to_string(read_state_.op_code))),
381383
close_code::protocol_error
382384
);
383385
}
@@ -409,7 +411,7 @@ class WebSocketClient
409411

410412
// check if timeout occurred
411413
if (timeout.is_expired())
412-
return WSError(WSErrorCode::timeout, "Timeout while reading message.");
414+
return WSError(WSErrorCode::timeout_error, "Timeout while reading WebSocket message.");
413415

414416
span<byte> payload_buffer;
415417

@@ -500,7 +502,8 @@ class WebSocketClient
500502
{
501503
return WSError(
502504
WSErrorCode::protocol_error,
503-
"Unexpected opcode frame received: " + to_string(read_state_.op_code),
505+
std::move(string("Unexpected opcode frame received: ")
506+
.append(to_string(read_state_.op_code))),
504507
close_code::protocol_error
505508
);
506509
}
@@ -957,8 +960,8 @@ class WebSocketClient
957960
{
958961
return WSError(
959962
WSErrorCode::protocol_error,
960-
"Unexpected opcode for websocket control frame received: " +
961-
to_string(frame.header.op_code()),
963+
std::move(string("Unexpected opcode for websocket control frame received: ")
964+
.append(to_string(frame.header.op_code()))),
962965
close_code::protocol_error
963966
);
964967
}

include/ws_client/WebSocketClientAsync.hpp

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,8 @@ class WebSocketClientAsync
262262
{
263263
co_return WSError(
264264
WSErrorCode::protocol_error,
265-
"Reserved opcode received: " + to_string(frame.header.op_code()),
265+
std::move(string("Reserved opcode received: ")
266+
.append(to_string(frame.header.op_code()))),
266267
close_code::protocol_error
267268
);
268269
}
@@ -293,7 +294,9 @@ class WebSocketClientAsync
293294
" bytes is too large, only " +
294295
std::to_string(buffer.max_size() - buffer.size()) +
295296
" bytes available.";
296-
co_return WSError(WSErrorCode::buffer_error, msg, close_code::message_too_big);
297+
co_return WSError(
298+
WSErrorCode::buffer_error, std::move(msg), close_code::message_too_big
299+
);
297300
}
298301

299302
// check if this is the first frame
@@ -336,8 +339,8 @@ class WebSocketClientAsync
336339
{
337340
co_return WSError(
338341
WSErrorCode::protocol_error,
339-
"Expected continuation frame, but received " +
340-
to_string(frame.header.op_code()),
342+
std::move(string("Expected continuation frame, but received ")
343+
.append(to_string(frame.header.op_code()))),
341344
close_code::protocol_error
342345
);
343346
}
@@ -358,8 +361,8 @@ class WebSocketClientAsync
358361
{
359362
co_return WSError(
360363
WSErrorCode::protocol_error,
361-
"Unexpected opcode in websocket frame received: " +
362-
to_string(read_state_.op_code),
364+
std::move(string("Unexpected opcode in websocket frame received: ")
365+
.append(to_string(read_state_.op_code))),
363366
close_code::protocol_error
364367
);
365368
}
@@ -372,7 +375,8 @@ class WebSocketClientAsync
372375
// read payload directly into decompression buffer
373376
WS_CO_TRY_RAW(
374377
frame_data_compressed_res,
375-
this->permessage_deflate_ctx_->decompress_buffer().append(frame.payload_size)
378+
this->permessage_deflate_ctx_->decompress_buffer().append(frame.payload_size
379+
)
376380
);
377381
WS_CO_TRYV_RAW(
378382
co_await this->socket_.read_exact(*frame_data_compressed_res, timeout)
@@ -392,7 +396,7 @@ class WebSocketClientAsync
392396

393397
// check if timeout occurred
394398
if (timeout.is_expired())
395-
co_return WSError(WSErrorCode::timeout, "Timeout while reading message.");
399+
co_return WSError(WSErrorCode::timeout_error, "Timeout while reading WebSocket message.");
396400

397401
span<byte> payload_buffer;
398402

@@ -403,7 +407,7 @@ class WebSocketClientAsync
403407
}
404408

405409
payload_buffer = buffer.data();
406-
410+
407411
switch (read_state_.op_code)
408412
{
409413
case opcode::text:
@@ -483,7 +487,8 @@ class WebSocketClientAsync
483487
{
484488
co_return WSError(
485489
WSErrorCode::protocol_error,
486-
"Unexpected opcode frame received: " + to_string(read_state_.op_code),
490+
std::move(string("Unexpected opcode frame received: ")
491+
.append(to_string(read_state_.op_code))),
487492
close_code::protocol_error
488493
);
489494
}
@@ -954,8 +959,8 @@ class WebSocketClientAsync
954959
{
955960
co_return WSError(
956961
WSErrorCode::protocol_error,
957-
"Unexpected opcode for websocket control frame received: " +
958-
to_string(frame.header.op_code()),
962+
std::move(string("Unexpected opcode for websocket control frame received: ")
963+
.append(to_string(frame.header.op_code()))),
959964
close_code::protocol_error
960965
);
961966
}

include/ws_client/close_code.hpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
#pragma once
22

33
#include <cstdint>
4+
#include <string_view>
45

56
namespace ws_client
67
{
7-
using std::string;
8-
98
/**
109
* Enum for WebSocket close frame status codes as defined in RFC 6455.
1110
*/
@@ -54,7 +53,7 @@ static bool is_valid_close_code(close_code code)
5453
(static_cast<uint16_t>(code) >= 3000 && static_cast<uint16_t>(code) <= 4999);
5554
}
5655

57-
static constexpr string to_string(close_code code)
56+
static constexpr std::string_view to_string(close_code code)
5857
{
5958
switch (code)
6059
{
@@ -77,7 +76,7 @@ static constexpr string to_string(close_code code)
7776
case close_code::unexpected_condition:
7877
return "unexpected_condition";
7978
default:
80-
return "Unknown (" + std::to_string(static_cast<uint16_t>(code)) + ")";
79+
return "unknown";
8180
}
8281
}
8382
}; // namespace ws_client

0 commit comments

Comments
 (0)