diff --git a/changelog b/changelog index 05880533..d66c7fad 100644 --- a/changelog +++ b/changelog @@ -37,6 +37,35 @@ simultaneous post-header connections as you like. Since the http header processing is completed and the allocation released after ESTABLISHED or the HTTP callback, even with a pool of 1 many connections can be handled rapidly. +2) There is a new callback that allows the user code to get acccess to the +optional close code + aux data that may have been sent by the peer. + +LWS_CALLBACK_WS_PEER_INITIATED_CLOSE: + The peer has sent an unsolicited Close WS packet. @in and + @len are the optional close code (first 2 bytes, network + order) and the optional additional information which is not + defined in the standard, and may be a string or non-human- + readble data. + If you return 0 lws will echo the close and then close the + connection. If you return nonzero lws will just close the connection. + +As usual not handling it does the right thing, if you're not interested in it +just ignore it. + +The test server has "open and close" testing buttons at the bottom, if you +open and close that connection, on close it will send a close code 3000 decimal +and the string "Bye!" as the aux data. + +The test server dumb-increment callback handles this callback reason and prints + +lwsts[15714]: LWS_CALLBACK_WS_PEER_INITIATED_CLOSE: len 6 +lwsts[15714]: 0: 0x0B +lwsts[15714]: 1: 0xB8 +lwsts[15714]: 2: 0x42 +lwsts[15714]: 3: 0x79 +lwsts[15714]: 4: 0x65 +lwsts[15714]: 5: 0x21 + User api changes ---------------- diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h index 807087d1..26587b66 100644 --- a/lib/libwebsockets.h +++ b/lib/libwebsockets.h @@ -320,6 +320,7 @@ enum lws_callback_reasons { LWS_CALLBACK_UNLOCK_POLL = 36, LWS_CALLBACK_OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY = 37, + LWS_CALLBACK_WS_PEER_INITIATED_CLOSE = 38, /****** add new things just above ---^ ******/ @@ -1039,6 +1040,16 @@ struct lws_extension; * len == 1 allows external threads to be synchronized against * wsi lifecycle changes if it acquires the same lock for the * duration of wsi dereference from the other thread context. + * + * LWS_CALLBACK_WS_PEER_INITIATED_CLOSE: + * The peer has sent an unsolicited Close WS packet. @in and + * @len are the optional close code (first 2 bytes, network + * order) and the optional additional information which is not + * defined in the standard, and may be a string or non-human- + * readble data. + * If you return 0 lws will echo the close and then close the + * connection. If you return nonzero lws will just close the + * connection. */ LWS_VISIBLE LWS_EXTERN int callback(const struct lws *wsi, enum lws_callback_reasons reason, void *user, diff --git a/lib/parsers.c b/lib/parsers.c index ae6c1db6..adcdc294 100644 --- a/lib/parsers.c +++ b/lib/parsers.c @@ -982,6 +982,7 @@ spill: switch (wsi->u.ws.opcode) { case LWSWSOPC_CLOSE: + /* is this an acknowledgement of our close? */ if (wsi->state == LWSS_AWAITING_CLOSE_ACK) { /* @@ -995,6 +996,15 @@ spill: /* if he sends us 2 CLOSE, kill him */ return -1; + if (user_callback_handle_rxflow( + wsi->protocol->callback, wsi, + LWS_CALLBACK_WS_PEER_INITIATED_CLOSE, + wsi->user_space, + &wsi->u.ws.rx_user_buffer[ + LWS_SEND_BUFFER_PRE_PADDING], + wsi->u.ws.rx_user_buffer_head)) + return -1; + lwsl_parser("server sees client close packet\n"); wsi->state = LWSS_RETURNED_CLOSE_ALREADY; /* deal with the close packet contents as a PONG */ diff --git a/lib/service.c b/lib/service.c index ccb5d1d4..46b924c5 100644 --- a/lib/service.c +++ b/lib/service.c @@ -37,7 +37,7 @@ lws_calllback_as_writeable(struct lws *wsi) n = LWS_CALLBACK_HTTP_WRITEABLE; break; } - lwsl_info("%s: %p (user=%p)\n", __func__, wsi, wsi->user_space); + lwsl_debug("%s: %p (user=%p)\n", __func__, wsi, wsi->user_space); return user_callback_handle_rxflow(wsi->protocol->callback, wsi, (enum lws_callback_reasons) n, wsi->user_space, NULL, 0); diff --git a/test-server/test-server-dumb-increment.c b/test-server/test-server-dumb-increment.c index e83a12be..ef24d502 100644 --- a/test-server/test-server-dumb-increment.c +++ b/test-server/test-server-dumb-increment.c @@ -67,6 +67,20 @@ callback_dumb_increment(struct lws *wsi, enum lws_callback_reasons reason, /* you could return non-zero here and kill the connection */ break; + /* + * this just demonstrates how to handle + * LWS_CALLBACK_WS_PEER_INITIATED_CLOSE and extract the peer's close + * code and auxiliary data. You can just not handle it if you don't + * have a use for this. + */ + case LWS_CALLBACK_WS_PEER_INITIATED_CLOSE: + lwsl_notice("LWS_CALLBACK_WS_PEER_INITIATED_CLOSE: len %d\n", + len); + for (n = 0; n < (int)len; n++) + lwsl_notice(" %d: 0x%02X\n", n, + ((unsigned char *)in)[n]); + break; + default: break; } diff --git a/test-server/test.html b/test-server/test.html index b9e48612..f773d154 100644 --- a/test-server/test.html +++ b/test-server/test.html @@ -325,7 +325,7 @@ function ot_open() { } function ot_close() { - socket_ot.close(); + socket_ot.close(3000, "Bye!"); } /* lws-mirror protocol */