12 namespace SWC {
namespace Comm {
41 error, msg.c_str(), msg.length() < INT16_MAX? msg.length() : INT16_MAX)
48 return send_response(cbp);
53 if(!connected || cbuf->expired())
56 write_or_queue(
Outgoing(std::move(cbuf), std::move(hdlr)));
73 <<
' ' << (
is_secure() ?
"SECURE" :
"PLAIN");
99 :
conn(std::move(a_conn)),
cbuf(a_cbuf) {
103 :
conn(std::move(other.conn)),
cbuf(std::move(other.cbuf)) {
109 void operator()(
const asio::error_code& ec, uint32_t bytes) noexcept {
114 conn->app_ctx->net_bytes_sent(
conn, bytes);
130 :
conn(std::move(a_conn)),
132 hdlr(std::move(a_hdlr)) {
136 :
conn(std::move(other.conn)),
137 cbuf(std::move(other.cbuf)),
138 hdlr(std::move(other.hdlr)) {
144 void operator()(
const asio::error_code& ec, uint32_t bytes) noexcept {
149 ev->header.initialize_from_response(
cbuf->header);
152 conn->app_ctx->net_bytes_sent(
conn, bytes);
163 auto cbuf = std::move(outgoing.
cbuf);
164 auto& header = cbuf->header;
195 auto timer = header.timeout_ms
196 ?
new asio::high_resolution_timer(
socket_layer()->get_executor())
211 r.first->second.hdlr = std::move(outgoing.
hdlr);
214 r.first->second.timer = timer;
215 timer->expires_after(
216 std::chrono::milliseconds(header.timeout_ms));
221 noexcept : conn(std::move(a_conn)), cbuf(a_cbuf) { }
223 TimerTask(TimerTask&& other) noexcept
224 : conn(std::move(other.conn)),
225 cbuf(std::move(other.cbuf)) {
227 TimerTask(
const TimerTask&) =
delete;
228 TimerTask&
operator=(TimerTask&&) =
delete;
229 TimerTask&
operator=(
const TimerTask&) =
delete;
230 ~TimerTask() noexcept { }
231 void operator()(
const asio::error_code& ec) {
232 if(ec == asio::error::operation_aborted)
235 ev->header.initialize_from_request(cbuf->header);
237 conn->run_pending(std::move(ev));
240 timer->async_wait(TimerTask(
ptr(), cbuf));
259 :
conn(std::move(a_conn)) { }
262 :
conn(std::move(other.conn)) { }
267 void operator()(
const asio::error_code& ec,
size_t filled) noexcept;
275 :
conn(a_conn),
ev(std::move(a_ev)) { }
278 :
conn(std::move(other.conn)),
ev(std::move(other.ev)) { }
283 void operator()(asio::error_code ec,
size_t filled) noexcept;
291 :
conn(std::move(a_conn)),
ev(std::move(a_ev)) { }
294 :
conn(std::move(other.conn)),
ev(std::move(other.ev)) { }
299 void operator()(asio::error_code ec,
size_t filled) noexcept;
304 const asio::error_code& ec,
size_t filled) noexcept {
306 conn->m_recv_bytes += filled;
312 const uint8_t* buf = conn->_buf_header;
313 ev->header.decode_prefix(&buf, &filled);
315 ev->header.header_len = 0;
318 if(!ev->header.header_len) {
320 "read, REQUEST HEADER_PREFIX_TRUNCATED: remain=" SWC_FMT_LU,
334 conn->do_close_recv();
338 asio::error_code ec,
size_t filled) noexcept {
340 conn->m_recv_bytes += filled;
343 ec = asio::error::eof;
345 filled = ev->header.header_len;
347 const uint8_t* buf = conn->_buf_header;
348 ev->header.decode(&buf, &filled);
350 ec = asio::error::eof;
356 ev->header.header_len);
358 }
else if(ev->header.buffers) {
359 conn->recv_buffers(std::move(ev));
361 conn->received(std::move(ev));
367 conn->do_close_recv();
371 size_t filled) noexcept {
373 conn->m_recv_bytes += filled;
377 if(!ev->data_ext.size) {
381 buffer = &ev->data_ext;
382 checksum = ev->header.data_ext.chksum;
384 if(filled != buffer->
size ||
386 ec = asio::error::eof;
392 << (
bool(ev->data.size) +
bool(ev->data_ext.size)) <<
") ";
396 }
else if(ev->header.buffers ==
bool(ev->data.size) +
397 bool(ev->data_ext.size)) {
398 conn->received(std::move(ev));
400 conn->recv_buffers(std::move(ev));
406 conn->do_close_recv();
426 remain = ev->header.data.
size;
428 buffer = &ev->data_ext;
429 remain = ev->header.data_ext.
size;
433 buffer->
base, remain,
443 run_pending(std::move(ev));
455 app_ctx->net_bytes_received(ptr(), m_recv_bytes);
463 outgoing.hdlr->handle_no_conn();
470 pending = std::move(
m_pending.begin()->second);
474 pending.timer->cancel();
475 pending.hdlr->handle_no_conn();
498 pending.
hdlr = it->second.hdlr;
500 pending = std::move(it->second);
506 pending.
timer->cancel();
516 : conn(std::move(a_conn)),
517 hdlr(std::move(a_hdlr)),
518 ev(std::move(a_ev)) {
521 Task(Task&& other) noexcept
522 : conn(std::move(other.conn)),
523 hdlr(std::move(other.hdlr)),
524 ev(std::move(other.ev)) {
526 Task(
const Task&) =
delete;
531 if(!ev->error && ev->header.buffers)
532 ev->decode_buffers();
533 hdlr->handle(conn, ev);
538 Task(
ptr(), std::move(pending.
hdlr), std::move(ev))
546 : conn(std::move(a_conn)), ev(std::move(a_ev)) { }
548 Task(Task&& other) noexcept
549 : conn(std::move(other.conn)), ev(std::move(other.ev)) { }
550 Task(
const Task&) =
delete;
555 if(!ev->error && ev->header.buffers)
556 ev->decode_buffers();
557 conn->
app_ctx->handle(conn, ev);
560 asio::post(
socket_layer()->get_executor(), Task(
ptr(), std::move(ev)));
576 m_sock(std::move(socket)) {
577 m_sock.lowest_layer().set_option(asio::ip::tcp::no_delay(
true));
605 return &
m_sock.lowest_layer();
608 #pragma GCC diagnostic push
609 #pragma GCC diagnostic ignored "-Wnull-dereference"
610 #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
616 asio::async_write(m_sock, std::move(
buffers), std::move(hdlr));
623 asio::async_write(m_sock, std::move(
buffers), std::move(hdlr));
627 uint8_t*
data, uint32_t sz,
629 asio::async_read(m_sock, asio::mutable_buffer(
data, sz), std::move(hdlr));
633 uint8_t*
data, uint32_t sz,
635 asio::async_read(m_sock, asio::mutable_buffer(
data, sz), std::move(hdlr));
639 uint8_t*
data, uint32_t sz,
641 asio::async_read(m_sock, asio::mutable_buffer(
data, sz), std::move(hdlr));
646 asio::error_code& ec) {
650 asio::mutable_buffer((*bufp)+=
read, *remainp), ec);
651 }
while(!ec && (*remainp -=
read));
654 #pragma GCC diagnostic pop
666 asio::ssl::context& ssl_ctx,
669 m_sock(std::move(socket), ssl_ctx),
670 m_strand(m_sock.get_executor()) {
671 m_sock.lowest_layer().set_option(asio::ip::tcp::no_delay(
true));
677 m_sock.lowest_layer().close(ec);
684 if(
m_sock.lowest_layer().is_open()) {
686 m_sock.lowest_layer().cancel(ec);
688 m_sock.lowest_layer().close(ec);
713 SocketSSL::handshake_type typ,
714 asio::error_code& ec)
720 m_sock.handshake(typ, ec);
724 return &
m_sock.lowest_layer();
727 #pragma GCC diagnostic push
728 #pragma GCC diagnostic ignored "-Wnull-dereference"
729 #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
737 asio::bind_executor(m_strand, std::move(hdlr))
747 asio::bind_executor(m_strand, std::move(hdlr))
752 uint8_t*
data, uint32_t sz,
755 m_sock, asio::mutable_buffer(
data, sz),
756 asio::bind_executor(m_strand, std::move(hdlr))
761 uint8_t*
data, uint32_t sz,
764 m_sock, asio::mutable_buffer(
data, sz),
765 asio::bind_executor(m_strand, std::move(hdlr))
770 uint8_t*
data, uint32_t sz,
773 m_sock, asio::mutable_buffer(
data, sz),
774 asio::bind_executor(m_strand, std::move(hdlr))
780 asio::error_code& ec) {
784 asio::mutable_buffer((*bufp)+=
read, *remainp), ec);
785 }
while(!ec && (*remainp -=
read));
788 #pragma GCC diagnostic pop